C++ 中从内存中解码 libvorbis 音频
libvorbis audio decode from memory in C++
给定一个C++编码的缓冲区,使用oggvorbis结构解码已经在内存中的数据的步骤是什么?
OggVorbis_File无法使用,因为资产位于压缩存档中。
我正在尝试研究必要的结构和方法,但我对音频编码和解码相当陌生。
任何可以帮助我进一步阅读的资源也值得赞赏!
我应该澄清一下,我打算使用解码的数据流式传输到 OpenAL。
谢谢。
回答我自己的问题。
这可以通过向 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源代码对此的大部分帮助,它可以查看地点 : 这里
你也可以不要
重新发明轮子并使用这样的fmemopen
:
FILE* memfile = fmemopen(data, len, "r");
其中data
是指向内存开始的指针,len
是数据的长度。然后像常规对象一样将memfile
传递给ov_open
FILE
对象。
也有缺点:此功能似乎是特定于Linux的(但是可以在arduino中找到,所以我对它的状态有点困惑),因此您在其他系统上没有它。但是有一些实现(检查窗口或苹果操作系统的libconfuse)。
相关文章:
- 用c++阅读音频
- 为什么这个音频包络不能通过开关的情况?
- FFMpeg库:如何在音频文件中精确查找
- 需要反转音频步进公式
- 如何在音频处理中使用超能力时间拉伸类
- C++新手,想知道如何使用VS code 2019播放音频文件
- 如何暂停插孔音频客户端
- 如何以编程方式将音频从任何录制设备路由到任何播放设备
- 将音频从浏览器流式传输到WebRTC本机C++应用程序
- 使用IMFSourceReader(Microsoft媒体基金会)进行音频流传输
- 大声音频无法播放
- 让 iaxClient 将音频发送到缓冲区而不是音频设备/从缓冲区获取音频
- 适用于 macOS 的 Xcode 应用程序。这就是我设置从USB麦克风输入获取音频的方式。一年前工作,现在没有了。为什么
- 波形音频 - waveOutWrite 发出断断续续的声音
- WASAPI 共享模式:音频引擎预期的振幅是多少?
- 在Win7上,在默认端点上轮询音频会话有时会崩溃
- 媒体基金会:WavSink以比实时消耗率更快的速度处理音频-是否可以实时限制后台处理
- PJSUA在两个或多个不同的音频声卡之间切换
- C++ 中从内存中解码 libvorbis 音频
- 解码循环逻辑从matroska (mkv, webm)到音频(c++通过libvorbis)