У меня ещё красивее значения: 6720, 0… 480, -7456, 52864, -55456, -1472
Windows 8 x64, встроенная Realtek HD Audio (ALC889)
http://paste.org.ru/?nklc06
Вид для печати
У меня ещё красивее значения: 6720, 0… 480, -7456, 52864, -55456, -1472
Windows 8 x64, встроенная Realtek HD Audio (ALC889)
http://paste.org.ru/?nklc06
Твоя теория далека от практики) Предлагаю тебе сделать рабочий макет)
---------- Post added at 17:34 ---------- Previous post was at 17:32 ----------
Т.е. каждый новый кадр спектрума совпадал с кадром развертки ПЦ?
Или же просто перед выводом нового кадра ожидался VBlank?
да вроде так. в этом режиме не надо было дополнительно указывать частоту прерываний спека. но это не 100%.
рабочий макет чего? эмулятора? больше заняться нечем.
ты утверждал, что при +-480 сэмплов нельзя точно определить частоту. я не поленился и проверил - считается ДОСТАТОЧНО точно. хочешь сказать, что я не прав - скажи почему.
1. скользящее среднее от буфера с разницами указателей на проигрывание между фреймами (тех самых, которые n*480).
2. скользящее среднее от 1.
быстро, дешево, точно.
каждый фрейм:
1. ищешь разницу указателей на проигрываемый кусок (у текущего и предыдущего фрейма), она будет 480 или 2*480 каждый раз.
2. кладешь в кольцевой буфер.
3. считаешь среднее от всего буфера, получаешь число.
4. кладешь это число во второй кольцевой буфер.
5. считаешь среднее от этого буфера, получаешь число.
вот это число и есть точное дробное значение кол-ва сэмплов за фрейм. фильтр можно подогнать под реальные условия, но главное, что из этих 480 и 2*480 он вполне выделяет точное число.
Кстати, Titus, обратил внимание на строчку:
А откуда берутся данные, что выбран режим 48000Hz. Тут много где рекомендуют, что бы не было глюков на встроенных звуковухах выставлять принудительно только 44000Hz, или это просто максимальные возможности указаны?Цитата:
Sound: 48000Hz, 16bit, 2 channels
Хм, вообще-то это я принудительно выставляю, в надежде, что это самый распространенный режим, и хорошее качество.
---------- Post added at 21:15 ---------- Previous post was at 20:59 ----------
У меня практически так и есть.
Вот смотри. При 48000Гц аудио и 75Гц видео в кадре умещается ровно 640 отсчетов. В начале каждого кадра я фиксирую позицию в аудиобуфере и вычисляю, сколько проигралось отсчетов. Обычно это 640 +- 2..5. Если разброс укладывается в необходимый коридор, то я добавляю длину проигранного буфера в кольцевой буфер статистики, если же нет, то отбраковываю и в статистике не учитываю. При длине кольцевого буфера 128 позиций, колебания +-2..5 уезжают в облась сотых долей отсчета, что позволяет ими пренебречь. В течение каждого кадра так же проверяется, отстаем мы от прогнозируемой текущей длины буфера (допустим, равной 640.01356) или же опережаем. Если отстаем то корректируем число отсчетов в кадре на +0.01, если опережаем, то наоборот, соответственно. И каждый кадр натягиваем звук на это дробное текущее число отсчетов в кадре. Если в случае экстренных тормозов Винды потеряли кадр, или же по каким-то причинам прогнозируемое число отсчетов отстало или уехало более, чем на пол-кадра (320 отсчетов), то все параметры обнуляются и указатели выставляются на 0 (тут будет склейка звука).
Теперь, что получается при биении +480? Да ничего не получается. Во-первых надо делать огромный пребуферинг, не в пол-кадра, а гораздо больше. Это означает, что звук уже будет заметно отставать от видео.
Во-вторых, колебания длины буфера будут в 100 раз больше, что для меня ну совсем неприемлимо.
возможно, это не самый лучший вид регулятора.
у меня получается, у тебя не получается, ага.
вот это с чего взято? что выдумывать-то? я брал пребуферинг в 480 сэмплов (не говоря о том, что я уже рассказывал, что можно его сильно ограничить 2м регулятором).
вот тебе джва столбца, один ты уже видел, второй - число реальных (не округленных до 480) непроигранных сэмплов в буфере:
как видишь, никаких колебаний длин в 100 раз больше не видится.Цитата:
881.292 444
881.292 447
881.292 451
881.292 453
881.292 457
881.28 456
881.292 454
881.292 456
881.292 457
881.292 460
881.292 462
881.28 458
881.292 454
881.292 453
881.292 453
881.292 457
881.292 458
881.28 459
881.292 463
881.292 461
881.292 463
881.292 460
881.292 463
881.28 459
881.292 460
881.292 460
881.292 459
881.292 464
881.292 465
881.28 466
881.292 470
881.292 471
881.292 474
881.292 471
881.292 472
881.28 471
881.292 474
881.292 477
881.292 480
не поленись, напиши симулятор и проверь. сначала на синтетических "ровных" данных, потом на неровных.
вообще, так можно про что угодно сказать. например, неприемлим никакой регулятор кроме релейного:) а уж если подходить профессионально, так винда вообще для этой затеи не приемлима. но если уж что-то выжимать, то пытаться это делать всеми способами.
исходник не с собой щас, завтра.
Сделал маленький тест возможности точного позиционирования при эксклюзивном владении первичным буфером.
Тестируем.
buffer: 32768, step 480, monitor freq = 60
visible/total scanlines: 1080/1080
timer period min -1ms
и больше ничего. ЧОООрный экрааан
по вводу hello! - закрывается :)
7ёрка, да
а вообще - что ожидалось в выводе теста?
хреново.
Вот тебе повод поставить 7
Азио - выдумка Стейнберга, свои быстрые дрова на звук под хорошие звуковухи.
поэтому народ и юзает азио4олл как переходник, кто в теме с музыкой но без крутого аудио-железа.
С Хаббра:
Цитата:
Меломанам: точный вывод звука
1. Как я писал выше, большинство приложений для вывода звука в Windows 7 (хотят они того, или нет) используют режим WASAPI Shared. Но есть и другой режим — WASAPI Exclusive. Если руководствоваться блок-схемой, то в этом режиме отбрасывается всё, что лежит между Application Programming Interface и Kernel Streaming Transport — грубо говоря, звук идет непосредственно от приложения через интерфейс WASAPI на звуковую карту.
Но надо сделать замечание: так как в этом режиме отключен микшер WASAPI, а к микшеру звуковой карты доступа всё равно нет (ибо нет DirectSound), при использовании приложением эксклюзивного режима, воспроизведение любого другого источника через WASAPI становится невозможным.
Но, так или иначе, мы получаем по-битовый вывод аудио на звуковую карту.
2. Есть и другой способ. Если ваша звуковая карта имеет родной драйвер ASIO — вам крупно повезло. ASIO функционирует совершенно отдельно от WASAPI, так что, при прослушивании музыки системные звуки не будут отключаться — потоки ASIO и WASAPI будут микшироваться самой звуковой картой.
Вывод: если ваш драйвер ASIO не вызывает сомнений, используйте его.
Да, чуть не забыл — ASIO4ALL использовать нежелательно — как и Kernel Streaming, в этой ОС он работает очень нестабильно (судя по всему, из-за того, что другие звуки, идущие через WASAPI, периодически блокируют Kernel Transport).
или hdmi, у меня монитор через hdmi может 60,59,50,48,30,25,24 а если подключить через VGA то только 59,60,75
---------- Post added at 10:49 ---------- Previous post was at 10:42 ----------
AC97 там никакого буфера нет, процом через последовательный интерфейс пишутся слова и она как DAC работает
вот и какие претензии могут к нему быть, буфер создается на сколько то там байт, dma натравливают что бы он с какой то частотой в кодек выкидывал, лишнее прерывание это переключение контекста проца, новая инициализация dma и переключение обратно, думаю из за этих соображений сделан буфер фиксированной длинны, если клоцать как на аппаратной звуковухе то у проца времени не останется на работу
И при запуске quartus на одном и том же ноуте, под XP музыка заикалась неподецки, на Win7/8 пофик, все гладенько
Я о том что 480 выборок в буфере и дискретность целая (хотя когда смотрел тесты когда hmdi основное звуковое устройство, у меня было 75% delta=0, остальное 480 и 224, иногда что то левое с большими значениями проскакивало)
На Win2003 вообще не работает тест, говорит "Can't create Back-Buffer Surface!"
вот код прототипа-симулятора. 2я колонка показывает реальное число сэмплов в буфере, оно должно стабилизироваться.
Код:# -*- coding: utf-8 -*-
import random
QUANT=882 # рассчетное число сэмплов в прерывание
RES=480 # разрешение указателей звукового буфера
bufpos=0 # позиция буфера записи
playpos=0 # позиция буфера чтения
# put data to buffer
def render_frame(n):
global bufpos
bufpos+=int(n+0.5)
# play data from buffer
def play_frame(n):
global bufpos,playpos
n+=random.randint(-5,3) # add some noise to samples number
playpos+=n
if bufpos<playpos:
print "Underrun!"
# get rounded position
def get_pos():
return playpos/RES*RES
# limit value from l to h
def lim(v,l,h):
return min(h,max(l,v))
render_frame(RES) # пребуфферинг
fff=[];fff2=[] # окна фильтров
delta=0.0 # добавка к рассчетному числу сэмплов
I=0.0 # сост. интегратора
avg=0 # среднее зн. числа сэмплов
while 1:
# "заполняем" буфер, проигрыванием, вычисляем изменение указателя
t1=get_pos()
render_frame(QUANT+delta)
play_frame(QUANT)
t2=get_pos()
print avg,bufpos-playpos,delta,I
# filter 1
fff.append(t2-t1)
fff=fff[-200:]
avg=float(sum(fff))/len(fff)
# filter 2
fff2.append(avg)
fff2=fff2[-200:]
avg=sum(fff2)/len(fff2) # вычисленное реальное число сэмплов за фрейм
# ПИ-регулятор
if len(fff)>=200: # работает, если есть статистика по 200 фреймам
smps=int(QUANT+delta+0.5) # кол-во положенных сэмплов (то, что ушло в render_frame() в этот раз)
err=lim(avg-smps,-5,5) # разница между вычисленным средним и отправленным
I+=err*0.01; I=lim(I,-5,5) # ограниченный интегратор
P=0.5*err # проп. звено
delta=P+I # сумма
Питон это, без знания синтаксиса может жестью показаться
Код:Да
разве
ж
это
жесть?