HRESULT TaudioCodecLibDTS::decode(TbyteBuffer &src) { unsigned char *p = src.size() ? &src[0] : NULL; unsigned char *base = p; unsigned char *end = p + src.size(); while (end - p >= 14) { int size = 0, flags, sample_rate, frame_length, bit_rate; if ((size = dca_syncinfo(state, p, &flags, &sample_rate, &bit_rate, &frame_length)) > 0) { bool enoughData = p + size <= end; if (enoughData) { if (codecId == CODEC_ID_SPDIF_DTS) { bpssum += (lastbps = bit_rate / 1000); numframes++; BYTE type; switch (frame_length) { case 512: type = 0x0b; break; case 1024: type = 0x0c; break; default : type = 0x0d; break; } HRESULT hr = deciA->deliverSampleBistream(p, size, bit_rate, sample_rate, true, frame_length, 0); if (hr != S_OK) { return hr; } } else { flags |= DCA_ADJUST_LEVEL; libdca::sample_t level = 1, bias = 0; if (dca_frame(state, p, &flags, &level, bias) == 0) { bpssum += (lastbps = bit_rate / 1000); numframes++; // Dynamic range compression - Not suppored yet by libdts if (deci->getParam2(IDFF_audio_decoder_DRC)) { libdca::sample_t drcLevel = ((libdca::sample_t)deci->getParam2(IDFF_audio_decoder_DRC_Level) / 100); if (drcLevel <= 0.5) { dca_dynrng(state, NULL, NULL); } } else { dca_dynrng(state, NULL, NULL); } int scmapidx = std::min(flags & DCA_CHANNEL_MASK, int(countof(scmaps) / 2)); const Tscmap &scmap = scmaps[scmapidx + ((flags & DCA_LFE) ? (countof(scmaps) / 2) : 0)]; int blocks = dca_blocks_num(state); float *dst0, *dst; dst0 = dst = (float*)getDst(blocks * 256 * scmap.nchannels * sizeof(float)); int i = 0; for (; i < blocks && dca_block(state) == 0; i++) { libdca::sample_t* samples = dca_samples(state); for (int j = 0; j < 256; j++, samples++) for (int ch = 0; ch < scmap.nchannels; ch++) { *dst++ = float(*(samples + 256 * scmap.ch[ch]) / level); } } if (i == blocks) { fmt.sf = TsampleFormat::SF_FLOAT32; fmt.freq = sample_rate; fmt.setChannels(scmap.nchannels, scmap.channelMask); HRESULT hr = sinkA->deliverDecodedSample(dst0, blocks * 256, fmt); if (hr != S_OK) { return hr; } } } } p += size; } memmove(base, p, end - p); end = base + (end - p); p = base; if (!enoughData) { break; } } else { p++; } } src.resize(end - p); return S_OK; }
HRESULT TaudioCodecLiba52::decode(TbyteBuffer &src) { unsigned char *p=src.size() ? &src[0] : NULL; unsigned char *base=p; unsigned char *end=p+src.size(); while (end-p>7) { int size=0,flags,sample_rate,bit_rate; if ((size=a52_syncinfo(p,&flags,&sample_rate,&bit_rate))>0) { bool enoughData=p+size<=end; if (enoughData) { if (codecId==CODEC_ID_SPDIF_AC3) { bpssum+=(lastbps=bit_rate/1000); numframes++; HRESULT hr=deciA->deliverSampleSPDIF(p,size,bit_rate,sample_rate,true); if (hr!=S_OK) { return hr; } } else { flags|=A52_ADJUST_LEVEL; liba52::sample_t level=1,bias=0; if (a52_frame(state,p,&flags,&level,bias)==0) { bpssum+=(lastbps=bit_rate/1000); numframes++; // Dynamic range compression if (deci->getParam2(IDFF_audio_decoder_DRC)) { liba52::sample_t drcLevel = ((liba52::sample_t)deci->getParam2(IDFF_audio_decoder_DRC_Level) / 100); a52_dynrngsetlevel(state, drcLevel); } else { a52_dynrngsetlevel(state, 0.0); } int scmapidx=std::min(flags&A52_CHANNEL_MASK,int(countof(scmaps)/2)); const Tscmap &scmap=scmaps[scmapidx+((flags&A52_LFE)?(countof(scmaps)/2):0)]; float *dst0,*dst; dst0=dst=(float*)getDst(6*256*scmap.nchannels*sizeof(float)); int i=0; for(; i<6 && a52_block(state)==0; i++) { liba52::sample_t* samples=a52_samples(state); for (int j=0; j<256; j++,samples++) for (int ch=0; ch<scmap.nchannels; ch++) { *dst++=float(*(samples+256*scmap.ch[ch])/level); } } if (i==6) { fmt.sf=TsampleFormat::SF_FLOAT32; fmt.freq=sample_rate; fmt.setChannels(scmap.nchannels,scmap.channelMask); HRESULT hr=sinkA->deliverDecodedSample(dst0,6*256,fmt); if (hr!=S_OK) { return hr; } } } } p+=size; } memmove(base,p,end-p); end=base+(end-p); p=base; if (!enoughData) { break; } } else { p++; } } src.resize(end-p); return S_OK; }