首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从Swift中的音频文件生成浮动数组

如何从Swift中的音频文件生成浮动数组
EN

Stack Overflow用户
提问于 2016-01-12 18:34:09
回答 4查看 7.8K关注 0票数 11

我希望将mp3和wav音频文件加载为浮点数或双倍数组,类似于io.wavfile.read函数在the中的作用。我可以使用麦克风数据或通过将音频流写入缓冲区来播放音频。但是,我不知道如何一次加载所有音频文件的数据。

-最新情况

对于将来处理音频信号数据的人来说,这里有一个函数可以实现这个功能。这是基于有节奏的费斯曼的回答。

代码语言:javascript
复制
    func loadAudioSignal(audioURL: NSURL) -> (signal: [Float], rate: Double, frameCount: Int) {
        let file = try! AVAudioFile(forReading: audioURL)
        let format = AVAudioFormat(commonFormat: .PCMFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: file.fileFormat.channelCount, interleaved: false)
        let buf = AVAudioPCMBuffer(PCMFormat: format, frameCapacity: UInt32(file.length))
        try! file.readIntoBuffer(buf) // You probably want better error handling
        let floatArray = Array(UnsafeBufferPointer(start: buf.floatChannelData[0], count:Int(buf.frameLength)))
        return (signal: floatArray, rate: file.fileFormat.sampleRate, frameCount: Int(file.length))
    }
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-01-13 05:38:16

AVAudioFile内置到iOS (和OS ),非常方便,还将为您进行格式转换:

代码语言:javascript
复制
import AVFoundation
// ...

let url = NSBundle.mainBundle().URLForResource("your audio file", withExtension: "wav")
let file = try! AVAudioFile(forReading: url!)
let format = AVAudioFormat(commonFormat: .PCMFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: 1, interleaved: false)

let buf = AVAudioPCMBuffer(PCMFormat: format, frameCapacity: 1024)
try! file.readIntoBuffer(buf)

// this makes a copy, you might not want that
let floatArray = Array(UnsafeBufferPointer(start: buf.floatChannelData[0], count:Int(buf.frameLength)))

print("floatArray \(floatArray)\n")

不幸的是,对于双倍,用.PCMFormatFloat64代替.PCMFormatFloat64似乎还不够,因为AVAudioPCMBuffer没有float64ChannelData方法。

因为我不太了解斯威夫特

您可以通过使用UnsafeBufferPointer来避免复制数组,这是一个非常好的集合类型:

代码语言:javascript
复制
let floatArray = UnsafeBufferPointer(start: buf.floatChannelData[0], count:Int(buf.frameLength))
票数 19
EN

Stack Overflow用户

发布于 2020-04-16 13:30:14

很难找到关于UnsafeBufferPointer的一切

这里我发布了SWIFT5.0的更新代码

代码语言:javascript
复制
if let url = Bundle.main.url(forResource: "silence", withExtension: "mp3") {
    let file = try! AVAudioFile(forReading: url)
    if let format = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: 1, interleaved: false) {
        if let buf = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: 1024) {
            try! file.read(into: buf)

            // this makes a copy, you might not want that
            let floatArray = UnsafeBufferPointer(start: buf.floatChannelData![0], count:Int(buf.frameLength))
            // convert to data
            var data = Data()
            for buf in floatArray {
                data.append(withUnsafeBytes(of: buf) { Data($0) })
            }
            // use the data if required.
        }
    }
}

希望它能帮助你:)

票数 4
EN

Stack Overflow用户

发布于 2020-09-07 17:29:30

上面的答案不适用于我,我使用的是Swift5,在这里我发现了这个扩展:https://gist.github.com/jtodaone/f2fa59c19794811dbe989dff65a772bc

这里也是我如何在游乐场上使用代码

代码语言:javascript
复制
import UIKit
import AVFoundation

let filePath: String = Bundle.main.path(forResource: "nameOfFile", ofType: "wav")!
print("\(filePath)")
let fileURL: NSURL = NSURL(fileURLWithPath: filePath)
let audioFile = try AVAudioFile(forReading: fileURL as URL)
let audioFormat = audioFile.processingFormat
let audioFrameCount = UInt32(audioFile.length)
let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: audioFrameCount)

try audioFile.read(into: audioFileBuffer!)

extension AudioBuffer {
    func array() -> [Float] {
        return Array(UnsafeBufferPointer(self))
    }
}

extension AVAudioPCMBuffer {
    func array() -> [Float] {
        return self.audioBufferList.pointee.mBuffers.array()
    }
}

extension Array where Element: FloatingPoint {
    mutating func buffer() -> AudioBuffer {
        return AudioBuffer(mNumberChannels: 1, mDataByteSize: UInt32(self.count * MemoryLayout<Element>.size), mData: &self)
    }
}

let array = audioFileBuffer?.array()
print(array?.count) //Optional(2705408)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34751294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档