2013-12-17 39 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); 
相關問題