§ Вступление
Я давно уже пытался разобраться в том, как работает синтезатор AY-3-8910 от спектрума. Наконец-то мне это удалось сделать, и потому об этом хочу написать статью. Сам по себе звук этого синтезатора работает очень просто и состоит из трех компонентов, которые идут в таком порядке:- Базовая громкость (level)
- Огибающая (envelope) - это некая форма сигнала (громкости)
- Тон (tone) - это обычный меандр, то есть сигнал, который имеет состояние либо 0, либо 1 разной громкости и разной частоты
- Шум (noise) - ну это шум, разной частоты, его формирование на самом деле опирается на уровень тона или огибающей
§ Регистры аудиопроцессора
Ниже перечислю регистры, которые используются:R0 | Младшие 8 бит частоты тона А[7:0] R1 | Старшие 4 бита частоты тона A[11:8] ----+----------------------------------------------------- R2 | Младшие 8 бит частоты тона B[7:0] R3 | Старшие 4 бита частоты тона B[11:8] ----+----------------------------------------------------- R4 | Младшие 8 бит частоты тона C[7:0] R5 | Старшие 4 бита частоты тона C[11:8] ----+----------------------------------------------------- R6 | Период шума (5 бит) от 0 до 31 ----+----------------------------------------------------- R7 | Управление активации канала | Бит 0 - если 0, то активирован тон A | Бит 1 - если 0, то активирован тон B | Бит 2 - если 0, то активирован тон C | Бит 3 - если 0, то активирован шум A | Бит 4 - если 0, то активирован шум B | Бит 5 - если 0, то активирован шум C | Бит 6 - если 0, то регистр R14 работает на вход, 1-на выход | Бит 7 - если 0, то регистр R15 работает на вход, 1-на выход ----+----------------------------------------------------- R8 | Громкость канала A в битах 0..3. | Если бит 4 равен 1, то громкость берется из огибающей R9 | Громкость канала B (аналогично) R10 | Громкость канала C (аналогично) ----+----------------------------------------------------- R11 | Младший байт периода огибающей R12 | Старший байт периода огибающей R13 | Тип огибающей (4 младших бита) ----+----------------------------------------------------- R14 | Регистр IOA R15 | Регистр IOBРегистр IOA и IOB отведены как регистры общего назначения и там можно что-то хранить, если они настроены на вывод (биты 6 и 7 регистра R7).
§ Тактирование
Каждый внутренний цикл обработки нового тона или шума или огибающей вырабатывается каждые 32 цикла процессора. То есть, другими словами, каждый 32-й t-state процессора (цикл) вырабатывает цикл работы синтезатора, который выполняет некоторую полезную работу. Например увеличивает счетчики.§ Запись в регистры
Запись в регистры осуществляется так: сначала выбирается номер регистра, для этого надо записать в порт 0xFFFD номер регистра AY, а потом в порт 0xBFFD записать данные:1ld bc, $fffd 2ld a, $00 3out (c), a ; Запись номера регистра 4ld b, $bf 5ld a, $ff 6out (c), a ; Запись значенияСтоит заметить, что при записи в регистр периода шума - шум сбрасывается, а также при записи в регистр R13 - огибающая тоже сбрасывает свои значения, то есть, она начинается заново.
§ Виды огибающих
Всего существует не так много видов для огибающих (envelope):Вид огибающей | Значение 4-х битов регистра R13 | Пример звука |
---|---|---|
00xx 1001 | ||
01xx 1111 | ||
1000 | ||
1010 | ||
1011 | ||
1100 | ||
1101 | ||
1110 |
Что делает огибающая? Она просто задает громкость тону. Когда установлен 4-й бит в регистрах громкости R8-R10, то для тона используется громкость огибающей. Есть огибающие, которые заканчивают свое изменение (пример 00xx). Чтобы перезапустить ее, надо записать в регистр R13 новое значение.
§ Тоны
Тоны - это основные "инструменты" для проигрывания музыки. Они представляют из себя прямоугольный сигнал, частота которого задается точно так же, как и огибащей, то есть каждые N x 32 тактов процессора меняется тон на противоположный. К примеру если период тона равен 100, то через каждые 3200 такта процессора он будет переброшен из 0 и 1, из 1 в 0. Громкость тона задается либо огибающей (если выбран бит 4), либо собственным значением в регистрах r8..r10. Тон активируется через регистр R7.§ Шумы
Шум активируется когда активирован соответствующий бит в регистре R7 (должен быть притянут к 0 для активации). Шум работает точно так же, как и все остальное. Есть период шума, который активирует его через каждые 32 x N тактов процессора, где N-это значение периода шума (от 0 до 15). Чем большее значение периода шума, тем он более низкий по частоте.Шум делает следующее - он через каждый случайный промежуток времени (естественно, с некоторой частотой), из тона удаляет громкость. Собственно, всё, там работает шум.
И вообще так работает весь звуковой чип. Тут больше подводных камней вроде как и нет.
§ Варианты использования
Поскольку в AY три канала, можно использовать их для генерации различного вида тона. Например на канал A установить огибающую пилообразного сигнала и получить "бас", на B - обычный тон без изменений, на канал C поставить шум. Естественно, здесь будут некоторые ограничения. Там где огибающая, невозможно настроить громкость, к тому же у нее будет несущий тон, что будет искажать звук. Ну и конечно все каналы находятся на разных сторонах, один слева, другой посереди и третий справа.Пример на Бейсике, как программировать один тон:
110 LET r=65533: LET d=49149 220 OUT r,2: OUT d,255 330 OUT r,3: OUT d,3 440 OUT r,9: OUT d,16 550 OUT r,7: OUT d,253 660 OUT r,11: OUT d,0 770 OUT r,12: OUT d,32 880 OUT r,13: OUT d,0В регистр 2 и 3 (строки 20-30) пишется число 0x3FF (1023), которые будут равны частоте тона для среднего канала B. Рассчитаем эту частоту. Зная, что каждые 32 такта меняется состояние тона, можно сказать, что полный период он проходит за 64 такта (CPU). Поскольку процессор совершает 3500000 тактов в секунду, то 3500000 / (64*1023) ~ 53 герца. Это довольно низкая частота, но уровень слышимости человеческого уха составляет около 20 Гц.
В строке 40 в регистр 9 пишется громкость канала B. Она задана огибающей (число 16 активирует бит 4).
В строке 50 записано число 253, что в двоичном виде равно 11111101. Бит номер 1 активирует тон (так как там число 0), все остальные каналы заглушены.
В строках 60-70 записывается период огибающей, равный 0x2000. Рассчитаем ее длительность. Поскольку вся огибающая проходит за 16 периодов, то 0x2000 x 16 x 32 (машинный циклов CPU на каждую единицу периода) = 4194304 тактов CPU, то занимает по длительности 4194304 / 3500000 ~ 1,19 секунд.
Ну и в 80 строке записываем команду огибающей - 0000b, что соответствует затуханию тона с 15 по 0 громкости и остановкой на 0.
§ Семплированный режим
Существует режим работы, при котором возможно выдавать любые звуки, словно это обычная звуковая карта. Его реализация сложна на практике, но реальна. Этот режим предполагает отключение всех тонов, огибающей и шума, кроме громкости каналов. Изменяя уровень громкости каждые 1/8000, 1/11025, 1/22050 или 1/44100, можно создавать на выходе дискретизированный сигнал так же, как это было бы при обычном WAV-файле§ Уровни громкости
В AY уровни громкости не являются линейными. В таблице приведено соответствие уровня громкости в регистрах (от 0 до 15) и реальном уровню громкости на выходе (от 0 до 65535).Уровень V 0x0000 0 0.000 0x0385 1 0.013 0x053D 2 0.020 0x0770 3 0.029 0x0AD7 4 0.042 0x0FD5 5 0.061 0x15B0 6 0.084 0x230C 7 0.136 0x2B4C 8 0.169 0x43C1 9 0.264 0x5A4B A 0.352 0x732F B 0.449 0x9204 C 0.570 0xAFF1 D 0.687 0xD921 E 0.848 0xFFFF F 1.000