1

I have to decode a stereo mp4 file and map the L and R channel to 5.1 or 7.1 surround. In addition I have to provide a specific output format: 16bit pcm 44.1kHz. Its no problem to convert the audio source to 44100Hz 16bit. The only problem is the channel mixing. I've got the following coding:

const string filename = @"stereo.mp3";
IWaveSource waveSource = CodecFactory.Instance.GetCodec(filename)
    .AppendSource(x => new CSCore.Streams.CachedSoundSource(x))
    .ChangeSampleRate(44100) //44.1kHz
    .ToSampleSource()
    .ToWaveSource(16); //16bit

The official project page here: http://cscore.codeplex.com/ tells me that channel mixing is possible. I've found the CSCore.DSP.ChannelMatrix class but its pretty hard to figure out how to use it. Maybe someone could help me out?

john green
  • 11
  • 1

1 Answers1

1

You are absolutely right, you have to use the CSCore.DSP.ChannelMatrix class. I've created a little example for you and added some comments. It should be pretty much self explaining:

static void Main(string[] args)
{
    const string filename = @"stereo.mp3";

    /*
     * First of all you need a channel matrix that fits your needs.
     * There are many ways to get one...:
     */

    //Simply use one of the predefined...
    ChannelMatrix channelMatrix = ChannelMatrix.StereoToSevenDotOneSurround;

    //or

    //use some kind of factory to get one
    channelMatrix = ChannelMatrix.GetMatrix(
        ChannelMasks.StereoMask,
        ChannelMasks.SevenDotOneMask);

    //or

    //or create your own one (the matrix below equals the two above but of course you can use custom values)
    //the rows represent your input channels (the stereo signal) and the columns your output channels.
    //specify with a value from 0-1 how much percentage of the L (row index 0) or the R (row index 1) channel
    //you want to apply to the specific column (the columns are getting mapped to the output channel mask
    // -> the SevenDotOneMask ordered by the values of the certain flags inside of the channel mask).
    channelMatrix = new ChannelMatrix(
        ChannelMasks.StereoMask,
        ChannelMasks.SevenDotOneMask);
    channelMatrix.SetMatrix(
        new[,]
        {
            {0.222f, 0f, 0.157f, 0.022f, 0.189f, 0.116f, 0.203f, 0.090f},
            {0f, 0.222f, 0.157f, 0.022f, 0.116f, 0.189f, 0.090f, 0.203f}
        });

    IWaveSource waveSource = CodecFactory.Instance.GetCodec(filename)
        .AppendSource(x => new CSCore.Streams.CachedSoundSource(x))
        .ChangeSampleRate(44100) //44.1kHz
        .AppendSource(x => new DmoChannelResampler(x, channelMatrix)) //append a channelresampler with the channelmatrix
        .ToSampleSource()
        .ToWaveSource(16); //16bit

    ...
}

I would strongly recommend you to use a predefined channel matrix. Of course, if you need some custom values define your own like in the example above.

Btw. you can also change the channel matrix in realtime: Simply make your changes to the channelMatrix and after that call CommitChannelMatrixChanges (of course you would have to store the DmoChannelResampler instance -> do that by using the out parameter of the AppendSource method).

Florian
  • 5,918
  • 3
  • 47
  • 86