Време между обратни повиквания?

Имам лабораторен проект, който използва основно PyAudio и за да разбера допълнително неговия начин на работа, направих някои измервания, в този случай времето между обратните извиквания (използвайки режим на обратно извикване).

Изчислих времето и получих интересен резултат

(@256 размер на част, 44.1k fs): 0.0099701;0.0000365;0.0000201;0.0201579

Този модел продължава и продължава.

Между две по-дълги обаждания имаме две по-кратки обаждания и понякога по-дългото обаждане е по-кратко (имайте предвид, че не правя нищо друго в програмата освен измерване на времето за обратно извикване).

Ако осредним това, получаваме желаното време за обратно извикване:

1/44100 * 256 (приблизително 5,8 ms)

Ето визуализираното ми измерване: въведете описание на изображението тук

Може ли някой да обясни какво точно се случва тук под капака?


person function_store    schedule 22.04.2014    source източник


Отговори (1)


Какво се случва под капака в 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
comment
Благодаря за изчерпателния отговор! Включва някои мисли, за които обмислихме с моя консултант :) Аз съм с win8 и използвам версията, достъпна от lfdi.uci.edu pythonlibs колекция, с доста основни настройки. Ще пробвам предложените варианти, пак благодаря! - person function_store; 23.04.2014
comment
Извинете ме, че ви безпокоя с моя noobish въпрос, но в PyAudio как да задам латентността или да използвам параметъра paFramesPerBufferUnspecified? Използвам изключително PyAudio - person function_store; 29.04.2014
comment
@function_store Не съм сигурен, никога не съм използвал PyAudio. За да получите paFramesPerBufferUnspecified, опитайте да предадете 0 за framesPerBuffer. - person Ross Bencina; 01.05.2014