ios - VoIP 限制 rendercallback 中的帧数

标签 ios objective-c audio core-audio audiounit

我目前正在开发一个 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的技术问答QA1533QA1606 .要设置每帧的首选样本数,请使用 AVAudioSessionsetPreferredIOBufferDuration:error: 方法。例如,如果采样率为 32,000,则可以使用:

NSError *error = nil;
NSTimeInterval bufferDuration = 0.008;
[session setPreferredIOBufferDuration:bufferDuration error:&error];

将帧长度设置为 256,因为 32,000 * 0.008 = 256。

但是请注意,setPreferredIOBufferDuration:error: 方法设置的是preferred 编号,而不是exact 编号。您可以向操作系统建议一个帧长度,但有时,由于硬件限制,您可能无法准确获得所需的长度,而是接近它的长度。

关于ios - VoIP 限制 rendercallback 中的帧数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30858814/

相关文章:

iOS:长按手势

ios - 如何从 Realm 数据库中读取单列数据?

iphone - UITextField 工件

ios - 是否可以在获取 header 之后、开始获取数据之前中断 NSURLSessionDownloadTask?

javascript - 当您的程序同时加载其他媒体时,有没有办法避免 javascript 音频打嗝?

ios - 从单元测试运行时,CATextLayer 不会出现在 AVMutableComposition 中

ios - 解析聊天室 - 将 NS 数组转换为 NSMutableArray 以在 TableView 上显示

objective-c - Objective-C 中的对象初始化顺序

c++ - 在 IMMDeviceEnumerator 上调用 SAFE_RELEASE 时崩溃

c++ - SFML 不播放任何声音,但没有错误