我正在编写一个iPhone应用程序,它应该记录用户的声音,并将音频数据输入库中进行修改,例如改变速度和音高.我开始使用Apple的SpeakHere示例代码:
http://developer.apple.com/library/ios/#samplecode/SpeakHere/Introduction/Intro.html
该项目为记录用户的声音并播放它奠定了基础.它运作良好.
现在我正在深入研究代码,我需要弄清楚如何将音频数据输入SoundTouch库(http://www.surina.net/soundtouch/)来改变音高.我在浏览代码时熟悉了音频队列框架,并找到了从录音中接收音频数据的地方.
实质上,您调用AudioQueueNewInput创建新的输入队列.您传递一个回调函数,每当有一大块音频数据可用时调用该函数.在这个回调中,我需要将数据块传递给SoundTouch.
我有所有的设置,但我从SoundTouch库回放的噪音是非常严重的(它几乎不像原来的).如果我没有通过SoundTouch传递它并播放原始音频它工作正常.
基本上,我错过了一些关于我得到的实际数据的信息.我假设我得到的是一个shorts 流样本,每个通道有1个样本.这就是SoundTouch所期待的,所以它不可能以某种方式正确.
以下是设置音频队列的代码,以便您可以看到它的配置方式.
void AQRecorder::SetupAudioFormat(UInt32 inFormatID)
{
memset(&mRecordFormat, 0, sizeof(mRecordFormat));
UInt32 size = sizeof(mRecordFormat.mSampleRate);
XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate,
&size,
&mRecordFormat.mSampleRate), "couldn't get hardware sample rate");
size = sizeof(mRecordFormat.mChannelsPerFrame);
XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels,
&size,
&mRecordFormat.mChannelsPerFrame), "couldn't get input channel count");
mRecordFormat.mFormatID = inFormatID;
if (inFormatID == kAudioFormatLinearPCM)
{
// if we want pcm, default to signed 16-bit little-endian
mRecordFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
mRecordFormat.mBitsPerChannel = 16;
mRecordFormat.mBytesPerPacket = mRecordFormat.mBytesPerFrame = (mRecordFormat.mBitsPerChannel / 8) * mRecordFormat.mChannelsPerFrame; …Run Code Online (Sandbox Code Playgroud) iphone ×1