/// <summary>
        /// Initializes the decoder with a MP4 decoder specific info.
        ///
        /// After this the MP4 frames can be passed to the
        /// <code>decodeFrame(byte[], SampleBuffer)</code> method to decode them.
        /// </summary>
        /// <param name="decoderSpecificInfo">decoderSpecificInfo a byte array containing the decoder specific info from an MP4 container</param>
        public Decoder(byte[] decoderSpecificInfo)
        {
            config = DecoderConfig.parseMP4DecoderSpecificInfo(decoderSpecificInfo);
            if (config == null)
            {
                throw new ArgumentException("illegal MP4 decoder specific info");
            }

            if (!canDecode(config.getProfile()))
            {
                throw new AACException("unsupported profile: " + config.getProfile());
            }

            syntacticElements = new SyntacticElements(config);
            filterBank        = new FilterBank(config.isSmallFrameUsed(), (int)config.getChannelConfiguration());

            Logger.LogInfo(string.Format("profile: {0}", config.getProfile()));
            Logger.LogInfo(string.Format("sf: {0}", config.getSampleFrequency().getFrequency()));
            Logger.LogInfo(string.Format("channels: {0}", config.getChannelConfiguration()));
        }
        //private void decodeCCE(BitStream in) throws AACException {
        //if(curCCE==MAX_ELEMENTS) throw new AACException("too much CCE elements");
        //if(cces[curCCE]==null) cces[curCCE] = new CCE(config.getFrameLength());
        //cces[curCCE].decode(in, config);
        //curCCE++;
        //}

        //private void decodeDSE(BitStream in) throws AACException {
        //if(curDSE==MAX_ELEMENTS) throw new AACException("too much CCE elements");
        //if(dses[curDSE]==null) dses[curDSE] = new DSE();
        //dses[curDSE].decode(in);
        //curDSE++;
        //}

        //private void decodePCE(BitStream in) throws AACException {
        //pce.decode(in);
        //config.setProfile(pce.getProfile());
        //config.setSampleFrequency(pce.getSampleFrequency());
        //config.setChannelConfiguration(ChannelConfiguration.forInt(pce.getChannelCount()));
        //}

        //private void decodeFIL(BitStream in, Element prev) throws AACException {
        //if(curFIL==MAX_ELEMENTS) throw new AACException("too much FIL elements");
        //if(fils[curFIL]==null) fils[curFIL] = new FIL(config.isSBRDownSampled());
        //fils[curFIL].decode(in, prev, config.getSampleFrequency(), config.isSBREnabled(), config.isSmallFrameUsed());
        //curFIL++;

        //if(prev!=null&&prev.isSBRPresent()) {
        //sbrPresent = true;
        //if(!psPresent&&prev.getSBR().isPSUsed()) psPresent = true;
        //}
        //}

        public void process(FilterBank filterBank)
        {
            Profile         profile = config.getProfile();
            SampleFrequency sf      = config.getSampleFrequency();
            //ChannelConfiguration channels = config.getChannelConfiguration();

            int chs = (int)config.getChannelConfiguration();

            if (chs == 1 && psPresent)
            {
                chs++;
            }
            int mult = sbrPresent ? 2 : 1;

            //only reallocate if needed
            if (data == null || chs != data.Length || (mult * config.getFrameLength()) != data[0].Length)
            {
                data = Enumerable.Range(0, chs).Select(x => new float[mult * config.getFrameLength()]).ToArray();
            }

            int     channel = 0;
            Element e;
            SCE_LFE scelfe;
            CPE     cpe;

            for (int i = 0; i < elements.Length && channel < chs; i++)
            {
                e = elements[i];
                if (e == null)
                {
                    continue;
                }
                if (e is SCE_LFE)
                {
                    scelfe = (SCE_LFE)e;
                    throw new NotImplementedException();
                    // channel += processSingle(scelfe, filterBank, channel, profile, sf);
                }
                else if (e is CPE)
                {
                    cpe = (CPE)e;
                    processPair(cpe, filterBank, channel, profile, sf);
                    channel += 2;
                }
                else if (e is CCE)
                {
                    //applies invquant and save the result in the CCE
                    throw new NotImplementedException();
                    // ((CCE)e).process();
                    channel++;
                }
            }
        }
Пример #3
0
        //  /* ========= decoding ========== */
        public void decode(BitStream inStream, bool commonWindow, DecoderConfig conf)
        {
            if (conf.isScalefactorResilienceUsed() && rvlc == null)
            {
                rvlc = new RVLC();
            }
            bool er = conf.getProfile().isErrorResilientProfile();

            globalGain = inStream.readBits(8);

            if (!commonWindow)
            {
                info.decode(inStream, conf, commonWindow);
            }

            decodeSectionData(inStream, conf.isSectionDataResilienceUsed());

            //if(conf.isScalefactorResilienceUsed()) rvlc.decode(in, this, scaleFactors);
            /*else*/
            decodeScaleFactors(inStream);

            pulseDataPresent = inStream.readBool();
            if (pulseDataPresent)
            {
                if (info.isEightShortFrame())
                {
                    throw new AACException("pulse data not allowed for short frames");
                }
                Logger.LogInfo("PULSE");
                throw new NotImplementedException();
                //decodePulseData(inStream);
            }

            tnsDataPresent = inStream.readBool();
            if (tnsDataPresent && !er)
            {
                if (tns == null)
                {
                    tns = new TNS();
                }
                tns.decode(inStream, info);
            }

            gainControlPresent = inStream.readBool();
            if (gainControlPresent)
            {
                if (gainControl == null)
                {
                    gainControl = new GainControl(frameLength);
                }
                Logger.LogInfo("GAIN");
                throw new NotImplementedException();
                // gainControl.decode(inStream, info.getWindowSequence());
            }

            //RVLC spectral data
            //if(conf.isScalefactorResilienceUsed()) rvlc.decodeScalefactors(this, in, scaleFactors);

            if (conf.isSpectralDataResilienceUsed())
            {
                int max = (conf.getChannelConfiguration() == ChannelConfiguration.CHANNEL_CONFIG_STEREO) ? 6144 : 12288;
                reorderedSpectralDataLen = Math.Max(inStream.readBits(14), max);
                longestCodewordLen       = Math.Max(inStream.readBits(6), 49);
                //HCR.decodeReorderedSpectralData(this, in, data, conf.isSectionDataResilienceUsed());
            }
            else
            {
                decodeSpectralData(inStream);
            }
        }