Как использовать AVAudioSessionCategoryMultiRoute на устройстве iPhone?

Я хотел бы использовать AVAudioSessionCategoryMultiRoute, но, к сожалению, нет примера ни в Apple dev center, ни в Google. Как использовать/реализовать AVAudioSessionCategoryMultiRoute, чтобы определить 2 разных маршрута на iPhone ios7.0.4? Моя цель - направить звук как через динамик, так и через наушники. (Я знаю, что раньше это было невозможно, но я хотел бы попробовать с ios7)

Спасибо за помощь,


person user3319663    schedule 17.02.2014    source источник


Ответы (1)


Мне помогают: AVAudioEngine и Multiroute, и это: Аудиосессия и Multiroute Audio в iOS.

В моем случае я использую два метода для реализации:

сначала запросите категорию MultiRoute

[_session setCategory:AVAudioSessionCategoryMultiRoute error:nil];

Метод 1: настроить назначение каналов AVAudioPlayer:

    // My hardware has 4 output channels
    if (_outputPortChannels.count == 4) {
        AVAudioSessionChannelDescription *desiredChannel1 = [_outputPortChannels objectAtIndex:2];
        AVAudioSessionChannelDescription *desiredChannel2 = [_outputPortChannels objectAtIndex:3];

        // Create an array of desired channels
        NSArray *channelDescriptions = [NSArray arrayWithObjects:desiredChannel1, desiredChannel2, nil];

        // Assign the channels
        _avAudioPlayer1.channelAssignments = channelDescriptions;

        NSLog(@"_player.channelAssignments: %@", _avAudioPlayer1.channelAssignments);

        // Play audio to output channel3, channel4
        [_avAudioPlayer1 play];
    }

method2: пользовательская карта канала

    // Get channel map indices based on user specified channelNames
    NSMutableArray *channelMapIndices = [self getOutputChannelMapIndices:_inChannelNames];

    NSAssert(channelMapIndices && channelMapIndices.count > 0, @"Error getting indices for user specified channel names!");

    // AVAudioEngine setup
    _engine = [[AVAudioEngine alloc] init];
    _output = _engine.outputNode;
    _mixer = _engine.mainMixerNode;
    _player = [[AVAudioPlayerNode alloc] init];
    [_engine attachNode:_player];

    // open the file to play
    NSString *path1 = [[NSBundle mainBundle] pathForResource:@"yujian" ofType:@"mp3"];
    NSURL *songURL1 = [NSURL fileURLWithPath:path1];
    _songFile = [[AVAudioFile alloc] initForReading:songURL1 error:nil];

    // create output channel map
    SInt32 source1NumChannels = (SInt32)_songFile.processingFormat.channelCount;

    // I use constant map
    // Play audio to output channel3, channel4
    SInt32 outputChannelMap[4] = {-1, -1, 0, 1};

    // This will play audio to output channel1, channel2
    //SInt32 outputChannelMap[4] = {0, 1, -1, -1};

    // set channel map on outputNode AU
    UInt32 propSize = (UInt32)sizeof(outputChannelMap);
    OSStatus err = AudioUnitSetProperty(_output.audioUnit, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Global, 1, outputChannelMap, propSize);
    NSAssert(noErr == err, @"Error setting channel map! %d", (int)err);

    // make connections
    AVAudioChannelLayout *channel1Layout = [[AVAudioChannelLayout alloc] initWithLayoutTag:kAudioChannelLayoutTag_DiscreteInOrder | (UInt32)source1NumChannels];
    AVAudioFormat *format1 = [[AVAudioFormat alloc] initWithStreamDescription:_songFile.processingFormat.streamDescription channelLayout:channel1Layout];
    [_engine connect:_player to:_mixer format:format1];
    [_engine connect:_mixer to:_output format:format1];

    // schedule the file on player
    [_player scheduleFile:_songFile atTime:nil completionHandler:nil];

    // start engine and player
    if (!_engine.isRunning) {
        [_engine startAndReturnError:nil];
    }

    [_player play];

Это работает для меня.

person Antony Wong    schedule 26.01.2016
comment
Как сделать карту каналов для входов? Что делать, если у меня есть вход для внешнего USB-микрофона, и я хочу читать с канала 5? Кажется, есть только kAudioOutputUnitProperty_ChannelMap и нет kAudioInputUnitProperty_ChannelMap - person jaybers; 04.08.2016
comment
Оказывается, выходные единицы имеют как ввод, так и вывод. В этом аудиоустройстве вы бы установили обратный вызов ввода, используя файл kAudioOutputUnitProperty_SetInputCallback property. Таким образом, технически есть две карты: одна для области ввода и одна для области вывода. Таким образом, приведенный выше код должен использовать kAudioUnitScope_Output вместо kAudioUnitScope_Global. - person Patrick Beard; 17.08.2018