将 Int16 写入 AVAudioPCMBuffer swift
Posted
技术标签:
【中文标题】将 Int16 写入 AVAudioPCMBuffer swift【英文标题】:Write Int16 Into AVAudioPCMBuffer swift 【发布时间】:2017-07-05 23:33:37 【问题描述】:我在 swift 中有一个 Data 对象,它是一个 Int16 对象数组。由于某种原因,使用“.pcmFormatInt16”不适用于我的 AVAudioPCMBuffer 格式,并且没有产生声音或内存错误。最终,通过将 Int16 转换为浮点数并将其放到我的 AVAudioPCMBuffer 的两个通道上,我能够从扬声器播放白噪声/静电。我有一种接近答案的感觉,因为每当我对着麦克风说话时,我都会听到不同频率的静电声。我认为问题在于我没有将转换后的 Int16 转换为缓冲区 floatChannelData。
这是我的代码:
for ch in 0..<2
for i in 0..<audio.count
var val = Float( Int16(audio[i]) ) / Float(Int16.max)
if( val > 1 )
val = 1;
if( val < -1 )
val = -1;
self.buffer.floatChannelData![ch][i+self.bufferCount] = val
self.bufferCount+=1
self.audioFilePlayer.scheduleBuffer(self.buffer, at:nil, options: .interruptsAtLoop, completionHandler:
print("played sum")
self.bufferCount=0
)
【问题讨论】:
对不起,我的代码的一些格式有点乱。在“这是我的代码:”这句话之后,剩下的就是代码 【参考方案1】:一个典型的多通道 PCM 缓冲区在每个样本的基础上都有通道交错,虽然我不熟悉 swift 音频,但我发现在这里看到通道给定缓冲区数据结构上的维度令人耳目一新
...当我看到您的警卫检查将 val > 1 设置为 val = 1 等时,一个标志会升起...在其他地方不需要,因为这些边界检查没有实际意义,因为数据很好地就位
...我猜你的输入音频 [] 是有符号的 int 16 因为你的 val > 1 和 val
我建议你仔细看看你的
var val = Float( Int16(audio[i]) ) / Float(Int16.max)
让我们检查音频[]中整数的范围
2^16 == 65536 // 如果无符号,则值范围从 0 到 (2^16 - 1),即 0 到 65535
2^15 == 32768 // 如果有符号,则值的范围是 -32768 到 (2^15 - 1),即 -32768 到 32767
请说明输入缓冲区音频[] 是否已签名...有时有助于识别输入数据的 max_seen 和 min_seen 值...这样做并告诉我们输入的 max_seen 和 min_seen 值音频[]
现在让我们专注于您想要的输出缓冲区 self.buffer.floatChannelData ... 因为您说的是它的 16 位浮点数...这里的有效范围是多少? -1
一旦您告诉我们这些基本问题的答案,我们就可以继续
【讨论】:
在这种情况下,我的缓冲区没有交错,因为我将该参数设置为 false。我相信缓冲区是无符号的,因为它是以字节为单位的,但我不完全确定。有没有办法检查缓冲区是有符号的还是无符号的?另外,是的,根据 swift/objective c 文档,您对范围是正确的,即 -1 我刚刚打印出缓冲区中的值,我相信缓冲区是有符号的,因为没有负值 我还应该提到,这适用于 android 到 android,(当我不将其转换为浮点数时),有什么理由说明字节可以在 android 到 android 上工作,而不是在 android 到 iPhone 上工作?以上是关于将 Int16 写入 AVAudioPCMBuffer swift的主要内容,如果未能解决你的问题,请参考以下文章
将 UnsafeMutablePointer<Int16> 转换为 UInt8