如何在 iPhone 上使用音频单元
Posted
技术标签:
【中文标题】如何在 iPhone 上使用音频单元【英文标题】:How to use an Audio Unit on the iPhone 【发布时间】:2009-06-25 15:09:24 【问题描述】:我正在寻找一种方法来更改录制的音频的音高,因为它被保存到磁盘或回放(实时)。我了解音频单元可用于此目的。 iPhone 对音频单元的支持有限(例如,据我所知,无法创建/使用自定义音频单元),但有几个开箱即用的音频单元可用,其中之一是 AUPitch。
我将如何使用音频单元(特别是 AUPitch)?您是否以某种方式将其连接到音频队列中?是否可以将音频单元链接在一起(例如,同时添加回声效果和音高变化)?
编辑:检查 iPhone SDK 标头后(我认为 AudioUnit.h,我现在不在 Mac 前),我注意到 AUPitch 已被注释掉。所以看起来 AUPitch 毕竟不能在 iPhone 上使用。 哭 哭
Apple 最近似乎在 developer.apple.com 上更好地组织了他们的 iPhone SDK 文档 - 现在更难找到对 AUPitch 等的引用。
也就是说,我仍然对在 iPhone 上使用音频单元(通常)的高质量答案感兴趣。
【问题讨论】:
【参考方案1】:这里有一些非常好的资源 (http://michael.tyson.id.au/2008/11/04/using-remoteio-audio-unit/) 用于使用 RemoteIO 音频单元。根据我在 iPhone 上使用音频单元的经验,我发现我可以在回调函数中手动实现转换。这样做,您可能会发现这可以解决您的问题。
【讨论】:
【参考方案2】:关于在 iPhone 上改变音调,OpenAL 是要走的路。查看 www.71squared.com 上的 SoundManager 类,了解支持音高的 OpenAL 声音引擎的一个很好的示例。
【讨论】:
请记住,OpenAL 只支持实时音频音高变化,意味着您无法保存更改后的音频【参考方案3】:- (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);
它将根据因素改变音高
【讨论】:
【参考方案4】:我之前用过 NewTimePitch 音频单元,音频组件描述是
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)
此音频单元的参数如下
// 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
;
但您只需要更改音高参数即可。有关如何实现此功能的指南,请参阅贾斯汀的回答
【讨论】:
以上是关于如何在 iPhone 上使用音频单元的主要内容,如果未能解决你的问题,请参考以下文章