I want to playback audio data received from the network. My incoming audio PCM data are in the format Int16, 1 channel, sample rate 8000, 160 bytes/package
Now I'm not sure, which audio format iOS is supporting on the speaker side? IMHO I have to work with Float32 and the sample rate 44.100 / 48000 is that right?
So I think I have to convert my Int16 linear PCM data to Float32. Maybe I have also tu resample the data from 8k to 48k,
I'm not sure (maybe the hardware does it).
Could someone help me? Here is my current code, where I build the AVAudioPCMBuffer.
func convertInt16ToFloat32(_ data: [Int16]) -> AVAudioPCMBuffer { let audioBuffer = AVAudioPCMBuffer(pcmFormat: outputFormat!, frameCapacity: 160)! // Each real data of the array input is reduced to the interval [-1, 1] for i in 0..<data.count { // Convert the buffer to floats. (before resampling) let div: Float32 = (1.0 / 32768.0) let floatKiller = div * Float32(i) audioBuffer.floatChannelData?.pointee[i] = floatKiller } audioBuffer.frameLength = audioBuffer.frameCapacity return audioBuffer }
And on the other side I play back the created AVAudioPCMBuffer in my AVAudioEngine.
func playFromNetwork(data: [Int16]) { // data: linear data PCM-Int16, sample rate 8000, 160 bytes let audio = convertInt16ToFloat32(data) // playback converted data on AVAudioPlayerNode self.playerNode!.scheduleBuffer(audio, completionHandler: nil) Logger.Audio.log("Play audio data .....") }
Here is my setup for AVAudioEngine:
func initAudio() { try! AVAudioSession.sharedInstance().setActive(true) try! AVAudioSession.sharedInstance().setCategory(.playback) let outputFormat = AVAudioFormat.init(commonFormat: AVAudioCommonFormat.pcmFormatFloat32, sampleRate: 8000, channels: 1, interleaved: false) engine = AVAudioEngine() playerNode = AVAudioPlayerNode() engine!.attach(playerNode!) engine!.connect(playerNode!, to: engine!.mainMixerNode, format: outputFormat) engine!.prepare() try! engine!.start() playerNode!.play() }