NorskTransform.audioMixMatrix() method

Given an audio stream of N channels, mix it down to M channels through a matrix of NxM gains.

Signature:

audioMixMatrix(settings: AudioMixMatrixSettings): Promise<AudioMixMatrixNode>;

Parameters

Parameter Type Description

settings

AudioMixMatrixSettings

Settings for the mixer, including the gain matrix

Returns:

Example [11_matrix_mixer.ts]

Downmix a 5.1 layout received over RTP to stereo and vary the mix over time

// Matrix mixer, downmix a 5.1 layout to stereo
export async function main() {
  const norsk = await Norsk.connect();

  const input = await norsk.input.rtp(rtpInputSettings);
  const matrixMixer = await norsk.processor.transform.audioMixMatrix(
    initialMixerSettings
  );
  const audioOutput = await norsk.output.cmafAudio(hlsAudioSettings);

  matrixMixer.subscribe([{ source: input, sourceSelector: selectAudio }]);
  audioOutput.subscribe([{ source: matrixMixer, sourceSelector: selectAudio }]);

  void audioOutput.url().then((playlistUrl) => {
    console.log(`playlistUrl: ${playlistUrl}`);
  });

  // Update gains every 3s
  let wasPreviousA = true;
  setInterval(function() {
    let newMixerConfig: AudioMixMatrixSettingsUpdate;
    if (wasPreviousA) {
      newMixerConfig = { channelGains: mixB };
      wasPreviousA = false;
    } else {
      newMixerConfig = { channelGains: mixA };
      wasPreviousA = true;
    }
    console.log("Apply mixer config:", newMixerConfig);
    matrixMixer.updateConfig(newMixerConfig);
  }, 3000);
}

const mixA: Gain[][] = [
  [0.0, null, -6.0, null, -9.0, null],
  [null, 0.0, null, -6.0, null, -9.0],
];

const mixB: Gain[][] = [
  [null, 0.0, null, -6.0, null, -9.0],
  [0.0, null, -6.0, null, -9.0, null],
];

const initialMixerSettings: AudioMixMatrixSettings = {
  id: "mixer",
  outputChannelLayout: "stereo",
  channelGains: mixA,
};

const hlsAudioSettings: CmafOutputSettings = {
  id: "hls-audio",
  partDurationSeconds: 1.0,
  segmentDurationSeconds: 4.0,
  destinations: [{ type: "local", retentionPeriodSeconds: 60, id: "local" }],
};

const rtpInputSettings: RtpInputSettings = {
  id: "rtp",
  onError: (err) => console.log("RTP INGEST ERR", err),
  sourceName: "rtp1",
  streams: [
    {
      ip: "0.0.0.0",
      rtpPort: 5001,
      rtcpPort: 5002,
      interface: "any",
      streamId: 1,
      streamType: {
        kind: "linearpcm",
        bitDepth: 24,
        sampleRate: 48000,
        channelLayout: "5.1",
      },
    },
  ],
};

Run the following command to generate example input at url rtp://127.0.0.1:5001:

ffmpeg -v error -re -f lavfi -i "testsrc[out0];sine=frequency=220:sample_rate=48000[out1]" -re -f lavfi -i "testsrc[out0];sine=frequency=275:sample_rate=48000[out1]" -re -f lavfi -i "testsrc[out0];sine=frequency=660:sample_rate=48000[out1]" -re -f lavfi -i "testsrc[out0];sine=frequency=440:sample_rate=48000[out1]" -re -f lavfi -i "testsrc[out0];sine=frequency=550:sample_rate=48000[out1]" -re -f lavfi -i "testsrc[out0];sine=frequency=1320:sample_rate=48000[out1]"  -filter_complex "[0:a][1:a][2:a][3:a][4:a][5:a]join=inputs=6:channel_layout=5.1:map=0.0-FL|1.0-FR|2.0-FC|3.0-LFE|4.0-BL|5.0-BR[a]" -map "[a]" -c:a pcm_s24be -f rtp 'rtp://127.0.0.1:5001'

Find Examples