Giriş ve çıkış için yapılandırılmış basit bir çıkış ses birimi kullanarak çekirdek ses (OS X, 10.11.4 Beta, eski mac mini) kullanarak oynatım yapıyorum (Sorunlarım çıktı olarak görünüyor). Bu, soket/internet beslemesinden bir boost kilitsiz kuyruğa beslenen bir akışlı ses kaynağıdır ve daha sonra çıkış AU'suna beslenir. AU'nun geri çekilmesinin bir sonucu olarak ortaya çıkan ses kesintilerini, aralıklı olarak çekirdek ses tarafından aranmıyor.
İşte bir graph. Bu bölümden önce ~ 10 saniye kusursuz ses vardı.OS X çekirdek ses çalma/çıkışı ile ses çıkışları yaşanıyor
siyah: örnek ses, basit bir sinüs dalgası
mavi: lockless sıranın boyutu (playback_buf: ms geri arama (OutputProc) işlemek yukarıdaki tabloda nokta ile duvar saat süresi ~ 120ms
turuncu ms zaman
Herşey OutputProc kaydedilir, böylece denilen değilse, o zaman hiçbir şey kaydediliyor alır, ancak grafik aracı olacak:) örneklerinde/1000 güzel
x ekseni grafiğinde sığdırmak için noktaları birbirine bağlayın dönemleri. Tamponda her zaman yeterli örnek var. Görünüşe göre ~ 22475ms ~ 22780ms, OutputProc sadece bir kez 22640 olarak adlandırılır. Bu belirli bir örnek üzerinde uzun bir duvar saati zamanı var, ama emilimden ötürü gibi görünüyor. Daha sonra 22800 ila 23000 aralığında hala çıkışlar var ama OutputProc normalden daha uzun sürmez ve gerçek zamanlı pencereyi kesinlikle aşmaz (~ 6ms burada ... HW örnekleme hızı 96kHz'dir). Öyleyse, sanırım bu bir şekilde önceden boşalan başka bir iş parçacığı. Çekirdek ses parçasının çok yüksek bir prioya sahip olmasını beklerdim. Paralel giriş/çıkışın paralel olarak devam etmesine (örneğin, boost :: asio :: io_service io_service) sahibim ama her zaman temel ses seviyesine öncelik vermeyi beklerim. Eğer asıl sorun için herhangi bir işaretçiniz varsa ... bu her zaman bekler ... ama, ilgilendiğiniz zamanlarda hangi iplik (ler) inin çalıştığını öğrenebilir miyim? Xcode'ta, muhtemelen bir işlemci çekirdeği başına bir zamanlayıcı geçmişi veya iş parçacığı geçmişi bildiren bir şey var mı? OutputProc eğer yardımcı olur:
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'nun geri çağırma duvar saati süreleri, Geri Çağırma veya kesintili sistem çağrılarını OutputProc'a dönüştürür. Geri arama iş parçacığı gerçek zamanlı ve zamanlayıcı tabanlı. Üretici iş parçacığı zamanında veri sağlamazsa, beklemez: sessizlik, aldığınız şeydir. Sanırım sorun başka bir yerde olmalı. Bu satır nedir: 'if (playback_buf_avail> = This-> playback_buf_thresh)' ve hangi mekanizma _This_ veri yapısını günceller? – user3078414