VoIP 限制 rendercallback 中的帧数
VoIP limiting the number of frames in rendercallback
我目前正在开发一个 VoIP 应用程序,我正在使用的库之一要求我在输入回调中发送帧。要求是我必须发送一个样本计数,该样本计数定义为帧中的样本数。每当麦克风接收新样本时,都会调用此回调。
有效数字为(采样率)*(音频长度)/1000。其中音频长度可以是 2.5、5、10、20、40 或 60 毫秒。
在使用 kAudioUnitProperty_MaximumFramesPerSlice 将我的 inNumberFrames 限制为 960 之前,它一直带来大约 1115 inNumberFrames。所以我决定通过设置 属性 来限制它。但是,当我这样做时,它会将 inNumberFrames 计数减少到 512???我是不是以错误的方式解决了这个问题?
static OSStatus inputRenderCallBack(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames, //512
AudioBufferList *ioData)
{
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = kNumberOfChannels;
bufferList.mBuffers[0].mData = NULL;
bufferList.mBuffers[0].mDataByteSize = inNumberFrames * sizeof(SInt16) * kNumberOfChannels;
OCTAudioEngine *engine = (__bridge OCTAudioEngine *)(inRefCon);
OSStatus status = AudioUnitRender(engine.ioUnit,
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames,
&bufferList);
NSError *error;
[engine.toxav sendAudioFrame:bufferList.mBuffers[0].mData
sampleCount:kSampleCount //960
channels:kNumberOfChannels //2
sampleRate:[engine currentAudioSampleRate] //24000
toFriend:engine.friendNumber
error:&error];
return status;
}
您可以(并且应该)使用 kAudioUnitProperty_MaximumFramesPerSlice
来指定每帧的 最大 样本数,而不是 首选 数字;请参考Apple的技术问答QA1533 and QA1606。要设置每帧的首选样本数,请使用 AVAudioSession
的 setPreferredIOBufferDuration:error:
方法。比如采样率为32000,可以使用:
NSError *error = nil;
NSTimeInterval bufferDuration = 0.008;
[session setPreferredIOBufferDuration:bufferDuration error:&error];
将帧长度设置为 256,因为 32,000 * 0.008 = 256。
但是请注意,setPreferredIOBufferDuration:error:
方法设置的是 preferred 号码,而不是 exact 号码。您可以向操作系统建议一个帧长度,但有时,由于硬件限制,您可能无法准确获得所需的帧长,而是接近它的值。
我目前正在开发一个 VoIP 应用程序,我正在使用的库之一要求我在输入回调中发送帧。要求是我必须发送一个样本计数,该样本计数定义为帧中的样本数。每当麦克风接收新样本时,都会调用此回调。
有效数字为(采样率)*(音频长度)/1000。其中音频长度可以是 2.5、5、10、20、40 或 60 毫秒。
在使用 kAudioUnitProperty_MaximumFramesPerSlice 将我的 inNumberFrames 限制为 960 之前,它一直带来大约 1115 inNumberFrames。所以我决定通过设置 属性 来限制它。但是,当我这样做时,它会将 inNumberFrames 计数减少到 512???我是不是以错误的方式解决了这个问题?
static OSStatus inputRenderCallBack(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames, //512
AudioBufferList *ioData)
{
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = kNumberOfChannels;
bufferList.mBuffers[0].mData = NULL;
bufferList.mBuffers[0].mDataByteSize = inNumberFrames * sizeof(SInt16) * kNumberOfChannels;
OCTAudioEngine *engine = (__bridge OCTAudioEngine *)(inRefCon);
OSStatus status = AudioUnitRender(engine.ioUnit,
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames,
&bufferList);
NSError *error;
[engine.toxav sendAudioFrame:bufferList.mBuffers[0].mData
sampleCount:kSampleCount //960
channels:kNumberOfChannels //2
sampleRate:[engine currentAudioSampleRate] //24000
toFriend:engine.friendNumber
error:&error];
return status;
}
您可以(并且应该)使用 kAudioUnitProperty_MaximumFramesPerSlice
来指定每帧的 最大 样本数,而不是 首选 数字;请参考Apple的技术问答QA1533 and QA1606。要设置每帧的首选样本数,请使用 AVAudioSession
的 setPreferredIOBufferDuration:error:
方法。比如采样率为32000,可以使用:
NSError *error = nil;
NSTimeInterval bufferDuration = 0.008;
[session setPreferredIOBufferDuration:bufferDuration error:&error];
将帧长度设置为 256,因为 32,000 * 0.008 = 256。
但是请注意,setPreferredIOBufferDuration:error:
方法设置的是 preferred 号码,而不是 exact 号码。您可以向操作系统建议一个帧长度,但有时,由于硬件限制,您可能无法准确获得所需的帧长,而是接近它的值。