当前位置: 首页 > 知识库问答 >
问题:

如何将Int16音频样本数据转换为浮点音频样本数组

岳泳
2023-03-14

我目前正在处理音频样本。我从AVAssetReader获得它们,并有一个cmsampleBuffer,其内容如下:

guard let sampleBuffer = readerOutput.copyNextSampleBuffer() else {
guard reader.status == .completed else { return nil }
// Completed
// samples is an array of Int16
let samples = sampleData.withUnsafeBytes {
  Array(UnsafeBufferPointer<Int16>(
  start: $0, count: sampleData.count / MemoryLayout<Int16>.size))
 }

 // The only way I found to convert [Int16] -> [Float]...
 return samples.map { Float($0) / Float(Int16.max)}
}

guard let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer) else {
return nil
}

let length = CMBlockBufferGetDataLength(blockBuffer)
let sampleBytes = UnsafeMutablePointer<UInt8>.allocate(capacity: length)
      CMBlockBufferCopyDataBytes(blockBuffer, 0, length, sampleBytes)

      sampleData.append(sampleBytes, count: length)
}

如您所见,我找到的唯一用于转换[Int16]->[Float]的方法是samples.map{Float($0)/Float(Int16.max),但这样做会增加我的处理时间。是否存在将Int16指针转换为Float指针的其他方法?

共有1个答案

姬和豫
2023-03-14

“强制转换”或“重新绑定”指针只会改变内存的解释方式。如果要从整数计算浮点值,则新值具有不同的内存表示形式(以及不同的大小)。

因此,您必须以某种方式迭代所有输入值并计算新值。您可以做的是省略数组创建:

let samples = sampleData.withUnsafeBytes {
    UnsafeBufferPointer<Int16>(start: $0, count: sampleData.count / MemoryLayout<Int16>.size)
}
return samples.map { Float($0) / Float(Int16.max) }

另一种选择是使用加速框架中的vDSP函数:

import Accelerate
// ...

let numSamples = sampleData.count / MemoryLayout<Int16>.size
var factor = Float(Int16.max)
var floats: [Float] = Array(repeating: 0.0, count: numSamples)

// Int16 array to Float array:
sampleData.withUnsafeBytes {
    vDSP_vflt16($0, 1, &floats, 1, vDSP_Length(numSamples))
}
// Scaling:
vDSP_vsdiv(&floats, 1, &factor, &floats, 1, vDSP_Length(numSamples))
let factor = Float(Int16.max)
let samples = sampleData.withUnsafeBytes {
    UnsafeBufferPointer<Int16>(start: $0, count: sampleData.count / MemoryLayout<Int16>.size)
}
var floats: [Float] = Array(repeating: 0.0, count: samples.count)
for i in 0..<samples.count {
    floats[i] = Float(samples[i]) / factor
}
return floats

在您的情况下,另一个选项可能是在分配的内存中使用CMBlockBufferGetDataPointer()而不是CMBlockBufferCopyDataBytes()

 类似资料:
  • 我有音频数据记录从麦克风这样:(ndarray的浮动) 这是我的代码: 但当我播放音频时,它就坏了,只有噪音。。。如何将其转换为。wav音频文件?

  • 问题内容: 我只想知道在Java或C#中是否有任何库或外部库中的构建允许我获取音频文件并对其进行解析并从中提取文本。 我需要创建一个应用程序,但是我不知道从哪里开始。 问题答案: 以下是您的一些选择: 微软演讲 光明 龙自然讲 狮身人面像4

  • 这个问题通常是作为另一个问题的一部分来问的,但结果是答案很长。我决定在这里回答它,这样我就可以链接到其他地方。 虽然我目前还不知道Java可以为我们制作音频样本的方法,但如果将来发生变化,这可能是一个地方。我知道有一些类似的东西,例如,但仍然不是直接访问样本的方法。 我正在使用< code>javax.sound.sampled进行回放和/或录音,但我想对音频做些什么。 也许我想直观地显示它或以某

  • 我正在使用这个方法将WAV文件读到字节数组(如下所示)。现在我已经将它存储在字节数组中,我想改变声音的音量。 编辑:根据要求提供音频格式的一些信息:

  • IBM speech to text-我如何将MP3音频文件转换成字节数组,然后发送到IBM Watson服务器,使用speech to text API将音频转换成文本

  • 我使用函数将音频文件读入。 这是音频的和ASBD: 因此,我们获得并交织了2个声道的音频,每个声道的16位符号为int init: 并读入缓冲区: 是的和实例,它在前面的代码中启动,为了节省空间,我没有粘贴到这里。 我试图完成的是在渲染回调中修改音频样本。 是否有可能从音频数据的UInt32阵列中获得Sint16左右声道样本?