Публикация аудиоустройства iOS

Я пытаюсь создать приложение для iOS для звука между приложениями, и похоже, что у меня проблемы с AudioOutputUnitPublish методом. Вот способ:

- (void)publishOutputAudioUnit {
    AudioComponentDescription desc = {kAudioUnitType_RemoteInstrument, 
                                     'iasp','rfoo', 0, 1};
    OSStatus result = AudioOutputUnitPublish(&desc, CFSTR("MyMusicApp"), 
                                             1, outputUnit);
    if (result != noErr) 
        NSLog(@"AudioOutputUnitPublish instrument result: %d", (int)result);

    desc = { kAudioUnitType_RemoteGenerator, 'iasp', 'rfoo', 0, 1 };
    result = AudioOutputUnitPublish(&desc, CFSTR("MyMusicApp"), 1, outputUnit);
    if (result != noErr) 
        NSLog(@"AudioOutputUnitPublish generator result: %d", (int)result);
}

Вот моя информация о plist:

<key>AudioComponents</key>
<array>
    <dict>
        <key>manufacturer</key>
        <string>rfoo</string>
        <key>name</key>
        <string>MyMusicApp</string>
        <key>subtype</key>
        <string>iasp</string>
        <key>type</key>
        <string>aurg</string>
        <key>version</key>
        <integer>1</integer>
    </dict>
    <dict>
        <key>manufacturer</key>
        <string>rfoo</string>
        <key>name</key>
        <string>MyMusicApp</string>
        <key>subtype</key>
        <string>iasp</string>
        <key>type</key>
        <string>auri</string>
        <key>version</key>
        <integer>1</integer>
    </dict>
</array>

Вот результат, который я получаю:

AudioOutputUnitPublish instrument result: -50
AudioOutputUnitPublish generator result: -50

Я знаю, что код OSStatus -50 означает недопустимый параметр ... но я не могу понять, какой из них недействителен. Может ли кто-нибудь помочь мне отладить здесь? Спасибо!


РЕДАКТИРОВАТЬ :

Просто хотел опубликовать больше кода, чтобы другие могли мне больше помочь:

У меня есть два аудиоустройства и, надеюсь, третий - MIDISynth (пока неактивен), MultiChannelMixer и RemoteIO audio unit. У меня есть обратный вызов рендеринга, прикрепленный к аудиоблоку микшера. Я предполагаю, что я что-то неправильно подключаю в своем AUGraph (ни один из примеров, которые я видел, не прикреплял обратный вызов рендеринга звука к аудиоустройству, поэтому, возможно, я делаю что-то не так). Надеюсь, кто-нибудь поймет, что я делаю неправильно!

Вот код:

