/// <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())); }
void decode(SampleBuffer buffer) { if (ADIFHeader.isPresent(inStream)) { adifHeader = ADIFHeader.readHeader(inStream); var pce = adifHeader.getFirstPCE(); config.setProfile(pce.getProfile()); config.setSampleFrequency(pce.getSampleFrequency()); config.setChannelConfiguration((ChannelConfiguration)pce.getChannelCount()); } if (!canDecode(config.getProfile())) { throw new AACException("unsupported profile: " + config.getProfile()); } syntacticElements.startNewFrame(); //try { // 1: bitstream parsing and noiseless coding syntacticElements.decode(inStream); // 2: spectral processing syntacticElements.process(filterBank); // 3: send to output buffer syntacticElements.sendToOutput(buffer); } //catch (AACException e) //{ // buffer.setData(new byte[0], 0, 0, 0, 0); // throw e; //} //catch (Exception e) //{ // buffer.setData(new byte[0], 0, 0, 0, 0); // throw new AACException(e); //} // throw new NotImplementedException(); }
// --- ========== decoding ========== --- public void decode(BitStream inStream, DecoderConfig conf, bool commonWindow) { var sf = conf.getSampleFrequency(); if (sf.getIndex() == -1) { throw new AACException("invalid sample frequency"); } inStream.skipBit(); //reserved windowSequence = (WindowSequence)inStream.readBits(2); windowShape[PREVIOUS] = windowShape[CURRENT]; windowShape[CURRENT] = inStream.readBit(); windowGroupCount = 1; windowGroupLength[0] = 1; if (windowSequence == WindowSequence.EIGHT_SHORT_SEQUENCE) { maxSFB = inStream.readBits(4); int i; for (i = 0; i < 7; i++) { if (inStream.readBool()) { windowGroupLength[windowGroupCount - 1]++; } else { windowGroupCount++; windowGroupLength[windowGroupCount - 1] = 1; } } windowCount = 8; swbOffsets = SWB_OFFSET_SHORT_WINDOW[sf.getIndex()]; swbCount = SWB_SHORT_WINDOW_COUNT[sf.getIndex()]; predictionDataPresent = false; } else { maxSFB = inStream.readBits(6); windowCount = 1; swbOffsets = SWB_OFFSET_LONG_WINDOW[sf.getIndex()]; swbCount = SWB_LONG_WINDOW_COUNT[sf.getIndex()]; predictionDataPresent = inStream.readBool(); if (predictionDataPresent) { readPredictionData(inStream, conf.getProfile(), sf, commonWindow); } } }
public void decode(BitStream inStream) { int start = inStream.getPosition(); // should be 0 bool content = true; if (!config.getProfile().isErrorResilientProfile()) { Element prev = null; int type; while (content && (type = inStream.readBits(3)) != ELEMENT_END) { switch (type) { case ELEMENT_SCE: case ELEMENT_LFE: { Logger.LogInfo("SCE"); prev = decodeSCE_LFE(inStream); } break; case ELEMENT_CPE: { Logger.LogVerbose("CPE"); prev = decodeCPE(inStream); } break; case ELEMENT_CCE: { Logger.LogInfo("CCE"); throw new NotImplementedException(); //decodeCCE(inStream); prev = null; } break; case ELEMENT_DSE: { Logger.LogInfo("DSE"); throw new NotImplementedException(); //decodeDSE(inStream); prev = null; } break; case ELEMENT_PCE: { Logger.LogInfo("PCE"); throw new NotImplementedException(); //decodePCE(inStream); prev = null; } break; case ELEMENT_FIL: { Logger.LogInfo("FIL"); throw new NotImplementedException(); //decodeFIL(inStream, prev); prev = null; } break; } } Logger.LogVerbose("END"); content = false; prev = null; } else { // error resilient raw data block throw new NotImplementedException(); //switch (config.getChannelConfiguration()) //{ // case CHANNEL_CONFIG_MONO: decodeSCE_LFE(inStream); break; // case CHANNEL_CONFIG_STEREO: decodeCPE(inStream); break; // case CHANNEL_CONFIG_STEREO_PLUS_CENTER: decodeSCE_LFE(inStream); decodeCPE(inStream); break; // case CHANNEL_CONFIG_STEREO_PLUS_CENTER_PLUS_REAR_MONO: decodeSCE_LFE(inStream); decodeCPE(inStream); decodeSCE_LFE(inStream); break; // case CHANNEL_CONFIG_FIVE: decodeSCE_LFE(inStream); decodeCPE(inStream); decodeCPE(inStream); break; // case CHANNEL_CONFIG_FIVE_PLUS_ONE: decodeSCE_LFE(inStream); decodeCPE(inStream); decodeCPE(inStream); decodeSCE_LFE(inStream); break; // case CHANNEL_CONFIG_SEVEN_PLUS_ONE: decodeSCE_LFE(inStream); decodeCPE(inStream); decodeCPE(inStream); decodeCPE(inStream); decodeSCE_LFE(inStream); break; // default: throw new AACException("unsupported channel configuration for error resilience: " + config.getChannelConfiguration()); //} } inStream.byteAlign(); bitsRead = inStream.getPosition() - start; }
public void decode(BitStream inStream, DecoderConfig conf) { var profile = conf.getProfile(); var sf = conf.getSampleFrequency(); if (sf.getIndex() == -1) { throw new AACException("invalid sample frequency"); } readElementInstanceTag(inStream); commonWindow = inStream.readBool(); var info = icsL.getInfo(); if (commonWindow) { info.decode(inStream, conf, commonWindow); icsR.getInfo().setData(info); msMask = (MSMask)inStream.readBits(2); if (msMask == MSMask.TYPE_USED) { int maxSFB = info.getMaxSFB(); int windowGroupCount = info.getWindowGroupCount(); for (int idx = 0; idx < windowGroupCount * maxSFB; idx++) { msUsed[idx] = inStream.readBool(); } } else if (msMask == MSMask.TYPE_ALL_1) { for (int i = 0; i < msUsed.Length; i++) { msUsed[i] = true; } } else if (msMask == MSMask.TYPE_ALL_0) { for (int i = 0; i < msUsed.Length; i++) { msUsed[i] = false; } } else { throw new AACException("reserved MS mask type used"); } } else { msMask = MSMask.TYPE_ALL_0; for (int i = 0; i < msUsed.Length; i++) { msUsed[i] = false; } } if (profile.isErrorResilientProfile() && (info.isLTPrediction1Present())) { if (info.ltpData2Present = inStream.readBool()) { info.getLTPrediction2().decode(inStream, info, profile); } } icsL.decode(inStream, commonWindow, conf); icsR.decode(inStream, commonWindow, conf); }
// /* ========= 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); } }