我正在尝试将“实时”(缓冲)音频数据编码为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);
答案 0 :(得分:0)
最后我开始工作了。我不得不使用memcpy来填充libOgg输入缓冲区,我必须修复我传入的值,因为我复制到缓冲区的样本数量。
请参阅以下工作代码:
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;
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);
memcpy(buffer[0], floatData->mBuffers[0].mData, floatData->mBuffers[0].mDataByteSize);
memcpy(buffer[1], floatData->mBuffers[1].mData, floatData->mBuffers[1].mDataByteSize);
checkresult (vorbis_analysis_wrote(&vd, ioLengthInFrames), @"Analysis Wrote");
int wrote = 0;
while (vorbis_analysis_blockout(&vd, &vb) == 1)
{
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)
{
int result = ogg_stream_pageout(&os, &og);
if (result==0)break;
int size = og.header_len + og.body_len;
int availableBytes;
unsigned char* head = TPCircularBufferHead(&outputBuffer, &availableBytes);
if (availableBytes < size)
{
NSLog(@"Buffer Full");
return;
}
memcpy(head, og.header, og.header_len);
memcpy(head+og.header_len, og.body, og.body_len);
TPCircularBufferProduce(&outputBuffer, size);
wrote += size;
if (ogg_page_eos(&og))eos=true;
}
}
}
NSLog(@"Rendering OggVorbis: %d bytes written", wrote);