Немного о скважности, сидсаунде и всём таком



Всем привет!
После прошедшего Multimatograf 2018 меня попросили рассказать о том, как именно мы (n1k-o , wbcbz7 и я) поиздевались над нашим любимым аигреком. Окей, начнём с самого начала — с того, как работает генератор тона.

Square Wave
Генератор тона AY/YM умеет вести обратный отсчёт, тикая 12-битным счётчиком, и выдавать на своём выходе ноль или единицу. Счётчик устроен так, что он переполняется по достижению половины периода, заданного нами в паре регистров периода тона. В этот момент состояние выхода генератора меняется на противоположное и отсчёт начинается сначала. Отметим сразу, что период генератора и частота получаемого тона связаны вот таким соотношением:

частота тона = частота чипа / (16 * период)

В итоге получается вот что:

Рис. 1: Меандр

Это та самая привычная уху правоверного спектрумиста square wave, или, по-русски говоря, меандр.
У меандра ширина импульса (та часть периода, на которой выход генератора в единице) равна половине периода. Именно так работает наш счётчик, и это обуславливает характерный тембр получаемого звука.
Отношение периода к длительности (ширине) импульса называют скважностью, и в нашем случае, как видно, она равна двум. Обычно более удобно использовать обратную скважности (и часто выражаемую в процентах) величину, называемую коэффициентом заполнения (duty cycle, DC). То есть, у нас DC = 1/2, или 50%.
На чипах AY/YM, в отличие от некоторых других, конструктивно нет возможности изменять скважность, получая иные тембры — логика счётчика такова, что на выходе мы имеем меандр и только меандр.
Но…

SID Sound
Кому первому на Atari ST в голову пришла эта мысль, мне достоверно установить не удалось. По всей вероятности, это был B.A.T. Ибо начало широкого распространения этой техники связывают с выпуском группой Synergy 27 сентября 1992 года шестого номера своего дискмага «DBA». В интро к нему, которое кодили как раз B.A.T и Rapido, звучала музыка легенды ST-сцены — Scavenger.

И ох, тысяча чертей, как же она звучала!



Слышите этот берущий за душу lead с плывущим тембром, совершенно непохожим на меандровый выхлоп генератора YM?



Вот примерно так все тогда и офигели.
А вся фишка вот в чём. Представим, что у нас есть ещё один такой же генератор, работающий с той же частотой, что и наш генератор тона на чипе, но чуть сдвинутый по фазе:

Рис. 2: Опять меандр

Для ясности совместим обе волны, производимые генераторами, на одном рисунке:

Рис. 3: Меандр на меандре

А теперь, собственно, фокус. Если мы каким-то образом объединим выходы обоих генераторов по AND (то есть, единица на выходе будет только в том случае, когда она на выходах обеих генераторов сразу), то получится…

Рис. 4: Больше не меандр

Ага! Это уже не похоже на меандр, не так ли? Да, на рисунке DC = 25%.
Дело за малым — осталось понять, как это сделать и где взять воображаемый генератор.

На Atari ST всё просто. Там есть два пользовательских таймера, умеющих генерировать прерывание. Таймер устанавливается так, чтобы получить частоту, равную частоте тона. При приходе прерывания от него мы просто либо инвертируем бит в микшере, отвечающий за подмешивание тона в канал, либо XOR-им амплитуду канала с её первоначальным значением (получая, соответственно, то 0, то изначальную амплитуду). В итоге получается именно то, что мы хотели, но с маленьким нюансом. Таймер Atari нельзя установить абсолютно точно на требуемую частоту из-за набора предопределённых делителей. Поэтому возникает некоторая погрешность. Но нет худа без добра: именно эта погрешность из-за разницы в частотах создаёт эффект «плавания» скважности — тот самый характерный SID Sound.

На нашей же любимой платформе всё несколько более грустно. Так как сэр Синклер был одержим идеей сделать ZX Spectrum максимально дешёвым, таймеров у нас нет, как и многого другого, впрочем. Ну, не то, чтобы совсем нет… есть один. Большой и толстый таймер под названием Z80 :)

Один из возможных способов повторения эффекта, который мы использовали — это точно выждать нужный интервал в тактах Z80 и произвести ту же манипуляцию с регистрами, что и на Atari ST. Не утомляя вас очевидными вычислениями, скажу сразу: поскольку частота PSG на наших родимых Пентагонах равна половине частоты Z80, требуемая задержка в тактах будет равна периоду тона, умноженному на 16. Вот так всё просто. И снова маленький нюанс: так как частоты Z80 и PSG кратны, то мы, в отличие от таймера Atari, получаем ровно нужную частоту. Что с этим делать, я думаю, понятно ;)

Да: дополнительные тембры можно получить, сдвигая частоту программного генератора на N октав вверх/вниз, к примеру, побитовым сдвигом результата в тактах влево/вправо.

