Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture audio samples with specific Sample Rate like Android in iOS Swift

I am a beginner in working with sounds and AVAudioEngine in IOS, and I'm developing an application that captures the audio samples as buffer and analyze it. Furthermore, the sample rate must be 8000 kHz and also must be encoded as PCM16Bit, but the default inputNode in the AVAudioEngine is 44.1 kHz.

In Android, the process is quite simple:

AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                8000, AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT, bufferSize);

and then start the reading function for the buffer. I searched a lot, but I didn't find any similar example. Instead, all the examples in which I encountered are capturing the samples in the default node's sample rate(44.1 kHz) like:

    let input = audioEngine.inputNode
    let inputFormat = input.inputFormat(forBus: 0)
    input.installTap(onBus: 0, bufferSize: 640, format: inputFormat) { (buffer, time) -> Void in
                print(inputFormat)
                if let channel1Buffer = buffer.floatChannelData?[0] {
                    for i in 0...Int(buffer.frameLength-1) {
                        print(channel1Buffer[i])
                    }
                }
            }
try! audioEngine.start()

So I would like to capture audio samples using AVAudioEngine with 8000 kHz sample rate and PCM16Bit encoding.

*Edit: I reached a solution to transform the input to 8 kHz:

    let inputNode = audioEngine.inputNode
    let downMixer = AVAudioMixerNode()
    let main = audioEngine.mainMixerNode

    let format = inputNode.inputFormat(forBus: 0)
    let format16KHzMono = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 8000, channels: 1, interleaved: true)

    audioEngine.attach(downMixer)
    downMixer.installTap(onBus: 0, bufferSize: 640, format: format16KHzMono) { (buffer, time) -> Void in
        do{
            print(buffer.description)
            if let channel1Buffer = buffer.int16ChannelData?[0] {
                // print(channel1Buffer[0])
                for i in 0 ... Int(buffer.frameLength-1) {
                    print((channel1Buffer[i]))
                }
            }
        }
    }

    audioEngine.connect(inputNode, to: downMixer, format: format)
    audioEngine.connect(downMixer, to: main, format: format16KHzMono)
    audioEngine.prepare()
    try! audioEngine.start()

, but when I use .pcmFormatInt16 it doesn't work. However, when I use .pcmFormatFloat32 it works fine !

Thanks,,

like image 300
Mohamed Salah Avatar asked Oct 17 '22 14:10

Mohamed Salah


1 Answers

Have you checked with settings parameter

let format16KHzMono = AVAudioFormat(settings: [AVFormatIDKey: AVAudioCommonFormat.pcmFormatInt16,
                                                               AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue,
                                                               AVEncoderBitRateKey: 16,
                                                               AVNumberOfChannelsKey: 1,
                                                               AVSampleRateKey: 8000.0] as [String : AnyObject])
like image 196
Pranavan SP Avatar answered Nov 13 '22 02:11

Pranavan SP