【问题标题】:how to encode/decode speex with AudioQueue in ios如何在 ios 中使用 AudioQueue 对 speex 进行编码/解码
【发布时间】:2011-08-02 15:29:48
【问题描述】:

如果有人有使用 AudioQueue 编码/解码 speex 音频格式的经验?

我试图通过编辑 SpeakHere 示例来实现它。但不是成功!

从苹果 API 文档中,AudioQueue 可以支持编解码器,但我找不到任何示例。谁能给我一些建议?我已经在 XCode 4 的项目中成功编译了 speex 编解码器。

【问题讨论】:

    标签: iphone ios codec audioqueue speex


    【解决方案1】:

    在苹果示例代码“SpeakHere”中,您可以执行以下操作:

    AudioQueueNewInput(
                                         &mRecordFormat,
                                         MyInputBufferHandler,
                                         this /* userData */,
                                         NULL /* run loop */,
                                         NULL /* run loop mode */,
                                         0 /* flags */, &mQueue)
    

    你可以在函数“MyInputBufferHandler”中做一些事情,比如

    [self encoder:(short *)buffer->mAudioData count:buffer->mAudioDataByteSize/sizeof(short)];
    

    编码器功能如:

    while ( count >= samplesPerFrame )
        {
            speex_bits_reset( &bits );
    
            speex_encode_int( enc_state, samples, &bits ); 
    
            static const unsigned maxSize = 256;
            char data[maxSize];
            unsigned size = (unsigned)speex_bits_write( &bits, data, maxSize );
            /*
                        do some thing... for example :send to server
            */
    
            samples += samplesPerFrame;
            count -= samplesPerFrame;
        }
    

    这是大意。当然事实很难,但是你可以看看一些开源的VOIP,也许可以帮助你。 祝你好运。

    【讨论】:

      【解决方案2】:

      您可以使用 FFMPEG 实现所有这些,然后使用 AudioQueue 将其作为 PCM 播放。 FFMPEG 库的构建并不是那么轻松,但整个解码/编码过程并不那么难:)

      FFMPEG official site SPEEX official site

      您必须下载这些库并自己构建它们,然后您必须将它们包含到 FFMPEG 中并构建它。

      【讨论】:

      【解决方案3】:

      以下是使用 audioqueue 捕获音频并使用 speex 进行编码(宽带)的代码 (为了更好的音频质量,您可以在单独的线程中编码数据,根据您的捕获格式更改样本大小)。

      音频格式

          mSampleRate = 16000;
          mFormatID = kAudioFormatLinearPCM;
          mFramesPerPacket = 1;
          mChannelsPerFrame = 1;
          mBytesPerFrame = 2;
          mBytesPerPacket = 2;
          mBitsPerChannel = 16;
          mReserved = 0;
          mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; 
      

      捕获回调

          void CAudioCapturer::AudioInputCallback(void *inUserData, 
                                 AudioQueueRef inAQ, 
                                 AudioQueueBufferRef inBuffer, 
                                 const AudioTimeStamp *inStartTime, 
                                 UInt32 inNumberPacketDescriptions, 
                                 const AudioStreamPacketDescription *inPacketDescs)
          {
          CAudioCapturer *This = (CMacAudioCapturer *)inUserData;
      
      int len = 640;
      char data[640];
      char *pSrc = (char *)inBuffer->mAudioData;
      
      while (len <= inBuffer->mAudioDataByteSize) 
      {
          memcpy(data,pSrc,640);
          int enclen = encode(buffer,encBuffer);
          len=len+640;
      
          pSrc+=640; // 640 is the frame size for WB in speex (320 short)
      }
      
      AudioQueueEnqueueBuffer(This->m_audioQueue, inBuffer, 0, NULL);
          }
      

      speex 编码器

          int encode(char *buffer,char *pDest)
          {
      int nbBytes=0;
      speex_bits_reset(&encbits);
      
      speex_encode_int(encstate, (short*)(buffer)  , &encbits);
      
      nbBytes = speex_bits_write(&encbits, pDest ,640/(sizeof(short))); 
      
      return nbBytes;
          }
      

      【讨论】:

      • 感谢您的信息。您提到 640 是 Speex 中的帧大小(短 320)。 “320短”是什么意思?既然一个 short 是两个字节长,那么我们有 320 对字节?
      猜你喜欢
      • 2019-09-05
      • 2015-03-25
      • 1970-01-01
      • 1970-01-01
      • 2015-07-23
      • 2012-01-08
      • 2015-08-07
      • 2012-03-31
      • 1970-01-01
      相关资源
      最近更新 更多