Exemplo n.º 1
0
        /// <summary>
        /// Pull from all our input pins, then combine, then subtract
        /// </summary>
        /// <param name="tsElapsed"></param>
        void DoPushPull(TimeSpan tsElapsed)
        {
            lock (PushPullLock)
            {
                PushPullObject[] members = null;
                lock (MemberLock)
                {
                    members = Members.ToArray();
                }

                if (members.Length <= 0)
                {
                    return;
                }

                Dictionary <IAudioSource, short[]> InputSamples = new Dictionary <IAudioSource, short[]>();

                /// Convert our short data to int so we don't during addition
                // int[] combinedint = Utils.MakeIntArrayFromShortArray(sInitialData);
                int[] combinedint = new int[AudioFormat.CalculateNumberOfSamplesForDuration(tsElapsed)];


                ///Sum the input data from all our input sources, storing the data for each source so we can subtract it when sending
                foreach (PushPullObject nextobj in members)
                {
                    if (nextobj.AudioSource == null)
                    {
                        continue;
                    }

                    // Always pull data from a source even if it's not active, because some just queue their buffers
                    MediaSample sample = nextobj.AudioSource.PullSample(AudioFormat, tsElapsed);
                    if (sample == null)
                    {
                        continue;
                    }

                    if (nextobj.AudioSource.IsSourceActive == false)
                    {
                        continue;
                    }

                    short[] sData = sample.GetShortData();

                    /// Amplify our data if told to
                    if (nextobj.AudioSource.SourceAmplitudeMultiplier != 1.0f)
                    {
                        for (int i = 0; i < sData.Length; i++)
                        {
                            sData[i] = (short)(nextobj.AudioSource.SourceAmplitudeMultiplier * sData[i]);
                        }
                    }

                    InputSamples.Add(nextobj.AudioSource, sData);

                    Utils.SumArrays(combinedint, sData);
                }

                /// Push data to all our output filters, subtracting the data this member supplied
                foreach (PushPullObject nextobj in members)
                {
                    if (nextobj.AudioSink == null)
                    {
                        continue;
                    }

                    if (nextobj.AudioSink.IsSinkActive == false)
                    {
                        continue;
                    }

                    /// copy the summed data so we don't mangle it for the next client
                    int[] nCopy = new int[combinedint.Length];
                    Array.Copy(combinedint, nCopy, nCopy.Length);

                    foreach (IAudioSource excludesource in nextobj.SourceExcludeList)
                    {
                        if (InputSamples.ContainsKey(excludesource) == true)  // If we are in the dictionary, we are not muted, so no need to subtract
                        {
                            short[] sData = InputSamples[excludesource];
                            Utils.SubtractArray(nCopy, sData);
                        }
                    }


                    /// Amplify our data if told to
                    if (nextobj.AudioSink.SinkAmplitudeMultiplier != 1.0f)
                    {
                        for (int i = 0; i < nCopy.Length; i++)
                        {
                            nCopy[i] = (int)(nextobj.AudioSink.SinkAmplitudeMultiplier * nCopy[i]);
                        }
                    }


                    //short[] sOutput = Utils.MakeShortArrayFromIntArray(nCopy);
                    short[] sOutput = Utils.AGCAndShortArray(nCopy, short.MaxValue);


                    MediaSample outputsample = new MediaSample(sOutput, AudioFormat);
                    nextobj.AudioSink.PushSample(outputsample, this);
                }
            }
        }