Какво се случва под капака в PortAudio зависи от редица фактори, включително:
- С кой естествен аудио API говори PortAudio
- Какъв размер на буфера и параметри за латентност сте предали на
Pa_OpenStream()
- Възможностите на аудио хардуера и неговите драйвери, включително поддържаните размери на буфера, модел на буфериране и характеристики на времето.
При някои обстоятелства PortAudio ще поиска по-големи буфери от родния аудио API и след това ще извика обратното извикване на потребителя PortAudio няколко пъти в бърза последователност. Това може да се случи, ако сте избрали малък размер на буфера за обратно извикване и дълго забавяне.
Друг сценарий е, че собственият аудио API не поддържа размера на буфера, който сте поискали за вашия размер за обратно извикване (framesPerBuffer
параметър към Pa_OpenStream()
). В този случай PortAudio ще бъде принуден да използва поддържан от драйвера размер на буфера и след това да се „адаптира“ между този размер на буфера и размера на вашия буфер за обратно извикване. Този процес на адаптиране може да причини неправилно време.
Още една възможност е естественият аудио API да използва голям пръстен буфер. Всеки път, когато PortAudio анкетира собствения API на хоста, той ще работи, за да запълни естествения буфер за пръстен, като извиква вашето обратно извикване толкова пъти, колкото е необходимо. В този случай нередовното време е свързано с честотата на гласуване.
Горните не са единствените възможности.
Едно вероятно обяснение на случващото се във вашия случай е, че PortAudio извиква вашето обратно извикване 3 пъти в бърза последователност (предположение би било, че естественият размер на буфера е 3 пъти размера на вашия буфер за обратно извикване), поради една от причините по-горе.
Друга възможност е естествената аудио подсистема да сигнализира PortAudio нередовно. Това може да се случи, ако системен слой под PortAudio извършва подобни видове буфериране като това, което описах по-горе. Виждал съм това да се случва с DirectSound на Windows 7 например. Драйверите ASIO4ALL ще показват +/- 1ms трептене (което не е това, което виждате).
Можете да опитате да намалите заявеното забавяне на потока до 0 и да видите дали това ще промени резултата. Това ще принуди двойно буфериране, което може или не може да доведе до стабилен изход. Друго нещо, което трябва да опитате, е да използвате параметъра paFramesPerBufferUnspecified
, който ще накара обратното извикване да бъде извикано с основния размер на буфера -- тогава можете да наблюдавате дали има по-голяма периодичност, какъв е този размер на буфера и също дали размерът на буфера варира от обратно повикване към обратно повикване.
Не казахте към коя операционна система и хост API се насочвате, така че е трудно да дадете по-конкретни подробности от горните.
Вътрешните модели на буфериране, използвани от различните бекендове на API на хоста на PortAudio, са описани в някои подробности в PortAudio wiki .
За да отговоря на свързан въпрос: защо е така? Освен случаите, когато това е функция на по-ниските слоеве на собствената аудио подсистема или процеса на адаптиране на буфера, това често е резултат от указване на голямо препоръчително забавяне на Pa_OpenStream()
. Някои приложни програмни интерфейси (API) на хоста на PortAudio ще облекчат периодичността на буфера, ако указаната латентност е много висока, за да се намали натоварването на системата, което би било причинено от високочестотни обратни извиквания на таймера.
person
Ross Bencina
schedule
22.04.2014