Write array of floats to a wav audio file in swift

I have this flow now: i record audio with AudioEngine, send it to an audio processing library and get an audio buffer back, then i have a strong will to write it to a wav file but i’m totally confused how to do that in swift.

I’ve tried this snippet from another stackoverflow answer but it writes an empty and corrupted file.( load a pcm into a AVAudioPCMBuffer )

  • Cordova video / audio won't play from cdvfile:// urls after update to 3.3.0
  • Why isn't my AVPlayer volume fading out?
  • what is the best way to play sound quickly upon fast button presses xcode?
  • Determining the relative position of 2 mobile devices using ultrasound
  • Can the Libsndfile library be used on the iPhone iOS?
  • CFURLRef requires a bridged cast error
  • //get data from library
    
    var len : CLong = 0
    let res: UnsafePointer<Double> = getData(CLong(), &len )
    let bufferPointer: UnsafeBufferPointer = UnsafeBufferPointer(start: res, count: len)
    
    //tranform it to Data
    
    let arrayDouble = Array(bufferPointer)
    let arrayFloats = arrayDouble.map{Float($0)}
    let data = try Data(buffer: bufferPointer)
    
    //attempt to write in file
        do {
            let format = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 16000, channels: 2, interleaved: false)
    
            var buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: AVAudioFrameCount(data.count))
            buffer.floatChannelData!.pointee.withMemoryRebound(to: UInt8.self, capacity: data.count) {
                let stream = OutputStream(toBuffer: $0, capacity: data.count)
                stream.open()
                _ = data.withUnsafeBytes {
                    stream.write($0, maxLength: data.count)
                }
                stream.close()
            }
            //settings are from AudioEngine.inputNode!.inputFormat(forBus: 0).settings
    
            var audioFile = try AVAudioFile(forWriting: url, settings: settings)
            try audioFile.write(from: buffer)
    
        } catch let error as NSError {
            print("ERROR HERE", error.localizedDescription)
        }
    

    So, i guess i do this transform of floatChannelData wrong or everything wrong. Any suggestions or pointers where to read about it would be great!

    Solutions Collect From Internet About “Write array of floats to a wav audio file in swift”

    With a great colleague help we’ve managed to get it to work. Apparently, AudioPCMBuffer after filling also needs to be notified about it’s new size.
    Also i was using totally wrong formats.

    Here is the code:

    let SAMPLE_RATE =  Float64(16000.0)
    
    let outputFormatSettings = [
        AVFormatIDKey:kAudioFormatLinearPCM,
        AVLinearPCMBitDepthKey:32,
        AVLinearPCMIsFloatKey: true,
        //  AVLinearPCMIsBigEndianKey: false,
        AVSampleRateKey: SAMPLE_RATE,
        AVNumberOfChannelsKey: 1
        ] as [String : Any]
    
    let audioFile = try? AVAudioFile(forWriting: url, settings: outputFormatSettings, commonFormat: AVAudioCommonFormat.pcmFormatFloat32, interleaved: true)
    
    let bufferFormat = AVAudioFormat(settings: outputFormatSettings)
    
    let outputBuffer = AVAudioPCMBuffer(pcmFormat: bufferFormat, frameCapacity: AVAudioFrameCount(buff.count))
    
    // i had my samples in doubles, so convert then write
    
    for i in 0..<buff.count {
        outputBuffer.floatChannelData!.pointee[i] = Float( buff[i] )
    }
    outputBuffer.frameLength = AVAudioFrameCount( buff.count )
    
    do{
        try audioFile?.write(from: outputBuffer)
    
    } catch let error as NSError {
        print("error:", error.localizedDescription)
    }