3

Appleの推奨に従って、I/Oオーディオユニットを使用してオーディオの録音と再生を同時に行うiPhoneアプリを作成しています。

再生する前に、録音したオーディオにいくつかの効果音(リバーブなど)を適用したいと思います。これらの効果をうまく機能させるには、サンプルを整数ではなく浮動小数点数にする必要があります。AudioStreamBasicDescriptionwith kAudioFormatFlagIsFloatset 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);

ただし、これを実行すると(iPhoneOS3.1.3を実行しているiPhone3GSで)、次のようになります。

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

(-10868はの値ですkAudioUnitErr_FormatNotSupported

16ビットのリトルエンディアンの整数に固執することを推奨していることを除けば、Appleのドキュメントには価値のあるものは何も見つかりませんでした。ただし、aurioTouchサンプルプロジェクトには、に関連するサポートコードが少なくともいくつか含まれていkAudioFormatFlagIsFloatます。

それで、私のストリームの説明は正しくありkAudioFormatFlagIsFloatませんか、それとも単にiPhoneOSでサポートされていませんか?

4

5 に答える 5

4

私の知る限り、サポートされていません。AudioConverterを使用すると、かなり簡単に float に変換できます。iOS オーディオで Accelerate フレームワークを使用するために、この変換 (両方の方法) をリアルタイムで行います。(注: このコードは、よりモジュール化されたコードからコピーして貼り付けたものであるため、小さなタイプミスがある可能性があります)

まず、入力から 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
于 2011-12-01T03:58:15.743 に答える
3

とは関係ないことをしていますが、iOSでAudioUnits使用しています。AudioStreamBasicDescription次のように指定することで、float サンプルを使用できました。

dstFormat.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagsNativeEndian | kLinearPCMFormatFlagIsPacked;

Learning Core Audio: A Hands-on Guide to Audio Programming for Mac and iOSがこれに役立ちました。

于 2013-11-21T02:38:48.650 に答える
2

サポートされています。

kAudioFormatFlagIsNonInterleaved問題は、 も設定する必要があることですmFormatFlags。設定時にこれを行わないkAudioFormatFlagIsFloatと、フォーマットエラーが発生します。

したがって、次のような準備をするときは、次のようにしますAudioStreamBasicDescription

streamDescription.mFormatFlags = kAudioFormatFlagIsFloat | 
                                 kAudioFormatFlagIsNonInterleaved;

iOS がこれを必要とする理由については、よくわかりません。試行錯誤して偶然見つけただけです。

于 2012-11-21T03:47:23.650 に答える
0

Core Audio ドキュメントから:

kAudioFormatFlagIsFloat
  Set for floating point, clear for integer.
  Available in iPhone OS 2.0 and later.
  Declared in CoreAudioTypes.h.

あなたのストリームについて、その[不正確さ]についてコメントできるほど十分に知りません。

于 2010-06-20T20:04:40.770 に答える