AVAudioEngine downsample issue

后端 未结 3 889
甜味超标
甜味超标 2020-12-11 06:04

I\'m having an issue with downsampling audio taken from the microphone. I\'m using AVAudioEngine to take samples from the microphone with the following code:



        
相关标签:
3条回答
  • 2020-12-11 06:58

    The only thing I found that worked to change the sampling rate was

    AVAudioSettings.sharedInstance().setPreferredSampleRate(...)
    

    Unfortunately, there is no guarantee that you will get the sample rate that you want, although it seems like 8000, 12000, 16000, 22050, 44100 all worked.

    The following did NOT work:

    1. Setting the my custom format in a tap off engine.inputNode. (Exception)
    2. Adding a mixer with my custom format and tapping that. (Exception)
    3. Adding a mixer, connecting it with the inputNode's format, connecting the mixer to the main mixer with my custom format, then removing the input of the outputNode so as not to send the audio to the speaker and get instant feedback. (Worked, but got all zeros)
    4. Not using my custom format at all in the AVAudioEngine, and using AVAudioConverter to convert from the hardware rate in my tap. [Length of the buffer was not set, no way to tell if results were correct]
    0 讨论(0)
  • 2020-12-11 07:03

    I solved this issue by simply changing my mixers volume to 0.

    mixer.volume = 0
    

    This makes me able to take advantage of the engines main mixer awesome ability to resample any samplerate to my desired samplerate, and not hearing the microphone feedback loop coming directly out from the speakers. If anyone needs any clarifying about this please let me know.

    This is my code now:

    assert(self.engine.inputNode != nil)
    let input = self.engine.inputNode!
    
    let audioFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 8000, channels: 1, interleaved: false)    
    let mixer = AVAudioMixerNode()
    engine.attach(mixer)
    engine.connect(input, to: mixer, format: input.inputFormat(forBus: 0))
    mixer.volume = 0
    engine.connect(mixer, to: mainMixer, format: audioFormat)
    
    do {
        try engine.start()
    
        mixer.installTap(onBus: 0, bufferSize: 1024, format: audioFormat, block: {
            (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in
            //some code here
        })
    
    } catch let error {
        print(error.localizedDescription)
    }
    
    0 讨论(0)
  • 2020-12-11 07:05

    An other way to do it , with AVAudioConverter in Swift 5

    let engine = AVAudioEngine()
    
    
    func setup() {
    
        let input = engine.inputNode
        let bus = 0
        let inputFormat = input.outputFormat(forBus: bus )
        guard let outputFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 8000, channels: 1, interleaved: true), let converter = AVAudioConverter(from: inputFormat, to: outputFormat) else{
            return
        }
    
        input.installTap(onBus: bus, bufferSize: 1024, format: inputFormat) { (buffer, time) -> Void in
            var newBufferAvailable = true
    
            let inputCallback: AVAudioConverterInputBlock = { inNumPackets, outStatus in
                if newBufferAvailable {
                    outStatus.pointee = .haveData
                    newBufferAvailable = false
                    return buffer
                } else {
                    outStatus.pointee = .noDataNow
                    return nil
                }
            }
    
            if let convertedBuffer = AVAudioPCMBuffer(pcmFormat: outputFormat, frameCapacity: AVAudioFrameCount(outputFormat.sampleRate) * buffer.frameLength / AVAudioFrameCount(buffer.format.sampleRate)){
                var error: NSError?
                let status = converter.convert(to: convertedBuffer, error: &error, withInputFrom: inputCallback)
                assert(status != .error)
    
                // 8kHz buffers
                print(convertedBuffer.format)
            }
        }
        do {
            try engine.start()
        } catch { print(error) }
    }
    
    0 讨论(0)
提交回复
热议问题