//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++; } } }
/// <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())); }
public void process(ICStream ics, float[] data, FilterBank filterBank, SampleFrequency sf) { var info = ics.getInfo(); if (!info.isEightShortFrame()) { int samples = frameLength << 1; var inf = new float[2048]; var outf = new float[2048]; for (int i = 0; i < samples; i++) { inf[i] = states[samples + i - lag] * CODEBOOK[coef]; } throw new NotImplementedException(); //filterBank.processLTP(info.getWindowSequence(), info.getWindowShape(ICSInfo.CURRENT), info.getWindowShape(ICSInfo.PREVIOUS), inf, outf); //if (ics.isTNSDataPresent()) ics.getTNS().process(ics, outf, sf, true); var swbOffsets = info.getSWBOffsets(); int swbOffsetMax = info.getSWBOffsetMax(); for (int sfb = 0; sfb < lastBand; sfb++) { if (longUsed[sfb]) { int low = swbOffsets[sfb]; int high = Math.Min(swbOffsets[sfb + 1], swbOffsetMax); for (int bin = low; bin < high; bin++) { data[bin] += outf[bin]; } } } } }
//private int processSingle(SCE_LFE scelfe, FilterBank filterBank, int channel, Profile profile, SampleFrequency sf) throws AACException { //ICStream ics = scelfe.getICStream(); //ICSInfo info = ics.getInfo(); //LTPrediction ltp = info.getLTPrediction1(); //int elementID = scelfe.getElementInstanceTag(); ////inverse quantization //float[] iqData = ics.getInvQuantData(); ////prediction //if(profile.equals(Profile.AAC_MAIN)&&info.isICPredictionPresent()) info.getICPrediction().process(ics, iqData, sf); //if(LTPrediction.isLTPProfile(profile)&&info.isLTPrediction1Present()) ltp.process(ics, iqData, filterBank, sf); ////dependent coupling //processDependentCoupling(false, elementID, CCE.BEFORE_TNS, iqData, null); ////TNS //if(ics.isTNSDataPresent()) ics.getTNS().process(ics, iqData, sf, false); ////dependent coupling //processDependentCoupling(false, elementID, CCE.AFTER_TNS, iqData, null); ////filterbank //filterBank.process(info.getWindowSequence(), info.getWindowShape(ICSInfo.CURRENT), info.getWindowShape(ICSInfo.PREVIOUS), iqData, data[channel], channel); //if(LTPrediction.isLTPProfile(profile)) ltp.updateState(data[channel], filterBank.getOverlap(channel), profile); ////dependent coupling //processIndependentCoupling(false, elementID, data[channel], null); ////gain control //if(ics.isGainControlPresent()) ics.getGainControl().process(iqData, info.getWindowShape(ICSInfo.CURRENT), info.getWindowShape(ICSInfo.PREVIOUS), info.getWindowSequence()); ////SBR //int chs = 1; //if(sbrPresent&&config.isSBREnabled()) { //if(data[channel].Length==config.getFrameLength()) LOGGER.log(Level.WARNING, "SBR data present, but buffer has normal size!"); //SBR sbr = scelfe.getSBR(); //if(sbr.isPSUsed()) { //chs = 2; //scelfe.getSBR().process(data[channel], data[channel+1], false); //} //else scelfe.getSBR().process(data[channel], false); //} //return chs; //} void processPair(CPE cpe, FilterBank filterBank, int channel, Profile profile, SampleFrequency sf) { var ics1 = cpe.getLeftChannel(); var ics2 = cpe.getRightChannel(); var info1 = ics1.getInfo(); var info2 = ics2.getInfo(); var ltp1 = info1.getLTPrediction1(); var ltp2 = cpe.isCommonWindow() ? info1.getLTPrediction2() : info2.getLTPrediction1(); int elementID = cpe.getElementInstanceTag(); // inverse quantization var iqData1 = ics1.getInvQuantData(); var iqData2 = ics2.getInvQuantData(); // MS if (cpe.isCommonWindow() && cpe.isMSMaskPresent()) { MS.process(cpe, iqData1, iqData2); } // main prediction if (profile.type == Profile.ProfileType.AAC_MAIN) { if (info1.isICPredictionPresent()) { throw new NotImplementedException(); // info1.getICPrediction().process(ics1, iqData1, sf); } if (info2.isICPredictionPresent()) { throw new NotImplementedException(); // info2.getICPrediction().process(ics2, iqData2, sf); } } // IS IS.process(cpe, iqData1, iqData2); // LTP if (LTPrediction.isLTPProfile(profile)) { if (info1.isLTPrediction1Present()) { ltp1.process(ics1, iqData1, filterBank, sf); } if (cpe.isCommonWindow() && info1.isLTPrediction2Present()) { ltp2.process(ics2, iqData2, filterBank, sf); } else if (info2.isLTPrediction1Present()) { ltp2.process(ics2, iqData2, filterBank, sf); } } // dependent coupling processDependentCoupling(true, elementID, CCE.BEFORE_TNS, iqData1, iqData2); // TNS if (ics1.isTNSDataPresent()) { ics1.getTNS().process(ics1, iqData1, sf, false); } if (ics2.isTNSDataPresent()) { ics2.getTNS().process(ics2, iqData2, sf, false); } // dependent coupling processDependentCoupling(true, elementID, CCE.AFTER_TNS, iqData1, iqData2); // filterbank filterBank.process(info1.getWindowSequence(), info1.getWindowShape(ICSInfo.CURRENT), info1.getWindowShape(ICSInfo.PREVIOUS), iqData1, data[channel], channel); filterBank.process(info2.getWindowSequence(), info2.getWindowShape(ICSInfo.CURRENT), info2.getWindowShape(ICSInfo.PREVIOUS), iqData2, data[channel + 1], channel + 1); if (LTPrediction.isLTPProfile(profile)) { ltp1.updateState(data[channel], filterBank.getOverlap(channel), profile); ltp2.updateState(data[channel + 1], filterBank.getOverlap(channel + 1), profile); } // independent coupling processIndependentCoupling(true, elementID, data[channel], data[channel + 1]); // gain control if (ics1.isGainControlPresent()) { ics1.getGainControl().process(iqData1, info1.getWindowShape(ICSInfo.CURRENT), info1.getWindowShape(ICSInfo.PREVIOUS), info1.getWindowSequence()); } if (ics2.isGainControlPresent()) { ics2.getGainControl().process(iqData2, info2.getWindowShape(ICSInfo.CURRENT), info2.getWindowShape(ICSInfo.PREVIOUS), info2.getWindowSequence()); } //SBR if (sbrPresent && config.isSBREnabled()) { if (data[channel].Length == config.getFrameLength()) { Logger.LogServe("SBR data present, but buffer has normal size!"); } cpe.getSBR().process(data[channel], data[channel + 1], false); } }