iOS Core Audio: преобразование между kAudioFormatFlagsCanonical и kAudioFormatFlagsAudioUnitCanonical

Мне нужно преобразовать этот формат:

format.mSampleRate = 44100.0; format.mFormatID = kAudioFormatLinearPCM; format.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved; format.mBytesPerPacket = sizeof(AudioUnitSampleType); format.mFramesPerPacket = 1; format.mBytesPerFrame = sizeof(AudioUnitSampleType); format.mChannelsPerFrame = 2 ; format.mBitsPerChannel = sizeof(AudioUnitSampleType)*8; 

и этот формат

 format.mSampleRate = 44100.0; format.mFormatID = kAudioFormatLinearPCM; format.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical; format.mBytesPerPacket = sizeof(AudioUnitSampleType); format.mFramesPerPacket = 1; format.mBytesPerFrame = sizeof(AudioUnitSampleType); format.mChannelsPerFrame = 2; format.mBitsPerChannel = sizeof(AudioUnitSampleType)*8; 

в пределах обратного вызова звукового рендеринга, где есть следующий код и буфер [] во втором формате, а массив [] требует 1-го формата.

 for (k = 0; k < channels; k++){ buffer = (AudioUnitSampleType *) ioData->mBuffers[k].mData; for(j=0; j < samples; j++){ array[j] = buffer[j]; } } 

Я знаю, что вы можете использовать блок конвертера Apple, но я не могу использовать аудиоустройство Apple Converter в своей ситуации (есть причина).

В основном единственная разница между двумя форматами – следующий флаг для format.mFormatFlags (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift).

Как преобразовать буфер [] (содержащий данные во 2-м формате) в массив [] (содержащий данные в 1-м формате) и наоборот?

Спасибо.

Ну, если вы ссылаетесь на документы на kAudioFormatFlagsAudioUnitCanonical , вы увидите:

 kAudioFormatFlagsAudioUnitCanonical The flags for the canonical audio unit sample type. This matches AudioUnitSampleType. 

а также

 The canonical audio sample type for audio units and other audio processing in iPhone OS is noninterleaved linear PCM with 8.24-bit fixed-point samples. 

Таким образом, сэмплы в массиве buffer[] находятся в формате 8.24 бит с фиксированной точкой. Что это значит?

8.24-битный формат с фиксированной точкой используется для представления чисел с фиксированной точностью с плавающей запятой – 32-разрядное целое число, где первые 8 бит представляют всю часть, а последние 24 бита представляют дробную часть (числа после десятичной). ( Дальнейшее чтение )

В iOS Audio Units есть незначительная разница – это число с плавающей запятой (обычно) находится в [-1, 1) ( [-1.000000000000, +0.999969482421875], если быть точным ). Значения вне этого диапазона просто обрезаются при преобразовании в 16-битный PCM. Вы можете проверить, что первые 8 бит были бы 0x00 или 0xff (-1 в двух комплиментах) для большей части.

Чтобы преобразовать это представление в 16-разрядное число, используйте это:

 SIGN((SInt8)(val >> 24)) * 32768 * (val & 0xFFFFFF)/(float)(1<<24) 

То есть: извлечь знак из 8 MSB, извлечь дробное значение из 24 LSB и делить на диапазон 24-битного целого (2 ^ 24), что приведет к поплавке между 0 и 1 и, наконец, умножить это на 32768, чтобы получить значение в желаемом диапазоне.

Я не пробовал это сам, хотя, возможно, вам придется приспособить несколько вещей здесь и там.

Может быть, поздний ответ, но так как метод смещения битов не работал для меня по какой-то причине, я нашел эту альтернативу, которая прекрасно работает, в аудиографике https://github.com/tkzic/audiograph

Я немного адаптировал метод оттуда и вуаля:

 void ConvertInputToInt16(AudioStreamBasicDescription inFormat, void *buf, void *outputBuf, size_t capacity) { AudioConverterRef converter; OSStatus err; size_t bytesPerSample = sizeof(SInt16); AudioStreamBasicDescription outFormat = {0}; outFormat.mFormatID = kAudioFormatLinearPCM; outFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; outFormat.mBitsPerChannel = 8 * bytesPerSample; outFormat.mFramesPerPacket = 1; outFormat.mChannelsPerFrame = 1; outFormat.mBytesPerPacket = bytesPerSample * outFormat.mFramesPerPacket; outFormat.mBytesPerFrame = bytesPerSample * outFormat.mChannelsPerFrame; outFormat.mSampleRate = inFormat.mSampleRate; NSLog(@"description for in format: %@", descriptionForAudioFormat(inFormat)); NSLog(@"description for out format: %@", descriptionForAudioFormat(outFormat)); UInt32 inSize = capacity*sizeof(SInt32); UInt32 outSize = capacity*sizeof(SInt16); // this is the famed audio converter err = AudioConverterNew(&inFormat, &outFormat, &converter); if(noErr != err) { NSLog(@"error in audioConverterNew: %d", (int)err); } err = AudioConverterConvertBuffer(converter, inSize, buf, &outSize, outputBuf); if(noErr != err) { NSLog(@"error in audioConverterConvertBuffer: %d", err); } } 
  • Получить точное время загрузки системы на iOS / OS X
  • Monodevelop iOS Unity не может подключиться к отладчику
  • Как мне прокомментировать строки в файле .plist?
  • Как скопировать код в SVN из xcode 6.4?
  • Когда вы добавляете встроенную инфраструктуру в проект Xcode, как вы проводите различие между Debug и Release?
  • Xcode 4.5.2 продолжает рушиться на Mac OS X Mountain Lion?
  • Передача нулевого аргумента метода nonnull
  • Требования к ОС для arc4random_uniform ()
  • Переключение ветви на Xcode 9
  • Как загрузить код Google из SVN на Mac
  • Знает ли CommonCrypto, когда мой ключ недействителен, когда я расшифровываю зашифрованный текст?
  • Interesting Posts

    iOS Ожидание запуска менеджера местоположений

    обнаружение пинча для увеличения iOS

    Скрытие всплывающего окна TouchId на SecItemUpdate

    UITextField – сбой на делегатах, которые возвращают BOOL

    обнаружение пальца вверх / вниз UITapGestureRecognizer

    Ссылка на переменные экземпляра внутри блока

    существует ли способ заменить реализацию основных данных для добавления и удаления методов для отношений общим способом?

    В чем разница между dispatch_get_global_queue и dispatch_queue_create?

    Ошибка приложения после обновления модели CoreData, отображаемой в UITableView

    ios7 CameraPickerController изображение с камеры заморожено

    Фоновые уведомления FCM, не работающие в iOS

    встроить несколько контроллеров в одном окне

    прерывистая ошибка «неправильной контрольной суммы для освобожденного объекта» на CGContextDrawImage (Swift)

    Xamarin Ios – Создайте закругленные кнопки только на одной стороне

    Как добавить GIF-изображения в каталог Asset в XCode5

    Давайте будем гением компьютера.