samstyle / Xpeccy

Multiplatform emulator of retro computers
MIT License
71 stars 13 forks source link

AY/YM renderer #45

Closed Volutar closed 3 years ago

Volutar commented 5 years ago

Насколько видел из исходников, никакой передискретизации и КИХ фильтрации звуковых чипов нету. Нельзя ли добавить опциональный рендеринг звуков с КИХ фильтрами? На высоких тонах артефакты дифракционные очень заметны и не очень приятны. Есть вот такая тема с готовой либой: http://hypr.ru/blog/168.html У Бульбы в zxemul с этим также все хорошо (помимо unreal и кучи других эмуляторов). А аюми вроде считается топом, кому это важно (типа меня) могли бы включать precise sound rendering.

samstyle commented 5 years ago

Можно. Добавляй.

Volutar commented 5 years ago

Вот пример. http://volutar.eu5.org/xp-comp.ogg Думаю, что особо не надо гадать чтобы понять какая из половин откуда взята. Части звуков вообще нет, стерео гуляет так что мягко скажем слуховой аппарат неуютно себя чувствует.

Более полные фрагменты: http://volutar.eu5.org/frg002.ogg vs http://volutar.eu5.org/frg004.ogg

P.S. Ещё совсем не помешал бы выбор частоты (хотя бы 1.75, 1.77, 1.7734) вне зависимости от микросхемы. Сейчас же это захардкодено 1.75 если YM и 1.7734 если AY.

samstyle commented 5 years ago

Человеческим языком - подстраивать частоту тактов чипа, чтобы она была делителем выходной частоты (44100, 22050, 11025 итд)? С учетом внутреннего делителя, конечно

Volutar commented 5 years ago

К сожалению это невозможно вот так вот просто. Если частоту dsp звуковухи поставить 96кгц, и ту же частоту (96к*16) как аушный (типа 1536000гц), то будет конечно идеально. Но на такой частоте аушки не работают. Передискретизация вносит искажения на высоких частотах. В том же фрагменте у кспекового звука просто отсутствует писк на огибающей, он тупо утерян. И когда в 7-8й октаве звуки питчить и вибратой играться - там низкоуровневые гармоники делают звук вообще неприемлемым.

samstyle commented 5 years ago

На. Человеческом. Языке. С формулами, а не с теоретической водой.

Volutar commented 5 years ago

Послушай примеры из 3го коммента - это не теория, а вещественный результат.

Посмотри статью с первого коммента - там подробно описана проблематика с графиками спектральных артефактов. Помимо того ссылка на уже работающий код.

Про какие "не теоретические формулы" речь?

samstyle commented 5 years ago

Послушай примеры из 3го коммента - это не теория, а вещественный результат Посмотри статью с первого коммента - там подробно описана проблематика с графиками спектральных артефактов

У меня есть исходные данные. У тебя - желание получить из них нужные данные. Для этого с исходными данными нужно провести какие-то операции. С использованием какого-то алгоритма. Описание какого-то алгоритма в студию. Человеческим языком - берём A, с ним проделываем Б чтобы получить В, это нужно чтобы Г. Копаться в чужом коде, чтобы восстанавливать алгоритм? Неееее

Volutar commented 5 years ago

Копаться в чужом коде, чтобы восстанавливать алгоритм? Неееее

Есть 2 пути. Или даже 3 (но третий нет смысла обсуждать).

  1. Изучить теоретическую часть, вникнув в суть (она изложена в статье из первого коммента). Запилить свой "недовелосипед", который будет явно хуже Аюма или даже Бульбовского (который мигрировал в zxtune). Может потом усовершенствовать и прийти к тому же zxtune варианту.
  2. Не вникая в теорию взять готовую функцию рендеринга звука AY/YM из бульбовского/ zxtune, или того же unreal speccy, но считаю что лучше - из ссылки по статье (алгоритм Аюми), и встроить. Ничего сложного в ней я не увидел. Математики полно (потому как там FIR-фильтр, без которого качественная передискретизация невозможна), и куча этих коэффициентов генерилась в MathLab (в том числе и у Бульбы и у SMT для Unreal). Нет никакого смысла пытаться их "проверять" и вникать в то, зачем каждый из них.

