AVAudioUnitSampler генерирует синусоиды после смены маршрута наушников, iOS 11 iPhone

Я столкнулся со странной проблемой на iPhone (iOS 11) при использовании AVAudioUnitSampler.

Допустим, у меня есть AVAudioUnitSampler, инициализированный звуком фортепиано. Таким образом, каждый раз, когда я подключаю или отключаю наушники, я слышу звук фортепиано плюс добавленный к нему синусоидальный тон, который становится тем громче, чем больше раз я подключаю/отключаю наушники.

Таким образом, мне кажется, что каждый раз, когда наушники подключаются/отключаются, новый сэмплер аудиоустройства будет внутренне подключен к звуковому выходу (и, поскольку он не инициализирован, он генерирует только синусоидальные тона).

Следующий класс уже показывает проблему. Обратите внимание, что я использую AudioKit для обработки MIDI-сигналов и запуска сэмплера (хотя на этом end все работает нормально, т. е. startNote() и stopNote() вызываются правильно):

class MidiController: NSObject, AKMIDIListener {

    var midi = AKMIDI()
    var engine = AVAudioEngine()
    var samplerUnit = AVAudioUnitSampler()

    override public init() {
        super.init()

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleRouteChange),
            name: .AVAudioSessionRouteChange,
            object: nil)

        midi.openInput()
        midi.addListener(self)
        engine.attach(samplerUnit)
        engine.connect(samplerUnit, to: engine.outputNode)
        startEngine()
    }

    func startEngine() {
        if (!engine.isRunning) {
            do {
                try self.engine.start()
            } catch  {
                fatalError("couldn't start engine.")
            }
        }
    }

    @objc func handleRouteChange(notification: NSNotification) {
        let deadlineTime = DispatchTime.now() + .milliseconds(100)
        DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
            self.startEngine()
        }
    }

    func receivedMIDINoteOn(noteNumber: MIDINoteNumber, velocity:MIDIVelocity, channel: MIDIChannel) {
        if velocity > 0 {
            samplerUnit.startNote(noteNumber: noteNumber, velocity: 127, channel: 0)
        } else {
            samplerUnit.stopNote(noteNumber: noteNumber, channel: 0)
        }
    }

    func receivedMIDINoteOff(noteNumber: MIDINoteNumber, velocity: MIDIVelocity, channel: MIDIChannel) {
        samplerUnit.stopNote(noteNumber: noteNumber, channel: 0)
    }
}

Я развил AudioKit и заменил пример HelloWorld минимальным проектом с помощью которого я могу воспроизвести эту проблему.

Кроме того, мне не удалось воспроизвести эту проблему на iPad с iOS 9.3 и 11, так что это может быть проблема, связанная с iPhone.

Любая помощь или предложение о том, как продолжить отладку, будут очень кстати, я очень озадачен этим, и я не являюсь экспертом по разработке аудио для iOS.

Спасибо!


person Eloi Marin    schedule 07.11.2017    source источник


Ответы (1)


Вы можете попробовать проверить, запущен ли движок в handleRouteChange, а затем отбросить его, если он запущен, а не просто запустить его. Дайте нам знать, если это сработает.

person Gene De Lisa    schedule 23.11.2017