[修正]IOS中使用SoundTouch库实现变声

 之前写过一片文章“IOS中使用SoundTouch库实现变声”。

最后有很多朋友在博客上说发出来的代码在模拟器上运行可以,不能在真机上运行,前段时间一直也很忙,没时间翻代码出来查看,望谅解。

今天抽空检查了一下问题的根源,并且在IPhone 4(ios5.0.1)上测试通过,下面更新一些代码。

同样是Apple官方的SpeakHere,要下载代码的,请查看上一篇文章。

 
  1. void AQRecorder::StartRecord(CFStringRef inRecordFile) 
  2. mSoundTouch.setSampleRate(44100);//mRecordFormat.mSampleRate 
  3.     mSoundTouch.setChannels(1);//mRecordFormat.mChannelsPerFrame 
  4.     mSoundTouch.setTempoChange(1.0); 
  5.     mSoundTouch.setPitchSemiTones(9); 
  6.     mSoundTouch.setRateChange(-0.7); 
  7.  
  8.     mSoundTouch.setSetting(SETTING_SEQUENCE_MS, 40); 
  9.     mSoundTouch.setSetting(SETTING_SEEKWINDOW_MS, 16); 
  10.     mSoundTouch.setSetting(SETTING_OVERLAP_MS, 8); 
  11.      
  12.     //Only use one of the following two options 
  13.     //  mSoundTouch.setSetting(SETTING_USE_QUICKSEEK, 0); 
  14.     //  mSoundTouch.setSetting(SETTING_USE_AA_FILTER, !(0)); 
  15.     //  mSoundTouch.setSetting(SETTING_AA_FILTER_LENGTH, 32); 

红色的两行很重要,需要指明采样率和声道。如果需要使用后面注释两个变量,需要在SetupAudioFormat方法执行之后才可以,否则无效,原因大家都懂的。

将麦克风捕捉的声音回调函数按照一下代码更新。

 
  1. // ____________________________________________________________________________________ 
  2. // AudioQueue callback function, called when an input buffers has been filled. 
  3. void AQRecorder::MyInputBufferHandler(  void *                              inUserData, 
  4.                                         AudioQueueRef                       inAQ, 
  5.                                         AudioQueueBufferRef                 inBuffer, 
  6.                                         const AudioTimeStamp *              inStartTime, 
  7.                                         UInt32                              inNumPackets, 
  8.                                         const AudioStreamPacketDescription* inPacketDesc) 
  9.      
  10.     AQRecorder *aqr = (AQRecorder *)inUserData; 
  11.     try { 
  12.         if (inNumPackets > 0) { 
  13.             UInt32 audioDataByteSize = inBuffer->mAudioDataByteSize; 
  14.             CAStreamBasicDescription queueFormat = aqr->DataFormat(); 
  15.             SoundTouch *soundTouch = aqr->GetSoundTouch(); 
  16.  
  17.             uint nSamples = audioDataByteSize/queueFormat.mBytesPerPacket; 
  18.             soundTouch->putSamples((const SAMPLETYPE *)inBuffer->mAudioData,nSamples); 
  19.              
  20.             SAMPLETYPE *samples = (SAMPLETYPE *)malloc(audioDataByteSize); 
  21.             UInt32 numSamples; 
  22.             do { 
  23.                 memset(samples, 0, audioDataByteSize); 
  24.                 numSamples = soundTouch->receiveSamples((SAMPLETYPE *)samples, nSamples); 
  25.                 // write packets to file 
  26.                 XThrowIfError(AudioFileWritePackets(aqr->mRecordFile, 
  27.                                                     FALSE, 
  28.                                                     numSamples*queueFormat.mBytesPerPacket, 
  29.                                                     NULL, 
  30.                                                     aqr->mRecordPacket, 
  31.                                                     &numSamples, 
  32.                                                     samples), 
  33.                               "AudioFileWritePackets failed"); 
  34.                 aqr->mRecordPacket += numSamples; 
  35.             } while (numSamples!=0); 
  36.             free(samples); 
  37.         } 
  38.          
  39.         // if we're not stopping, re-enqueue the buffe so that it gets filled again 
  40.         if (aqr->IsRunning()) 
  41.             XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed"); 
  42.     } catch (CAXException e) { 
  43.         char buf[256]; 
  44.         fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); 
  45.     } 

原因大家自己应该能看明白。

之前是在xcode 3.x上写的代码,刚开始有朋友反馈时,我以为是版本问题产生的,结果不是。

本次更新的代码是我在xcode4.2和iphone4上测试无误的,如果还有问题的,可以仔细看看前后两篇文章。不要吧参数设置错误了。

ps:QQ经常不在线,有问题上微博:http://weibo.com/yarin





本文转自 yarin 51CTO博客,原文链接:http://blog.51cto.com/yarin/794768,如需转载请自行联系原作者


优秀的个人博客,低调大师

微信关注我们

原文链接:https://yq.aliyun.com/articles/402091

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
优质分享Android(本站安卓app)

优质分享Android(本站安卓app)

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Java Development Kit(Java开发工具)

Java Development Kit(Java开发工具)

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。

Sublime Text 一个代码编辑器

Sublime Text 一个代码编辑器

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。