如何使用音频单元在iPhone
-
20-08-2019 - |
题
我在寻找一种方法来改变录制音频的音调,因为它保存到磁盘,或回放(实时)。我明白了音频单元,可以用于此目的。 iPhone提供了音频单元有限的支持(例如它无法创建/使用自定义音频单元,据我可以告诉),但有几个出的现成音频单元可供选择,其中之一是AUPitch。
我会如何准确使用音频单元(具体AUPitch)?你把它嵌入音频队列不知何故?是否有可能链音频单元一起(例如,同时添加的回声效应和音高的变化)?
编辑:检查iPhone SDK头后(我想AudioUnit.h,我不是在Mac上的那一刻前),我注意到,AUPitch被注释掉。因此,它看起来并不像AUPitch是iPhone上可用毕竟。 泄水 泄水
苹果似乎有更好的在后期developer.apple.com组织了iPhone SDK文档 - 现在它更难以找到AUPitch等引用
这是说,我仍然有兴趣在质量上的答案在iPhone上使用音频单元(一般)。
解决方案
有一些很好的资源,这里( http://michael.tyson.id.au/2008/11/04/using-remoteio-audio-unit/ )使用RemoteIO音频单元。根据我的经验用在iPhone上的音频单元工作时,我发现我可以在回调函数手动实现转换。在此过程中,你可能会发现,解决您的问题。
其他提示
关于在iPhone上改变音高,OpenAL的是去的方式。检查出可用的SoundManager类类从www.71squared.com为支持节距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);
}
将根据因子改变间距
我以前使用的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
};
但你只需要改变音高参数为您的目的。关于如何实现这一指贾斯汀的回答引导