[修正]IOS中使用SoundTouch库实现变声
2012-03-08 20:26
627 查看
之前写过一片文章“IOS中使用SoundTouch库实现变声”。
最后有很多朋友在博客上说发出来的代码在模拟器上运行可以,不能在真机上运行,前段时间一直也很忙,没时间翻代码出来查看,望谅解。
今天抽空检查了一下问题的根源,并且在IPhone 4(ios5.0.1)上测试通过,下面更新一些代码。
同样是Apple官方的SpeakHere,要下载代码的,请查看上一篇文章。
void AQRecorder::StartRecord(CFStringRef inRecordFile)
{
mSoundTouch.setSampleRate(44100);//mRecordFormat.mSampleRate
mSoundTouch.setChannels(1);//mRecordFormat.mChannelsPerFrame
mSoundTouch.setTempoChange(1.0);
mSoundTouch.setPitchSemiTones(9);
mSoundTouch.setRateChange(-0.7);
mSoundTouch.setSetting(SETTING_SEQUENCE_MS, 40);
mSoundTouch.setSetting(SETTING_SEEKWINDOW_MS, 16);
mSoundTouch.setSetting(SETTING_OVERLAP_MS, 8);
//Only use one of the following two options
// mSoundTouch.setSetting(SETTING_USE_QUICKSEEK, 0);
// mSoundTouch.setSetting(SETTING_USE_AA_FILTER, !(0));
// mSoundTouch.setSetting(SETTING_AA_FILTER_LENGTH, 32);
红色的两行很重要,需要指明采样率和声道。如果需要使用后面注释两个变量,需要在SetupAudioFormat方法执行之后才可以,否则无效,原因大家都懂的。
将麦克风捕捉的声音回调函数按照一下代码更新。
// ____________________________________________________________________________________
// AudioQueue callback function, called when an input buffers has been filled.
void AQRecorder::MyInputBufferHandler( void * inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp * inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription* inPacketDesc)
{
AQRecorder *aqr = (AQRecorder *)inUserData;
try {
if (inNumPackets > 0) {
UInt32 audioDataByteSize = inBuffer->mAudioDataByteSize;
CAStreamBasicDescription queueFormat = aqr->DataFormat();
SoundTouch *soundTouch = aqr->GetSoundTouch();
uint nSamples = audioDataByteSize/queueFormat.mBytesPerPacket;
soundTouch->putSamples((const SAMPLETYPE *)inBuffer->mAudioData,nSamples);
SAMPLETYPE *samples = (SAMPLETYPE *)malloc(audioDataByteSize);
UInt32 numSamples;
do {
memset(samples, 0, audioDataByteSize);
numSamples = soundTouch->receiveSamples((SAMPLETYPE *)samples, nSamples);
// write packets to file
XThrowIfError(AudioFileWritePackets(aqr->mRecordFile,
FALSE,
numSamples*queueFormat.mBytesPerPacket,
NULL,
aqr->mRecordPacket,
&numSamples,
samples),
"AudioFileWritePackets failed");
aqr->mRecordPacket += numSamples;
} while (numSamples!=0);
free(samples);
}
// if we're not stopping, re-enqueue the buffe so that it gets filled again
if (aqr->IsRunning())
XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed");
} catch (CAXException e) {
char buf[256];
fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
}
} 原因大家自己应该能看明白。
之前是在xcode 3.x上写的代码,刚开始有朋友反馈时,我以为是版本问题产生的,结果不是。
本次更新的代码是我在xcode4.2和iphone4上测试无误的,如果还有问题的,可以仔细看看前后两篇文章。不要吧参数设置错误了。
ps:QQ经常不在线,有问题上微博:http://weibo.com/yarin
最后有很多朋友在博客上说发出来的代码在模拟器上运行可以,不能在真机上运行,前段时间一直也很忙,没时间翻代码出来查看,望谅解。
今天抽空检查了一下问题的根源,并且在IPhone 4(ios5.0.1)上测试通过,下面更新一些代码。
同样是Apple官方的SpeakHere,要下载代码的,请查看上一篇文章。
void AQRecorder::StartRecord(CFStringRef inRecordFile)
{
mSoundTouch.setSampleRate(44100);//mRecordFormat.mSampleRate
mSoundTouch.setChannels(1);//mRecordFormat.mChannelsPerFrame
mSoundTouch.setTempoChange(1.0);
mSoundTouch.setPitchSemiTones(9);
mSoundTouch.setRateChange(-0.7);
mSoundTouch.setSetting(SETTING_SEQUENCE_MS, 40);
mSoundTouch.setSetting(SETTING_SEEKWINDOW_MS, 16);
mSoundTouch.setSetting(SETTING_OVERLAP_MS, 8);
//Only use one of the following two options
// mSoundTouch.setSetting(SETTING_USE_QUICKSEEK, 0);
// mSoundTouch.setSetting(SETTING_USE_AA_FILTER, !(0));
// mSoundTouch.setSetting(SETTING_AA_FILTER_LENGTH, 32);
红色的两行很重要,需要指明采样率和声道。如果需要使用后面注释两个变量,需要在SetupAudioFormat方法执行之后才可以,否则无效,原因大家都懂的。
将麦克风捕捉的声音回调函数按照一下代码更新。
// ____________________________________________________________________________________
// AudioQueue callback function, called when an input buffers has been filled.
void AQRecorder::MyInputBufferHandler( void * inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp * inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription* inPacketDesc)
{
AQRecorder *aqr = (AQRecorder *)inUserData;
try {
if (inNumPackets > 0) {
UInt32 audioDataByteSize = inBuffer->mAudioDataByteSize;
CAStreamBasicDescription queueFormat = aqr->DataFormat();
SoundTouch *soundTouch = aqr->GetSoundTouch();
uint nSamples = audioDataByteSize/queueFormat.mBytesPerPacket;
soundTouch->putSamples((const SAMPLETYPE *)inBuffer->mAudioData,nSamples);
SAMPLETYPE *samples = (SAMPLETYPE *)malloc(audioDataByteSize);
UInt32 numSamples;
do {
memset(samples, 0, audioDataByteSize);
numSamples = soundTouch->receiveSamples((SAMPLETYPE *)samples, nSamples);
// write packets to file
XThrowIfError(AudioFileWritePackets(aqr->mRecordFile,
FALSE,
numSamples*queueFormat.mBytesPerPacket,
NULL,
aqr->mRecordPacket,
&numSamples,
samples),
"AudioFileWritePackets failed");
aqr->mRecordPacket += numSamples;
} while (numSamples!=0);
free(samples);
}
// if we're not stopping, re-enqueue the buffe so that it gets filled again
if (aqr->IsRunning())
XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed");
} catch (CAXException e) {
char buf[256];
fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
}
} 原因大家自己应该能看明白。
之前是在xcode 3.x上写的代码,刚开始有朋友反馈时,我以为是版本问题产生的,结果不是。
本次更新的代码是我在xcode4.2和iphone4上测试无误的,如果还有问题的,可以仔细看看前后两篇文章。不要吧参数设置错误了。
ps:QQ经常不在线,有问题上微博:http://weibo.com/yarin
相关文章推荐
- [修正]IOS中使用SoundTouch库实现变声 推荐
- 在ios中使用soundtouch库实现变声
- 在ios中使用soundtouch库实现变声
- IOS中使用SoundTouch库实现变声
- [项目总结]在ios中使用soundtouch库实现变声 推荐
- 在ios中使用soundtouch库实现变声 2011-08-16 11:36:56
- 转:在ios中使用soundtouch库实现变声
- 在ios中使用soundtouch库实现变声
- iOS下使用SoundTouch实现变声并转为wav格式进行播放(山寨汤姆猫完整版)
- Android使用SlidingPaneLayout实现仿IOS滑动返回
- iOS --- 使用UIActivityViewController实现分享功能
- iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载
- iOS开发笔记--使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
- 实现下拉刷新效果 IOS所有版本均可使用
- 使用Swift实现iOScollectionView广告无限滚动效果(DEMO)
- iOS实现图形编程可以使用三种API
- iOS应用开发中使用UIScrollView控件来实现图片缩放
- iOS编译FFmpeg及使用实现视频播放
- Opencv中使用Surf特征实现图像配准及对透视变换矩阵H的平移修正
- Opencv中使用Surf特征实现图像配准及对透视变换矩阵H的平移修正