gpt4 book ai didi

c++ - 使用 OS X 核心音频播放/输出体验音频丢失

转载 作者:行者123 更新时间:2023-11-30 05:28:52 24 4
gpt4 key购买 nike

我正在使用核心音频(OS X、10.11.4 Beta、较旧的 mac mini)进行播放,使用为输入和输出配置的简单输出音频单元(尽管我的所有问题似乎都与输出有关)。这是一个来自 socket/internet 的流式音频源,输入到 boost 无锁队列,然后输入到输出 AU。我收到音频丢失,这似乎是 AU 渲染回调未被核心音频间歇性调用的结果。
这是一个graph .在这一部分之前有大约 10 秒的完美音频。

黑色:样本音频,简单的正弦波

蓝色:渲染回调 (OutputProc) 的挂钟持续时间,以毫秒为单位,上表中的点为 ~120 毫秒

橙色:无锁队列(playback_buf)的大小(以 samples/1000 为单位)以很好地适应图表

x 轴:以毫秒为单位的时间

所有内容都记录在 OutputProc 中,因此如果未调用它,则不会记录任何内容,但绘图工具会连接这些期间的点。缓冲区中总是有足够的样本。似乎从 ~22475ms 到 ~22780ms,OutputProc 只在 22640 被调用一次。它在那个特定实例上确实有很长的挂钟时间,但似乎是由于抢占。后来在 22800 到 23000 的范围内仍然存在丢失,但 OutputProc 不会比正常情况持续更长时间,并且肯定不会超过实时窗口(此处为 ~6ms ...硬件采样率为 96kHz)。所以,我认为这是其他一些以某种方式抢先的线程。不过,我希望核心音频线程具有非常高的优先级。我确实有一些并行进行的 boost asio 套接字输入/输出(例如 boost::asio::io_service io_service),但我希望它总是失去核心音频的优先级。如果您对实际问题有任何指示……总是欢迎……但是,如果我能找出在那些感兴趣的时间正在执行的线程,我就能取得进展吗? Xcode 中是否有某些东西可以告诉我调度程序历史记录或线程历史记录,可能是每个 CPU 内核?OutputProc 如果有帮助的话:

OSStatus AudioStream::OutputProc(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *TimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
AudioStream *This = (AudioStream *) inRefCon;

playback_cb_dur_log.StartTime();

static bool first_call = true;
if (first_call)
{
std::cout << TIME(timer) << " playback starting\n";
This->playback_state = PLAYBACK_ACTIVE;
first_call = false;
}

int playback_buf_avail = (int) This->playback_buf.read_available();
playback_buf_size_log.AddPoint(playback_buf_avail/1000.);
if (playback_buf_avail >= This->playback_buf_thresh)
{
std::cout << TIME() << " audio, thresh: " << This->playback_buf_thresh << ", buf_size: " << playback_buf_avail << std::endl;
// new threshold just one frame of data
This->playback_buf_thresh = This->frames_total;
for(int i = 0; i < This->num_channels; i++)
{
float *temp = (float *) ioData->mBuffers[i].mData;
This->playback_buf.pop(temp, inNumberFrames);
playback_sample_log.AddData(ioData->mBuffers[i].mData, inNumberFrames, This->chan_params.sample_rate);
}
}
else
{
std::cout << TIME() << " silence, thresh: " << This->playback_buf_thresh << ", buf_size: " << This->playback_buf.read_available() << std::endl;
for(int i = 0; i < This->num_channels; i++)
{
memset(ioData->mBuffers[i].mData, 0, inNumberFrames * sizeof(Float32));
playback_sample_log.AddData(ioData->mBuffers[i].mData, inNumberFrames, This->chan_params.sample_rate);
}
}


playback_cb_dur_log.StopAndCaptureTime();

return noErr;
}

最佳答案

您的日志记录机制可能会干扰实时线程。任何可以锁定或管理内存(例如字符串创建或标准输出文件 IO)的任何调用都可能导致音频单元回调中的丢失和其他故障。

如果是这种情况,您可以尝试将时间戳填充到无锁循环日志记录 FIFO 中,并在另一个线程中执行任何文件 IO。

关于c++ - 使用 OS X 核心音频播放/输出体验音频丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36615010/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com