Custom duty cycle
А что, если мы хотим точную, а не «плавающую» скважность?
Тут всё довольно просто: мы выключаем генератор тона совсем и вместо этого генерируем тон самостоятельно, меняя значение регистра амплитуды — так же, как мы это делаем для воспроизведения цифровых сэмплов.
Думаю, понятно, как получить произвольную скважность: два интервала в тактах, во время первого генерим единицу, во время второго — ноль. Опять же, всё совершенно легко считается из периода тона.

Syncbuzzer
Более поздним и очень красивым по звучанию эффектом является Syncbuzzer.
Авторство этого эффекта (и ряда других) на Atari принадлежит ещё одной ST-легенде — Tao / Cream.



В принципе, Карбо всё уже доходчиво изложил, так что повторяться не буду. Скажу лишь, что реализуется он практически так же, как и предыдущие. Генератор огибающей в нужный момент сбрасывается записью в регистр формы огибающей. Рассчитав момент сброса, можно получить очень интересные формы волны. Мы реализовали Syncbuzzer в своём плеере, но никак не использовали, ибо нервов на то, чтобы добавить ещё одну колонку в интерфейс Vortex Tracker, не хватило ни у меня, ни у wbcbz7 — а жаль. Ибо, повторюсь, звучит он шикарно.

Всё вместе
Возиться со сжатием дампа регистров я затеялся довольно давно, со времени своей первой 1К-интры, но особых успехов не достиг.
Все Америки уже были давным-давно открыты, так вышло и с идеей паковать LZ каждый регистр дампа по отдельности, которую я реализовал после того, как наткнулся на формат FYM для PC. Вроде бы вышло хорошо: размер упакованного дампа часто был близок к размеру исходного pt3-файла, а иногда и был даже меньше него. По скорости плеер, конечно, сильно уступал люто шустрому лидеру от psndcj и introspec , но по сжатию превосходил. Когда я рассказал о своих «успехах» introspec 'у, тот сообщил, что подобный пакер давным-давно написал psb , хоть и не релизил его (тем не менее, он как-то засветился в каких-то продах Гоблина). Ну, стоило ожидать. В итоге я забросил плеер в дальний угол диска и оставил там валяться до лучших времён.

Лучшие времена настали, когда я решил разобраться, как же на Atari ST получается такой непохожий на YM звук. Не помню уже, почему: видимо, опять слушал !cube и завидовал :) В интернетах была откопана и разобрана куча YM5/6 дампов, тут-то и пригодилось то, что плеер умеет пошагово распаковывать и проигрывать за фиксированное число тактов. В итоге где-то прошлой осенью все дампы были успешно переконверчены на ZX, и SID Sound заиграл, как у себя дома. Надо сказать, что такое давно проворачивал Poke / Patisoners, аж эндцать лет назад — и даже грозился открыть исходники, но воз и ныне там. Ничего, мы и сами справились. Хотя, конечно же, интересно, как это было сделано у него.

Кидание наконверченным в друзей привело к появлению патча на Vortex Tracker от Артёма, позволявшего задавать 16 уровней скважности тона. И, конечно же, Олежа немедленно воспылал, запилив кавер на «Drunken Sailor» для тизера игры «Остров Сокровищ»:



Дальше было добавление в Вортекс SID Sound, дигисэмплов и кое-чего ещё. В воздухе к тому времени определённо что-то витало: все вдруг начали интересоваться звуком с Атари. Мы решили, что будет прикольно зарелизить на МФ что-нибудь эдакое, так что я запланировал отпуск на конец апреля, чтобы мы за пару недель успели подготовиться, попробовать сделать демо и съездить на пати.

Момент, в который у нас начал образовываться кавер на «Татарина», я как-то пропустил — всё получилось само собой ) Олежа, как всегда, был великолепен (название с подколом тоже на его совести, а атари-адидасное лого — на совести Артёма). И, как всегда, жизнь всё расставила по своим местам: вместо отпуска за две недели я написал «по собственному» за неделю до МФ и был занят передачей дел сменщику. В итоге из нашей затеи получилось скорее интро, чем демо, практически без визуальных эффектов и с кучей косяков по коду. Всё собиралось буквально в последнюю ночь, отсюда путаница со снапшотами и отсутствие нормального TRD. Ещё раз приношу всем извинения — в первую очередь Олеже, Артёму и Нюку с Нодеусом.

Так или иначе, хорошо ли, плохо ли, но мы это сделали.



Спасибо!

36 комментариев

