如何在iOS中从服务器播放流式PCM数据?

use*_*283 2 core-audio pcm audioqueue ios swift

我正在尝试开发app从服务器播放流式PCM数据.

我使用过AudioQueue,但效果不好.

PCM数据格式(来自服务器):

Sample rate = 48000, num of channel = 2, Bit per sample = 16
Run Code Online (Sandbox Code Playgroud)

并且,服务器不会将固定字节流式传输到客户端.

(流变量字节.例如:30848,128,2764,......字节)

我的源代码:

在这里,ASBD结构我已经设置并创建了音频队列对象(语言:Swift)

// Create ASBD structure & set properties.
var streamFormat = AudioStreamBasicDescription()

streamFormat.mSampleRate = 48000
streamFormat.mFormatID = kAudioFormatLinearPCM
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked
streamFormat.mFramesPerPacket = 1
streamFormat.mChannelsPerFrame = 2
streamFormat.mBitsPerChannel = 16

streamFormat.mBytesPerFrame = (streamFormat.mBitsPerChannel / 8) * streamFormat.mChannelsPerFrame
streamFormat.mBytesPerPacket = streamFormat.mBytesPerFrame
streamFormat.mReserved = 0

// Create AudioQueue for playing PCM streaming data.
var err = AudioQueueNewOutput(&streamFormat, self.queueCallbackProc, nil, nil, nil, 0, &aq)

...
Run Code Online (Sandbox Code Playgroud)

我已经设置了ASBD结构并创建了如上所述的AudioQueue对象.

几秒钟内,AudioQueue可以很好地播放PCM数据,

但很快就会播放声音.我能做什么?

(仍然流式传输,并排队AudioQueue)

请给我任何想法.

hot*_*aw2 5

你需要做(至少)两件事:

您需要缓冲数据以处理来自服务器的数据与音频队列回调请求的数据之间的延迟抖动和不同数据包大小.典型的解决方案是使用预先填充了一定数量数据的循环FIFO /缓冲区,足以处理更糟糕的网络抖动(您需要统计分析这个数字).音频队列回调只能从圆形fifo中复制请求的数据量.网络代码试图保持填充.

当两个速率不完全相同时,您可能还需要某种方法来隐藏错误:例如,当网络速率太慢时某种方式复制或合成额外声音,以及在网络速率过高时遗漏样本的某种方式,这两种方式都试图尽可能听不到声音,并且在任何速率不连续或网络辍学时都不会产生大声咔嗒声.