AVAudioSession, AudioStreamBasicDescription и устройства RemoteIO по умолчанию

Я пытаюсь написать приложение, которое будет выполнять цифровую обработку сигналов, и хочу сделать его максимально легким. Одной вещью, которая некоторое время меня смущала, было то, какими могут быть значения по умолчанию для различных устройств, чтобы я мог избежать нежелательных преобразований, происходящих до того, как я получил данные из буферов. Я наткнулся на следующую ссылку http://club15cc.com/code-snippets/ios-2/get-the-default-output-stream-format-for-an-audio-unit-in-ios которые поставили меня на то, что я считаю правильным путем.

Я расширил код из ссылки для создания и активации AVAudioSession до получения содержимого ASBD (AudioStreamBasicDescription), затем AudioSession можно использовать для запроса различных «предпочтительных» настроек, чтобы увидеть, какое влияние они оказывают. Я также объединил код Apple для перечисления значений ASBD с кодом из приведенной выше ссылки.

Приведенный ниже код помещается в файл ViewController.m, созданный путем выбора шаблона приложения с одним представлением. Обратите внимание, что вам потребуется добавить AudioToolbox.framework и CoreAudio.framework в связанные платформы и библиотеки проекта.

#import "ViewController.h"
@import AVFoundation;
@import AudioUnit;

@interface ViewController ()

@end

@implementation ViewController

- (void) printASBD:(AudioStreamBasicDescription) asbd {
    char formatIDString[5];
    UInt32 formatID = CFSwapInt32HostToBig (asbd.mFormatID);
    bcopy (&formatID, formatIDString, 4);
    formatIDString[4] = '\0';

    NSLog (@"  Sample Rate:         %10.0f",  asbd.mSampleRate);
    NSLog (@"  Format ID:           %10s",    formatIDString);
    NSLog (@"  Format Flags:        %10X",    (unsigned int)asbd.mFormatFlags);
    NSLog (@"  Bytes per Packet:    %10d",    (unsigned int)asbd.mBytesPerPacket);
    NSLog (@"  Frames per Packet:   %10d",    (unsigned int)asbd.mFramesPerPacket);
    NSLog (@"  Bytes per Frame:     %10d",    (unsigned int)asbd.mBytesPerFrame);
    NSLog (@"  Channels per Frame:  %10d",    (unsigned int)asbd.mChannelsPerFrame);
    NSLog (@"  Bits per Channel:    %10d",    (unsigned int)asbd.mBitsPerChannel);
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSError *error = nil;
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];

    // Get a reference to the AudioSession and activate it
    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
    [audioSession setActive:YES error:&error];


    // Then get RemoteIO AudioUnit and use it to get the content of the default AudioStreamBasicDescription
    AudioUnit remoteIOUnit;

    AudioComponentDescription audioComponentDesc = {0};
    audioComponentDesc.componentType = kAudioUnitType_Output;
    audioComponentDesc.componentSubType = kAudioUnitSubType_RemoteIO;
    audioComponentDesc.componentManufacturer = kAudioUnitManufacturer_Apple;

    // Get component
    AudioComponent audioComponent = AudioComponentFindNext(NULL, &audioComponentDesc);
    AudioComponentInstanceNew(audioComponent, &remoteIOUnit);

    // Read the stream format
    size_t asbdSize = sizeof(AudioStreamBasicDescription);
    AudioStreamBasicDescription asbd = {0};
    AudioUnitGetProperty(remoteIOUnit,
                         kAudioUnitProperty_StreamFormat,
                         kAudioUnitScope_Output,
                         0,
                         (void *)&asbd,
                         &asbdSize);

    [self printASBD:asbd];
}

@end

Мне было бы интересно узнать результаты, которые люди получают для другого реального оборудования. Обратите внимание, что код был собран и развернут в IOS 7.1.


person TJA    schedule 22.04.2014    source источник


Ответы (1)


Флаги формата:

kAudioFormatFlagIsFloat                  = (1 << 0),    // 0x1
kAudioFormatFlagIsBigEndian              = (1 << 1),    // 0x2
kAudioFormatFlagIsSignedInteger          = (1 << 2),    // 0x4
kAudioFormatFlagIsPacked                 = (1 << 3),    // 0x8
kAudioFormatFlagIsAlignedHigh            = (1 << 4),    // 0x10
kAudioFormatFlagIsNonInterleaved         = (1 << 5),    // 0x20
kAudioFormatFlagIsNonMixable             = (1 << 6),    // 0x40
kAudioFormatFlagsAreAllClear             = (1 << 31),

Результаты, которые я получил для iPad 4, следующие:

Sample Rate:                  0
Format ID:                 lpcm
Format Flags:                29
Bytes per Packet:             4
Frames per Packet:            1
Bytes per Frame:              4
Channels per Frame:           2
Bits per Channel:            32

Я предполагаю, что lpcm (линейная импульсно-кодированная модуляция) не была неожиданностью, и флаги формата = x'29' kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked вместе с 32 битами на канал, похоже, указывают на ожидаемое 8,24 «фиксированное число».

person TJA    schedule 22.04.2014
comment
Благодарю за разъяснение. - person TJA; 31.03.2015
comment
Взглянув еще раз, я думаю, что вы просто видите здесь настройки по умолчанию, независимо от устройства, что отражает рекомендацию kAudioFormatFlagsNativeFloatPacked. Было бы интересно посмотреть, действительно ли kAudioFormatFlagIsNonInterleaved говорит о том, является ли устройство стереофоническим или монофоническим. - person Potatoswatter; 31.03.2015