Я делаю воспроизведение с использованием основного звука (OS X, 10.11.4 Beta, более старый mac mini), используя простой выходной аудиоустройство, настроенное для ввода и вывода (хотя все мои проблемы, похоже, с выходом). Это потоковый источник звука из розетки/интернет-подачи в очередь без блокировки, которая затем подается на выход AU. Я получаю аудиопакеты, которые, по-видимому, являются результатом обратного вызова рендеринга AU, который не прерывается с помощью основного звука с перерывами.
Адрес graph. Перед этим разделом было ~ 10 секунд безупречного звука.Опытные аудиопоходы с воспроизведением/воспроизведением основного звука OS X
черный: аудио дискретизации, простой синусоидальной волны
синий: стены Продолжительность часы рендеринга обратного вызова (OutputProc) в мс, указать от диаграммы выше ~ 120 мс
оранжевый: размер очереди беззамочные (playback_buf) в образцах/1000, чтобы уместить его в графике хорошо
оси х: время в мс
Все вошли в OutputProc, так что, если не вызывается, то ничто не регистрируется, но инструмент изображая будет соединить точки периоды. В буфере всегда достаточно образцов. Кажется, что от ~ 22475 мс до ~ 22780 мс OutputProc вызывается только один раз на 22640. У этого есть длительное время настенных часов в этом конкретном случае, но, похоже, связано с преимущественным преимуществом. Позже в диапазоне от 22800 до 23000 все еще остаются отсева, но OutputProc не длится дольше, чем обычно, и, конечно же, не переполняет окно реального времени (~ 6 мс здесь ... Частота кадров HW составляет 96 кГц). Итак, я думаю, что это какой-то другой поток, который как-то упреждает. Я бы ожидал, что основной аудиопоток будет иметь очень высокий приоритет. У меня есть несколько дополнительных входов/выходов asio сокета, идущих параллельно (например, boost :: asio :: io_service io_service), но я бы ожидал, что всегда будет потерять приоритет для основного звука. Если у вас есть какие-то указатели на настоящую проблему ... это всегда приветствуется ... но я могу добиться прогресса, если я просто смогу узнать, какие потоки выполняются в те моменты, когда они интересны? Есть ли что-то в Xcode, которое сообщает мне историю планировщика или историю потоков, возможно, для ядра процессора? 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;
}
Я никогда не сталкивался с нарастающими настенными часами длительностью CoreAudio, вызывая обратные вызовы или прерывистые системные вызовы OutputProc. Обратный поток - это режим реального времени и таймер. Если поток производителей не обеспечивает своевременную доставку данных, он не ждет: тишина - это то, что вы получаете. Я полагаю, что проблема должна быть в другом месте. Что это за строка: 'if (playback_buf_avail> = This-> playback_buf_thresh)' и какой механизм обновляет структуру данных _This_ data? – user3078414