Вкратце, повторяю, проблема в том что AY имеет квадратную с частотой дискретизации например 110837.5 периодов, а выводить это надо с частотой 44100. Невозможно "легко" интерполировать одно в другое без порождения в спектре кучи всякого шлака (см рисунки из статьи), в том числе исчезновений частот (как из примера, взята огибающая с периодом 1, то есть 110кгц, звука слышимого такая огибающая не создаёт сама по себе, нет, но есть интерференция с тоном под огибающей, что даёт характерный звук в этой stracker из примера).

Volutar commented 5 years ago

Речь про oversampling генерируемого сигнала, и формулу интерполяции до целевой частоты. В UnrealSpeccy oversampling ratio = 2^6 = 64. То есть фактически "квадратная волна" генерируется для частоты 44100*64, которая через свёртку FIR фильтра со 128 коэффицентами схлопывается до 44100 (для каждого отсчёта звуковухи вычисляется 64 значения АУка). https://github.com/darvin/unreal-speccy-portable/blob/master/devices/sound/device_sound.cpp

Но в унреале звук тоже совсем неидеален, хотя и несравненно лучше банального рендеринга на частоте 44100. Недостаток в той же Stracker слышен на огибающей с делителем 0 (который эквивалентен 1) - http://volutar.eu5.org/frg001.ogg на 53 секунде этот показательный фрагмент, слышно какое-то лишнее прищёлкивание.

Всё-таки предлагаю рассмотреть вот эту версию: https://github.com/true-grue/ayumi/blob/master/ayumi.c

Её в принципе можно назвать близкой к безупречной (к звучанию реального АУка). Разумеется, тип интерполяции надо чтобы был опциональным (LQ/HQ, а то мало ли - может железо будет совсем слабое для всех этих oversampling+FIR).

И, да, коэффициенты стерео не должны быть строго 0/50/100 - звучит совсем неестественно (особенно в наушниках). Как правило в большинстве эмуляторов используют формула 10/50/90, со слышимым взаимопроникновением каналов.

samstyle commented 5 years ago

Сигнал генерируется постоянно. Обновляется после каждого опкода. В любой момент можно снять громкость с AY. Так что не заливай про оверсамплинг каналов. Ты что-то не то в моём коде вычитал. ЗЫ: Я знаю, что надо сделать, но я слишком жирный тролль X)

qboneteam commented 5 years ago

Недостаток в той же Stracker слышен на огибающей с делителем 0 (который эквивалентен 1) - http://volutar.eu5.org/frg001.ogg на 53 секунде этот показательный фрагмент, слышно какое-то лишнее прищёлкивание.

Надобно для сравнения обе версии. Ну и там из какого нить музредактора частоты с показаниями где там лишнее щёлкает

Volutar commented 5 years ago

Надобно для сравнения обе версии. Ну и там из какого нить музредактора частоты с показаниями где там лишнее щёлкает

Все что надо - уже предоставлено.

Volutar commented 5 years ago

Сигнал генерируется постоянно. Обновляется после каждого опкода. В любой момент можно снять громкость с AY. Так что не заливай про оверсамплинг каналов.

Если даже генерируется 10^10000 выборок каждую секунду, но в итоговую выборку для DSP звуковухи в секунду попадает только 44100 из них, это ЭКВИВАЛЕНТНО генерированию 44100 раз в секунду. Они все должны сворачиваться в итоговую выборку. Как вот тут они сворачиваются по 128 для каждого из сэмплов звуковухи: https://github.com/darvin/unreal-speccy-portable/blob/master/devices/sound/device_sound.cpp#L178

Так что "заливание про оверсамплинг" тут более чем уместно. Какое сворачивание при генерировании каждый такт z80 нужно - это вообще хз. Для звука свёртка должна идти независимо от отображаемого в дебаге, частота процессора может быть вообще произвольной (кнопка turbo), в отличие от частоты AY и DSP эмулятора.

В коде, кстати, я не увидел чтобы делитель 0 был корректно обслуживаемым. Но даже если починить только это - это не нивелирует проблему низкочастотных гармоник.

samstyle commented 5 years ago

частота процессора может быть вообще произвольной (кнопка turbo), в отличие от частоты AY и DSP эмулятора

Так оно и не зависит от частоты проца. Для этого есть абсолютная величина - ВРЕМЯ.

Volutar commented 5 years ago

Пример по гармоникам (не по огибающим). Начало внутриигровой мелодии из Peter Pack Rat

