コード例 #1
0
HRESULT TaudioCodecLibFAAD::decode(TbyteBuffer &src)
{
    NeAACDecFrameInfo frameInfo;
    unsigned long size = (unsigned long)src.size();
    float *outsamples = (float*)NeAACDecDecode(m_decHandle, &frameInfo, size ? &src[0] : NULL, size);
    src.clear();
    if (frameInfo.error) {
        DPRINTF(_l("AAC: Error %d [%s]\n"), frameInfo.error, (const char_t*)text<char_t>(NeAACDecGetErrorMessage(frameInfo.error)));
        return S_OK;//S_FALSE
    } else if (outsamples && frameInfo.samples) {
        ps = !!frameInfo.ps;
        sbr = !!frameInfo.sbr;
        numframes++;
        bpssum += (lastbps = 8 * fmt.freq * frameInfo.bytesconsumed / (frameInfo.samples / fmt.nchannels) / 1000);
        if (frameInfo.channels == 2 && frameInfo.channel_position[1] == UNKNOWN_CHANNEL) {
            frameInfo.channel_position[0] = FRONT_CHANNEL_LEFT;
            frameInfo.channel_position[1] = FRONT_CHANNEL_RIGHT;
        }

        fmt = this->fmt;
        fmt.channelmask = 0;
        for (int i = 0; i < frameInfo.channels; i++) {
            fmt.channelmask |= chmask[frameInfo.channel_position[i]];
        }

        int chmap[countof(frameInfo.channel_position)];
        memset(chmap, 0, sizeof(chmap));

        for (int i = 0; i < frameInfo.channels; i++) {
            unsigned int ch = 0;
            int mask = chmask[frameInfo.channel_position[i]];
            for (int j = 0; j < 32; j++)
                if (fmt.channelmask & (1 << j)) {
                    if ((1 << j) == mask) {
                        chmap[i] = ch;
                        break;
                    }
                    ch++;
                }
        }

        if (frameInfo.channels <= 2) {
            fmt.channelmask = 0;
        }

        float *dst, *dst0;
        dst = dst0 = (float*)getDst(frameInfo.samples * sizeof(float));
        for (unsigned int j = 0; j < frameInfo.samples; j += frameInfo.channels, dst += frameInfo.channels)
            for (int i = 0; i < frameInfo.channels; i++) {
                dst[chmap[i]] = *outsamples++;
            }

        return sinkA->deliverDecodedSample(dst0, frameInfo.samples / frameInfo.channels, fmt);
    } else {
        return S_OK;
    }
}
コード例 #2
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;
}
コード例 #3
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;
}