Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/121.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios VoIP限制rendercallback中的帧数_Ios_Objective C_Audio_Core Audio_Audiounit - Fatal编程技术网

Ios VoIP限制rendercallback中的帧数

Ios VoIP限制rendercallback中的帧数,ios,objective-c,audio,core-audio,audiounit,Ios,Objective C,Audio,Core Audio,Audiounit,我目前正在开发一个VoIP应用程序,我正在使用的一个库要求我在输入回调中发送帧。要求是我必须发送一个样本计数,该计数定义为一帧中的样本数。只要麦克风接收新样本,就会调用此回调 有效数字为(采样率)*(音频长度)/1000。其中音频长度可以是2.5、5、10、20、40或60毫秒 在使用kAudioUnitProperty_MaximumFramesPerSlice将我的inNumberFrames限制在960之前,它一直在引入大约1115个inNumberFrames。所以我决定通过设置这个属性

我目前正在开发一个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\u MaximumFramesPerSlice
指定每帧的最大采样数,而不是首选数;请参考苹果公司的技术问答。要设置每帧的首选采样数,请使用
AVAudioSession
setPreferredIOBufferDuration:error:
方法。例如,如果采样率为32000,则可以使用:

NSError *error = nil;
NSTimeInterval bufferDuration = 0.008;
[session setPreferredIOBufferDuration:bufferDuration error:&error];
将帧长度设置为256,因为32000*0.008=256


但是,请注意,
setPreferredIOBufferDuration:error:
方法设置的是preferred数字,而不是确切的数字。您可以向操作系统建议一个帧长度,但有时,由于硬件限制,您可能无法得到您想要的确切内容,而是得到接近它的内容。

您试图限制进入的帧数的原因是什么?使用循环缓冲区可以更好地解决这些问题。看看这个。我想看看我是否可以避免循环缓冲的情况摆在首位。我已经在用它来接收音频了,因为在播放音频的时候它是必要的。为什么要避免使用循环缓冲区呢?它们很便宜,可以解决您的问题。但这难道不意味着我必须在回调期间填充循环缓冲区,然后让另一个线程不断检查循环缓冲区中是否有足够的帧可以使用吗?听起来像是一团糟,但我想我会尝试一下。它确实更混乱,但这是多线程应用的本质。我相信如果您需要特定的帧数,这是必要的。当你习惯了它们,它们就好了。硬件总是需要基本的2帧计数。1115帧听起来很奇怪。1024是默认值。您可以将其低至128,但在remoteIO上,它几乎总是以2为基数。底线是inNumberFrames不在您的控制范围内,因此您必须为自己提供一个工作缓冲。如果你能在音频线程上完成你的工作,你可以添加到头部,也可以在渲染回调中从尾部拉。