PDA

Просмотр полной версии : Генератор шума в AY-3-8910



EvgenRU
24.08.2016, 12:17
Меня постоянно мучает вопрос, какой же алгоритм правильный.
Надеюсь те кто ковырял внутренности чипа смогут прояснить данный вопрос.

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

1. ay8910.c,v 1.6 2006/02/08
noise_level = noise_level ^ (shiftreg.bit0 ^ shiftreg.bit1)
shiftreg = (shiftreg.bit0 ^ shiftreg.bit3) ? (shiftreg >> 1) ^ 0x12000 : (shiftreg >> 1)

Лог уровень шума меняется, если операция XOR битов 0 и 1 дает единицу (т.е. если бит 0 и бит 1 различаются)
Если биты 0 и 3 различаются, то значение псевдогенератора случайных чисел ксорится с 0x12000

2. http://www.cpcwiki.eu/index.php/PSG
noise_level = noise_level ^ shiftreg.bit0
newbit = shiftreg.bit0 ^ shiftreg.bit3
shiftreg = (shiftreg >> 1) + (newbit << 16)

Лог уровень шума ксорится с вытолкнутым из генератора битом, результат XOR бита 0 и бита 3 становится новым битом генератора

3. http://wiki.intellivision.us/index.php?title=PSG
noise_level = shiftreg.bit0
shiftreg = (shiftreg >> 1) ^ ((shiftreg & 1) ? 0x14000 : 0);

Уровень шума равен вытолкнутому биту, если он равен единице, то значение генератора ксорится с 0x14000

4. ay-8910.v (тот что для FPGA)
noise_level = shiftreg.bit0
newbit = shiftreg.bit0 ^ shiftreg.bit3
shiftreg = (shiftreg >> 1) + (newbit << 16)
Инициализируется значением 0x10000
вход bit0 ^ bit3
выход нулевой бит


ТРЕБУЕТСЯ ПОМОЩЬ В ПОИСКЕ ИСТИНЫ :-)

PS: чисто на слух наиболее приятен такой вариант (это смесь 1 и 4)
noise_level = noise_level ^ (shiftreg.bit0 ^ shiftreg.bit1)
shiftreg = (shiftreg >> 1) + ((shiftreg.bit0 ^ shiftreg.bit3) << 16)
Инициализируется значением 0x10000

PS2: данные две операции равнозначны, видимо на чем-то удобнее делать так, а на чем-то иначе
1) noise_level = noise_level ^ (shiftreg.bit0 ^ shiftreg.bit1)
2) noise_level = shiftreg.bit0

PS3: третий вариант дает более равномерный белый шум и я лично склоняюсь к тому, что в чипе используется именно он.

PS4: т.е. простейший алгоритм такой, выталкиваем бит справа, он будет уровнем шума, если он равен единице, то устанавливаем 16 бит и инвертируем 14-й бит, таким образом, правильные алгоритмы вроде как 3 и 4

NEO SPECTRUMAN
24.08.2016, 23:17
йа пользуюсь этим
http://bulba.untergrund.net/AY_YM_NoiseGenerator.7z
на слух это он
внешне сравнивал с плеером Витамина
в принципе ну очень похоже

еще алгоритм описан в оригинальной доке
к более старшему Ау 3 89**(может 30?) не помню какому
имеющему режим совместимости с AY-3-8910

EvgenRU
24.08.2016, 23:45
Вот это спасибо! Просто огромное!
Вот он http://www.vgmpf.com/Wiki/images/7/7c/AY8930_-_Manual.pdf
А то я сижу гадаю как оно там :)

В этом мануале расписаны все потроха, как он мне раньше не попался....

Вот так оно там выглядит, значит второй бит ксорится с нулевым а не третий...
57981

Еще и на шум идет не нулевой, а первый...

PS: поменял как написано в мануале, сразу зазвучало всё совершенно по-другому, никаких всплесков, всё идеально :)

UPD: так что итоговая оригинальная формула будет выглядеть так
noise_level = shiftreg.bit0
newbit = shiftreg.bit0 ^ shiftreg.bit2
shiftreg = (shiftreg >> 1) + (newbit << 16)

так что в исходниках на VHDL поменяйте строчку

shift_n <= {shift_n[0]^shift_n[3],shift_n[16:1]};

на

shift_n <= {shift_n[0]^shift_n[2],shift_n[16:1]};

newart
25.08.2016, 02:47
всё идеально
Было бы интересно сравнить с реалом.

Barmaley_m
09.07.2018, 22:38
С реалом можно сравнить следующим образом:

1) записываем на реале кусок шума хотя бы в несколько секунд длиной.
2) генерируем последовательность на регистре сдвига с (хотя бы примерно) совпадающей длительностью периода обновления регистра
3) вычисляем взаимно-корреляционную функцию обоих сигналов
4) если взаимно-корреляционная функция имеет ярко выраженный пик - то Profit.