avatar
Очень классная статья! Даже я что-то понял. Жду новых издевательств над AY. :-)
avatar
Спасибо! Ну, если уж даже ты что-то НЕ понял, то я, наверное, провалился как рассказчик )
avatar
УРА!!! Свершилось… 18 лет я писал на форумах про свой MASON, сотни раз рассказывал, что можно лёгким движением одного параметра добавить PWM, что можно складывать каналы, но никакой отдачи не было. Разозлился, и сделал свою платку которая заменяет AY на WildSound, поотправлял кому смог. Платка эмулирует классические ДВА AY и добавляет возможность двух синтезированых WS, то что описано в статье, плюс добавляет возможность играть 8 каналов цифры(8 бит) в левое ухо, и 8 каналов в правое ухо, примеры выкладывал. Так никто и не обратил внимание на возможность сложения каналов, как это делалось в ATARI. Эта функция уже мирно, лет 10 лежит в редакторе MASON, и называется 2xAY. Вот пример как оно работает, в точности одна и та же мелодия только одна клавиша корректирует инструменты, как на классический AY так и на 2xAY так и на 2хWS. Всё пакуется и проигрывается плеером СТАБИЛЬНЫМ в прерывании до такта, в зависимости от мелодии, по желанию, и стабильным до градиента на 8 тактов, что даёт делать легко горизонтальные мультколоры на бордерах. И этот плеер в каждом продукте, где ступала моя нога.
Вот пример мелодии для AY — yadi.sk/d/vg9pdf_63VSYFk
Вот пример мелодии для WS — yadi.sk/d/nizQf5LP3VSYFx
Спасибо автору статьи, что хоть сейчас, хоть кто-то наконец-то воспримет сложение каналов.
Вот ещё пример мелодии для AY — yadi.sk/d/9Pt3pOLt3VSbQW
Вот ещё пример мелодии для WS — yadi.sk/d/OZaxP4K03VSbQn
Очень надеюсь, что музыканты начнут обращать внимание на этот прекрасные метод 2xAY и возможно на то что описано в статье 2xWS!!!
Ещё раз ура и спасибо…
avatar
Я тут уже второй день порываюсь написать то же самое про АУХ-32 и никак не мог понять, почему я этого до сих пор не сделал. А разгадка успеха простая: фишка не в скважности, а в том, что эти извращенцы ЭТО сделали на АУ без стероидов.
Работает это так:
1. Показываешь им новую железяку, которая захватит голактего (можно даже не показывать, а просто рассказать).
2. Они начинают шевелиться и ВНЕЗАПНО выходит чудо-эффект.
3. Жду реализации 85 аппаратных спрайтов на строку в обычном пентагоне :D
avatar
3. Жду реализации 85 аппаратных спрайтов на строку в обычном пентагоне :D
Что-то мне...
avatar
а почему бы и нет? не сказано же каков размер у спрайтов :D
avatar
Реально вдохновляющий комментарий!
avatar
Спасибо! Как раз на днях в одном из телеграм-канальчиков вспоминали о Mason в контексте того, что он был сильно недооценен, и что там есть чему поучиться. Я вернулся на ZX не так давно, поэтому всю эту тему пропустил (хотя Вова меня и толкал посмотреть, но, как обычно, руки всё никак не доходили), а жаль: возможно, иначе статья была бы совершенно другой. Я понимаю, что в свете написанного в комментарии это как-то странно прозвучит, но, может быть, стоит попытаться достучаться ещё раз? Прямо здесь, на Хайпе? Многие с тех пор пришли и многие вернулись всё же.
avatar
«Момент, в который у нас начал образовываться кавер на «Татарина», я как-то пропустил» — всё началось с того, что вы с артемом внезапно объявили, что у нас могут легко звучать цифровые семплы, хотя до этого мы только скважностью баловались, поэтому мы тут же загорелись идеей их использовать — артем впиливал их поддержку в вортекс, а дайвер мимоходом предложил трек «татарин», который мы некоторое время назад уже слушали, я выбрал в нем те места, которые годились для семплирования, скидывал в чатик ребятам, в итоге, выбрали ту часть, в которой поется про парня-татарина, а в процессе нарезки «татарин» стал звучать, как «атарин», поэтому в рабочем порядке сохранили проект с этим названием. так и определилось общее направление :)
avatar
У меня интересный эффект дежа-вю.
Не уверен, что слышал ранее «Татарина». А вокалоид вызвал у меня ассоциации с каким то более древним музлом, вспомнить бы только с каким…
Кстати, думал, что это не оцифровка а именно игрой с тоном в реальном времени такого эффекта добились, то есть расширенным синтезом.
avatar
Это интересная тема на самом деле. Насколько я помню, что-то такое на генераторах тона (правда, четь более, чем на трёх) умудрялись выделывать на MSX — играли речевые сэмплы одним тиком на фрейм, как-то хитро аппроксимируя их тоном (Фурье там и всё такое):
avatar
ну это уже чтото типа MP3
вот знали бы что так можно — не стали бы всякие ковоксы и GS то делать :)
avatar
Вот! Вот так всё и было! :)
avatar
ох, а впиливание диги в вортекс — отдельная история: среди каши бульбокода воткнуть нужную фичу, не сломав остальное (что мы таки несколько раз и натворили, оставляя ковальского без рабочего psg-экспорта и вообще :)

