Отключите звук через динамик во время записи звука с помощью AUAudioUnit - PullRequest
0 голосов
/ 06 апреля 2020

Я пытаюсь записать звук с помощью AUAudioUnit. Я успешно получаю аудио буферы, но я также слышу записанный звук через динамик во время записи. Вопрос в том, как получить только буферы, не пропускающие звук в динамик?

func startRecording() {
    setupAudioSessionForRecording()

    do {
        let audioComponentDescription = AudioComponentDescription(
            componentType: kAudioUnitType_Output,
            componentSubType: kAudioUnitSubType_RemoteIO,
            componentManufacturer: kAudioUnitManufacturer_Apple,
            componentFlags: 0,
            componentFlagsMask: 0 )

        try auAudioUnit = AUAudioUnit(componentDescription: audioComponentDescription)
        let audioFormat = AVAudioFormat(commonFormat: .pcmFormatInt16,
                                        sampleRate: sampleRate,
                                        interleaved: true,
                                        channelLayout: AVAudioChannelLayout(layoutTag: kAudioChannelLayoutTag_Mono)!)

        try auAudioUnit.inputBusses[0].setFormat(audioFormat)
        try auAudioUnit.outputBusses[1].setFormat(audioFormat)
    } catch {
        print(error)
    }

    auAudioUnit.isInputEnabled  = true

    auAudioUnit.outputProvider = {(actionFlags, timestamp, frameCount, inputBusNumber, inputData) -> AUAudioUnitStatus in
        let err : OSStatus = self.auAudioUnit.renderBlock(actionFlags,
                                                          timestamp,
                                                          frameCount,
                                                          1,
                                                          inputData,
                                                          .none)
        if err == noErr {
            self.processMicrophoneBuffer(inputDataList:  inputData,
                                         frameCount: UInt32(frameCount) )
        } else {
            print(err)
        }
        return err
    }

    do {
        try auAudioUnit.allocateRenderResources()
        try auAudioUnit.startHardware()
    } catch {
        print(error)
    }
}

РЕШЕНИЕ:

Решение было найдено здесь: https://gist.github.com/leonid-s-usov/dcd674b0a8baf96123cac6c4e08e3e0c

Идея состоит в том, чтобы вызывать блок рендеринга внутри inputHandler вместо outputProvider

auAudioUnit.inputHandler = { (actionFlags, timestamp, frameCount, inputBusNumber) in
    var bufferList = AudioBufferList(mNumberBuffers: 1,
                                     mBuffers: AudioBuffer(
                                     mNumberChannels: audioFormat!.channelCount,
                                     mDataByteSize: 0,
                                     mData: nil))

    let err: OSStatus = block(actionFlags,
                              timestamp,
                              frameCount,
                              inputBusNumber,
                              &bufferList,
                              .none)
    if err == noErr {
        self.processMicrophoneBuffer(inputDataList: inputData,
                                     frameCount: UInt32(frameCount) )
    } else {
        print(err)
    }
}

1 Ответ

0 голосов
/ 07 апреля 2020

Один из способов заглушить вывод RemoteIO - обнуление содержимого (выборок frameCount) аудиобуферов в записанных входных данных после обработки (копирования) каждого буфера.

...