11

C++ でエンコードされたバッファーが与えられた場合、oggvorbis 構造体を使用して既にメモリ内にあるデータをデコードする手順は何でしょうか?

アセットは圧縮されたアーカイブ内にあるため、OggVorbis_File は使用できません。

必要な構造体とメソッドを調査しようとしていますが、オーディオのエンコードとデコードにはかなり慣れていません。

私の読書をさらに進めるのに役立つリソースも高く評価されます!

明確にする必要がありますが、デコードされたデータを使用して OpenAL にストリーミングするつもりです。

ありがとう。

4

2 に答える 2

12

私自身の質問に答えます。

これは、vorbis にカスタム コールバックを提供することで実行できます。

struct ogg_file
{
    char* curPtr;
    char* filePtr;
    size_t fileSize;
};

size_t AR_readOgg(void* dst, size_t size1, size_t size2, void* fh)
{
    ogg_file* of = reinterpret_cast<ogg_file*>(fh);
    size_t len = size1 * size2;
    if ( of->curPtr + len > of->filePtr + of->fileSize )
    {
        len = of->filePtr + of->fileSize - of->curPtr;
    }
    memcpy( dst, of->curPtr, len );
    of->curPtr += len;
    return len;
}

int AR_seekOgg( void *fh, ogg_int64_t to, int type ) {
    ogg_file* of = reinterpret_cast<ogg_file*>(fh);

    switch( type ) {
        case SEEK_CUR:
            of->curPtr += to;
            break;
        case SEEK_END:
            of->curPtr = of->filePtr + of->fileSize - to;
            break;
        case SEEK_SET:
            of->curPtr = of->filePtr + to;
            break;
        default:
            return -1;
    }
    if ( of->curPtr < of->filePtr ) {
        of->curPtr = of->filePtr;
        return -1;
    }
    if ( of->curPtr > of->filePtr + of->fileSize ) {
        of->curPtr = of->filePtr + of->fileSize;
        return -1;
    }
    return 0;
}

int AR_closeOgg(void* fh)
{
    return 0;
}

long AR_tellOgg( void *fh )
{
    ogg_file* of = reinterpret_cast<ogg_file*>(fh);
    return (of->curPtr - of->filePtr);
}

使用法

ov_callbacks callbacks;
ogg_file t;
t.curPtr = t.filePtr = compressedData;
t.fileSize = compressedDataSize;

OggVorbis_File* ov = new OggVorbis_File;
mOggFile = ov;
memset( ov, 0, sizeof( OggVorbis_File ) );

callbacks.read_func = AR_readOgg;
callbacks.seek_func = AR_seekOgg;
callbacks.close_func = AR_closeOgg;
callbacks.tell_func = AR_tellOgg;

int ret = ov_open_callbacks((void *)&t, ov, NULL, -1, callbacks);

vorbis_info* vi = ov_info(ov, -1);
assert(vi);

/* compressed data is available to use, to uncompress look into ov_read */

これに関するほとんどのヘルプについて、Doom3 GPL ソースに特に感謝します。

于 2012-11-18T16:51:50.737 に答える