コード例 #1
0
ファイル: AudioData.cs プロジェクト: cruuud/GotaSoundIO
        /// <summary>
        /// Mix the audio data to stereo. This also converts the format to PCM32Float.
        /// </summary>
        /// <param name="mutes">Channels to mute.</param>
        /// <param name="isRightChannel">If a channel is to be on the right.</param>
        /// <param name="isBoth">If channel is both.</param>
        public void MixToStereo(bool[] mutes = null, bool[] isRightChannel = null, bool[] isBoth = null)
        {
            //Test.
            if (Channels.Count < 3 && mutes == null)
            {
                return;
            }

            //Get data.
            if (mutes == null)
            {
                mutes = new bool[Channels.Count];
            }
            if (isRightChannel == null)
            {
                isRightChannel = new bool[Channels.Count];
                for (int i = 0; i < Channels.Count; i++)
                {
                    if (i % 2 == 1)
                    {
                        isRightChannel[i] = true;
                    }
                }
            }
            if (isBoth == null)
            {
                isBoth = new bool[Channels.Count];
                if (Channels.Count % 2 != 0)
                {
                    isBoth[Channels.Count - 1] = true;
                }
            }

            //Test.
            if (Channels.Count == 0 || mutes.Where(x => false).Count() == 0)
            {
                return;
            }

            //Organize tracks.
            List <int> lefts  = new List <int>();
            List <int> rights = new List <int>();

            for (int i = 0; i < mutes.Length; i++)
            {
                if (!mutes[i])
                {
                    if (isBoth[i])
                    {
                        lefts.Add(i);
                        rights.Add(i);
                    }
                    else if (isRightChannel[i])
                    {
                        rights.Add(i);
                    }
                    else
                    {
                        lefts.Add(i);
                    }
                }
            }

            //Convert data.
            Convert(typeof(PCM32Float), BlockSamples);

            //Get divisors.
            double divL = 1 / Math.Sqrt(lefts.Count);
            double divR = 1 / Math.Sqrt(rights.Count);

            //Start mixing.
            List <IAudioEncoding> left  = new List <IAudioEncoding>();
            List <IAudioEncoding> right = new List <IAudioEncoding>();

            for (int i = 0; i < NumBlocks; i++)
            {
                List <float>   samplesL = new List <float>();
                List <float>   samplesR = new List <float>();
                IAudioEncoding blockL   = new PCM32Float();
                IAudioEncoding blockR   = new PCM32Float();
                for (int j = 0; j < Channels[0][i].SampleCount(); j++)
                {
                    double sampleL = 0;
                    double sampleR = 0;
                    for (int k = 0; k < Channels.Count; k++)
                    {
                        if (!mutes[k])
                        {
                            if (lefts.Contains(k))
                            {
                                sampleL += Channels[k][i].ToFloatPCM()[j];
                            }
                            if (rights.Contains(k))
                            {
                                sampleR += Channels[k][i].ToFloatPCM()[j];
                            }
                        }
                    }
                    sampleL /= divL;
                    if (sampleL > 1)
                    {
                        sampleL = 1;
                    }
                    if (sampleL < -1)
                    {
                        sampleL = -1;
                    }
                    samplesL.Add((float)sampleL);
                    sampleR /= divR;
                    if (sampleR > 1)
                    {
                        sampleR = 1;
                    }
                    if (sampleR < -1)
                    {
                        sampleR = -1;
                    }
                    samplesR.Add((float)sampleR);
                }
                blockL.FromFloatPCM(samplesL.ToArray());
                blockR.FromFloatPCM(samplesR.ToArray());
                left.Add(blockL);
                right.Add(blockR);
            }

            //Set data.
            Channels.Clear();
            Channels.Add(left);
            Channels.Add(right);
        }
コード例 #2
0
ファイル: AudioData.cs プロジェクト: cruuud/GotaSoundIO
        /// <summary>
        /// Mix the audio data to mono. This also converts the format to PCM32Float. This does not support muting everything.
        /// </summary>
        /// <param name="mutes">Channels to mute.</param>
        public void MixToMono(bool[] mutes = null)
        {
            //Test.
            if (Channels.Count < 2 && mutes == null)
            {
                return;
            }

            //Get mutes.
            if (mutes == null)
            {
                mutes = new bool[Channels.Count];
            }

            //Test.
            if (Channels.Count == 0 || mutes.Where(x => x == false).Count() == 0)
            {
                return;
            }

            //Divisor to make audio not loud.
            double divisor = 1 / Math.Sqrt(mutes.Where(x => x == false).Count());

            //Convert data.
            Convert(typeof(PCM32Float), BlockSamples);

            //Start mixing.
            List <IAudioEncoding> newData = new List <IAudioEncoding>();

            for (int i = 0; i < NumBlocks; i++)
            {
                List <float>   samples = new List <float>();
                IAudioEncoding block   = new PCM32Float();
                for (int j = 0; j < Channels[0][i].SampleCount(); j++)
                {
                    double sample = 0;
                    for (int k = 0; k < Channels.Count; k++)
                    {
                        if (!mutes[k])
                        {
                            sample += Channels[k][i].ToFloatPCM()[j];
                        }
                    }
                    sample /= divisor;
                    if (sample > 1)
                    {
                        sample = 1;
                    }
                    if (sample < -1)
                    {
                        sample = -1;
                    }
                    samples.Add((float)sample);
                }
                block.FromFloatPCM(samples.ToArray());
                newData.Add(block);
            }

            //Set data.
            Channels.Clear();
            Channels.Add(newData);
        }