впрочем, VT3.0 будет, так что stay tuned! :)
avatar
avatar
леха, это неполая версия :)) вот так все было
avatar
За Интроспеком, я как понимаю, как раз тот самый генератор клоков разместили :)
avatar
Нене, интроспек просто поддерживает команду морально и готовится опорожниться на свежезаваренный шов.
avatar
А чо у вас wbcbz7 такой синий и железный?
avatar
Услышать такое на AY — это натуральный шок. Спасибо за разъяснения, очень понятно и доходчиво изложен принцип. Я не музыкант, но в целом вроде все даже понял.
Насколько серьезно такая техника ограничивает кодинг? Я так понимаю, что надо периодически делать проверку и коррекцию в течение всего кадра, а насколько часто? Или всё прощее/сложнее?
avatar
Спасибо! Скажем так, попытки впихнуть эффекты во время воспроизведения всего вот этого напоминают попытки пробежать между струями дождя так, чтобы не намокнуть. В нашем случае струи — это моменты переключения состояния софт-генератора. Если успеваешь что-то сделать между ними — то хорошо. В целом сейчас плеер устроен так, что у нас на большей части фрейма остаются свободные куски времени ЦПУ где-то по 250 тактов — то есть, если хочется показать эффект параллельно воспроизведению, надо разбивать его код на куски так, чтобы он в эти такты влезал. (Морока ещё та, короче).
avatar
как раз прикидывали в «курилке» сколько свободных тактов — сошлись на мнении, что в районе 200))
avatar
Да и не совсем в тему, но я щас загуглил по своим нуждам Drunken Sailor и нагулилось прикольное:
What will we do with a drunken coder? What will we do with a drunken coder? What will we do with a drunken coder? Early in the morning?
Let him alone deploy to production, Way hay and up to production, Way hay and up to production, Early in the morning!
avatar
Я пошагал чучуть в дебаггере.
1. Извращения производятся с одним каналом АУ (канал В).
2. Заметил 2 эффекта: дига и скважность.
3. Скважность делается так: берется значение периода канала: период из рега * 32 = период меандра в тактах Z80. Из этого вычисляется сколько тактов держать канал включенным (рег. 09 = громкость), и остальные такты — выключенным (рег. 09 = 0). Сумма тактов в обоих полупериодах должна быть точно одинаковой. Значение скважности варьируется в пределах 0-50%.
4. Как происходит сихронизация с фазой меандра не разбирался.
avatar
Ну, как-то так, да. Кстати, забыл сказать про важный момент: в анриле для правильного воспроизведения надо выставить клок аигрека в полклока Z80 руками, вписав в ини-файле в секции [AY] значение FQ=1792000. Я себе все мозги выделал, прежде чем дошло, почему играет неправильно.
avatar
вот кстати да, я тоже не мог понять, почему все фальшивило, пока не понял, что проц и AY несинхронны, а вся логика конфы вместе с зетником работает на 50гц кадровой :)
avatar
Хех, это я еще на АУХ не пробовал. У него сейчас клок берется с собственного кварца. Он хоть и 1.75, но несинхронный с клоком з80.
avatar
Вроде бы на AYX никаких проблем не слышал. Главное, что частоты не расходятся.
avatar
Ох, сколько же было разговоров на тему реализации Atari-звучания на ZX… И вот, наконец-то, свершилось! Молодцы! :)
avatar
Спасибо ) Надеюсь, музыканты заинтересуются и с выходом Vortex 3 это вот всё добавит новизны в music compo )
avatar
БИПОР! Бипор не забудьте в остатки тактов вкорячить!
avatar
Ну что, пора на пати вместо AY-music делать executable ay-music? ))
avatar
Мне кажется, уже давно нужно разрешать Executable AY-music в музыкальном компо.
avatar
Ну если исходить из сегодняшних реалий, то под категорию Executable AY-music попадают разве что треки, написанные в 3-м вортексе. Причем, есть он пока только у пары человек, насколько я знаю. Ну может еще кто-то что-то своё накодит, но это очень маловероятно.

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

Но вообще-то упомянуть Executable AY-music в правилах основного компо стоит. Во избежании.
avatar
3й вортекс, в какой бы форме он не вышел, не охватит всего разнообразия executable music. Да, скорее всего в нём будет работать большинство людей. Но если не разрешить явно executable music, кол-во людей, замотивированных что-то накодить, уменьшится.
avatar
Соображения примерно как были в своё время с мультигигой: отдельное компо набрать будет наверное трудно, а так будет стимул развивать новое направление. Заодно, это может потенциально возродить цифровую музыку на АУ.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.