Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}