/// <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); } } }