如何在iPhone上使用audio设备
我正在寻找一种方式来改变录制audio的音调,因为它保存到磁盘,或实时播放。 我明白audio单元可以用于此。 iPhone对audio单元提供有限的支持(例如,据我所知,不可能创build/使用自定义audio单元),但是有几个现成的audio单元可用,其中之一是AUPitch。
我将如何使用audio设备(特别是AUPitch)? 你有没有把它挂到一个audio队列? 是否可以将audio单元链接在一起(例如,同时添加回声效果和音高变化)?
编辑:在检查iPhone SDK头(我认为AudioUnit.h,我现在不在Mac的面前)后,我注意到,AUPitch被注释掉。 因此,毕竟iPhone上看起来并不像AUPitch。 哭泣
苹果公司似乎最好在developer.apple.com上组织他们的iPhone SDK文档 – 现在更难以find对AUPitch的引用等等。
这就是说,我仍然对在iPhone上使用audio单元(一般)的质量问题感兴趣。
这里有一些非常好的资源( http://michael.tyson.id.au/2008/11/04/using-remoteio-audio-unit/ )用于使用RemoteIOaudio单元。 根据我在iPhone上使用Audio Units的经验,我发现我可以在callback函数中手动实现转换。 这样做,你可能会发现,解决你的问题。
关于改变iPhone上的音调,OpenAL是要走的路。 请查看www.71squared.com上提供的SoundManager类,以获取支持音高的OpenAL声音引擎的一个很好的例子。
- (void)modifySpeedOf:(CFURLRef)inputURL byFactor:(float)factor andWriteTo:(CFURLRef)outputURL { ExtAudioFileRef inputFile = NULL; ExtAudioFileRef outputFile = NULL; AudioStreamBasicDescription destFormat; destFormat.mFormatID = kAudioFormatLinearPCM; destFormat.mFormatFlags = kAudioFormatFlagsCanonical; destFormat.mSampleRate = 44100 * factor; destFormat.mBytesPerPacket = 2; destFormat.mFramesPerPacket = 1; destFormat.mBytesPerFrame = 2; destFormat.mChannelsPerFrame = 1; destFormat.mBitsPerChannel = 16; destFormat.mReserved = 0; ExtAudioFileCreateWithURL(outputURL, kAudioFileCAFType, &destFormat, NULL, kAudioFileFlags_EraseFile, &outputFile); ExtAudioFileOpenURL(inputURL, &inputFile); //find out how many frames is this file long SInt64 length = 0; UInt32 dataSize2 = (UInt32)sizeof(length); ExtAudioFileGetProperty(inputFile, kExtAudioFileProperty_FileLengthFrames, &dataSize2, &length); SInt16 *buffer = (SInt16*)malloc(kBufferSize * sizeof(SInt16)); UInt32 totalFramecount = 0; AudioBufferList bufferList; bufferList.mNumberBuffers = 1; bufferList.mBuffers[0].mNumberChannels = 1; bufferList.mBuffers[0].mData = buffer; // pointer to buffer of audio data bufferList.mBuffers[0].mDataByteSize = kBufferSize * sizeof(SInt16); // number of bytes in the buffer while(true) { UInt32 frameCount = kBufferSize * sizeof(SInt16) / 2; // Read a chunk of input ExtAudioFileRead(inputFile, &frameCount, &bufferList); totalFramecount += frameCount; if (!frameCount || totalFramecount >= length) { //termination condition break; } ExtAudioFileWrite(outputFile, frameCount, &bufferList); } free(buffer); ExtAudioFileDispose(inputFile); ExtAudioFileDispose(outputFile); }
它会根据因素改变音调
我之前使用过NewTimePitchaudio单元,audio组件描述就是这样
var newTimePitchDesc = AudioComponentDescription(componentType: kAudioUnitType_FormatConverter, componentSubType: kAudioUnitSubType_NewTimePitch, componentManufacturer: kAudioUnitManufacturer_Apple, componentFlags: 0, componentFlagsMask: 0)
那么你可以用一个AudioUnitSetParamater调用来改变音高参数。 例如,这改变了音调-1000美分
err = AudioUnitSetParameter(newTimePitchAudioUnit, kNewTimePitchParam_Pitch, kAudioUnitScope_Global, 0, -1000, 0)
这个audio单元的参数如下
// Parameters for AUNewTimePitch enum { // Global, rate, 1/32 -> 32.0, 1.0 kNewTimePitchParam_Rate = 0, // Global, Cents, -2400 -> 2400, 1.0 kNewTimePitchParam_Pitch = 1, // Global, generic, 3.0 -> 32.0, 8.0 kNewTimePitchParam_Overlap = 4, // Global, Boolean, 0->1, 1 kNewTimePitchParam_EnablePeakLocking = 6 };
但是你只需要为你的目的改变音高参数。 关于如何实现这个指南,请参阅Justin的答案