/// <summary> /// Gets the audio samples of each object for the next timeslot. /// </summary> public float[][] Apply(float[][] input, JointObjectCoding actual) { if (timeslot == 0) { mixMatrix = actual.GetMixingMatrices(frameSize); } // Forward transformations int runs = actual.ChannelCount; using (ManualResetEvent reset = new ManualResetEvent(false)) { for (int ch = 0; ch < actual.ChannelCount; ++ch) { ThreadPool.QueueUserWorkItem( new WaitCallback(channel => { int ch = (int)channel; results[ch] = converters[ch].ProcessForward(input[ch]); if (Interlocked.Decrement(ref runs) == 0) { reset.Set(); } }), ch); } reset.WaitOne(); } // Inverse transformations runs = objects; using (ManualResetEvent reset = new ManualResetEvent(false)) { for (int obj = 0; obj < objects; ++obj) { ThreadPool.QueueUserWorkItem( new WaitCallback(objectId => { int obj = (int)objectId; ProcessObject(actual, obj, mixMatrix[obj][timeslot], actual.Gain); if (Interlocked.Decrement(ref runs) == 0) { reset.Set(); } }), obj); } reset.WaitOne(); } if (++timeslot == input.Length) { timeslot = 0; } return(timeslotCache); }
void ProcessObject(JointObjectCoding joc, int obj, float[][] mixMatrix, float gain) { Array.Clear(qmfbCache[obj], 0, QuadratureMirrorFilterBank.subbands); Vector2[] objCache = qmfbCache[obj]; for (int ch = 0; ch < joc.ChannelCount; ++ch) { Vector2[] channelResult = results[ch]; float[] channelMatrix = mixMatrix[ch]; for (int sb = 0; sb < QuadratureMirrorFilterBank.subbands; ++sb) { objCache[sb] += channelResult[sb] * channelMatrix[sb]; } } converters[obj].ProcessInverse(qmfbCache[obj], timeslotCache[obj]); if (gain != 1) { WaveformUtils.Gain(timeslotCache[obj], gain); } }