首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVCaptureOutput到音频单元通过TPCircularBuffer回调

AVCaptureOutput到音频单元通过TPCircularBuffer回调
EN

Stack Overflow用户
提问于 2014-06-01 10:09:33
回答 1查看 1.2K关注 0票数 0

我正在构建一个AUGraph,并试图通过AVCaptureAudioDataOutput委托方法从输入设备获取音频。

AVCaptureSession的使用是这里解释的问题的结果。我成功地通过一个CARingbuffer构建了一个使用这种方法的音频播放,正如在“学习核心音频”一书中所解释的那样。但是,从CARingbuffer获取数据意味着提供一个有效的样本时间,并且当我停止AVCaptureSession时,来自AVCaptureOutput的示例时间和单元输入回调不再同步。所以,根据我所读到的,我现在正在尝试使用迈克尔·泰森的TPCircularBuffer,它看起来很棒。但是,即使我找到了一些例子,我也无法从它得到一些音频(或者仅仅是裂缝)。

我的图是这样的:

代码语言:javascript
复制
AVCaptureSession -> callback -> AUConverter -> ... -> HALOutput

这是我的AVCaptureOutput方法的代码

代码语言:javascript
复制
- (void) captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{

CMFormatDescriptionRef formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer);
const AudioStreamBasicDescription *sampleBufferASBD = CMAudioFormatDescriptionGetStreamBasicDescription(formatDescription);

if (kAudioFormatLinearPCM != sampleBufferASBD->mFormatID) {

    NSLog(@"Bad format or bogus ASBD!");
    return;

}

if ((sampleBufferASBD->mChannelsPerFrame != _audioStreamDescription.mChannelsPerFrame) || (sampleBufferASBD->mSampleRate != _audioStreamDescription.mSampleRate)) {

    _audioStreamDescription = *sampleBufferASBD;
    NSLog(@"sample input format changed");

}




CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer,
                                                        NULL,
                                                        _currentInputAudioBufferList,
                                                        CAAudioBufferList::CalculateByteSize(_audioStreamDescription.mChannelsPerFrame),
                                                        kCFAllocatorSystemDefault,
                                                        kCFAllocatorSystemDefault,
                                                        kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
                                                        &_blockBufferOut);


TPCircularBufferProduceBytes(&_circularBuffer, _currentInputAudioBufferList->mBuffers[0].mData, _currentInputAudioBufferList->mBuffers[0].mDataByteSize);

以及呈现回调:

代码语言:javascript
复制
OSStatus PushCurrentInputBufferIntoAudioUnit(void inRefCon,
                                             AudioUnitRenderActionFlags *   ioActionFlags,
                                             const AudioTimeStamp *         inTimeStamp,
                                             UInt32                         inBusNumber,
                                             UInt32                         inNumberFrames,
                                             AudioBufferList *              ioData)
{

ozAVHardwareInput *hardWareInput = (ozAVHardwareInput *)inRefCon;
TPCircularBuffer circularBuffer = [hardWareInput circularBuffer];

Float32 *targetBuffer = (Float32 *)ioData->mBuffers[0].mData;

int32_t availableBytes;
TPCircularBufferTail(&circularBuffer, &availableBytes);
UInt32 dataSize = ioData->mBuffers[0].mDataByteSize;

if (availableBytes > ozAudioDataSizeForSeconds(3.)) {

    // There is too much audio data to play -> clear buffer & mute output
    TPCircularBufferClear(&circularBuffer);

    for(UInt32 i = 0; i < ioData->mNumberBuffers; i++)
        memset(ioData->mBuffers[i].mData, 0, ioData->mBuffers[i].mDataByteSize);

} else if (availableBytes > ozAudioDataSizeForSeconds(0.5)) {

    // SHOULD PLAY
    Float32 *cbuffer = (Float32 *)TPCircularBufferTail(&circularBuffer, &availableBytes);
    int32_t min = MIN(dataSize, availableBytes);

    memcpy(targetBuffer, cbuffer, min);
    TPCircularBufferConsume(&circularBuffer, min);
    ioData->mBuffers[0].mDataByteSize = min;

} else {

    // No data to play -> mute output
    for(UInt32 i = 0; i < ioData->mNumberBuffers; i++)
        memset(ioData->mBuffers[i].mData, 0, ioData->mBuffers[i].mDataByteSize);
}

return noErr;

}

TPCIrcularBuffer被输入了AudioBufferList,但是没有输出,有时只是裂口。

我做错什么了?

EN

回答 1

Stack Overflow用户

发布于 2014-06-08 21:27:36

音频单元呈现回调时应始终返回样本的inNumberFrames。检查您的回调返回了多少数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23978741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档