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
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
}