【发布时间】:2015-04-17 08:24:05
【问题描述】:
我在udacity 上遵循了一个非常好的教程来探索使用 Swift 的音频应用程序的基础。我想扩展它当前的功能,从显示WAV 文件的波形开始。为此,我需要从WAV 文件中检索幅度与样本的关系。鉴于我已经有一个录制的文件,我怎么能迅速进行?
谢谢!
【问题讨论】:
我在udacity 上遵循了一个非常好的教程来探索使用 Swift 的音频应用程序的基础。我想扩展它当前的功能,从显示WAV 文件的波形开始。为此,我需要从WAV 文件中检索幅度与样本的关系。鉴于我已经有一个录制的文件,我怎么能迅速进行?
谢谢!
【问题讨论】:
AudioToolBox 满足您的需求。
您可以使用AudioFileService从音频文件中获取音频样本,例如WAV文件,
然后你可以得到每个样本的振幅。
// this is your desired amplitude data
public internal(set) var packetsX = [Data]()
public required init(src path: URL) throws {
Utility.check(error: AudioFileOpenURL(path as CFURL, .readPermission, 0, &playbackFile) , // set on output to the AudioFileID
operation: "AudioFileOpenURL failed")
guard let file = playbackFile else {
return
}
var numPacketsToRead: UInt32 = 0
GetPropertyValue(val: &numPacketsToRead, file: file, prop: kAudioFilePropertyAudioDataPacketCount)
var asbdFormat = AudioStreamBasicDescription()
GetPropertyValue(val: &asbdFormat, file: file, prop: kAudioFilePropertyDataFormat)
dataFormatD = AVAudioFormat(streamDescription: &asbdFormat)
/// At this point we should definitely have a data format
var bytesRead: UInt32 = 0
GetPropertyValue(val: &bytesRead, file: file, prop: kAudioFilePropertyAudioDataByteCount)
guard let dataFormat = dataFormatD else {
return
}
let format = dataFormat.streamDescription.pointee
let bytesPerPacket = Int(format.mBytesPerPacket)
for i in 0 ..< Int(numPacketsToRead) {
var packetSize = UInt32(bytesPerPacket)
let packetStart = Int64(i * bytesPerPacket)
let dataPt: UnsafeMutableRawPointer = malloc(MemoryLayout<UInt8>.size * bytesPerPacket)
AudioFileReadBytes(file, false, packetStart, &packetSize, dataPt)
let startPt = dataPt.bindMemory(to: UInt8.self, capacity: bytesPerPacket)
let buffer = UnsafeBufferPointer(start: startPt, count: bytesPerPacket)
let array = Array(buffer)
packetsX.append(Data(array))
}
}
例如WAV文件的通道一、位深为Int16。
// buffer is of two Int8, to express an Int16
let buffer = UnsafeBufferPointer(start: startPt, count: bytesPerPacket)
更多信息,您可以查看my github repo
【讨论】: