CAPlayThrough示例的问题

时间:2016-03-22 21:40:29

标签: macos audio device capture

我正在尝试学习Xcode Core Audio并偶然发现了这个例子:

https://developer.apple.com/library/mac/samplecode/CAPlayThrough/Introduction/Intro.html#//apple_ref/doc/uid/DTS10004443

我的目的是捕获原始音频。每当我遇到断点时,我都会失去音频。因为它使用CARingBuffer

  1. 你如何删除时间因素。我不需要实时音频。
  2. 由于它正在使用CARingBuffer,它应该继续写入相同的内存位置?那么为什么我听不到音频呢?如果我有断点?
  3. 我正在阅读学习核心音频一书。但是,到目前为止,我无法弄清楚以下代码的这一部分:

    CARingBufferError CARingBuffer::Store(const AudioBufferList *abl, UInt32 framesToWrite, SampleTime startWrite)
    {
        if (framesToWrite == 0)
            return kCARingBufferError_OK;
    
        if (framesToWrite > mCapacityFrames)
            return kCARingBufferError_TooMuch;      // too big!
    
        SampleTime endWrite = startWrite + framesToWrite;
    
        if (startWrite < EndTime()) {
            // going backwards, throw everything out
            SetTimeBounds(startWrite, startWrite);
        } else if (endWrite - StartTime() <= mCapacityFrames) {
            // the buffer has not yet wrapped and will not need to
        } else {
            // advance the start time past the region we are about to overwrite
            SampleTime newStart = endWrite - mCapacityFrames;   // one buffer of time behind where we're writing
            SampleTime newEnd = std::max(newStart, EndTime());
            SetTimeBounds(newStart, newEnd);
        }
    
        // write the new frames
        Byte **buffers = mBuffers;
        int nchannels = mNumberChannels;
        int offset0, offset1, nbytes;
        SampleTime curEnd = EndTime();
    
        if (startWrite > curEnd) {
            // we are skipping some samples, so zero the range we are skipping
            offset0 = FrameOffset(curEnd);
            offset1 = FrameOffset(startWrite);
            if (offset0 < offset1)
                ZeroRange(buffers, nchannels, offset0, offset1 - offset0);
            else {
                ZeroRange(buffers, nchannels, offset0, mCapacityBytes - offset0);
                ZeroRange(buffers, nchannels, 0, offset1);
            }
            offset0 = offset1;
        } else {
            offset0 = FrameOffset(startWrite);
        }
    
        offset1 = FrameOffset(endWrite);
        if (offset0 < offset1)
            StoreABL(buffers, offset0, abl, 0, offset1 - offset0);
        else {
            nbytes = mCapacityBytes - offset0;
            StoreABL(buffers, offset0, abl, 0, nbytes);
            StoreABL(buffers, 0, abl, nbytes, offset1);
        }
    
        // now update the end time
        SetTimeBounds(StartTime(), endWrite);
    
        return kCARingBufferError_OK;   // success
    }
    

    谢谢!

1 个答案:

答案 0 :(得分:0)

如果我理解了这个问题,输入单元(生产者)在断点处停止时信号会丢失。我认为这可能是预期的行为。 CoreAudio是运行实时线程的 拉模型 引擎。这意味着在某些情况下你的制作人会遇到一个断点,环形缓冲区清空,输出单元(消费者)继续运行,但是当游戏链中断时从缓冲区中得不到任何东西,因此可能会产生静音。

也许这个示例中的代码并不是最简单的代码:如果环形缓冲区溢出/欠载,AFAICT,我认为它也会将音频缓冲区归为零。 问题中的术语“原始音频”也不是不言自明的,我不确定它是什么意思。我建议尝试使用更简单的循环缓冲区来学习异步i / o。 GitHub上很少有(没有强制性时间值)。

请格式化源代码以便于阅读。