язык нравится!
Вид для печати
язык нравится!
имхо, синтаксис отличный, очевидный. даже табы.
Ну понять работу с массивами не прочитав хотя бы азов питона маловероятно (сильно от c-like языков отличается)
хотя согласен для расширения сознания с питоном полезно хотя бы ознакомиться
psb, а Маяковский тебе в детстве нравился? =)
>для прототипов супер штука.
Я склонен согласиться с этим, но сам как-то хреново питон воспринимаю, и логика зависящая от пробелов меня коробит.
>но к чему такая аналогия?
Да к внешнему виду исходника, очень похоже.
Доделал версию, котрая использует эксклюзивный режим DirectSound.
В архиве лежат три версии:
EmuStudio-ZX Primary - воспроизведение в эксклюзивном режиме
EmuStudio-ZX Primary 3.5 - воспроизведение в эксклюзивном режиме с задержкой 3.5 кадра.
EmuStudio-ZX Secondary - обычная версия.
В эксклюзивном режиме всем другим приложениям запрещается вывод звука, а первичный аудиобуфер отдается одной единственной программе, т.е. эмулятору.
Некоторые особенности работы в подобном режиме:
1. При потере фокуса приложения, аудиобуфер отбирается, и восстанавливается при возвращении фокуса. Т.е. если окно эмулятора не активно, то звук не играет.
2. Закрывать эмулятор нужно крестиком на окне эмулятора, а не консольного окна, иначе в системе не восстановится глобальный регулятор громкости, и придется его восстанавливать самим в настройках.
3. Судя по всему, в эксклюзивном режиме информация о курсоре проигрывания не совсем верная и звук отстает. Поэтому я сделал еще версию с коррекцией (3.5 которая), в которой, во всяком случае у меня, звук воспроизводится без задержки.
Тестируем на WinXP и Win7 (хотя надежд в отношении нее я не чаю).
Так же, если у кого звук работает, нажимаем клавиши и слушаем, не задерживается ли звук от нажатых клавиш. Меня, как и раньше, интересует скриншот с первой страницей лога.
p.s.: В отладочном окне появилась дополнительная информация в реальном времени на сколько прогнозируемый размер аудиофрейма отстает или опережает реальный.
Звук везде ужасен - булькает и скрипит.
P
http://i.piccy_.info/i8/9983a9d4b4d2...6276/p_500.jpghttp://i.piccy_.info/a3/2013-10-02-1...00x246-r/i.gif
S
http://i.piccy_.info/i8/f7670cd77b0d...6276/s_500.jpghttp://i.piccy_.info/a3/2013-10-02-1...00x247-r/i.gif
3,5
http://i.piccy_.info/i8/9fc4024b5b30...76/3_5_500.jpghttp://i.piccy_.info/a3/2013-10-02-1...00x246-r/i.gif
еще раз напоминаю - эмуль вешает CPU 80-90% как так?
забыл - win xp 32 звук встроенный
во всех случаях:
хрипит и теряет 2,3 (самый частый случай, вообще - от 1 до 4) фрейма, потом не может синхриться.
"Секондари" смог играть вместе с другой музой из анрила :), другие музыку останавливали.
На самом деле, он вешает проц примерно 30% + сколько нужно для собственно эмуляции.
30%, потому что ближе к концу кадра, чтобы не прозевать начало луча, он перехватывает управление на себя.
А эмуляция не очень быстрая, т.к. львиную ее долю занимает программный рендеринг видеоизображения в формате точки 3x3 со сканлайнами. Если это переложить на плечи блиттера, то будет заметно быстрее.
---------- Post added at 22:27 ---------- Previous post was at 22:26 ----------
Лог и версия винды.
другой комп,точнее уже бук.
WIN XP 32 .звук soundMax ,видео ATI 9600 все встроенное.тут вообще жесть - звук набор звуков и еще изображение разьехалось.
Версия P
http://i.piccy_.info/i8/55a57df6d586...5579/p_500.jpghttp://i.piccy_.info/a3/2013-10-02-1...86x343-r/i.gif
CPU уже под 80% загрузка.intel pentium m 1600.другие эмули просто летают на нем
http://i.piccy_.info/i8/25249258b3a9...5579/u_500.jpghttp://i.piccy_.info/a3/2013-10-02-1...00x285-r/i.gif
http://i.piccy_.info/i8/d5bbe6881a85...79/123_500.jpghttp://i.piccy_.info/a3/2013-10-02-1...00x218-r/i.gif
А другие версии? На этом буке, судя по данным, все же должно работать. Попробуй удержать окно эмулятора пару секунд, не сбросятся ли величины расхождения звука в 0 в консольном окне?
На счет изображения - у тебя там случайно не стоит ли видеорежим отличный от 32 бит?
---------- Post added at 23:16 ---------- Previous post was at 23:09 ----------
Описание индикатора быстродействия:
http://s40.radikal.ru/i087/1310/a6/2080aa4fe8c9.png
EmuStudio-ZX Primary 3.5.exe тут звук классный
http://i.piccy_.info/i8/d5ad88706da7.../55555_500.jpghttp://i.piccy_.info/a3/2013-10-02-1...72x354-r/i.gif
да ,стояло 16 бит почему то .щас изображение нормальное - загрузка cpu 80%
на скриншоте видно этот индикатор -когда музыка не играет примерно на 65% заполнен.звук без задержек вроде .
---------- Post added at 22:26 ---------- Previous post was at 22:19 ----------
сейчас звук более менее в версии P .Ускорен из за 60 герц.
Если держать окно эмулятора то звук зацикливается.на скриншоте результат удержания окна
http://i.piccy_.info/i8/1c236a47fe9a...9/6666_500.jpghttp://i.piccy_.info/a3/2013-10-02-1...72x354-r/i.gif
Titus, после того как сделал экран с 16 на 32 то звук в DIZZY очень узнаваем и в обоих версиях реакция звука без задержек.поиграл маленько мин 10 - вроде норм
На восьмерке все плохо, все версии
---------- Post added at 23:46 ---------- Previous post was at 23:35 ----------
Зато если переключить на 50гц развертки, все почти идеально, 99,9% выводит 0> иногда пропускает фреймы тот что Primary
скрин
В данном случае работает потому, что 'случайно' параметры кратны друг другу.
при 50Гц 48000/50 = 960 (а это 480*2),
ну и при 100Гц 48000/100 = 480.
Т.е. все кратно дискретности буфера на Win7.
---------- Post added at 03:24 ---------- Previous post was at 02:25 ----------
Попробовал понять, все-таки ничего не понял)
Попробуй изобразить на си, если не сложно.
блин, ну я же уже и словами описывал... что именно там не понятно? функции (def) должны быть понятны.
# filter 1
fff.append(t2-t1)
fff=fff[-200:]
avg=float(sum(fff))/len(fff)
fff - массив из чисел. append добавляет в него новое число, fff=fff[-200:] оставляет последние 200 чисел, avg - сумма всех чисел делится на кол-во чисел. второй фильтр - то же самое.
в регуляторе чистая математика. где не понятно?
Набросал на си твою програму, как я ее понял:
На 882 выходит только через несколько сот итераций.Код:// PSB-Test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "math.h"
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define DIMLEN 200
float QUANT = 882; // рассчетное число сэмплов в прерывание
float RES = 480; // разрешение указателей звукового буфера
float bufpos = 0; // позиция буфера записи
float playpos = 0; // позиция буфера чтения
float FFF[DIMLEN]; // фильтр 1
float FFF2[DIMLEN]; // фильтр 2
float delta = 0; // добавка к рассчетному числу сэмплов
float I = 0; // сост. интегратора
float avg = 0; // среднее зн. числа сэмплов
long len = 1; // начальная длина массива
void render_frame(float n) // put data to buffer
{
bufpos = bufpos + long(n + 0.5);
}
void play_frame(float n)
{
n = n - 5 + rand() * 10.0 / RAND_MAX; // add some noise to samples number
playpos = playpos + n;
if (bufpos < playpos)
printf("Underrun!\n");
}
float get_pos(void) // get rounded position
{
return((long)((long)playpos / RES) * RES);
}
float lim(float v, float l, float h) // limit value from l to h
{
return(min(h, max(l, v)));
}
int _tmain(int argc, _TCHAR* argv[])
{
long j, k;
float t1, t2, sum, err, P, smps;
printf("Test!\n");
render_frame(RES); // пребуфферинг
for (j=0; j<1050; j++) // заполняем" буфер, проигрыванием, вычисляем изменение указателя
{
t1 = get_pos(); //
render_frame(QUANT + delta); //
play_frame(QUANT); //
t2 = get_pos(); //
printf("avg = %f, b-p = %f, delta = %f, I = %f\n",
avg, bufpos-playpos, delta, I);
// filter 1
for (k=0; k<(DIMLEN-1); k++) //
FFF[k] = FFF[k+1]; //
FFF[k] = t2 - t1; //
sum = 0; //
for (k=DIMLEN-len; k<DIMLEN; k++) //
sum = sum + FFF[k]; //
avg = sum / len; //
// filter 2
for (k=0; k<(DIMLEN-1); k++) //
FFF2[k] = FFF2[k+1]; //
FFF2[k] = avg; //
sum = 0; //
for (k=DIMLEN-len; k<DIMLEN; k++) //
sum = sum + FFF2[k]; //
avg = sum / len; // вычисленное реальное число сэмплов за фрейм
// ПИ-регулятор
if (len == 200) // работает, если есть статистика по 200 фреймам
{
smps = long(QUANT + delta + 0.5); // кол-во положенных сэмплов (то, что ушло в render_frame() в этот раз)
err = lim(avg - smps, -5, 5); // разница между вычисленным средним и отправленным
I = I + err * 0.01; // ограниченный интегратор
I = lim(I, -5, 5); //
P = 0.5 * err; // проп. звено
delta = P + I; // сумма
}
else
len++;
}
return 0;
}
А колебания длины кадра даже на 1000-й итерации доходят до 0.1, что очень грубо.
Пока что не вникал в подробности, только перенес на Си.
да, 0.1 семпла.
В реальных условиях, если я не ошибаюсь, около 0.01. Причем никаких заметных на слух колебаний даже в самом начале регулировки. Таким образом сразу после запуска эмулятора слышится ровный, никуда не плавающий звук.
И еще, ты не знаешь о таком моменте, что нет никакой гарантии точного временнОго детектирования начала кадра. Т.е. в среднем, колебания может быть в несколько сканлайнов, но, особенно в зависимости от загрузки винды, скачки могут быть непредсказуемые и достаточно большие. У меня на это тоже идет корректировка, без чего не было бы такой точности.
+- даже несколько целых сэмплов за фрейм ты не услышишь.
Да и у нас на форуме она у 80%.
---------- Post added at 21:52 ---------- Previous post was at 21:14 ----------
Начитался, что Kernel Streaming не использует системный миксер и имеет малую задержку (во всяком случае для систем до Win7). Но ссылки на доки от него на майкрософте давно протухли. Не смог ничего найти. Ни у кого нет доки и примеров? Называется вроде DirectKS.
deathsoft и unreal передают тебе привет (сорцы примера directks)
http://www.microsoft.com/en-us/downl....aspx?id=18989
Спасибо за тестовый пример Direct Streaming.
Поразбиравшись, сделал на основе него тест, позволяющий проверить точность позицирования этим методом.
Запускаем тест, и несколько раз в меню нажимаем RUN и STOP, должен получиться такой лог. А так же звучать гладкий без щелчков и прерываний синус. Потом лог пишем сюда. Особенно владельцы Win7, т.к. не факт, что там это заработает. А если заработает, да еще и с малым разрешением - будет вообще супер.
Код:0.027: Заполнение буфера 16-битным синусом
0.036: Pin state is KSSTATE_STOP
2.460: Setting Pin to KSSTATE_RUN ...
2.461: Packet 0 is available... Submitting packet 0
2.462: Position = 5, Position2 = 6, Delta = 1
4.700: Setting Pin to KSSTATE_STOP ...
5.804: Setting Pin to KSSTATE_RUN ...
5.805: Packet 0 is available... Submitting packet 0
5.806: Position = 4, Position2 = 5, Delta = 1
7.380: Setting Pin to KSSTATE_STOP ...
8.300: Setting Pin to KSSTATE_RUN ...
8.301: Packet 0 is available... Submitting packet 0
8.302: Position = 14, Position2 = 15, Delta = 1
9.436: Setting Pin to KSSTATE_STOP ...
Так, один семерочник написал, что под вин7 у него не работает.
Дождемся других.
Titus, ок :)
походу 139 было на стационарном компе.Сейчас гляну на буке с xp и на стационаре с Win7
запуск на буке win XP 32
win 7 x64 sp1Цитата:
0.055: Заполнение буфера 16-битным синусом
0.139: Pin state is KSSTATE_STOP
6.040: Losing focus!! We must relenquish our resources ...
6.040: Aborting streaming loop ...
6.046: Leaving RenderThreadProc
6.146: Gaining focus!! Must build graph ...
6.150: Entering RenderThreadProc
6.161: Заполнение буфера 16-битным синусом
6.183: Pin state is KSSTATE_STOP
11.277: Setting Pin to KSSTATE_STOP ...
13.988: Setting Pin to KSSTATE_RUN ...
13.990: Packet 0 is available... Submitting packet 0
13.992: Position = 11, Position2 = 13, Delta = 2
18.220: Setting Pin to KSSTATE_STOP ...
19.899: Setting Pin to KSSTATE_RUN ...
19.901: Packet 0 is available... Submitting packet 0
19.902: Position = 11, Position2 = 13, Delta = 2
25.803: Setting Pin to KSSTATE_STOP ...
27.579: Setting Pin to KSSTATE_RUN ...
27.581: Packet 0 is available... Submitting packet 0
27.582: Position = 11, Position2 = 13, Delta = 2
32.697: Setting Pin to KSSTATE_STOP ...
34.553: Losing focus!! We must relenquish our resources ...
34.555: Aborting streaming loop ...
34.556: Leaving RenderThreadProc
55.838: Gaining focus!! Must build graph ...
55.841: Entering RenderThreadProc
55.852: Заполнение буфера 16-битным синусом
55.875: Pin state is KSSTATE_STOP
Цитата:
0.031: Заполнение буфера 16-битным синусом
0.047: Pin state is KSSTATE_STOP
2.325: Losing focus!! We must relenquish our resources ...
2.325: Aborting streaming loop ...
2.325: Leaving RenderThreadProc
2.387: Gaining focus!! Must build graph ...
2.387: Entering RenderThreadProc
2.403: Заполнение буфера 16-битным синусом
2.403: Pin state is KSSTATE_STOP
6.646: Setting Pin to KSSTATE_RUN ...
6.646: Packet 0 is available... Submitting packet 0
6.661: Position = 216, Position2 = 220, Delta = 4
11.232: Setting Pin to KSSTATE_STOP ...
14.586: Setting Pin to KSSTATE_RUN ...
14.602: Packet 0 is available... Submitting packet 0
14.602: Position = 168, Position2 = 172, Delta = 4
24.118: Setting Pin to KSSTATE_STOP ...
27.035: Setting Pin to KSSTATE_RUN ...
27.035: Packet 0 is available... Submitting packet 0
27.035: Position = 192, Position2 = 196, Delta = 4
34.601: Setting Pin to KSSTATE_STOP ...
39.281: Losing focus!! We must relenquish our resources ...
39.281: Aborting streaming loop ...
39.281: Leaving RenderThreadProc
76.674: Gaining focus!! Must build graph ...
76.674: Entering RenderThreadProc
76.690: Заполнение буфера 16-битным синусом
76.690: Pin state is KSSTATE_STOP