Last active
August 29, 2015 14:26
-
-
Save iluvcapra/624cc86c545ef16f156e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AVAudioFile_Digest.swift | |
// Bag of Holding | |
// | |
// Created by Jamie Hardt on 7/30/15. | |
// Copyright © 2015 Jamie Hardt. All rights reserved. | |
// | |
import Foundation | |
import AVFoundation | |
func writeSamplesFromBuffer(buffer: AVAudioPCMBuffer, toStream : NSOutputStream) { | |
assert(buffer.format.interleaved == true) | |
var rawBuffer = UnsafePointer<UInt8>(buffer.int32ChannelData.memory) | |
var toWrite = sizeof(Int32) * Int(buffer.format.channelCount) * Int(buffer.frameLength) | |
while toWrite > 0 { | |
let written = toStream.write(rawBuffer, maxLength: toWrite) | |
rawBuffer = rawBuffer.advancedBy(written) | |
toWrite -= written | |
} | |
} | |
let AudioDataWriterAVAudioFileError = "AudioDataWriterAVAUdioFileError" | |
func writeAudioDataFromURL(url : NSURL, | |
usingFormat format: AVAudioCommonFormat, | |
toStream: NSOutputStream) throws { | |
let audioFile = try AVAudioFile(forReading: url, | |
commonFormat: format, | |
interleaved: true) | |
let pcmBuffer = AVAudioPCMBuffer(PCMFormat: | |
audioFile.processingFormat, | |
frameCapacity: 0x400) | |
toStream.open() | |
let writerQueue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) | |
dispatch_async(writerQueue) { | |
do { | |
while true { | |
try audioFile.readIntoBuffer(pcmBuffer) | |
if pcmBuffer.frameLength == 0 { break } | |
writeSamplesFromBuffer(pcmBuffer, toStream: toStream) | |
} | |
} catch let error as NSError { | |
toStream.setProperty(error, forKey: AudioDataWriterAVAudioFileError) | |
} catch let error { | |
fatalError("Fatal error: \(error) while reading audio file \(audioFile) at URL \(url)") | |
} | |
toStream.close() | |
} | |
} | |
func digestForStream(stream : NSInputStream, | |
digestType type : CFStringRef, length : Int) throws -> NSData { | |
let transform = SecTransformCreateGroupTransform().takeRetainedValue() | |
let readXform = SecTransformCreateReadTransformWithReadStream(stream as CFReadStreamRef).takeRetainedValue() | |
var error : Unmanaged<CFErrorRef>? = nil | |
let digestXform : SecTransformRef = try { | |
let d = SecDigestTransformCreate(type, length, &error) | |
if d == nil { | |
throw error!.takeUnretainedValue() | |
} else { | |
return d.takeRetainedValue() | |
} | |
}() | |
SecTransformConnectTransforms(readXform, kSecTransformOutputAttributeName, | |
digestXform, kSecTransformInputAttributeName, | |
transform, &error) | |
if let e = error { throw e.takeUnretainedValue() } | |
if let output = SecTransformExecute(transform, &error) as? NSData { | |
return output | |
} else { | |
throw error!.takeUnretainedValue() | |
} | |
} | |
func sha256DigestForInterleavedAudioAtURL(url : NSURL, | |
convertedToSampleFormat sampleFormat: AVAudioCommonFormat) throws -> NSData { | |
let streamBufSize = 0x1000 | |
var rs : NSInputStream? = nil | |
var ws : NSOutputStream? = nil | |
NSStream.getBoundStreamsWithBufferSize(streamBufSize, | |
inputStream: &rs, outputStream: &ws) | |
guard let readStream = rs, writeStream = ws else { | |
fatalError("Failed to create file read streams") | |
} | |
try writeAudioDataFromURL(url, | |
usingFormat: sampleFormat, toStream: writeStream) | |
let retVal = try digestForStream(readStream, digestType: kSecDigestSHA2 , length: 256) | |
if let error = writeStream.propertyForKey(AudioDataWriterAVAudioFileError) as? NSError { | |
throw error | |
} | |
return retVal | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment