我正在尝试将“实时”(缓冲)音频数据编码为 OggVorbis 格式,但它对我不起作用。无论我做什么,输出流都只包含 Vorbis 标头(没有 Ogg 数据)。
我已经成功地使用 libLAME 以相同的方式编码到 MP3 流(显然用 LAME 替换了 ogg 函数)。
我已经包含了用于检索 PCM 数据、将其提供给 libOgg 并检索输出并对其进行缓冲的代码。目前我正在“缓冲区溢出”阶段中断并使用 Xcode 查看 outputBuffer 中包含的内存。
正如我上面所说,这适用于使用 libLAME 的 MP3,所以我知道我离得不远了。如果我查看 ogg.header 和 ogg.body,它们包含数据,ogg.header_length 是 282,ogg.body_length 是 255。
如果需要,我可以将 outputBuffer 粘贴到 bin 供人们查看。
UInt32 ioLengthInFrames = 256;//ioBufferDuration * self.audioFormat->mSampleRate;
AudioBufferList *ioData = AllocateABL(self.audioFormat->mChannelsPerFrame, self.audioFormat->mBytesPerFrame, NO, ioLengthInFrames);
AudioBufferList *floatData = AllocateABL(self.audioFormat->mChannelsPerFrame, self.audioFormat->mBytesPerFrame, NO, ioLengthInFrames);
UInt32 retVal = TPCircularBufferPeek(inputBuffer, NULL, self.audioFormat);
if (!retVal > 0)
return;
//NSLog (@"Frames Available: %ld", retVal);
TPCircularBufferDequeueBufferListFrames(inputBuffer, &ioLengthInFrames, ioData, NULL, self.audioFormat);
AEFloatConverterToFloatBufferList(self.floatConverter, ioData, floatData, ioLengthInFrames);
if (ioLengthInFrames <= 0)
{
NSLog(@"Not enough frames");
return;
}
float **buffer = vorbis_analysis_buffer(&vd, ioLengthInFrames * self.audioFormat->mBytesPerFrame);
buffer[0] = floatData->mBuffers[0].mData;
buffer[1] = floatData->mBuffers[1].mData;
checkresult (vorbis_analysis_wrote(&vd, ioLengthInFrames * self.audioFormat->mBytesPerFrame), @"Analysis Wrote");
int wrote = 0;
while (vorbis_analysis_blockout(&vd, &vb) == 1)
{
NSLog(@"Block Out");
checkresult (vorbis_analysis(&vb, NULL), @"Analysis");
checkresult (vorbis_bitrate_addblock(&vb), @"BitRate AddBlock");
while (vorbis_bitrate_flushpacket(&vd, &op))
{
NSLog(@"Flush Packet");
ogg_stream_packetin(&os, &op);
bool eos = false;
while (!eos)
{
NSLog(@"EOS");
int result = ogg_stream_pageout(&os, &og);
if (result==0)break;
NSLog(@"EOS 2");
int availableBytes;
unsigned char* head = TPCircularBufferHead(&outputBuffer, &availableBytes);
if (availableBytes < og.header_len + og.body_len)
{
return;
// Buffer Full
}
memcpy(head, og.header, og.header_len);
memcpy(head+og.header_len, og.body, og.body_len);
TPCircularBufferProduce(&outputBuffer, og.header_len + og.body_len);
wrote += og.header_len + og.body_len;
if (ogg_page_eos(&og))eos=true;
}
}
}
NSLog(@"Rendering OggVorbis: %d bytes written", wrote);