SegaBoy, я предлагаю такой формат только для оценки предела возможностей. Чтобы возможные недостатки плеера и нехватка вычислительной мощности 8080 не мешали оценить потенциал крутой звуковухи.
SegaBoy, я предлагаю такой формат только для оценки предела возможностей. Чтобы возможные недостатки плеера и нехватка вычислительной мощности 8080 не мешали оценить потенциал крутой звуковухи.
Больше игр нет
Как насчет того, чтобы перейти на схему звукового генератора из ПК11/16:
Относительно простая доработка (ставим дополнительный таймер втором этажом), но можно весьма интересные эффекты за счет скважности получать, типа таких: http://hypr.ru/blog/809.html
Другая крайность (в плане сложности): аналоговые синтезаторы, вроде ячейки звукового синтеза 5/2 для Агатов на двух ВИ53.
Последний раз редактировалось troosh; 18.09.2018 в 19:19.
Пример звучания данной схемы из ПК11/16: https://youtu.be/cP6gJM3OF70
В принципе можно вытащить все мелодии из доступных дисков и разобраться с их форматом.
Мелодий там не много оказалось. Вот сконвертировал и выложил описание штатного драйвера этого звукового генератора в ПК11/16: https://github.com/troosh/pk11-16/bl...VPSNC1.DOC.txt (там же все найденные мелодии и конвертор из текстового вида в бинарный).
Забавно там сделано, просто копируется файл с мелодией в специальный файл, а далее уже в фоне драйвер воспроизводит музыку.
Привет! большое спасибо за отличную работу с 3х канальным генератором)))
звучит классно =)
Можно дать пояснение, как происходит синхронизация с кадровой частотой?
как часто приходит кадровая? 50Гц или 25? и как долго длится импульс кадровой,
что бы его не пропустить, сколько множно ставить опереций в цикле ожидания?
wait_vsync:
lda crt_cmd_port
lda crt_cmd_port
ani crt_ir_flag
jz wait_vsync+3
------------
Ещё такой момент, касаемый Pitch bend (я просто не музыкант вообще =)
При разборе Midi мне вообще показалось, что существует только момент нажатия клавиши,
Если смотреть только на вариант пианино, то по идее длительность звучания каждой ноты
одинаковое, если это не пианино, то нота да - тянется...
Как это кодируется в midi? и как в вашем плеере? То есть длительность звучания ноты? =)
------------
Если вы не против, то возму некоторые кусочки кода вашего плеера в свои поделки =)
Синхронизация происходит просто - начинаем в цикле опрашивать бит IR у ВГ75 пока он не будет установлен. После этого выполняем свою процедуру делающую что угодно и по окончании снова возвращаемся к опросу IR. Таким образом все наши телодвижения происходят не чаще чем раз в кадр.
Если оставить настройки ВГ75 по-умолчанию, то кадровая 50 Гц. У меня есть примеры где выставлен режим 60 Гц. Импульс кадровой длится 645 мкс - сколько выставлено строк для VRTC и сколько линий в строке. Изначально это одна строка в 10 линий. Чтобы его не пропустить нужно чтобы основная процедура "уместилась" в один кадр.
Про операции в цикле ожидания не понял. Ожидание синхроимпульса это просто зацикленное чтение регистра ВГ75, затем сравнение с константой и прыжок назад на чтение если бит не установлен.
- - - Добавлено - - -
"Звуковысотное колесо (Pitch Wheel) используется для плавного изменения высоты тона звучащей ноты. Процесс изменения высоты называется питч-бендом (Pitch Bend), а соответствующее MIDI-сообщение — Pitch Wheel Change (его часто и называют Pitch Bend)."
"Pitch Wheel Change — сообщение высокого разрешения, то есть позволяет использовать 16384 значений изменения высоты, и относится к контроллерам непрерывного типа. При движении колеса высота ноты скачкообразно изменяется во времени, но благодаря маленьким шагам (равным 1/16384 диапазона изменения) эти скачки обычно незаметны, и создается ощущение плавного изменения высоты."
Кодируется в midi примерно так:
Временная метка, команда Pitch Bend, номер канала и значение (от 1 до 16384).Код:91 Pb ch=1 v=4526 98 Pb ch=1 v=2371 105 Pb ch=1 v=7163 112 Pb ch=1 v=4526 119 Pb ch=1 v=2371
Значение можно рассматривать как знаковое от -8192 до +8192, что для конкретной ноты равно понижению или понижению на одну октаву. Ну и промежуточные значения это гуляние где-то в диапазоне. В моём плеере я никак это не выделяю, просто проигрываю новую "ноту" с заранее просчитанным значением. На длительности это никак не сказывается - когда приходит команда выключить канал, тогда я и отключаю звук в нём.
Последний раз редактировалось SegaBoy; 15.05.2020 в 12:48.
Pyhesty (15.05.2020)
Круто! большое спасибо за подробный ответ!
Я так понимаю, что сигнал длится долго, более 10 линий кадровой синхронизации и в принципе его сложно проморгать, а вопрос был в том, можно ли успеть
в ожидании этого импульса что-то посчитать? например, складывать 32битное число и класть в память (для оценки запаса производительности между кадрами, например). Мне так кажется, что за 600мкс, можно успеть считать из памяти и положить в память число ) проверю)
Ещё такой вопрос, а есть ли программы, которые преобразуют MIDI в удобный текстовый формат с сообщениями? просто ну уж очень не хочется самому
в ручную сырой MIDI разбирать =)))
Если что-то посоветуете, буду очень признателен =)
Спасибо!
Вот попробую объяснить на примере:
В кадре 123 получаем команду включить ноту с номером 48 (130,81 Гц). Затем следующая команда выставляет pitch 8192, то есть смещение 0 относительно частоты ноты. Через шесть кадров приходит команда выключить данный канал.Код:123 On ch=1 n=48 v=127 123 Pb ch=1 v=8192 129 Off ch=1 n=48 v=0
Для условного плеера это превратится в следующие команды:
Другой пример:Код:123 - послать в канал 1 значение 13590 (константа для частоты 130,81 Гц) 129 - выключить канал 1
В кадре 235 получаем команду включить ноту с номером 53 (174,61 Гц). Затем следует смещение равное нулю как и в предыдущем примере. Через пять кадров получаем новую команду изменить pitch bend.Код:235 On ch=1 n=53 v=127 235 Pb ch=1 v=8192 240 Pb ch=1 v=9540 241 Off ch=1 n=53 v=0Берём частоту 174,61 умножаем на значение pitch bend (9540) и делим на 8192 (174,61*9540/8192=203,34).Частоту ноты 174,61 делим на 2 и умножаем на 2 в степени значения pitch bend делённое на 8192 (174,61/2 * 2^(9540/8192) = 195,71). На следующем кадре приходит команда выключить канал.
Для условного плеера это превратится в следующие команды:
Таким образом в обоих примерах ноты звучат по шесть кадров, но во втором случае в последнем кадре чуток приподняли частоту.Код:235 - послать в канал 1 значение 10181 (константа для частоты 174,61 Гц)240 - послать в канал 1 значение 8742 (константа для частоты 203,34 Гц)240 - послать в канал 1 значение 9084 (константа для частоты 195,71 Гц) 241 - выключить канал 1
- - - Добавлено - - -
Это всегда пожалуйста - используйте наздоровье = ))
- - - Добавлено - - -
Есть онлайн конвертер миди-файлов в текст Binary MIDI file to text conversion. Я им как раз и пользуюсь.
- - - Добавлено - - -
Если кадровая 50 Гц, то у нас в целом не 600 мкс, а все 20000 (20 мс). Отловили импульс и почти всё это время можно складывать, музыку выводить, отрисовывать на экране и прочее. Главное закончить чуть раньше и пойти по-новой "ловить" импульс.
Или мы о разном?
Последний раз редактировалось SegaBoy; 15.05.2020 в 15:30.
Pyhesty (15.05.2020)
Большое спасибо за подробный ответ! =)
Это значительно проясняет всё )
И не меньшее спасибо за ссылку)
да =) мне это проще проверить видимо будет)
но я вел разговор, чтобы внутри цикла ожидания ещё что-то успевать делать ) между командами lda crt_cmd_port и jz wait_vsync+3,
в частности посчитать сколько тактов остаётся в запасе =) а так да, я понял, что между кадрами 20мс.
ps: и такой момент почему два раза с порта загружается, а потом прыгает и загружается один раз )Код:wait_vsync: lda crt_cmd_port lda crt_cmd_port ani crt_ir_flag jz wait_vsync+3
я чуть в архитектуре не очень секу )) хотя могу как есть копипастнуть)
спасибо)
pss: раньше такими вещами не занимался, но интересно ))) извиняюсь, если вопросы банальные)
Последний раз редактировалось Pyhesty; 15.05.2020 в 11:22.
Глянул весь код - действительно два раза подряд здесь не нужно. Можно переделать так:
Первым чтением сбрасываем IR, потому что он самостоятельно только выставляется, а сбрасывается чтением. Это нужно (но необязательно) только один раз в самом начале программы, чтобы точно определить начало кадра. Иначе можно попасть и в конец и в середину.Код:lda crt_cmd_port wait_vsync: lda crt_cmd_port ani crt_ir_flag jz wait_vsync
Pyhesty (15.05.2020)
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)