示例#1
0
void CASpeexDecoder::InitializeCompressionSettings()
{
    if (mCookie == NULL)
        return;

    if (mCompressionInitialized) {
        memset(&mSpeexHeader, 0, sizeof(mSpeexHeader));

        mSpeexStereoState.balance = 1.0;
        mSpeexStereoState.e_ratio = 0.5;
        mSpeexStereoState.smooth_left = 1.0;
        mSpeexStereoState.smooth_right = 1.0;

        if (mSpeexDecoderState != NULL) {
            speex_decoder_destroy(mSpeexDecoderState);
            mSpeexDecoderState = NULL;
        }
    }

    mCompressionInitialized = false;

    OggSerialNoAtom *atom = reinterpret_cast<OggSerialNoAtom*> (mCookie);
    Byte *ptrheader = mCookie + EndianU32_BtoN(atom->size);
    CookieAtomHeader *aheader = reinterpret_cast<CookieAtomHeader*> (ptrheader);

    // scan quickly through the cookie, check types and packet sizes
    if (EndianS32_BtoN(atom->type) != kCookieTypeOggSerialNo || static_cast<UInt32> (ptrheader - mCookie) > mCookieSize)
        return;
    ptrheader += EndianU32_BtoN(aheader->size);
    if (EndianS32_BtoN(aheader->type) != kCookieTypeSpeexHeader || static_cast<UInt32> (ptrheader - mCookie) > mCookieSize)
        return;
    // we ignore the rest: comments and extra headers

    // all OK, back to the first speex packet
    aheader = reinterpret_cast<CookieAtomHeader*> (mCookie + EndianU32_BtoN(atom->size));
    SpeexHeader *inheader = reinterpret_cast<SpeexHeader *> (&aheader->data[0]);

    // TODO: convert, at some point, mSpeexHeader to a pointer?
    mSpeexHeader.bitrate =                 EndianS32_LtoN(inheader->bitrate);
    mSpeexHeader.extra_headers =           EndianS32_LtoN(inheader->extra_headers);
    mSpeexHeader.frame_size =              EndianS32_LtoN(inheader->frame_size);
    mSpeexHeader.frames_per_packet =       EndianS32_LtoN(inheader->frames_per_packet);
    mSpeexHeader.header_size =             EndianS32_LtoN(inheader->header_size);
    mSpeexHeader.mode =                    EndianS32_LtoN(inheader->mode);
    mSpeexHeader.mode_bitstream_version =  EndianS32_LtoN(inheader->mode_bitstream_version);
    mSpeexHeader.nb_channels =             EndianS32_LtoN(inheader->nb_channels);
    mSpeexHeader.rate =                    EndianS32_LtoN(inheader->rate);
    mSpeexHeader.reserved1 =               EndianS32_LtoN(inheader->reserved1);
    mSpeexHeader.reserved2 =               EndianS32_LtoN(inheader->reserved2);
    mSpeexHeader.speex_version_id =        EndianS32_LtoN(inheader->speex_version_id);
    mSpeexHeader.vbr =                     EndianS32_LtoN(inheader->vbr);

    if (mSpeexHeader.mode >= SPEEX_NB_MODES)
        CODEC_THROW(kAudioCodecUnsupportedFormatError);

    //TODO: check bitstream version here

    mSpeexDecoderState = speex_decoder_init(speex_lib_get_mode(mSpeexHeader.mode));

    if (!mSpeexDecoderState)
        CODEC_THROW(kAudioCodecUnsupportedFormatError);

    //TODO: fix some of the header fields here

    int enhzero = 0;
    speex_decoder_ctl(mSpeexDecoderState, SPEEX_SET_ENH, &enhzero);

    if (mSpeexHeader.nb_channels == 2)
    {
        SpeexCallback callback;
        callback.callback_id = SPEEX_INBAND_STEREO;
        callback.func = speex_std_stereo_request_handler;
        callback.data = &mSpeexStereoState;
        speex_decoder_ctl(mSpeexDecoderState, SPEEX_SET_HANDLER, &callback);
    }

    mCompressionInitialized = true;
}
示例#2
0
int process_first_packet__speex(StreamInfo *si, ogg_page *op, ogg_packet *opckt)
{
    unsigned long serialnoatom[3] = { EndianU32_NtoB(sizeof(serialnoatom)), EndianU32_NtoB(kCookieTypeOggSerialNo),
                                      EndianS32_NtoB(ogg_page_serialno(op)) };
    unsigned long atomhead[2] = { EndianU32_NtoB(opckt->bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeSpeexHeader) };
    SpeexHeader *inheader = (SpeexHeader *) opckt->packet;

    si->si_speex.header.bitrate =                 EndianS32_LtoN(inheader->bitrate);
    si->si_speex.header.extra_headers =           EndianS32_LtoN(inheader->extra_headers);
    si->si_speex.header.frame_size =              EndianS32_LtoN(inheader->frame_size);
    si->si_speex.header.frames_per_packet =       EndianS32_LtoN(inheader->frames_per_packet);
    si->si_speex.header.header_size =             EndianS32_LtoN(inheader->header_size);
    si->si_speex.header.mode =                    EndianS32_LtoN(inheader->mode);
    si->si_speex.header.mode_bitstream_version =  EndianS32_LtoN(inheader->mode_bitstream_version);
    si->si_speex.header.nb_channels =             EndianS32_LtoN(inheader->nb_channels);
    si->si_speex.header.rate =                    EndianS32_LtoN(inheader->rate);
    si->si_speex.header.reserved1 =               EndianS32_LtoN(inheader->reserved1);
    si->si_speex.header.reserved2 =               EndianS32_LtoN(inheader->reserved2);
    si->si_speex.header.speex_version_id =        EndianS32_LtoN(inheader->speex_version_id);
    si->si_speex.header.vbr =                     EndianS32_LtoN(inheader->vbr);
    //si->si_speex.header. = EndianS32_LtoN(inheader->);

    dbg_printf("! -- - speex_first_packet: ch: %d, rate: %ld\n", si->si_speex.header.nb_channels, si->si_speex.header.rate);
    si->numChannels = si->si_speex.header.nb_channels;
    si->rate = si->si_speex.header.rate;
    //si->lastMediaInserted = 0;
    si->mediaLength = 0;

    PtrAndHand(serialnoatom, si->soundDescExtension, sizeof(serialnoatom)); //check errors?
    PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead)); //check errors?
    PtrAndHand(opckt->packet, si->soundDescExtension, opckt->bytes); //check errors?

    si->si_speex.state = kSStateReadingComments;

    return 0;
};