在iOS应用程序中,
播放来自BLE的音频流,使用TPCircularBuffer
和Audio Unit.
声音播放良好,但当缓冲区为空且没有字节可播放时,它会导致实例中的爆裂声.
这是我的音频流配置,
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 8000.00;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsPacked;
// || kAudioFormatFlagsNativeFloatPacked || kAudioFormatFlagIsSignedInteger
//kAudioFormatFlagIsSignedInteger
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 32;// Update when required
audioFormat.mBytesPerPacket = 4; // Update when required
audioFormat.mBytesPerFrame = 4; // Update when required
Below is a Playback function of Audio Unit
static OSStatus playbackCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
//1
for (int i=0; i < ioData->mNumberBuffers; i++) {
IosAudioController *THIS = (__bridge IosAudioController *)inRefCon;
int bytesAskingByPlayback = ioData->mBuffers[i].mDataByteSize;
SInt16 *targetBuffer = (SInt16*)ioData->mBuffers[i].mData;
// Pull audio from playthrough buffer
int32_t availableBytesFromBuffer;
SInt16 *sBuffer = TPCircularBufferTail(iosAudio.addressOfTPBuffer, &availableBytesFromBuffer);
int willRemainBytes = availableBytesFromBuffer - bytesAskingByPlayback;
if (willRemainBytes > 0) {
memcpy(targetBuffer, sBuffer, bytesAskingByPlayback);
TPCircularBufferConsume(iosAudio.addressOfTPBuffer,bytesAskingByPlayback);
} else {
//Note: Mostly need to update code here
memcpy(targetBuffer, sBuffer, availableBytesFromBuffer);
TPCircularBufferConsume(iosAudio.addressOfTPBuffer, availableBytesFromBuffer);
}
}
return noErr;
}
缓冲区大小为16384
一些解决方案说我会用0填充目标缓冲区以静音,但它不工作.
Some Solution说我可以用以前的值填充目标缓冲区来填补空白.