设为首页收藏本站
查看: 452|回复: 0

[业界探讨] 麦克风PCM数据实时编码MP3数据的方法

[复制链接]

75

主题

75

帖子

442

积分

网站编辑

Rank: 8Rank: 8

积分
442
发表于 2017-1-18 10:42:24 | 显示全部楼层 |阅读模式
从麦克风获取PCM数据的方法,参看Apple的官方例子:SpeakHere

注意,以下方法实现的前提是:
录音格式为kAudioFormatLinearPCM;
录音格式的mBitsPerChannel要设置为16

SpeakHere的InputBufferHandler回调方法中,可以获取到PCM数据:
  1. // AudioQueue callback function, called when an input buffers has been filled.
  2. void AudioInputBufferHandler( void *                               inUserData,
  3.                               AudioQueueRef                        inAQ,
  4.                               AudioQueueBufferRef                  inBuffer,
  5.                               const AudioTimeStamp *               inStartTime,
  6.                               UInt32                               inNumPackets,
  7.                               const AudioStreamPacketDescription * inPacketDesc ) {
  8.      
  9.     AudioRecorder *recorder = (AudioRecorder *)inUserData;
  10.     try {
  11.          
  12.         if ( recorder.isRunning && inNumPackets > 0 ) {

  13.             [recorder.mp3Encoder encodePcmData:inBuffer->mAudioData withDataSize:inNumPackets];
  14.             // write packets to file
  15.             /*
  16.             XThrowIfError( AudioFileWritePackets( aqr->mRecordFile,
  17.                                                   FALSE,
  18.                                                   inBuffer->mAudioDataByteSize,
  19.                                                   inPacketDesc,
  20.                                                   aqr->mRecordPacket,
  21.                                                   &inNumPackets,
  22.                                                   inBuffer->mAudioData ),
  23.                            "AudioFileWritePackets failed!");
  24.             aqr->mRecordPacket += inNumPackets;
  25.             */
  26.         }
  27.          
  28.         // if we're not stopping, re-enqueue the buffe so that it gets filled again
  29.         if ( recorder.isRunning ) {
  30.             
  31.             XThrowIfError( AudioQueueEnqueueBuffer( inAQ, inBuffer, 0, NULL ), @"AudioQueueEnqueueBuffer failed!" );
  32.         }
  33.     }
  34.     catch ( NSException *e ) {

  35.         [Dialog simpleToast:[NSString stringWithFormat:@"Error: %@ (%@)\n", [e name], [e reason]]];
  36.         // DLog(@"Error: %@ (%@)\n", [e name], [e reason]);
  37.     }
  38. }
复制代码
通过[recorder.mp3Encoder encodePcmData:inBuffer->mAudioData withDataSize:inNumPackets];
把PCM数据扔给MP3编码器
  1. - (void)encodePcmData:(void *)pcmBuffer withDataSize:(UInt32)pcmDataSize {

  2.         int mp3DataSize = pcmDataSize * 4;
  3.          
  4.         unsigned char mp3Buffer[mp3DataSize];
  5.          
  6.         int encodedBytes = lame_encode_buffer( lame, pcmBuffer, pcmBuffer, pcmDataSize, mp3Buffer, mp3DataSize );
  7.         //lame_encode_buffer_interleaved( lame, pcmBuffer, PCM_DATA_SIZE, mp3Buffer, MP3_DATA_SIZE );
  8.          
  9.         NSData *mp3Data = [NSData dataWithBytes:&mp3Buffer length:encodedBytes];
  10. }
复制代码
之前在BaiDu上搜了一些文章,都是把PCM文件转成MP3文件的,所用的方法是lame_encode_buffer_interleaved
而且传递数据长度的参数,用的是inBuffer->mAudioDataByteSize
也许转换文件用这个方法可以,也有可能是PCM的格式问题,用这个方法编码出来的数据,有问题,爆音,而且,声音断断续续

在StackOverFlow上找到的方法,用的数据长度参数是inNumPackets,编码方法是lame_encode_buffer
结果大不相同!

我为人人,人人为我!
回复

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

推荐阅读 More>
广告位

Powered by Discuz X3.2

© 2001-2016   

合作伙伴

返回顶部 返回列表