将Int16写入AVAudioPCMBuffer swift

时间:2017-07-05 23:33:37

标签: ios swift audio avaudioplayer avaudiopcmbuffer

我在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 个答案:

答案 0 :(得分:1)

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

......当我看到你的后卫检查夹紧val时,标志会上升。 1设置为val = 1等......在其他地方不需要,因为这些边界检查没有实际意义,因为数据很好地落实到位

...我的猜测是你的输入音频[]因为你的val&gt;而被签名为int 16 1和val&lt; -1?如果为真,则除以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&lt; valid_value&lt; 1?

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