예제 #1
0
 /// <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);
     }
 }
예제 #2
0
        /// <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);
                }
            }
        }