/// <summary>
        ///     Flips the axis of the matrix and returns the new matrix with the flipped axis.
        /// </summary>
        /// <returns>A matrix with flipped axis.</returns>
        /// <remarks>
        ///     This could be typically used in the following scenario: There is a
        ///     5.1 to stereo matrix. By using the <see cref="Flip" /> method the 5.1 to stereo matrix can be
        ///     converted into a stereo to 5.1 matrix.
        /// </remarks>
        public ChannelMatrix Flip()
        {
            var result = new ChannelMatrix(OutputMask, InputMask);

            for (int x = 0; x < OutputChannelCount; x++)
            {
                for (int y = 0; y < InputChannelCount; y++)
                {
                    ChannelMatrixElement input = this[y, x];
                    result[x, y] = new ChannelMatrixElement(input.OutputChannel, input.InputChannel)
                    {
                        Value = input.Value
                    };
                }
            }
            return(result);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DmoChannelResampler"/> class.
        /// </summary>
        /// <param name="source">Underlying source which has to get resampled.</param>
        /// <param name="channelMatrix"><see cref="ChannelMatrix" /> which defines how to map each channel.</param>
        /// <param name="outputFormat">Waveformat, which specifies the new format. Note, that by far not all formats are supported.</param>
        /// <exception cref="System.ArgumentNullException">
        /// source
        /// or
        /// channelMatrix
        /// or
        /// outputFormat
        /// </exception>
        /// <exception cref="System.ArgumentException">The number of channels of the source has to be equal to the number of input channels specified by the channelMatrix.</exception>
        public DmoChannelResampler(IWaveSource source, ChannelMatrix channelMatrix, WaveFormat outputFormat)
            : base(source, outputFormat)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (channelMatrix == null)
            {
                throw new ArgumentNullException("channelMatrix");
            }
            if (outputFormat == null)
            {
                throw new ArgumentNullException("outputFormat");
            }

            if (source.WaveFormat.Channels != channelMatrix.InputChannelCount)
            {
                throw new ArgumentException(
                          "The number of channels of the source has to be equal to the number of input channels specified by the channelMatrix.");
            }

            var inputFormat = new WaveFormatExtensible(
                source.WaveFormat.SampleRate,
                source.WaveFormat.BitsPerSample,
                source.WaveFormat.Channels,
                WaveFormatExtensible.SubTypeFromWaveFormat(source.WaveFormat),
                channelMatrix.InputMask);

            Outputformat = new WaveFormatExtensible(
                outputFormat.SampleRate,
                outputFormat.BitsPerSample,
                outputFormat.Channels,
                WaveFormatExtensible.SubTypeFromWaveFormat(outputFormat),
                channelMatrix.OutputMask);

            Initialize(inputFormat, Outputformat);
            _channelMatrix = channelMatrix;
            CommitChannelMatrixChanges();
        }
 public FactoryEntry(ChannelMask input, ChannelMask output, ChannelMatrix matrix)
 {
     Input  = input;
     Output = output;
     Matrix = matrix;
 }
        static ChannelMatrix()
        {
            StereoToFiveDotOneSurroundWithRear = new ChannelMatrix(
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight,
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight |
                ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency |
                ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight);
            StereoToFiveDotOneSurroundWithRear.SetMatrix(
                new[, ]
            {
                { 0.314f, 0f, 0.222f, 0.031f, 0.268f, 0.164f },  //left      - input
                { 0f, 0.314f, 0.222f, 0.031f, 0.164f, 0.268f }   //right     - output
            });
            FiveDotOneSurroundWithRearToStereo = StereoToFiveDotOneSurroundWithRear.Flip();

            StereoToFiveDotOneSurroundWithSide = new ChannelMatrix(
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight,
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight |
                ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency |
                ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight);
            StereoToFiveDotOneSurroundWithSide.SetMatrix(
                new[, ]
            {
                { 0.320f, 0f, 0.226f, 0.032f, 0.292f, 0.130f },
                { 0f, 0.320f, 0.226f, 0.032f, 0.130f, 0.292f }
            });
            FiveDotOneSurroundWithSideToStereo = StereoToFiveDotOneSurroundWithSide.Flip();

            StereoToSevenDotOneSurround = new ChannelMatrix(
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight,
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight |
                ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency |
                ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight |
                ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight);
            StereoToSevenDotOneSurround.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 }
            });
            SevenDotOneSurroundToStereo = StereoToSevenDotOneSurround.Flip();

            //--

            MonoToFiveDotOneSurroundWithRear = new ChannelMatrix(
                ChannelMask.SpeakerFrontCenter,
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight |
                ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency |
                ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight);
            MonoToFiveDotOneSurroundWithRear.SetMatrix(
                new[, ]
            {
                { 0.192f, 0.192f, 0.192f, 0.038f, 0.192f, 0.192f }
            });
            FiveDotOneSurroundWithRearToMono = MonoToFiveDotOneSurroundWithRear.Flip();

            MonoToFiveDotOneSurroundWithSide = new ChannelMatrix(
                ChannelMask.SpeakerFrontCenter,
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight |
                ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency |
                ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight);
            MonoToFiveDotOneSurroundWithSide.SetMatrix(
                new[, ]
            {
                { 0.192f, 0.192f, 0.192f, 0.038f, 0.192f, 0.192f }
            });
            FiveDotOneSurroundWithSideToMono = MonoToFiveDotOneSurroundWithSide.Flip();

            MonoToSevenDotOneSurround = new ChannelMatrix(
                ChannelMask.SpeakerFrontCenter,
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight |
                ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency |
                ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight |
                ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight);
            MonoToSevenDotOneSurround.SetMatrix(
                new[, ]
            {
                { 0.139f, 0.139f, 0.139f, 0.028f, 0.139f, 0.139f, 0.139f, 0.139f }
            });
            SevenDotOneSurroundToMono = MonoToSevenDotOneSurround.Flip();

            //--
            FiveDotOneSurroundWithRearToSevenDotOne = new ChannelMatrix(
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight |
                ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency |
                ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight,
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight |
                ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency |
                ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight |
                ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight);
            FiveDotOneSurroundWithRearToSevenDotOne.SetMatrix(
                new[, ]
            {
                { 0.518f, 0f, 0f, 0f, 0f, 0f, 0.189f, 0f },
                { 0f, 0.518f, 0f, 0f, 0f, 0f, 0f, 0.189f },
                { 0f, 0f, 0.518f, 0f, 0f, 0f, 0f, 0f },
                { 0f, 0f, 0f, 0.518f, 0f, 0f, 0f, 0f },
                { 0f, 0f, 0f, 0f, 0.518f, 0f, 0.482f, 0f },
                { 0f, 0f, 0f, 0f, 0f, 0.518f, 0f, 0.482f }
            });
            SevenDotOneSurroundToFiveDotOneSurroundWithRear = FiveDotOneSurroundWithRearToSevenDotOne.Flip();

            FiveDotOneSurroundWithSideToSevenDotOne = new ChannelMatrix(
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight |
                ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency |
                ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight,
                ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight |
                ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency |
                ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight |
                ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight);
            FiveDotOneSurroundWithSideToSevenDotOne.SetMatrix(
                new[, ]
            {
                { 0.447f, 0f, 0f, 0f, 0f, 0f, 0f, 0f },
                { 0f, 0.447f, 0f, 0f, 0f, 0f, 0f, 0f },
                { 0f, 0f, 0.447f, 0f, 0f, 0f, 0f, 0f },
                { 0f, 0f, 0f, 0.447f, 0f, 0f, 0f, 0f },
                { 0f, 0f, 0f, 0f, 0.429f, 0.124f, 0.447f, 0f },
                { 0f, 0f, 0f, 0f, 0.124f, 0.429f, 0f, 0.447f }
            });
            SevenDotOneSurroundToFiveDotOneSurroundWithSide = FiveDotOneSurroundWithSideToSevenDotOne.Flip();


            StereoToMonoMatrix = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight,
                                                   ChannelMask.SpeakerFrontCenter);
            StereoToMonoMatrix.SetMatrix(
                new[, ]
            {
                { 0.5f },  //left
                { 0.5f }   //right
            });

            MonoToStereoMatrix = new ChannelMatrix(ChannelMask.SpeakerFrontCenter,
                                                   ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight);
            MonoToStereoMatrix.SetMatrix(
                new[, ]
            {
                //left|right
                { 1f, 1f }   //mono
            });
        }
        private static WaveFormat GetOutputWaveFormat(IWaveSource source, int sampleRate, ChannelMatrix channelMatrix)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (channelMatrix == null)
            {
                throw new ArgumentNullException("channelMatrix");
            }

            var waveFormat = channelMatrix.BuildOutputWaveFormat(source);

            waveFormat.SampleRate = sampleRate;
            return(waveFormat);
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="DmoChannelResampler" /> class.
 /// </summary>
 /// <param name="source">Underlying source which has to get resampled.</param>
 /// <param name="channelMatrix"><see cref="ChannelMatrix" /> which defines how to map each channel.</param>
 /// <param name="destinationSampleRate">The destination sample rate.</param>
 public DmoChannelResampler(IWaveSource source, ChannelMatrix channelMatrix, int destinationSampleRate)
     : this(source, channelMatrix, GetOutputWaveFormat(source, destinationSampleRate, channelMatrix))
 {
 }
 /// <summary>
 ///     Initializes a new instance of the <see cref="DmoChannelResampler" /> class.
 /// </summary>
 /// <param name="source">Underlying source which has to get resampled.</param>
 /// <param name="channelMatrix"><see cref="ChannelMatrix" /> which defines how to map each channel.</param>
 public DmoChannelResampler(IWaveSource source, ChannelMatrix channelMatrix)
     : this(source, channelMatrix, source.WaveFormat.SampleRate)
 {
 }