- (AUGraph)createAUGraphWithSynth:(AudioUnit *)sUnit mixUnit:(AudioUnit *)mixUnit remoteUnit:(AudioUnit *)remUnit {
    // Initializations
    AUGraph graph = 0;
    OSStatus result = noErr;
    // Create graph nodes
    AUNode mixerNode, ioNode;

    // Create Component Descriptor
    AudioComponentDescription cd;
    cd.componentManufacturer    = kAudioUnitManufacturer_Apple;
    cd.componentFlags           = 0;
    cd.componentFlagsMask       = 0;

    // Init AUGraph
    Check(result = NewAUGraph(&graph));

    // Init Mixer unit
    cd.componentType    = kAudioUnitType_Mixer;
    cd.componentSubType = kAudioUnitSubType_MultiChannelMixer;
    Check(result = AUGraphAddNode(graph, &cd, &mixerNode));

    // Init io Unit
    cd.componentType    = kAudioUnitType_Output;
    cd.componentSubType = kAudioUnitSubType_RemoteIO;
    Check(result = AUGraphAddNode(graph, &cd, &ioNode));

    // Open AUGraph
    Check(AUGraphOpen(graph));

    // Get mixer unit
    Check(AUGraphNodeInfo(graph, mixerNode, NULL, mixUnit));

    // Get io unit
    Check(AUGraphNodeInfo(graph, ioNode, NULL, remUnit));

    // Set number of input busses
    UInt32 numBuses = 1;
    UInt32 size = sizeof(numBuses);
    Check(AudioUnitSetProperty(*mixUnit,
                               kAudioUnitProperty_ElementCount,
                               kAudioUnitScope_Input,
                               0, &numBuses, size));

    AudioStreamBasicDescription desc;
    const int four_bytes_per_float = 4;
    const int eight_bits_per_byte = 8;

    for (int i = 0; i < numBuses; ++i) {
        AURenderCallbackStruct callbackStruct;
        callbackStruct.inputProc        = outputCallback;
        callbackStruct.inputProcRefCon  = (__bridge void *)self;
    
        Check(AUGraphSetNodeInputCallback(graph, mixerNode, i, &callbackStruct));

        UInt32 size = sizeof(desc);
        Check(AudioUnitGetProperty(*mixUnit,
                                   kAudioUnitProperty_StreamFormat,
                                   kAudioUnitScope_Input,
                                   0, &desc, &size));
    
        memset(&desc, 0, sizeof(desc));
    

        desc.mSampleRate        = SAMPLE_RATE;
        desc.mFormatID          = kAudioFormatLinearPCM;
        desc.mFormatFlags       = kAudioFormatFlagsNativeFloatPacked 
                                | kAudioFormatFlagIsNonInterleaved;
        desc.mBytesPerPacket    = four_bytes_per_float;
        desc.mFramesPerPacket   = 1;
        desc.mBytesPerFrame     = four_bytes_per_float;
        desc.mBitsPerChannel    = four_bytes_per_float * eight_bits_per_byte;
        desc.mChannelsPerFrame  = 2;
        Check(AudioUnitSetProperty(*remUnit,
                                   kAudioUnitProperty_StreamFormat,
                                   kAudioUnitScope_Input,
                                   0, &desc, sizeof(desc)));

    }

    Check(AudioUnitSetProperty(*mixUnit,
                               kAudioUnitProperty_StreamFormat,
                               kAudioUnitScope_Output,
                               0, &desc, sizeof(desc)));

    Check(AudioUnitGetProperty(*mixUnit,
                               kAudioUnitProperty_StreamFormat,
                               kAudioUnitScope_Output,
                               0, &desc, &size));

    memset(&desc, 0, sizeof(desc));

    desc.mSampleRate        = SAMPLE_RATE;
    desc.mFormatID          = kAudioFormatLinearPCM;
    desc.mFormatFlags       = kAudioFormatFlagsNativeFloatPacked 
                            | kAudioFormatFlagIsNonInterleaved;
    desc.mBytesPerPacket    = four_bytes_per_float;
    desc.mFramesPerPacket   = 1;
    desc.mBytesPerFrame     = four_bytes_per_float;
    desc.mBitsPerChannel    = four_bytes_per_float * eight_bits_per_byte;
    desc.mChannelsPerFrame  = 2;
     
    Check(AudioUnitSetProperty(*mixUnit,
                               kAudioUnitProperty_StreamFormat,
                               kAudioUnitScope_Output,
                               0, &desc, sizeof(desc)));

    // Must configure remote io unit:
    Check(AudioUnitSetProperty(*remUnit,
                               kAudioUnitProperty_StreamFormat,
                               kAudioUnitScope_Output,
                               1, &desc, sizeof(desc)));

     // Connect nodes (synth->output)
     Check(AUGraphConnectNodeInput(graph, mixerNode, 0, ioNode, 0));

     return graph;
 }

person yun    schedule 18.02.2016    source источник


Ответы (1)


Последнее поле в AudioComponentDescription, componentFlagsMask, должно быть 0, а не 1. (См. документация. Похоже, по крайней мере, одна tutorial ошибочно идентифицирует это поле как версию компонента.)

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

person walkytalky    schedule 19.02.2016
comment
Привет, Walkytalky, спасибо, что обратились ко мне. Я установил его на 0, но все равно получаю ту же ошибку -50 :( - Я включил Inter-App Audio и фоновые режимы для аудио ... Что-то еще мне не хватает? - person yun; 19.02.2016
comment
В этом случае я бы предположил, что outputUnit не был должным образом инициализирован. Это должно быть установлено с помощью параметра remUnit в вашем методе создания графика? Если вы пройдете через это, произойдет ли это на самом деле? - person walkytalky; 22.02.2016
comment
да, похоже, я прикрепляю его неправильно, позвольте мне вернуться к вам после того, как я исправлю это ... - person yun; 22.02.2016
comment
У меня явно не было всех настроек - я не установил отображаемое имя пакета в моем plist. Мне потребовалась вечность, чтобы узнать, но теперь это публикуется! Спасибо за помощь. - person yun; 22.02.2016