/// <summary> /// Parse an E-AC-3 decoder to a renderer. /// </summary> public EnhancedAC3Renderer(EnhancedAC3Decoder stream) : base(stream) { // Object-based rendering if (HasObjects = stream.Extensions.HasObjects) { ObjectAudioMetadata oamd = stream.Extensions.OAMD; JointObjectCoding joc = stream.Extensions.JOC; DynamicObjects = joc.ObjectCount; finalResult = new float[joc.ObjectCount][]; applier = new JointObjectCodingApplier(joc.ObjectCount, stream.FrameSize); SetupObjects(oamd.ObjectCount); } // Channel-based rendering else { ReferenceChannel[] channels = stream.GetChannels(); for (int channel = 0; channel < channels.Length; ++channel) { Source source = new StreamMasterSource(reader, channel) { Position = channelPositions[(int)channels[channel]] * Listener.EnvironmentSize }; objects.Add(source); } finalResult = new float[channels.Length][]; FinishSetup(channels.Length); } }
/// <summary> /// Render new object samples for the next timeslot /// </summary> void RenderNextTimeslot() { float[] input = new float[QuadratureMirrorFilterBank.subbands * stream.ChannelCount]; stream.DecodeBlock(input, 0, input.LongLength); Source?.ReadBlock(input, 0, input.LongLength); WaveformUtils.InterlacedToMultichannel(input, inputData); ReferenceChannel[] matrix = ChannelPrototype.GetStandardMatrix(stream.ChannelCount); EnhancedAC3Decoder decoder = (EnhancedAC3Decoder)stream; // Object-based rendering if (HasObjects = decoder.Extensions.HasObjects) { decoder.Extensions.OAMD.UpdateSources(decoder.LastFetchStart / stream.ChannelCount, objects); float[][] sources = new float[JointObjectCodingTables.inputMatrix.Length][]; for (int i = 0; i < sources.Length; ++i) { for (int j = 0; j < matrix.Length; ++j) { if (JointObjectCodingTables.inputMatrix[i] == matrix[j]) { sources[i] = inputData[j]; break; } } } for (int i = 0; i < matrix.Length; ++i) { if (matrix[i] == ReferenceChannel.ScreenLFE) { lfeTimeslot = inputData[i]; } } timeslotResult = applier.Apply(sources, decoder.Extensions.JOC); } // Channel-based rendering or fallback to it when OAMD or JOC can't be decoded correctly else { for (int i = 0; i < matrix.Length; ++i) { timeslotResult[i] = inputData[i]; objects[i].Position = channelPositions[(int)matrix[i]] * Listener.EnvironmentSize; if (ChannelPrototype.Mapping[(int)matrix[i]].LFE) // LFE is handled elsewhere { objects[i].Position = default; Array.Clear(timeslotResult[i], 0, timeslotResult[i].Length); } } for (int i = matrix.Length; i < timeslotResult.Length; ++i) { objects[i].Position = default; Array.Clear(timeslotResult[i], 0, timeslotResult[i].Length); } } }