KAudioFormatFlagIsFloat поддерживается на iPhoneOS? - PullRequest
3 голосов
/ 21 мая 2010

Я пишу приложение для iPhone, которое записывает и воспроизводит аудио одновременно с помощью аудиоустройства ввода / вывода согласно рекомендациям Apple .

Я хочу применить некоторые звуковые эффекты (реверберацию и т. Д.) К записанному звуку перед его воспроизведением. Чтобы эти эффекты работали хорошо, мне нужно, чтобы образцы были числами с плавающей точкой, а не целыми числами. Кажется, это должно быть возможно путем создания AudioStreamBasicDescription с kAudioFormatFlagIsFloat, установленным на 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);

Однако, когда я запускаю это (на iPhone 3GS под управлением iPhoneOS 3.1.3), я получаю это:

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

(- 10868 - значение kAudioUnitErr_FormatNotSupported)

Я не нашел ничего ценного в документации Apple, кроме рекомендации , чтобы придерживаться 16-битных младших порядковых чисел. Однако пример проекта aurioTouch содержит по крайней мере некоторый код поддержки, связанный с kAudioFormatFlagIsFloat.

.

Итак, мое потоковое описание неверно или kAudioFormatFlagIsFloat просто не поддерживается на iPhoneOS?

Ответы [ 4 ]

2 голосов
/ 01 декабря 2011

Насколько я знаю, это не поддерживается. Вы можете довольно легко конвертировать в поплавки, хотя и с помощью AudioConverter. Я делаю это преобразование (в обе стороны) в режиме реального времени, чтобы использовать платформу Accelerate с iOS-аудио. (примечание: этот код копируется и вставляется из более модульного кода, поэтому возможны некоторые незначительные опечатки)

Во-первых, вам понадобится описание AudioStreamBasicDescription из ввода. Say

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

Затем сгенерируйте соответствующее AudioStreamBasicDescription для float.

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 - это ваш AudioBufferList, содержащий int audio)

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
1 голос
/ 21 ноября 2013

Я делаю что-то не связанное с AudioUnits, но я использую AudioStreamBasicDescription на iOS.Я смог использовать образцы с плавающей запятой, указав:

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

Книга Изучение основного звука: практическое руководство по программированию звука для Mac и iOS было полезно для этого.

1 голос
/ 21 ноября 2012

Поддерживается.

Проблема в том, что вы также должны установить kAudioFormatFlagIsNonInterleaved на mFormatFlags.Если вы не сделаете этого при установке kAudioFormatFlagIsFloat, вы получите ошибку формата.

Итак, вы хотите сделать что-то подобное при подготовке вашего AudioStreamBasicDescription:

streamDescription.mFormatFlags = kAudioFormatFlagIsFloat | 
                                 kAudioFormatFlagIsNonInterleaved;

Что касается того, почему iOS требует этого, я не уверен - я наткнулся на него только методом проб и ошибок.

1 голос
/ 21 июня 2010

Из документации Core Audio:

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

Я недостаточно знаю о вашем потоке, чтобы прокомментировать его [in] правильность.

...