iPhoneOS 支持 kAudioFormatFlagIsFloat 吗?

2024-05-04

我正在编写一个 iPhone 应用程序,它使用 I/O 音频单元同时录制和播放音频苹果的建议 http://developer.apple.com/iphone/library/codinghowtos/AudioAndVideo/index.html#PLAYBACK-RECORD_AND_PLAY_BACK_AUDIO_AT_THE_SAME_TIME.

我想在播放之前对录制的音频应用一些声音效果(混响等)。为了使这些效果正常工作,我需要样本是浮点数,而不是整数。看来这应该是可能的,通过创建一个AudioStreamBasicDescription with kAudioFormatFlagIsFloat set on mFormatFlags。这就是我的代码的样子:

AudioStreamBasicDescription streamDescription;

streamDescription.mSampleRate = 44100.0;
streamDescription.mFormatID = kAudioFormatLinearPCM;
streamDescription.mFormatFlags = kAudioFormatFlagIsFloat;
streamDescription.mBitsPerChannel = 32;
streamDescription.mBytesPerFrame = 4;
streamDescription.mBytesPerPacket = 4;
streamDescription.mChannelsPerFrame = 1;
streamDescription.mFramesPerPacket = 1;
streamDescription.mReserved = 0;

OSStatus status;

status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamDescription, sizeof(streamDescription));
if (status != noErr)
  fprintf(stderr, "AudioUnitSetProperty (kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input) returned status %ld\n", status);

status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &streamDescription, sizeof(streamDescription));
if (status != noErr)
  fprintf(stderr, "AudioUnitSetProperty (kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output) returned status %ld\n", status);

然而,当我运行这个(在运行 iPhoneOS 3.1.3 的 iPhone 3GS 上)时,我得到:

AudioUnitSetProperty (kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input) returned error -10868
AudioUnitSetProperty (kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output) returned error -10868

(-10868 的值是kAudioUnitErr_FormatNotSupported)

我在苹果的文档中没有找到任何有价值的东西,除了推荐 http://developer.apple.com/iphone/library/codinghowtos/AudioAndVideo/index.html#PLAYBACK-CHOOSE_THE_BEST_AUDIO_FORMATS_IN_IPHONE_OS坚持 16 位小端整数。但是,那奥里奥触摸 http://developer.apple.com/iphone/library/samplecode/aurioTouch/Introduction/Intro.html示例项目至少包含一些相关的支持代码kAudioFormatFlagIsFloat.

那么,我的流描述是否不正确,或者是kAudioFormatFlagIsFloatiPhoneOS 根本不支持?


据我所知,不支持。你can尽管使用 AudioConverter,但很容易转换为浮点数。我实时进行此转换(两种方式),以将 Accelerate 框架与 iOS 音频结合使用。 (注意:此代码是从更模块化的代码复制并粘贴的,因此可能存在一些小拼写错误)

首先,您需要输入中的 AudioStreamBasicDescription。说

AudioStreamBasicDescription aBasicDescription = {0};
aBasicDescription.mSampleRate       = self.samplerate;
aBasicDescription.mFormatID         = kAudioFormatLinearPCM;
aBasicDescription.mFormatFlags      = kAudioFormatFlagIsSignedInteger |     kAudioFormatFlagIsPacked;
aBasicDescription.mFramesPerPacket          = 1;
aBasicDescription.mChannelsPerFrame     = 1;
aBasicDescription.mBitsPerChannel       = 8 * sizeof(SInt16);
aBasicDescription.mBytesPerPacket       = sizeof(SInt16) * aBasicDescription.mFramesPerPacket;
aBasicDescription.mBytesPerFrame        = sizeof(SInt16) * aBasicDescription.mChannelsPerFrame

然后,为float生成对应的AudioStreamBasicDescription。

AudioStreamBasicDescription floatDesc = {0};
floatDesc.mFormatID = kAudioFormatLinearPCM;      
floatDesc.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked;
floatDesc.mBitsPerChannel = 8 * sizeof(float);
floatDesc.mFramesPerPacket = 1;                                          
floatDesc.mChannelsPerFrame = 1;           
floatDesc.mBytesPerPacket = sizeof(float) * floatDesc.mFramesPerPacket;                                                                            
floatDesc.mBytesPerFrame = sizeof(float) * floatDesc.mChannelsPerFrame;                                                                                   
floatDesc.mSampleRate = [controller samplerate];

制作一些缓冲区。

UInt32 intSize = inNumberFrames * sizeof(SInt16);
UInt32 floatSize = inNumberFrames * sizeof(float);
float *dataBuffer = (float *)calloc(numberOfAudioFramesIn, sizeof(float));

然后转换。 (ioData 是包含 int 音频的 AudioBufferList)

AudioConverterRef converter;
OSStatus err = noErr;
err = AudioConverterNew(&aBasicDescription, &floatDesct, &converter);
//check for error here in "real" code
err = AudioConverterConvertBuffer(converter, intSize, ioData->mBuffers[0].mData, &floatSize, dataBuffer);
//check for error here in "real" code
//do stuff to dataBuffer, which now contains floats
//convert the floats back by running the conversion the other way
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iPhoneOS 支持 kAudioFormatFlagIsFloat 吗? 的相关文章

随机推荐