First, you will need to convert the audio file to the output format you specify. Declaring a buffer with a different format will not work.
Here's a code snippet for converting AVAudioFile into AVAudioPCMBuffer:
static func convert(audioFile: AVAudioFile, outputFormat: AVAudioFormat, pcmBlock: (AVAudioPCMBuffer) -> Void) {
let frameCount = AVAudioFrameCount(
(1024 * 64) / (audioFile.processingFormat.streamDescription.pointee.mBytesPerFrame)
)
let outputFrameCapacity = AVAudioFrameCount(
round(Double(frameCount) * (outputFormat.sampleRate / audioFile.processingFormat.sampleRate))
)
guard let inputBuffer = AVAudioPCMBuffer(pcmFormat: audioFile.processingFormat, frameCapacity: frameCount),
let outputBuffer = AVAudioPCMBuffer(pcmFormat: outputFormat, frameCapacity: outputFrameCapacity) else {
return
}
let inputBlock : AVAudioConverterInputBlock = { inNumPackets, outStatus in
do {
try audioFile.read(into: inputBuffer)
outStatus.pointee = .haveData
return inputBuffer
} catch {
if audioFile.framePosition >= audioFile.length {
outStatus.pointee = .endOfStream
return nil
} else {
outStatus.pointee = .noDataNow
return nil
}
}
}
guard let converter = AVAudioConverter(from: audioFile.processingFormat, to: outputFormat) else {
return
}
while true {
let status = converter.convert(to: outputBuffer, error: nil, withInputFrom: inputBlock)
if status == .error || status == .endOfStream {
return
}
pcmBlock(outputBuffer)
if status == .inputRanDry {
return
}
inputBuffer.frameLength = 0
outputBuffer.frameLength = 0
}
}
Then you can call this function and convert the audio file into a SHSignature. Your code might look something like this:
guard let audioURL = Bundle.main.url(forResource: "CustomAudio", withExtension: "m4a") else {
return nil
}
guard let audioFormat = AVAudioFormat(standardFormatWithSampleRate: 44100, channels: 1) else {
return nil
}
let signatureGenerator = SHSignatureGenerator()
do {
let audioFile = try AVAudioFile(forReading: audioURL)
let pcmBlock: ((AVAudioPCMBuffer) -> Void) = { buffer in
do {
try signatureGenerator.append(buffer, at: nil)
} catch {
// Handle signature generator error
}
}
convert(audioFile: audioFile, outputFormat: audioFormat, pcmBlock: pcmBlock)
} catch {
// Handle audio file error
}
let signature = signatureGenerator.signature()