Skip to content

Instantly share code, notes, and snippets.

@joanmolinas
Created May 6, 2020 09:09
Show Gist options
  • Save joanmolinas/543c125d397d00d8399f34a5bd4343a2 to your computer and use it in GitHub Desktop.
Save joanmolinas/543c125d397d00d8399f34a5bd4343a2 to your computer and use it in GitHub Desktop.
import Foundation
fileprivate typealias WavByte = UInt8
fileprivate typealias WavInt = UInt32
fileprivate typealias WavShort = UInt16
fileprivate struct WavConstants {
static let RIFF = [WavByte]("RIFF".utf8)
static let WAVE = [WavByte]("WAVE".utf8)
static let fmt = [WavByte]("fmt ".utf8)
static let data = [WavByte]("data".utf8)
static let rawSampleRate = 48000
static let sampleRate = WavInt(rawSampleRate).byteArray
static let rawBitsPerSample = 16
static let bitsPerSample = WavShort(rawBitsPerSample).byteArray
static let rawChannels = 2
static let channels = WavShort(rawChannels).byteArray
}
struct Wav {
private static let headerLength = 44
private static let intSize = MemoryLayout<WavInt>.size
private static let shortSize = MemoryLayout<WavShort>.size
func createWav(_ data: Data) -> Data {
var header = Data(capacity: Wav.headerLength)
header.append(WavConstants.RIFF, count: Wav.intSize) // Big 0...3
header.append(WavInt(data.count + Wav.headerLength - 8).byteArray, count: Wav.intSize) // Little 4...7 Filesize
header.append(WavConstants.WAVE, count: Wav.intSize) // Big 8...11
header.append(WavConstants.fmt, count: Wav.intSize) // Big 12...15
header.append(WavInt(16).byteArray, count: Wav.intSize) // Little 16...19 Length of above data
header.append(WavShort(1).byteArray, count: Wav.shortSize) // Little 20...21 Pcm format
header.append(WavConstants.channels, count: Wav.shortSize) // Little 22..23
header.append(WavConstants.sampleRate, count: Wav.intSize) // Little 24...27
header.append(WavInt((WavConstants.rawSampleRate * WavConstants.rawBitsPerSample * WavConstants.rawChannels)/8).byteArray, count: Wav.intSize) // Little 28...31
header.append(WavShort(WavConstants.rawBitsPerSample * WavConstants.rawChannels / 8).byteArray, count: Wav.shortSize) // Little 32...33
header.append(WavConstants.bitsPerSample, count: Wav.shortSize) // Little 34...35
header.append(WavConstants.data, count: Wav.intSize) // Big 36...39
header.append(WavInt(max(0, data.count - Wav.headerLength)).byteArray, count: Wav.intSize) // Little 40...43
header.append(data)
return header
}
}
fileprivate extension UInt32 {
var byteArray: [WavByte] {
// Little Endian
return [
WavByte(self & 0xff),
WavByte((self >> 8) & 0xff),
WavByte((self >> 16) & 0xff),
WavByte((self >> 32) & 0xff)
]
}
}
fileprivate extension UInt16 {
var byteArray: [WavByte] {
// Little endian
return [
WavByte(self & 0xff),
WavByte((self >> 8) & 0xff)
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment