2012-11-18 16 views
8

Dato un buffer codificato in C++, quali sarebbero i passaggi utilizzando le strutture di oggvorbis per decodificare i dati già in memoria?decodifica audio libvorbis dalla memoria in C++

OggVorbis_File non può essere utilizzato, poiché le risorse si trovano all'interno di archivi compressi.

Sto cercando di ricercare le strutture e i metodi necessari, ma sono abbastanza nuovo per la codifica e la decodifica audio.

Tutte le risorse che possono aiutare ulteriormente la mia lettura sono apprezzate pure!

Devo chiarire, ho intenzione di utilizzare i dati decodificati per lo streaming in OpenAL.

Grazie.

risposta

9

Rispondere alla mia domanda.

Questo può essere fatto fornendo callback personalizzati a 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); 
} 

Uso

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 */ 

un ringraziamento speciale alla fonte Doom3 GPL per la maggior parte del aiuto con questo, si può essere visualizzate sul: here

+0

Inoltre è possibile checkout http: // svn.xiph.org/trunk/vorbis/examples/decoder_example.c –

+0

Ottima risposta! Ti capita di avere un esempio operativo completo minimo con cui posso giocare? – Chimera