В консоли Win7? :)
- - - Добавлено - - -
https://i.imgur.com/X6DTjLX.png
https://i.imgur.com/r9bEu93.png
Вид для печати
В консоли Win7? :)
- - - Добавлено - - -
https://i.imgur.com/X6DTjLX.png
https://i.imgur.com/r9bEu93.png
Странно, что у тебя работает классическая версия, т.к. ни у кого другого на Win7 она еще не работала нормально.
То, что DWM-версия не работает, это нормально при отключенной композиции рабочего стола.
Значит отмечу, что не все Win7 имеют блокирующий вызов ожидания VBlank. Может быть от драйверов зависит.
И не стоит автоматически переключаться с ожидания VBlank на DWM на Win7.
Благодарю, да, то что надо.
Ну заработала только DWM, но на 75Гц ускоренно работает. Остальные запускаются, звук идет, картинка даже первая тоже появляется, потом идет потеря всех остальных кадров, в консоли Resync и куча звездочек, картинка замирает. Все, как у человека выше. Потом может обновиться одним кадром, и снова замереть, было такое. В общем, если там что-то исправить, то заработает.
Ну это не очень корректное сравнение. Плавности не будет, потому что это 50Гц. Если выставить у ЖК-монитора 50Гц, это выглядит все равно плохо, хоть и аутентично. А несоответствие частот развертки эмулируемой системы и развертки монитора влияет только на линии разрыва, их количество, расположение и их движение по экрану. Ну хотя тут от реализации зависит... Если ждать вертикальной синхронизации, то будут рывки, да.
Нужны скриншоты полного консольного окна и окна графиков
- - - Добавлено - - -
Это понятно, потому что у большинства людей (до @Bedazzle думал, что у всех), синхронизация VBlank под Win7 блокирующая, поэтому поток останавливается. А DWM не блокирующая, хотя и худшей точности.
- - - Добавлено - - -
Тут понятие 'плохо' слишком абстрактное.
Для меня выглядит прекрасно)
А если я включаю 100Гц, то еще прекраснее.
Повторюсь - тем, кому нравится другое соотношение частот, никто не мешает использовать их. Когда они будут поддерживаться, разумеется. Или на других эмуляторах.
Я же няшку делал прежде всего для своего удовольствия, а если она кому-то еще пригодится, я тоже только рад.
Но мне нужен график и консольное окно для статистики)
- - - Добавлено - - -
Не эмулируется. Это чисто номинальное ядро Z80 только для теста движка эмулятора.
- - - Добавлено - - -
Все еще актуален запрос к @Enigmatic о полной информации, которая вывелась в окно консоли.
- - - Добавлено - - -
И к @cafedead тоже самое.
Опа. А а вот внешняя звуковуха USB мне первый раз попадается.
И сразу бросается в глаза то, что ее размер буфера подкачки не равен 10мс, а равен общему размеру буфера 22мс.
Интересно погонять эмулятор хотя бы минут 5-10, и посмотреть, сколько раз напишет Resync в консольном окне.
Если много раз напишет, то запустить версию с аудиобуфером 3.5 вместо 1.5.
Всё бы хорошо, но в нашем случае ситуация обратная - в спектруме видео и звук тактируются от одного клока, поэтому они строго синхронизированы. А на ПК тактирование видео и звука идёт от разных, асинхронных источников.
Если использовать аналогию с конвейером, то у нас две линии – для муки и сахара. На входе строго синхронно, каждую секунду, подаётся ровно по 1 литру муки и 1 литру сахара. Но на выходе муку забирают ложкой объёмом 1.1 литра в секунду, а сахар - 0.9 литра в секунду.
Очевидно, что мука расходуется быстрее, чем сахар, хотя поступают они с одинаковой скоростью. Мы не можем изменить скорость забора, она фиксирована и не поддается регулировке. Единственное, что нам доступно - регулировать подачу на входе, но подача всё равно должна быть строго равными объёмами муки и сахара.
И хуже того, скорость забора муки не синхронизирована со скоростью забора сахара и случайным образом меняется со временем, поэтому в какой-то момент времени соотношение скоростей забора может измениться и мука будет забирается со скоростью 0.8 литра в секунду, а сахар 1.15 литра в секунду.
И вот главный вопрос - откуда брать недостающую муку или куда девать лишний сахар?
Второй момент - точность измерения частоты видео и звука. Любой пропуск кадра может вносить значительные ошибки, особенно при высокой нагрузке системы. Также, по моим тестам, некоторые драйверы звуковых карт ведут себя нестабильно - уведомления о позиции воспроизведения могут приходить нерегулярными порциями (например, сначала 1 сэмпл, затем 1024, потом 7 сэмплов, потом 1600 и т. д.), а иногда обновления могут даже группироваться в серии без задержек. Все эти факторы значительно снижают точность определения реальной частоты дискретизации звука, поскольку затрудняют точное измерение объёма аппаратного буфера и частоты его обновления в процессе воспроизведения.
Растягивать и недосыпать)
Если у тебя монитор на компьютере дает 50.1Гц, а спектрум 49.9Гц (для примеру), то придется растянуть времянки спектрума до 50.1Гц.
Тоже самое и со звуком.
- - - Добавлено - - -
Совершенно, верно. Точность измерения частоты кадров и семплов - это самое сложное, над чем я долго работал.
Твои тесты драйверов звуковых карт, как я понял, опираются на DirectSound. А это очень старая технология, которая эмулируется через WASAPI уже сто лет как.
Что же касается WASAPI, то даже в кооперативном (обычном) режиме, забор данных идет плюс-минус равномерно. Но даже с теми звуковухами, которые имеют внутренние дополнительные буфера-прослойки (у меня есть такая карта), все равно получается стабильно с моим алгоритмом, приходится только несколько побольше сделать зазор звукового буфера (лишние 10мс, в худшем случае 20мс). А в целом основная часть звуковух работает стабильно с зазором 5мс. Впрочем, можно ставить 2-3мс, но это такие мелочи, которые можно округлить до 5мс для надежности.
Я гонял эту систему стабилизации на совершенно разных и даже очень тормозных компах, пока что прекрасно справляется.
Впрочем, вполне возможно, что найдутся какие-то экзотические случаи, но пока что не встретились.
Система на столько универсальна, что любые большие биения и нестабильности лечатся одним и тем же алгоритмом, просто требуют несколько большего зазора звукового буфера, вот и все.
- - - Добавлено - - -
Приведу такую аналогию.
В комнате болтается маятник подвешенный под потолком (трения нет, он качается не затухая). Если маятник хороший, стандартный, то он качается равномерно, и если зазор от крайних положений маятника до стен 1 метр, маятник с большой долей вероятности будет всегда качаться одинаково, не доставая до стен (не вызывая переполнения буфера, пересинхронизации и требования новой раскачки). Частоту качаний маятника тоже легко измерить на достаточно коротком окне.
Но предположим, что на маятник действуют дополнительные силы, например, крюк, на котором он качается, ездит туда-сюда с какой-то периодичностью. А этот крюк ездит еще по одним рельсам со своей периодичностью. Теперь, чтобы маятник не касался стен, стены надо немного раздвинуть. Иногда много. Но всегда есть такое положение стен, когда даже такой сложно предсказуемый на коротком отрезке времени маятник будет качаться не доставая до стен. Что же касается вычисления частоты качания маятника, то тут становится сложнее, но на более большом окне она вычисляется стабильно. И чем больше проходит времени с момента запуска эмулятора, тем стабильность выше.
- - - Добавлено - - -
Если ты посмотришь на графики работы аудиосистемы, которые тут выкладывали, то фиолетовый график - это и есть диаграмма качания маятника.
Он то приближается к одной стене, то к другой, качается у всех по разному (в зависимости от интерференции частоты семплов и кадров на конкретной машине), но все время удерживается в стабильном коридоре. Если же качнется за пределы, то наступит пересинхронизация (установка маятника в середину коридора). Но при оптимальном зазоре сверху и снизу пересинхронизация не наступит никогда.
Регулировать скорость эмуляции не проблема, но вот беда - если нам не хватает скорости обновления видео и мы увеличиваем скорость эмуляции, то это приводит к увеличению скорости поступления сэмплов со звуком, а скорость забора звуковых сэмплов мы регулировать не можем.
Если-же отбрасывать сэмплы или вставлять копии - это приведет к искажению звука или видео. В этом собственно и вопрос - как это решать?
Насколько понимаю, задача точной синхронизации трёх независимых осцилляторов с медленно дрейфующими частотами и случайным начальным отклонением частот в общем случае не имеет точного решения. Поправьте, если ошибаюсь.
Например, можно взять два генератора, смешать их сигналы на смесителе и наблюдать результат на осциллографе. Плавно регулируя частоту одного из генераторов, можно добиться стабилизации биений. Однако, если генераторы тактируются от асинхронных источников, то после настройки на стабильные биения система довольно быстро выходит из этого состояния в одну или другую случайную сторону, требуя непрерывной подстройки частоты для удержания стабильного состояния.
Если же добавить третий генератор с независимым тактированием, то добиться устойчивой стабилизации биений, регулируя частоту только одного из генераторов, уже не получится. В этом случае фаза и частота биений будут постоянно дрейфовать, так как система имеет три независимых осциллятора с несвязанными дрейфующими частотами.
Это по сути модель нашей системы с эмулятором и приёмниками видео и аудио фреймов на ПК. Где мы можем регулировать частоту только одного осциллятора (скорость эмуляции). Мы можем подстроить скорость эмуляции под стабилизацию к частоте видеокарты или под стабилизацию к частоте звуковой карты, но не к обоим одновременно.
Поэтому в ZXMAK2 сделан выбор источника синхронизации, позволяющий выбрать под что именно подстраиваться.
Нет, я тестировал на Linux используя Pipewire, который появился только в 2017 году и используя свежие обновления 2024 года. Такие результаты я получал на USB звуковой карте, чип которой появился примерно в 2021 году. Насколько помню, проблема там именно в драйвере,т.к. с другими бекэндами результаты были аналогичными. А вот на другой звуковой карте все было красиво - достаточно быстрые уведомления и более менее стабильно, хотя всеравно иногда наблюдались отклонения в размере нотификации и нотификации также иногда приходили пачками.
При использовании OpenAL можно задавать число сэмплов через которое драйвер будет обновлять позицию воспроизведения, но у звуковых карт есть нижний лимит, если задать ниже - уведомления будут приходить просто с минимально возможным для данной звуковой карты периодом. И гарантии, что уведомления будут приходит с фиксированным интервалом нет, два уведомления могут приходить без задержки вообще и тогда следующая задержка будет в два раза больше обычной.
Что значит как решать? Я просто вписываю нужное число тактов процессора Z80, отработанное за кадр в необходимую длину аудиокадра.
Если у меня в этом кадре по расчетам должно быть проиграно 960.001 семпла, то ровно во столько семплов я и сгенерю звук от текущего кадра Z80.
- - - Добавлено - - -
Линукс меня не интересует в принципе)
Равно как и OpenAL.
У меня есть стандартный PC со стандартной Виндой, и это моя область разработки.
Тоесть ты по сути точно также выкидываешь или добавляешь сэмплы, только с апсэмплиногом до 3.5 МГц?
Да, так влияение искажений будет ослаблено за счет апсэмплинга, который в данном случае составит порядка 3.5М/48k=x73.
А как происходит децимация с частоты Fclk Z80 до Fs аудиопотока? Как понимаю, от реализации этой части и будет зависеть уровень искажений. Частота Z80 не делится кратно на стандартные частоты звуковых карт (48 кГц или 44.1 кГц). Какой подход тут применяется?
так в том кадре, на котором набежал уже целый сэмпл (почему "байт", кстати? у тебя что, звук восьмибитный?) будут те же самые "доли процента", как у меня :v2_dizzy_biggrin2:
- - - Добавлено - - -
да не так, блин :v2_dizzy_facepalm: мы дискретизируем волну, непрерывную
то есть разливаем по дискретным бутылкам непрерывный поток воды, вытекающий из трубы
за одно и то же время разлить можем или в 100 бутылок, или в 101, или в 99
в любом случае объём останется тем же, как и минеральный состав
никто ничего не отбрасывает и тем более не вставляет копий, не фантазируй
сэмплы - это равномерно расставленные точки на графике исходной волны
на том же графике при другом кол-ве сэмплов их координаты будут другими
расстояние между соседними - будет другим (это как объём воды в бутылке как раз)
Корежить звук, даже на минимальную писечку, в угоду "плавности картинки" - концептуально неправильно. Если опции "не трогать звук" нет, то нафиг такую эмуляцию, ИМХО.
что значит "не трогать"? если вдруг кто еще не в курсе, звук - это аналоговый сигнал, был дискретизирован = уже тронули, ЛЮБАЯ дискретизация "звук корёжит" :D
- - - Добавлено - - -
отсюда логический вывод - если всё равно "корёжить" приходится, то надо делать это именно "в угоду картинке" :p
э нет, для звуковой карты время течет иначе чем для видеокарты, поэтому условно говоря за время 100 кадров видеокарты, на часах звуковой карты может набежать 100 ± 5 кадров (цифры взяты от балды для примера). И скорость течения времени постоянно меняется, как у звуковой карты, так и у видеокарты, поэтому в какой-то момент часы видеокарты могут идти быстрее, в другой момент времени наоборот.
Это для эмулятора время звука и видео всегда одинаково, т.к. у спектрума они синхронизированы от одного клока. А для звуковой карты и видеокарты время течет по разному, поэтому 1 секунда эмулятора (50 кадров) на видеокарте и на звуковой карте будут воспроизводиться разное время.
для того чтобы координаты сэмплов стали другими, сигнал нужно реконструировать в непрерывный и передискретизировать заново в новой координатной сетке. Грубо говоря сделать апсемплинг и затем даунсемплинг к другой частоте дискретизации. Операция довольно тяжелая и проблематичная, особенно учитывая дробные коэффициенты преобразования. Без искажений сигнала и нагрузки на процессор тут не обойтись.
ZXMAK, Воспроизводимая частота не должна дрейфовать дальше чем на 1/10 герца (или правильнее - 0.1%). Это заметно.
- - - Добавлено - - -
Lethargeek, Чтобы подогнать синхронизированный звук между прыгающими между 49/50/51 герцами развертки, тебе придется замедлять или ускорять звук (чем твич и занимается, когда у него моча в голове вдруг появляется). И этот подгон за счет ускорения и замедления - ужасен.
э, да! ЕЩЕ РАЗ: кол-во бутылок может меняться, а кол-во воды в них - нет! ну вот вылилось у нас из трубы сто литров, а потребитель говорит - хочу 105 бутылок - на тебе 100 литров в 105 бутылках; потребитель говорит - хочу 95 бутылок - на тебе те же 100 литров в 95 бутылках - и в чём проблема?
"горе от ума" :v2_dizzy_facepalm: НЕ ВЫДУМЫВАЙ ПРОБЛЕМЫ НА РОВНОМ МЕСТЕ, ничего не нужно "реконструировать", нужно сразу КОНСТРУИРОВАТЬ с другой сеткой - ведь с какой-то всё равно нужно
у всех разные "пределы", в моих - "корёжится" :p
учитывая, что частоты звуковой карты и видеокарты плывут друг относительно друга, да плюс к этому измерения их частот относительно таймера системы тоже плывут, то плавание частоты звука вполне нормальное явление при правильной реализации подстройки частоты дискретизации. Именно в том и заключается задача - сделать чтобы частоты плавали, подстраиваясь друг под друга.
:v2_dizzy_facepalm: ЕЩЕ РАЗ:
это разные "частоты", не путай их (и да, "таймер системы" тут - третий лишний)
нет, задача заключается, чтоб НЕ плавали - при достаточно небольших и стабильных флуктуациях и не будут
а при слишком нестабильных - ничего хорошего со звуком всяко не будет, даже если звуковуха главная, а не видео
вот мне и интересно - как это делается?
Пусть частота Z80 Fclk=3504000 Гц. Звуковая карта Fs=48000 Гц. Т.е. без подстройки нам нужно просто наложить ФНЧ и сделать децимацию с коэффициентом x73. Итого получаем 3504000 / 73 = 48000 Гц. Пока всё красиво.
Далее, допустим мы намеряли, что нам нужна частота дискретизации 47999.357 Гц. Но у нас есть возможность делать децимацию с коэффициентом 72, 73 или 74. Соответственно мы можем получить 48666.66(6) Гц, 48000 Гц или 47351.351 Гц. Требуемая частота в этот ряд не вписывается, т.к. разрешение координатной сетки сэмплов на частоте Z80 3.5 МГц недостаточно, нужно делать апсэмплинг до более высокой частоты дискретизации. А это уже приличная нагрузка на процессор.
ZXMAK, есть такое слово - "интерполяция" ;)
Не надо так воспринимать задачи 'в лоб'. У всего есть адекватные по времени методы.
Впрочем, еще раз повторюсь - сейчас я не тестирую качество фильтров, качество эмуляции Z80. Это вторично.
Сейчас я тестирую только движок эмулятора на разных машинах.
Хотя, похоже, мы своим флудом всех распугали и актуальный пост уехал слишком далеко.
Я понимаю, что тебя в твоем эмуляторе сейчас интересует именно эта тема, но меня нет. И я даже заморачиваться пока не хочу над этим) Придет время писать фильтр, тогда и посмотрю, как сделать лучше)
- - - Добавлено - - -
Кстати, если мне будет не хватать для чего-то вычислительной мощности процессора (что вряд ли), можно перенести вычисления на вычислительные шейдеры графического процессора.
Как раз фильтры хорошо на нем делаются.
Вернее, дать пользователю выбор в настройках, на чем вычислять, на CPU или на GPU.
Например, сканлайны у меня сейчас считаются на шейдерах, что разгрузило процессор.
если плавает частота дискретизации, то будет странным, если частота волны сигнала будет оставаться неизменной. Конечно она тоже будет плавать. В среднем она будет плавать в небольшом диапазоне, например если частота звуковухи плавает в пределах 500 Гц, то частота 1 кГц сигнала будет плавать в пределах 10 Гц.
Если системный таймер лишний, то относительно чего измеряются частоты дискретизации звуковой карты и видеоадаптера? Без него точно измерить не получится...
Продублирую.
Windows 10, монитор Viewsonic vp930
Окно консоли на 50 hz :
Скрытый текст
EmuStudio 0.9 test 1 (ZX-Mode)
Written by dr.Titus 2006,2025
CPU: AMD FX(tm)-8120 Eight-Core Processor
Support: MMX SSE SSE2 SSE3 SSSE3 SSE4.1 SSE4.2 AVX
Logical CPU cores: 8
Current CPU #0 frequency: 3100MHz
DWM Composition: Enabled
Powered from AC
Power scheme already exist
Low CPU AC threshold = 90%
Low CPU DC threshold = 20%
Power scheme activated
WM_CREATE
Windows version: 10 (10.0.19041.5072)
Multimedia timer resolution: 2057 mks
Multimedia timer resolution: 1997 mks
Desktop DPI: 96 dpi (scale: 100%)
DXGI version 1.6
Direct2D version 1.3
Monitor[0] - NVIDIA GeForce 9800 GT : VP930 Series
Mode: 1280 x 1024, 60.020000Hz
Frequences set: 60.02Hz, 75.03Hz
Hardware composition: not supported
Adapter[0]: Direct3D feature level 10.0
Allow tearing (variable framerate): supported
Shader model 5.0 not supported!
WASAPI system mix format: 48000 Hz, 32 bits, 2 channels, float
Endpoint name: Наушники (High Definition Audio Device)
WASAPI endpoint format: 48000 Hz, 16 bits, 2 channels, PCM
Audio system: WASAPI Shared
Audio format: 48000 Hz, 32 bits, 2 channels
Device minimum period: 2 ms
Audio Buffer Size: 1056 samples (22.0 ms)
480, 0, 0, 0, 480, 0, 0, 0,
Process priority: 128
Main thread priority: 0
High resolution timer: 10000000Hz
CPU Mode: Pure
WMI thread priority = -15
Emulation thread priority = 2
Audio thread priority = 15
Audiobuffer padding: 29.1 ms
Total audio delay: 48.4 ms
Audio buffer is empty
Video thread priority = 1
Class name WIND_0000
Init: Pentagon
Snapshot snapshot.z80 loaded
SoundProfiler: Init
Viewport size changed: 812 x 572
Frames lost: 2
Resync
*********@.@SoundProfiler: End
****.......*
[свернуть]
На 100 Hz
Скрытый текст
EmuStudio 0.9 test 1 (ZX-Mode)
Written by dr.Titus 2006,2025
CPU: AMD FX(tm)-8120 Eight-Core Processor
Support: MMX SSE SSE2 SSE3 SSSE3 SSE4.1 SSE4.2 AVX
Logical CPU cores: 8
Current CPU #0 frequency: 3100MHz
DWM Composition: Enabled
Powered from AC
Power scheme already exist
Low CPU AC threshold = 90%
Low CPU DC threshold = 20%
Power scheme activated
WM_CREATE
Windows version: 10 (10.0.19041.5072)
Multimedia timer resolution: 1962 mks
Multimedia timer resolution: 1950 mks
Desktop DPI: 96 dpi (scale: 100%)
DXGI version 1.6
Direct2D version 1.3
Monitor[0] - NVIDIA GeForce 9800 GT : VP930 Series
Mode: 1280 x 1024, 60.020000Hz
Frequences set: 60.02Hz, 75.03Hz
Hardware composition: not supported
Adapter[0]: Direct3D feature level 10.0
Allow tearing (variable framerate): supported
Shader model 5.0 not supported!
WASAPI system mix format: 48000 Hz, 32 bits, 2 channels, float
Endpoint name: Наушники (High Definition Audio Device)
WASAPI endpoint format: 48000 Hz, 16 bits, 2 channels, PCM
Audio system: WASAPI Shared
Audio format: 48000 Hz, 32 bits, 2 channels
Device minimum period: 2 ms
Audio Buffer Size: 1056 samples (22.0 ms)
480, 0, 0, 0, 480, 0, 0, 0,
Process priority: 128
Main thread priority: 0
High resolution timer: 10000000Hz
CPU Mode: Pure
WMI thread priority = -15
Emulation thread priority = 2
Audio thread priority = 15
Audiobuffer padding: 58.3 ms
Total audio delay: 85.9 ms
Audio buffer is empty
Video thread priority = 1
Class name WIND_0000
Init: Pentagon
Snapshot snapshot.z80 loaded
SoundProfiler: Init
Viewport size changed: 812 x 572
Frames lost: 2
Resync
***@********SoundProfiler: End
***
[свернуть]
Скрин:
Скрытый текст
https://i.postimg.cc/rs3fx0W3/1x.png[свернуть]
100 Hz
Скрытый текст
https://i.postimg.cc/W125rvJ2/2x.png[свернуть]
С чего это частота звуковухи будет плавать?
- - - Добавлено - - -
Конечно таймер не лишний, он является опорным для всех измерений.
- - - Добавлено - - -
Понятно, почему шейдеры 5.0 не поддерживаются. Видеокарте уже почти 20 лет)
А почему-бы ей не плавать? Рубидиевые стандарты частоты в звуковухи вроде не ставят :)
Осциллятор с печкой тоже не ставят - он дорогой и кушает несколько Ампер. TCXO имеет большие фазовые шумы, что для звуковухи плохо.
А обычные китайские кварцы гуляют так, что с телеграфным 500 Гц фильтром - попробуй еще поймай, а поймаешь - через пару минут уже уйдет из полосы приёма.
- - - Добавлено - - -
это в настройках драйвера можно менять, в Windows была какая-то утилита в ней можно было все эти параметры менять, не помню точно уже название, помоему rivatuner. Можно также установкой переменной среды управлять, имя перменной зависит от драйвера.
Да ну даже близко нет такого даже с самыми отбитыми китайскими кварцами, чтобы оно из полосы 500 Гц за пару минут вылезло. Даже если частота кварцевого генератора уведена от центральной при помощи LC-цепочки, всё равно максимум до десятки герц может уехать. Для какого нибудь WSPR/FT8 это критично, но уши не услышат.
может у вас осциллятор с термостабилизацией? У меня в тестах на обычном кварце 32 МГц частота за 1 минуту уплывала больше чем на 2 кГц (за счет нагрева платы). Это порядка 60 ppm. Отклонение у обычных кварцев допускается порядка 200-400 ppm.
А сейчас вместо кварцев могут и MEMS осцилляторы ставить для экономии, у них вообще частота гуляет как ... в проруби - подносишь руку и частота легко на 100 кГц улетает :)