IOS中使用SoundTouch库实现变声

原创 2017年08月26日 17:40:18
IOS中使用SoundTouch库实现变声
  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.     } 


      这个简单的歌声合成程序,我称它为FA♂乐器好了,因为音源是FA(滑稽

 http://files.cnblogs.com/files/CodeMIRACLE/fa.zip

  开发环境是win10 CodeBlock+Mingw32,直接把源代码添加到工程里。source\SouthStretch文件夹里面有个WavFile.cpp提供了一系列对WAV文件操作的函数,很方便,直接加进工程里使用。

  程序的设计参考了官方SouthStretch的实现。编译的时候这个库的SSE和MMX优化会报编译错误,我就把那些优化的代码都注释掉了。

  SoundTouch的使用十分简单

复制代码
  1  #include <stdexcept>
  2  #include <stdio.h>
  3  #include <string.h>
  4  #include <time.h>
  5  #include<cstdlib>
  6  #include "WavFile.h"
  7  #include "SoundTouch.h"
  8  #include "BPMDetect.h"
  9  #include<iostream>
 10  #include<algorithm>
 11  #include "STTypes.h"
 12  #include <vector>
 13  #include <sstream>
 14  #include <map>
 15  #include <windows.h>
 16  using namespace soundtouch;
 17  using namespace std;
 18  #define BUFF_SIZE           6720
 19  map<string,int> tonemap;
 20  template<class T>
 21  string tostring(T& x)
 22  {
 23      stringstream ss;
 24      ss<<x;
 25      return ss.str();
 26  }
 27  void InitToneMap()
 28  {
 29      string keys[]={"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};
 30      for(int i=0;i<=10;i++)
 31      {
 32          for(int j=0;j<12;j++)
 33             tonemap[keys[j]+tostring(i)]=i*12+j-82;
 34      }
 35  }
 36  void WriteVoidSample(WavOutFile* wavout,SoundTouch* pSoundTouch,int num,int channels,double tempo)
 37  {
 38          short *sampleBuffer=new short[num];
 39          memset(sampleBuffer,0,sizeof(short)*num);
 40          pSoundTouch->setTempo(tempo);
 41          pSoundTouch->putSamples(sampleBuffer,num/channels);
 42          pSoundTouch->receiveSamples(sampleBuffer,num);
 43          wavout->write(sampleBuffer,num);
 44          delete []sampleBuffer;
 45  }
 46  void WriteProcessSample(WavInFile* wavin,WavOutFile* wavout,SoundTouch* pSoundTouch,int tone,double tempo)
 47  {
 48          int nSamples;
 49          int nChannels;
 50          int buffSizeSamples;
 51          short *sampleBuffer=new short[BUFF_SIZE];
 52          pSoundTouch->setPitchSemiTones(tone);
 53          pSoundTouch->setTempo(tempo);
 54          while(!wavin->eof())
 55          {
 56              int num;
 57              num = wavin->read(sampleBuffer, BUFF_SIZE);
 58              nSamples = num / (int)wavin->getNumChannels();
 59              nChannels = (int)wavin->getNumChannels();
 60              buffSizeSamples = BUFF_SIZE / nChannels;
 61              pSoundTouch->putSamples(sampleBuffer, nSamples);
 62              do
 63              {
 64                  nSamples = pSoundTouch->receiveSamples(sampleBuffer,buffSizeSamples);
 65                  wavout->write(sampleBuffer, nSamples * nChannels);
 66              } while (nSamples != 0);
 67          }
 68          wavin->rewind();
 69          pSoundTouch->clear();
 70          delete []sampleBuffer;
 71  }
 72  int main()
 73  {
 74      FILE* fp=fopen("tone.txt","r");
 75      if(fp)
 76      {
 77          WavInFile *wavin;
 78          WavOutFile *wavout;
 79          SoundTouch *pSoundTouch;
 80          wavin = new WavInFile("fa.wav");
 81          pSoundTouch = new SoundTouch;
 82          pSoundTouch->setSampleRate(wavin->getSampleRate());
 83          pSoundTouch->setChannels(wavin->getNumChannels());
 84          wavout = new WavOutFile("out.wav",wavin->getSampleRate(),wavin->getNumBits(),wavin->getNumChannels());
 85          InitToneMap();
 86          char tone[4];
 87          double meter;
 88          while(~fscanf(fp,"%s%lf",tone,&meter))
 89          {
 90                  if(tone[0]!='0')
 91                      WriteProcessSample(wavin,wavout,pSoundTouch,tonemap[tone],1/meter);
 92                  else
 93                      WriteVoidSample(wavout,pSoundTouch,wavin->getDataSizeInBytes(),wavin->getNumChannels(),1/meter);
 94          }
 95          delete wavin;
 96          delete wavout;
 97          delete pSoundTouch;
 98          PlaySound("out.wav",NULL,SND_SYNC);
 99      }
100  }
复制代码

 


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

通过开源项目SoundTouch实现类似Tom猫的变声功能

SoundTouch是一个开源的音频处理库,用于改变音频流或音频文件的节奏、音调和播放速率。         通过调节Tempo、Pitch和Playback Rate可以实现类似Tom猫的变声效果...
  • zmywly
  • zmywly
  • 2014年10月30日 20:41
  • 6764

在ios中使用soundtouch库实现变声

要在ios中实现一个变声技术,而且又要要求能在iphone 3g上也能运行,所以自带的一些api就显得比较麻烦,因此决定使用soundtouch开源库,该库可以实现变声效果,包括可以调节声音的频率而...

iOS变声语音项目总结

最近做了一个变声语音的项目,里面涉及到很多音频相关的知识,怕时间久了记不住,写下来备忘。 1. 语音的编码      语音录制的时候要选择一个编码格式,因为移动端的原因,这个编码格式需要满足压缩比高、...

IOS音频变成之变声处理

IOS音频编程之变声处理需求耳塞Mic实时录音变声处理后实时输出 初始化 程序使用44100HZ的频率对原始的音频数据进行采样并在音频输入的回调中处理采样的数据 音频处理 预备知识 音频输入输出回调函...

soundtouch之变调、变速、节拍

前一段日子在做变调不变速的算法,通过频域实现,谁知道到相位同步一直搞不定了,声音效果比较差。后来去偶然看到了soundtouch,这个强大的库让我为之振奋,现在已经完成,并做成了一个实时播放的demo...

在ios中使用soundtouch库实现变声

这篇文章是项目总结了。 做了段时间的项目,过程中也遇到了很多麻烦,但是好在终于都解决了,这里是这里是项目之后凭着记忆总结出来,大家有遇到同样的问题,希望能参考了,但是我记忆可能不太好了,要是实践...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

音频文件变调

使用soundtouch实现变调,使用ffmpeg实现解码,基于mac平台。

在ios中使用soundtouch库实现变声 2011-08-16 11:36:56

标签:ios iphone开发 soundtouch 变声技术 talkingtom 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将...

soundtouch 变声使用和算法

soundtouch 源码下载地址 编译完成之后$soundstretch --help This program is subject to (L)GPL license. Run "so...
  • dangxw_
  • dangxw_
  • 2016年03月24日 19:39
  • 4090
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IOS中使用SoundTouch库实现变声
举报原因:
原因补充:

(最多只允许输入30个字)