2013-12-17 40 views
1

我试图编码“活”(缓冲)的音频数据为OggVorbis格式,但它只是不适合我。不管我做什么,输出流只包含Vorbis头(不包含Ogg数据)。libOgg/libVorbis和AudioBufferList

我已经用同样的方式使用libLAME成功编码为MP3流(明显地用LAME替换ogg函数)。

我已经包含了我的代码,用于检索PCM数据,将它提供给libOgg并检索输出并缓冲它。目前我正在打破“缓冲区溢出”阶段,并使用Xcode查看outputBuffer中包含的内存。

正如我上面所说,这适用于使用libLAME的MP3,所以我知道我不能离得很远。如果我看看ogg.header和ogg.body,它们包含数据,ogg.header_length是282,ogg.body_length是255.

如果需要,我可以粘贴bin的outputBuffer供人们查看。

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

最后我得到了它的工作。我必须使用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); 
相关问题