Аудиофрагменты: http://volutar.eu5.org/ppackrat.mp3

  1. Xpeccy
  2. US
  3. Ayumi

В первую очередь слышатся небольшие щелчки из-за 16 ступеней громкости AY - селяви. От этого никуда не деться. Далее по частотам. В первом - слышатся очевидные артефакты кривой дискретизации в гармониках. Много. Во втором и третьем всё на слух чисто. Кстати, очевидно противоестественное отсутствие небольшой доли левого канала в правом, в наушниках будто просто глухой на правое ухо.

Сделал спектрограмму одной из более-менее длинных нот этого фрагмента. И картина следующая:

image

В Xpeccy видно кучу паразитических гармоник дискретизации. В Unreal тоже есть, но совсем маленькие и немногочисленные. В Ayumi - по факту нет никаких паразитических гармоник. Практически идеальный спектр меандра.

Добавлено

Так оно и не зависит от частоты проца. Для этого есть абсолютная величина - ВРЕМЯ.

Отлично. В режиме трассировки никакой звуковой буфер не генерируется, идёт отладка по "наносекундам", и значения меандра прекрасно видны. Это отлично для отладки всяких Atarin-подобных штук. Но то что там генерируется - не идёт в звук, это чисто для отладки, визуальная часть. А для звуковухи волна генерируется вне трассировки. И там все прелести с гармониками вынужденно вылазят наружу, ибо 44100 (ну или 48000, или что там).

samstyle commented 5 years ago

Во делать людям нечего...

  1. XSpeccy

Это что?

Volutar commented 5 years ago
  1. XSpeccy Это что?

Это единственный вопрос, который возник по приведённым доводам? Тогда отвечаю - это Xpeccy с опечаткой.

samstyle commented 5 years ago

Ты уже 2 день тычешь пальцем в очевидное, выпендриваясь терминами и графиками. Я где-то сказал, что такой проблемы нет?

Volutar commented 5 years ago

Ты уже 2 день тычешь пальцем в очевидное, выпендриваясь терминами и графиками.

Во-первых я не выпендриваюсь графиками и цифрами. Я в первом же посте дал ссылку на полное описание проблемы и одно из её решений. Во-вторых, сразу же последовали "прокрастенации", "человеческим языком", и "алгоритмы в студию". Попытался уже своим языком объяснить, иллюстрированно. Не понимаю, зачем тут было разводить этот троллинг, раз всё и так очевидно.

samstyle commented 5 years ago

Хочу график на ночном коммите

Volutar commented 5 years ago

Бинарник под винду будет нужен.

samstyle commented 5 years ago

Нате. xpeccy_0.6.20190219_win32.zip ЗЫ: А тема не про рендер AY/YM

Volutar commented 5 years ago

Сверху - было, снизу - стало. image

Очевидно что паразитических стало меньше, особенно ниже. Но отражённых (симметричных) гармоник всё равно полно. Я там увидел в коде идёт просто усреднение, безо всякой весовой функции. В идеале это должна быть функция для свёртки типа sinc, но вроде и вот подобное может улучшить ситуацию: image

Но лучше конечно фильтр Lanczos

Прошу всё-таки в интерфейс настройки звука добавить выбор частоты и поменять коэффициенты стерео смешивания с полностью дифференцированной на какое-то (например 10%) взаимопроникновение, типа 10+90, 66+66, 90+10, а не 0+100, 66+66, 100+0.

samstyle commented 5 years ago

Всё это, кроме стерео, видно только на графике и слышно только эльфам :smile_cat:

Volutar commented 5 years ago

Ну я не считаю себя эльфом, но тем не менее все слышу к сожалению довольно внятно, когда начинается трель на 7-8 октаве. (Текущий вариант в любом случае существенно лучше предыдущего).

Volutar commented 5 years ago

Шумы сейчас играют совсем не так как в других плеерах. В примере - первый из анрила (да и из бульбы и zxtune), второй - из xpeccy. http://volutar.myds.me/xp-nois.mp3

Volutar commented 5 years ago

Шумы все еще кривые.

Volutar commented 4 years ago

Шумы всё еще кривые.

Volutar commented 3 years ago

Похоже, всё исправлено. Незначительные гармоники на ультразвуковых делителях не сильно ломают звук. Теперь не хуже чем в любых других эмуляторах.

samstyle commented 3 years ago

Уот это да, уот это да, уот это нифига себе. И всего-то полтора года прошло XD