【问题标题】:UnsafeMutablePointer<Float> to UnsafeMutablePointer<_>UnsafeMutablePointer<Float> 到 UnsafeMutablePointer<_>
【发布时间】:2016-11-30 15:56:19
【问题描述】:

我真的被一个愚蠢且看似简单的问题发疯了...... 我必须将Data 转换为AVAudioPCMBuffer

this question 似乎很容易,但随着 Swift 3 一切都变了。这种被诅咒的语言不断变化(抱歉爆发)!

我有这段代码

let audioBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat!, frameCapacity: UInt32(data.count)/(audioFormat?.streamDescription.pointee.mBytesPerFrame)!)
audioBuffer.frameLength = audioBuffer.frameCapacity
let channels = UnsafeBufferPointer(start: audioBuffer.floatChannelData, count: Int(audioFormat!.channelCount))
data.copyBytes(to: UnsafeMutablePointer<Float>(channels[0]))

但是最后一行给了我这个错误:

Cannot convert value of type 'UnsafeMutablePointer<Float>' to expected 
argument type 'UnsafeMutablePointer<_>'

有人可以解决这个问题吗?

【问题讨论】:

  • 您可能需要将第三行声明为UnsafeBufferPointer&lt;Float&gt;?

标签: swift swift3 unsafemutablepointer avaudiopcmbuffer


【解决方案1】:

查看API Reference of Data,可以发现copyBytes的3个重载:

func copyBytes(to: UnsafeMutablePointer&lt;UInt8&gt;, count: Int)

func copyBytes(to: UnsafeMutablePointer&lt;UInt8&gt;, from: Range&lt;Data.Index&gt;)

func copyBytes&lt;DestinationType&gt;(to: UnsafeMutableBufferPointer&lt;DestinationType&gt;, from: Range&lt;Data.Index&gt;?)

它们都没有将UnsafeMutablePointer&lt;Float&gt; 作为其to: 参数。

(在您的代码中,channels[0] 的类型变为 UnsafeMutablePointer&lt;Float&gt;,将其传递给 UnsafeMutablePointer&lt;Float&gt; 的初始化程序是“什么都不做”。)

如果你想调用第三个copyBytes,你需要创建一个UnsafeMutableBufferPointer&lt;DestinationType&gt;,在你的情况下DestinationType应该是Float

_ = data.copyBytes(to: UnsafeMutableBufferPointer(start: channels[0], count: Int(audioBuffer.frameLength)))

from: 参数在这个copyBytes 中是可选的,如果不输入_ =,Swift 会抱怨没有使用结果。)

如果您想使用copyBytes 的其他重载,您可能需要将UnsafeMutablePointer&lt;Float&gt; 转换为UnsafeMutablePointer&lt;UInt8&gt;。您可以在 SO 的其他一些文章中找到如何做到这一点。请记住count:from:(在第二个中)不是可选的。

【讨论】:

  • 它工作正常,但最后我不得不手动执行复制,因为我收到了 [UInt8] 并需要将其转换为 [Float32]...谢谢!
  • @Massimo 你能展示一下你是如何手动复制并将 [UInt8] 转换为 [Float32] 的吗?
  • @zzzel 对于我的问题,我有一个包含 n/2 个样本(样本 2 个字节)的数据,我必须将每个样本(2 个字节)转换为一个浮点数(介于 -1.0 和 1.0 之间)。如果您的问题相同,这是我的代码(示例是 Dataobject):for i in 0..&lt;samples.count/2 { floatArray[i] = Float(Int16(samples[i*2+1]) &lt;&lt; 8 | Int16(samples[i*2]))/Float(INT16_MAX) }
  • @Massimo 你是怎么想出来的?你怎么知道它是 [UInt8]?好奇
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-08
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
相关资源
最近更新 更多