How to add playable(such as wav,wmv) header with PCM data/buffer in iOS?

后端 未结 2 1175
清歌不尽
清歌不尽 2020-12-03 09:09

I am trying to add a wav header on top of raw PCM data to make it playable via AVAudioPlayer. But i couldn\'t find any solution or source code to do that on iOS using Object

2条回答
  •  温柔的废话
    2020-12-03 10:09

    Very helpful question and answer, thank you very much.

    This swift version is for those in need:

    static func createWAV(from pcmFilePath: String, to wavFilePath: String) -> Bool {
    
        // Make sure that the path does not contain non-ascii characters
        guard let fout = fopen(wavFilePath.cString(using: .ascii), "w") else { return false }
    
        guard let pcmData = try? Data(contentsOf: URL(fileURLWithPath: pcmFilePath)) else { return false }
    
        var numChannels: CShort = 1
        let numChannelsInt: CInt = 1
        var bitsPerSample: CShort = 16
        let bitsPerSampleInt: CInt = 16
        var samplingRate: CInt = 16000
        let numOfSamples = CInt(pcmData.count)
        var byteRate = numChannelsInt * bitsPerSampleInt * samplingRate / 8
        var blockAlign = numChannelsInt * bitsPerSampleInt / 8
        var dataSize = numChannelsInt * numOfSamples * bitsPerSampleInt / 8
        var chunkSize: CInt = 16
        var totalSize = 46 + dataSize
        var audioFormat: CShort = 1
    
        fwrite("RIFF".cString(using: .ascii), MemoryLayout.size, 4, fout)
        fwrite(&totalSize, MemoryLayout.size, 1, fout)
        fwrite("WAVE".cString(using: .ascii), MemoryLayout.size, 4, fout);
        fwrite("fmt ".cString(using: .ascii), MemoryLayout.size, 4, fout);
        fwrite(&chunkSize, MemoryLayout.size,1,fout);
        fwrite(&audioFormat, MemoryLayout.size, 1, fout);
        fwrite(&numChannels, MemoryLayout.size,1,fout);
        fwrite(&samplingRate, MemoryLayout.size, 1, fout);
        fwrite(&byteRate, MemoryLayout.size, 1, fout);
        fwrite(&blockAlign, MemoryLayout.size, 1, fout);
        fwrite(&bitsPerSample, MemoryLayout.size, 1, fout);
        fwrite("data".cString(using: .ascii), MemoryLayout.size, 4, fout);
        fwrite(&dataSize, MemoryLayout.size, 1, fout);
        fclose(fout);
    
        guard let handle = FileHandle(forUpdatingAtPath: wavFilePath) else { return false }
    
        handle.seekToEndOfFile()
        handle.write(pcmData)
        handle.closeFile()
    
        return true
    }
    

提交回复
热议问题