0

我在 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
  })
4

1 回答 1

1

一个典型的多通道 PCM 缓冲区在每个样本的基础上都有通道交错,虽然我不熟悉 swift 音频,但我发现在这里看到给定缓冲区数据结构维度的通道令人耳目一新

...当我看到您的警卫检查将 val > 1 设置为 val = 1 等时,一个标志会升起。...其他不需要的地方,因为这些边界检查没有实际意义,因为数据很好地就位

...我的猜测是您的输入音频 [] 由于您的 val > 1 和 val < -1 而被签署 int 16 吗?如果为真,则除以 max int float 是错误的,因为您将失去一半的动态范围...

我建议你仔细看看你的

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 值...这样做并告诉我们输入音频 [] 的最大值和最小值

现在让我们专注于您想要的输出缓冲区 self.buffer.floatChannelData ...因为您说它的 16 位浮点数...这里的有效范围是多少?-1 < 有效值 < 1 ?

一旦您告诉我们这些基本问题的答案,我们就可以继续

于 2017-07-06T03:57:33.010 回答