libvorbis 音频从 C++ 中的内存解码
Posted
技术标签:
【中文标题】libvorbis 音频从 C++ 中的内存解码【英文标题】:libvorbis audio decode from memory in C++ 【发布时间】:2012-11-06 09:47:40 【问题描述】:给定 C++ 中的编码缓冲区,使用 oggvorbis 结构解码已经在内存中的数据的步骤是什么?
无法使用 OggVorbis_File,因为资产在压缩档案中。
我正在尝试研究必要的结构和方法,但我对音频编码和解码还很陌生。
也感谢任何可以帮助我进一步阅读的资源!
我要澄清一下,我打算使用解码后的数据流入 OpenAL。
谢谢。
【问题讨论】:
【参考方案1】:回答我自己的问题。
这可以通过向 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 源提供的大部分帮助,它可以 查看地址:here
【讨论】:
也可以结账svn.xiph.org/trunk/vorbis/examples/decoder_example.c 很好的答案!你碰巧有一个我可以玩的最小的完整工作示例吗?【参考方案2】:你也不能重新发明***,像这样使用fmemopen
:
FILE* memfile = fmemopen(data, len, "r");
data
是指向内存开头的指针,len
是数据的长度。然后将memfile
传递给ov_open
,就像普通的FILE
对象一样。
但是,有一个缺点:这个函数似乎是 linux 特有的(但它可以在 arduino 中找到,所以我对它的状态有点困惑),所以你在其他系统上没有它。但是它们有一些实现(检查libconfuse 的窗口或apple OSes)。
【讨论】:
不过,我们在 Windows 上没有这个功能。以上是关于libvorbis 音频从 C++ 中的内存解码的主要内容,如果未能解决你的问题,请参考以下文章
音频 MP2 编码和解码产生半数据 C++ 和 FFMPEG