GEMS sound driver research
| |
SeregaZ | Дата: Понедельник, 12.09.2016, 04:36 | Сообщение # 121 |
Сообщений: 50 Статус: Offline
| все. я решил окончательно засесть за один из старых долгостроев VGM2CODE (который потом через комбайн в GEMS)
и значит в моем мониторе инструментов и нот VGM файла при проигрывании в логе пишется следующее: стопнота инструмент изменился на 24 нажата нота инструмент изменился на 4 (изменялась громкость 4) нажата нота нажата нота нажата нота нажата нота нажата нота
инструмент изменился на 24 - понятно, произошло выставление инструмента в канал
пока про громкость опустим... так вот нажата нота - началось проигрывание... команды стоп ноты нет, сразу идет следующая - то есть предполагается что это пошел слайд ноты (трек из RRR). коим образом это отобразить в CODE файле?
patch patch_01 (скажем выставление того инструмента) duration 50 (общая длительность ноты, она же как-бы не прерывается командой на стоп - слайд же типа) delay 10 note $3C pitch $0010 delay 10 pitch $0020 delay 10 pitch $0030 delay 10 pitch $0040
правильно?
теперь про громкость. в моем мониторе инструментов пишет что произошло изменение параметров инструмента на 20 сколько-то там регистров - это означает что инструмент в этом виде имеет 100% значение громкости? volume? то есть потом когда встречается изменение инструмента всего на 4 регистра и все 4 касаются Total Level - значит изменился не сам инструмент, а должна быть команда volume в этом месте? вся закавыка только как расчитать теперь :) предположим инструменту эта громкость выставлялась как 10 10 10 10, потом произошло приглушение до 8, 8, 8, 8 скажем. 10 10 10 10 принимается как volume 1, как расчитать сколько должно быть у 8, 8, 8, 8? дойдет до первых версий конвертера можно будет конечно мониторить сколько volume в code файле в конечном итоге даст в логе эмулятора... и может быть даже получится родить более менее похожую формулу, но может быть есть что-то готовое для подобного расчета?
а второй момент опять таки как выставлять подобное изменение громкости, если нота не завершилась стопнотой, а продолжается слайд, просто в середине слайда идет изменение громкости? так-же как со слайдом?
patch patch_01 (скажем выставление того инструмента, типа как volume 1) duration 50 (общая длительность ноты, она же как-бы не прерывается командой на стоп - слайд же типа) delay 10 note $3C volume 5 (понижение громкости) pitch $0010 delay 10 pitch $0020 delay 10 pitch $0030 delay 10 pitch $0040Добавлено (10.09.2016, 04:21) --------------------------------------------- VGM2GEMS конвертер :)
Добавлено (11.09.2016, 19:17) --------------------------------------------- команда volume для PSG не работает?
Код SECTION HEADER dc.b 1 dc.t channel_0
SECTION CODE channel_0: tempo 120 pitch $0000 patch patch_0F delay 0 volume 1 delay 0 duration 3 delay 12 note $31 volume 30 delay 0 duration 3 delay 12 note $31 eos что-то помоему без эмоций, что так что так одинаково вроде.
потом дальше для того чтоб разобраться где что - взял дюнские треки, отпилил все FM, оставил только PSG, оставил только 1 ноту, проиграл в эмуляторе, записав при этом GYM лог, а после расковырял этот самый GYM - а где там команды или что там, чтобы выставляло эти самые значения из инструмента? там только выставление частоты - ноты, и громкость - то есть своего рода клавиша нажата\отжата. а инструмент то где? :)Добавлено (11.09.2016, 21:32) --------------------------------------------- хотя видимо ясно откуда он берется... из алгоритма поведения повышения ноты и понижения. но откуда тада брать Type и Noise Data? Добавлено (12.09.2016, 04:36) --------------------------------------------- так. ладно. вопрос про Noise - у него нет чтоль своего канала?
Код patch patch_01 delay 0 duration 2 delay 3 note $5F
note $5F, судя по логу GYM ставит ноту во 2 канал
Код 2 канал, частота ноты 28 pause 3 канал, noise 7 2 канал, громкость 15 3 канал, громкость 6 pause 3 канал, громкость 6 pause 3 канал, громкость 6 pause 3 канал, громкость 15 pause с какого перепугу он во 2 канал то лезет и ставит туда ноту? хотя может я просто читаю не правильно... пойду перепроверю.
Сообщение отредактировал SeregaZ - Среда, 31.08.2016, 22:05 |
|
| |
r57shell | Дата: Понедельник, 12.09.2016, 05:47 | Сообщение # 122 |
Сообщений: 632 Статус: Offline
| не знаю что ответить. про питч правильно всё. громкость для PSG вроде работает. (не помню точно) инструменты для PSG нигде не брать, гемс регулирует громкость сам.
инструменты + сэмплы выдерает vgmjuice + делает MIDI файл. https://github.com/realmonster/GEMS
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Понедельник, 12.09.2016, 18:31 | Сообщение # 123 |
Сообщений: 50 Статус: Offline
| ну почти все вопросы то я решил - непонятно мне с каналами PSG. так их 3 или 4? просто повторюсь - пишу patch patch_01 delay 0 duration 2 delay 3 note $5F
а судя по логу нота идет не в 3 канале - который четвертый шумовой, а во 2 канале - который PSG. что меня несколько сбивает столку :) получается у процессора 2 канала точно PSG, а третий канал ИЛИ PSG ИЛИ шум? в смысле история повторяется как с 2612 - где 6 канал ИЛИ FM ИЛИ сэмплы. правильно?
сами инструменты то вроде понятно как рожать - надо ловить любой чих в изменениях громкости по каналу и от него уже ловить алгоритм поведения и потом переводить этот алгоритм в 7 цифр инструмента. вручную то я вроде уже могу создать файл инструмента, надо теперь формулу какую-то придумать. но сначала определится с этим непонятным использованием каналов... так 4 канала или 3 имеет этот процессор? эти ноты во втором канале, когда используется вроде бы третий-шумовой - меня смущают :)
|
|
| |
r57shell | Дата: Понедельник, 12.09.2016, 18:50 | Сообщение # 124 |
Сообщений: 632 Статус: Offline
| Гугл забанил? Да, ровно 3 канала, и третий либо шум либо нормальный. Я точно не помню, может быть любой может быть шумом... гугл в помощь. Не, дока говорит 4 канала:
Цитата The PSG contains four sound channels, consisting of three tone generators and a noise generator. Each of the four channels has an independent volume control (attenuator). The PSG is controlled through output port $7F.
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Понедельник, 12.09.2016, 21:04 | Сообщение # 125 |
Сообщений: 50 Статус: Offline
| гугл пишет витиевато :) вот ты процитировал - я прочитаю и сделаю вывод что 4 канала. но по идее там должна быть пометка, что 4 канал использует частоты ноты из 3 канала. то есть получается одновременно можно использовать только 3 канала, либо может и 4, но 4 канал будет использовать ту-же ноту, что и 3 канал.
ну тогда вроде все - все вопросы утряс :) хотя громкость для PSG все-ж не работает. сам поэксперементируй. за громкость будет отвечать Attack Level в инструменте, нежели команда volume. хотя это бредово... если понадобится в конце сделать плавное затухание это придется 10 дополнительных инструментов для PSG делать? :)
а хотя во! остался еще вопрос :)
Код 0x4F dd Game Gear PSG stereo, write dd to port 0x06 то есть в VGM можно разводить звучание на левый или правый канал для PSG. как это в CODE файле отобразить? или тут с GEMS опять таки повторяется история как с сэмплами? то есть поддержки... эээ... panning? в GEMS как для сэмплов так и для PSG нет? только получается в FM есть через настройку самого инструмента.
насчет сэмплов - а ты чуток допилить сам движок GEMS не можешь? :) до 2.9с какогонить... как ValleyBell говорил: перед использованием сэмпла в регистры пишется предварительное включение обоих каналов левого и правого:
Цитата 2016-09-06 21:48:25 ValleyBell According to the source code, it doesn't support panned DAC. 2016-09-06 21:48:34 ValleyBell it seems 2016-09-06 21:49:00 ValleyBell FMWrite(2, 0xB6, 0xC0); // enable ch6 output to both R and L 2016-09-06 21:49:12 ValleyBell That's done before playing any DAC sound in GEMS. 2016-09-06 21:50:05 ValleyBell So unless I ported it incorrectly from Z80 ASM to C, it has no DAC panning.
вот там бы добавить еще два варианта: FMWrite(2, 0xB6, 0xC0) - оба, FMWrite(2, 0xB6, 0x80) - левый, FMWrite(2, 0xB6, 0x40) а выставлялось чтоб это дело в файле .sfx в конце:
Код RAW 'sample_0C.snd' FLAGS =$46 SKIP =$0000 FIRST =$0838 LOOP =$0000 END =$0000 CHAN=$0000 $0000 - стерео, оба (на случай совместимости со старыми треками, где нет этого параметра в файле) $0010 - правый (левый отключен этой единичкой) FMWrite(2, 0xB6, 0x40) $0001 - левый (правый отключен этой единичкой) FMWrite(2, 0xB6, 0x80)
а вот насчет PSG - там без понятия, поскольку там все 4 канала рулятся в одной команде. Цитата When a byte is written to port 0x06 on the Game Gear, the PSG output is affected as follows: Bit Channel Side 0 0 Right 1 1 Right 2 2 Right 3 3 Right 4 0 Left 5 1 Left 6 2 Left 7 3 Left If a bit is set, the corresponding channel is output to the corresponding side. So, 0xff outputs all channels to all sides, 0xf0 outputs to the left side only, etc. Добавлено (12.09.2016, 20:26) --------------------------------------------- хотя нет. вот еще затык: в VGM файле частота ноты во 2 канале объявлена как 17, однако в GEMS максимальная нота может быть note $5F, что выдает частоту как 28. я подумал видимо догнать 17 придется питчем, однако pitch видимо на последней ноте игнорирует. это мне чего 1 в 1 не получится конвертануть из-за ограничений GEMS? Добавлено (12.09.2016, 21:04) --------------------------------------------- и еще про сам ром проигрыватель треков - самый первый раз запускаю, то сэмплы барабанов на своем месте. остановил, запускаю - барабаны сбились на такт.
|
|
| |
r57shell | Дата: Вторник, 13.09.2016, 02:06 | Сообщение # 126 |
Сообщений: 632 Статус: Offline
| Цитата SeregaZ ( ) вот там бы добавить еще два варианта: FMWrite(2, 0xB6, 0xC0) - оба, FMWrite(2, 0xB6, 0x80) - левый, FMWrite(2, 0xB6, 0x40)а выставлялось чтоб это дело в файле .sfx в конце: модифицируй движок сам, если так хочешь ). Я честно не помню, умеет ли вообще DAC на сеге играть только в одном "ухе". Понятно, что можно послать в регистр это значение, но будет ли желаемый эффект на железе?
гейм гир не путай с сегой. одно может пахать на одном, а на другом хрен.
Цитата SeregaZ ( ) в VGM файле частота ноты во 2 канале объявлена как 17, однако в GEMS максимальная нота может быть note $5F, что выдает частоту как 28. я подумал видимо догнать 17 придется питчем, однако pitch видимо на последней ноте игнорирует. это мне чего 1 в 1 не получится конвертануть из-за ограничений GEMS? сам думай как эквиваленты получать. возможно ты косячишь с вычислениями.
Цитата SeregaZ ( ) и еще про сам ром проигрыватель треков - самый первый раз запускаю, то сэмплы барабанов на своем месте. остановил, запускаю - барабаны сбились на такт.в в делеях и дюрейшенах наврал.
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Воскресенье, 18.09.2016, 22:09 | Сообщение # 127 |
Сообщений: 50 Статус: Offline
| должон уметь играть. это был VGM файл мелодии игры из Battletoads. там сэмплы - барабаны, и есть момент там там - в левом, там там - в обоих, там там - в правом. не знаю как этот переход барабанов называется, но звучит здорово. правда в самой игре нет в опциях прослушать треки. там только если ручками дойти до той миссии с мелодией арктической, над которой я колдовал. конечно может быть риперы мелодий от себя уже добавляли в VGM'ку эти навороты.
по поводу вычислений - я тоже думаю... но весь вопрос где косяк :) %1 00 0 1110 Latch, channel 0, tone, data %1110 %0 0 001111 Data %001111
то есть сначала получается конец значения - 4 нижних бита, после должно прийти второе значение, где 6 бит читается последних. и потом эти 6 бит << 4 + те 4 бита из первого значения.
Set channel 0 tone to %0011111110 = 0xfe (440Hz @ 3579545Hz clock)
в делеях и дюрейшенах наврал. - тоже скорей всего. но разве если ты нажал на стоп - стоп не нажался? :) по идее стоп нажал - все сбросилось и должно играть нормально. ведь только когда запускаешь ром - все нормально. а после перезапуска начинается в деревне утро... (хотя может быть дело в переборщении delay 0 - проблема в том, что эти delay 0 надо сувать везде где непопадя. инструмент изменился? delay 0. питч поменялся? delay 0. громкость поменялась? delay 0 - видимо эти делеи где-то и портят картину, но все-ж первый раз то играет все верно :))))
пока прислать архив не могу. я там испортил чуть чуть :) PSG добавлял... но вручную. там теперь рассинхрон... покамись вроде нашлась библиотека с PSGaми и вроде как подсказали примерную схему как это дело вообще подключается. пока там торчу - очень хочется подключить, чтоб проигрыватель-конвертер мог играть все :) а не только сраные FM. потом засяду поплотнее за само конвертирование PSG.Добавлено (18.09.2016, 22:09) --------------------------------------------- и тут я щас спрошу... ты только не заори в голос от моего вопроса :) я ж не программист. этот SN76489 это просто тон генератор? а эти самые тоны - они везде одинаковые? в смысле если частота одинаковая - то звучание SN76489 будет таким-же как и любой другой генератор тона?
просто я тут парился парился - максимум что получилось какие-то хрипы, но в процессе работы много для себя америк понаоткрывал. а потом вспомнил что у меня примеры генератора тонов были в папке. открыл а там все вопросы решены и с организацией звука и с просчетом как этот самый звук выглядеть должен и все такое прочее. вот я и подумал - а не делаю ли я тоже самое, только в профиль? в смысле со всей разницей что там 3 канала, а тут пример только для одного - звучание будет одинаковым при условии подачи одинаковой частоты им обоим? причем в этом геренаторе есть еще и галка про шум и что-то там про зубосверло... просто я вроде когда читал буржуйские мануалы по SN76489 мне это название попадалось про дрель для зубов :)
просто я думаю если звучание действительно должно быть одинаковое, как я предполагаю, то тогда нафиг мне те чужие исходники - основную то мысль я вроде уяснил - и просто взять этот готовый тоновый генератор и прилепить к нему процедуру по разбору значения команды в регистр на частоту и номер канала.
|
|
| |
r57shell | Дата: Понедельник, 19.09.2016, 03:33 | Сообщение # 128 |
Сообщений: 632 Статус: Offline
| Цитата SeregaZ ( ) этот SN76489 это просто тон генератор? а эти самые тоны - они везде одинаковые? в смысле если частота одинаковая - то звучание SN76489 будет таким-же как и любой другой генератор тона? В плане тона: до ре ми фа соль - они и в Африке тоны. Дело только в звучании: где-то скрипка, где-то труба, где-то орган. Можешь попробовать заменить, но это будет очень отдалённое звучание.
По звуковому чипу могу сказать, тебе всего лишь надо правильно по скорости крутить ему clock, и параллельно правильно по скорости забирать сэмплы. (уровень звука) И с правильной скоростью эти семплы воспроизводить в аудиоканале.
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Вторник, 11.10.2016, 20:58 | Сообщение # 129 |
Сообщений: 50 Статус: Offline
| угу. не орган :) сам абалдел, что получилось заставить петь... пойду буржуям еще мозг поколупаю мож чо подскажут по ихнему генератору.
а насчет шума я так понимаю там частота у этого самого шума тоже выставляется? просто в моем случае шум и есть шум - хоть завыкручивай ему частоту, ничо не меняется в том тон генераторе...
Добавлено (20.09.2016, 01:07) --------------------------------------------- так. вроде раздуплил. я не тот тип сигнала использовал :)
в итоге три сигнала играют. смешивание меня правда несколько смутило - но предложили идею занизить общую громкость, и тогда при смешивании каналов, а там предложили сплюсовать все 3 канала (4 потом еще же и шумовой) в одно значение и его уже писать, так вот при смешивании каналов играло несколько с искажениями. а так с занижением вроде играет.
теперь бы раздуплить насчет шума... там столько непонятной писанины в статье, да еще и на буржуйском - что я вообще не представляю, что от меня хотят...
Добавлено (11.10.2016, 00:50) --------------------------------------------- PSG мы с буржуйским товарищем добили :) точнее он добивал. я сидел, да смотрел... работает, но еще не прикручивал. там как представлю что надо придумать - так и не хочется думать... пока решил допилить code проигрыватель и пока без PSG. со всеми "инструментами" вроде ясно... однако с модуляцией не понятно. там файлы типа modulation_00.mod - все разного размера... чо они делают то? в треках дюны этих модуляций вагоны... без них, по моему, играет не верно :) правда я еще питч тоже не доделал и громкость там выставляется не совсем верно, точнее совсем неверно я бы сказал :) но все равно уже более менее должно играть близко, а не играет. понять бы что эти modulation_00.mod делают. там написано что частотые чото там модуляции... но мне бы на пальцах бы, чтоб хоть примерно понять что она делает и как это втолковать процессору в регистровом плане.Добавлено (11.10.2016, 20:58) --------------------------------------------- громкость согласно алгоритму вроде приделал. правда скорей всего путанница у меня с 1, 2, 3, 4 - где вроде как должно быть 1, 3, 2, 4... там тоже бы уточнить повнимательнее. а то тут вроде как надо делать, а смотрел кажись в VGM MM - там вроде не было этого переворота внутри как шли по порядку, так и шли вроде 1, 2, 3, 4... теперь питч. я так полагаю сначала берем ноту из коде файла, делаем ей + 12, после ноту прогоняем через процедуру нотного переделывания в значения регистров и потом к этому значению прибавить питч?
жила была нота $18. но тут проигрыватель её сожрал... прибавил + 12 = стало $24. потом переварил в $1284, которую после разложил на $12 и $84, где $12 пошло бабушке $A4, а $84 пошло дедушке $A0. мораль: а в каком месте прибавлять значение питч? $1284 + pitch $000F? и тогда становится $1293 и тогда $A4 = также $12, а $A0 меняется на $93. верно?
и так-же вопрос про модуляцию висит :) чо с ней делать...
Сообщение отредактировал SeregaZ - Вторник, 11.10.2016, 00:52 |
|
| |
r57shell | Дата: Среда, 12.10.2016, 02:10 | Сообщение # 130 |
Сообщений: 632 Статус: Offline
| Цитата SeregaZ ( ) правда скорей всего путанница у меня с 1, 2, 3, 4 - где вроде как должно быть 1, 3, 2, 4... там тоже бы уточнить Это по регистрам надо смотреть.
Цитата SeregaZ ( ) мораль: а в каком месте прибавлять значение питч? До конверсии частоты. Надо на выходе иметь дробное значение высоты ноты. Например если 12 это ДО (С), то 12.5 это ДО + половина полутона, то есть, четверть тона. Если что, половина тона от ДО это уже РЕ. pitch этот в 256-х полутона, то есть pitch 128 note 12 будет 12.5 Или в шестнадцатеричной системе: pitch $80 note $C будет 12.5 нота ).
Модуляции, это пакеты (пачки, стопки) из pitch в сжатой форме. с pitch указанным в канале тупо складываются. Формат файла: сначала идёт word кол-во блоков, потом блоки по 4 байта вроде (не помню точно). Что-то типо: скорость добавления питча, и длительность. Посмотреть примеры можно в досовском GEMS.
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Среда, 12.10.2016, 05:01 | Сообщение # 131 |
Сообщений: 50 Статус: Offline
| с питчем вроде понятно. я значит не правильно сделал :) и тут после твоего объяснения посмотрел еще раз на ту функцию, а там оказывается на входе питч то уже есть: GetOPNNote(Note.i, Pitch.i) - я его просто не указывал, а прибавлял уже к готовому значению в конце :) потестил с этой нотой до: Debug Hex(GetOPNNote(12, 0)) - показало $284 Debug Hex(GetOPNNote(13, 0)) - $2AA Debug Hex(GetOPNNote(12, 128)) - $2AA вроде выходит как ты и сказал. с этим вроде разобрались окончательно :) надеюсь :)
а вот с модуляцией... досовского гемса у меня нет и как там пользоваться даже без понятия, и я не думаю что он мне родит точно такой-же файл, как твой сплиттер делает - отдельный файл типа modulation_03.mod.
и чего форум картинки не дает вставлять? блин. неудобно же...
"скорость добавления питча, и длительность" - походу опять тот-еще геморрой... это своеобразный эффект слайда или как он там? звук типа может менять частоту, без необходимости указывать питч в течении проигрывания одной ноты, скажем через delay 1? типа слайдом вверх и вниз ездить без остановки ноты? как в треках рокнролл рейсинг? я его кстати планировал как раз через делай 1 воспроизводить... однако если подобное можно сделать с помощью этой модуляции и если я еще пойму - то было бы вообще замечательно. хотя наверное не... не то. тут эта модуляция получается выставляется перед треком, а не перед отдельной нотой. в РРР там надо её для каких-то отдельных определенных нот, а тут видимо сразу для всего трека... или это вибрато типа?
ну попробывать разобраться можно... думаю ковырять модуляционные файлы, после собирать ром, записывать GYM файл в эмуляторе, после разбирать этот файл и смотреть как себя регистры вести будут. думаю общее представление составить можно будет :) это через жопу конечно, причем доооооолгую такую жопу - но так думаю смогу хоть приблизительно понять :)
Сообщение отредактировал SeregaZ - Среда, 12.10.2016, 05:16 |
|
| |
r57shell | Дата: Среда, 12.10.2016, 16:41 | Сообщение # 132 |
Сообщений: 632 Статус: Offline
| Цитата SeregaZ ( ) Debug Hex(GetOPNNote(13, 0)) - $2AA Debug Hex(GetOPNNote(12, 128)) - $2AA 12.5 != 13 Но возможно 128 это целый полутон, но вроде всё же 128 это половина полутона.
Цитата SeregaZ ( ) досовского гемса у меня нет и как там пользоваться даже без понятия, и я не думаю что он мне родит точно такой-же файл, как твой сплиттер делает - отдельный файл типа modulation_03.mod. родить файл такой не родит, а вот чтобы посмотреть график который рисует он, и редактор модуляций - можно. Берёшь качаешь dosbox любой, потом надо положить в некоторую папку GEMS.EXE и в ту же папку положить EGAVGA.BGI. Затем запускаешь досбокс, монтируешь эту папку через команду mount, и запускаешь GEMS.EXE Там заходишь в модуляции - послушать не сможешь но посмотреть )
Цитата SeregaZ ( ) типа слайдом вверх и вниз ездить без остановки ноты? как в треках рокнролл рейсинг? Да, для любой ноты можно указать свою модуляцию, она начинает воспроизводится с note on.
Вся математика этого известна. Просто, видимо тебе без шишек не понять. Если что-то не работает - то ты просто написал не правильно, и всё.
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Среда, 12.10.2016, 20:58 | Сообщение # 133 |
Сообщений: 50 Статус: Offline
| по идее я путем тестирования точно разберусь - указывая различные значения питч в коде файле, после компиляции смотря опять таки через GYM какие значения регистров в итоге родились.
с другой стороны - 12 это может для миди до. а для этой процедуры хрен его знает... и если 12 это до, то кто сказал что 13 это ре? мож это до диез или как она там... а ре это 14. ща... гамму надо нарисовать в коде файле и послушать. там точно будет ясно :)Добавлено (12.10.2016, 18:35) --------------------------------------------- ну точно. гамма это: note $13 note $15 note $17 note $18 note $1A note $1C note $1E
ток почему до конвертануло как $13 - то есть 19, вместо 12... ну да фиг с ней :) 12 до, 13 до диез, 14 ре. тогда 12 + питч 128 = 13. Добавлено (12.10.2016, 19:14) --------------------------------------------- про модуляцию видимо вот эта часть:
Код // DOENVELOPE - update the pitch envelope processor static void DOENVELOPE(void) { UINT8* CurECB; // Register IX UINT8 TestRes; UINT32 SegPos; // Register HL UINT8 SegCntr; // Register A UINT16 SegVal; UINT8* CurPB; // Register IY CurECB = ECB; // point at the envelope control blocks //envloop: while(1) { DACxME(); if (CurECB[ECBCHAN] & 0x80) // end of list? [BIT #7] break; // yup - return if (! (CurECB[ECBCHAN] & 0x40)) // active ? [BIT #6] { //envactive: // check if this envelope's timebase has ticked if (TBASEFLAGS & 0x20) // sfx timebase? [BIT #5] //envsfx: TestRes = (TBASEFLAGS & 0x01); // yes - check sfx tick flag [BIT #0] else TestRes = (TBASEFLAGS & 0x02); // no - check music tick flag [BIT #1] if (TestRes) { //envticked: if (CurECB[ECBCTR] == 0) // ctr at 0? { //envnextseg: // yes - [Note: The comment is really cut here.] SegPos = (CurECB[ECBPTRH] << 8) | (CurECB[ECBPTRL] << 0); SegPos -= 0x1E80; // [1E80 is subtracted to make up for ENV0BUF[]] SegCntr = ENV0BUF[SegPos]; if (SegCntr == 0) { // jr envdone TestRes = 0x00; } else { SegPos ++; CurECB[ECBDELL] = ENV0BUF[SegPos]; SegPos ++; CurECB[ECBDELH] = ENV0BUF[SegPos]; // ECB's delta <- this segment's delta SegPos ++; DACxME(); SegPos += 0x1E80; // [not in actual code, SegPos is relative to ENV0BUF here] CurECB[ECBPTRL] = (SegPos & 0x00FF) >> 0; CurECB[ECBPTRH] = (SegPos & 0xFF00) >> 8; // [fall through to envseg] } } else // no - process segment { SegCntr = CurECB[ECBCTR] - 1; } if (TestRes) // [need to check that, since envdone skips envseg] { //envseg: CurPB = &PBTBL[CurECB[ECBCHAN] & ~0x20]; // ptr to this channel's pitchbend entries [RES #5] CurECB[ECBCTR] = SegCntr; SegVal = (CurPB[PBEBH] << 8) | (CurPB[PBEBL] << 0); SegVal += (CurECB[ECBDELH] << 8) | (CurECB[ECBDELL] << 0); CurPB[PBEBL] = (SegVal & 0x00FF) >> 0; CurPB[PBEBH] = (SegVal & 0xFF00) >> 8; // [fall through to envneedupd] } else { //envdone: CurPB = &PBTBL[CurECB[ECBCHAN] & ~0x20]; // ptr to this channel's pitchbend entries [RES #5] CurPB[PBEBL] = 0; // zero the envelope bend on this channel CurPB[PBEBH] = 0; CurECB[ECBCHAN] = 0x40; // shut off this envelope //jr envneedupd } //envneedupd: CurPB[PBRETRIG] |= 0x01; // [SET #0] NEEDBEND = 1; //jr envnext } } //envnext: // nope - loop CurECB ++; } return; } Добавлено (12.10.2016, 20:22) --------------------------------------------- досовский графики чот не рисует никакие... там глюки для модуляции. мож я не то чо скачал... но глючно однако.
Код * * Modulator Offset Table *
dc.b $02,$00 ; Offset to modulator #0: 2 * * Modulator Data *
* Modulator 0 "NEW": Pitch dc.b $0B,$00 ; initial value = 11 dc.b $21,$2C,$00 ; len = 33, slope = 44 dc.b 0
и как ожидалось файл он мне не родит... это должно выглядеть типа как: 00 00 0B 00 21 00 2C 00 три значения по два байта? хотя там в досовском редакторе было какое-то четвертое, куда я 22 вбивал - но тут чот её ненаблюдается...Добавлено (12.10.2016, 20:58) --------------------------------------------- неа. по 2 байта не клеится. в дюнавских модуляциях файлы кратно 3. и есть файл 6 байт. два первых нуля - видимо название там скрывается текстовое, потом три байта данных по байту видимо и в конце нуль.
|
|
| |
r57shell | Дата: Четверг, 13.10.2016, 03:27 | Сообщение # 134 |
Сообщений: 632 Статус: Offline
| Цитата SeregaZ ( ) и если 12 это до, то кто сказал что 13 это ре? Именно 13 до диез и должен быть. Я просто оговорился. 12.5 должен быть что-то между до и до диез.
Цитата SeregaZ ( ) тогда 12 + питч 128 = 13. На сколько я помню, должно быть 12.5
Цитата SeregaZ ( ) про модуляцию видимо вот эта часть: В коде z80 она именно DOENVELOPE обозначена.
Цитата SeregaZ ( ) досовский графики чот не рисует никакие...
Цитата r57shell ( ) Берёшь качаешь dosbox любой, потом надо положить в некоторую папку GEMS.EXE и в ту же папку положить EGAVGA.BGI. Может там ещё надо остальные файлы которые идут с GEMS.EXE
Цитата SeregaZ ( ) неа. по 2 байта не клеится. Посмотрел. Теперь инфа 100%: Первые два байта - изначальный питч. Затем по 3 байта: счётчик (1 байт), скорость (дельта) питча (2 байта). У последних "трёх" байт первый байт - нуль, поэтому остальные 2 байта из трёх не пишутся.
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Воскресенье, 16.10.2016, 01:02 | Сообщение # 135 |
Сообщений: 50 Статус: Offline
| проглядел я это упоминание файла... сижу и думаю чото у меня не то :) из 2.5 взял в 2.8 засунул. там и текст в кнопки вмещаться стал и вообще красота с графиком появилась. что-то стало прояснятся :) и дос бокс по моему не обязателен. точнее видимо надо сказать для ХР не обязателен.
в дос геймсе тогда параметры означают: Initial Level - это те два первых нуля, которые начальный питч Current Segment - номер блока из трех байт Duration - счетчик? и судя по описанию 1 единица в нем равна 1/24, то есть выходит по длительности это delay 1. Slope - эта самая дельта? если так, то вроде бы понятно... и по моему даже что-то в голове вырисовывается как это играть :)Добавлено (15.10.2016, 05:18) --------------------------------------------- вроде более менее ясно.
1. применение
Код modulation modulation_03 delay 0 duration 50 delay 50 note $13 note $30 note $13 модуляция действительна для первой, идущей после объявления этой модуляции, ноты. последующая - вторая нота уже без модуляции играет. хотя я думал эта модуляция для всех нот фигачит, пока не будет отключена - ибо видел где-то фрагмент, что модуляция была, шла пара тройка нот, и появлялась другая модуляция где просто 3 байта и все 3 нулями забиты. что несколько странно. изначально то я думал что она отключает модуляцию, но если модуляция работает только для одной единственной ноты - зачем тогда отключать? она ж по идее сама по себе и отключает как эта нота закончится... но зачем-то еще приписана эта нулевая модуляция. как-то это странновато :)
2. содержание файла модуляции
00 00 - стартовый питч
19 - количество delay 1 - сколько по времени это безобразие будет повторятся 10 01 - значение питч, которое следует прибавлять к регистрам А4 А0 через каждый delay 1 пока не истечет то значение длительности или пока нота не закончится. 00 - пошел следующий блок из 3 байт, но поскольку счетчик равен 0 - значит модуляция заканчивается, а последующие 2 байта из блока просто не рисуются. судя по примеру выше длительность ноты duration 50. а длинна безобразия $19 то есть 25. получается половина ноты играет все время повышаясь по частоте, а вторая половина - грубо возвращается на оригинальную частоту первоначальной ноты и нота доигрывается в оригинальном звучании.
так поведение ноты можно выставлять этими блоками по 3 байта, то есть можно такую загогулину на графике нарисовать, что мама не горюй :)
3. в чем суть можно обойтись и без этой модуляции, тогда код выглядел бы примерно так:
Код duration 50 delay 1 note $13 delay 1 pitch $0110 delay 1 pitch $0220 delay 1 pitch $0330 ...
и это весь код шел бы только к одной ноте, причем это только верхушка айсберга. и в результате объем песни был бы километровым. так что модуляция содержит в себе план поведения ноты, без необходимости таких больших портянок - экономит место в роме.Добавлено (16.10.2016, 01:02) --------------------------------------------- кароче рано радовался :) затык один еще надо будет придумать как учитывать. когда меняется октава - то сложение питча работает уже не корректно. нужно будет все переделывать и пересчитывать ноту, что типа если стартовая нота + питч = той же октаве, то считать как есть. если октава сменилась, изменить стартовую ноту на До последующей октавы, пересчитать значение питча сминусовав сколько-то там лишнее осталось от предыдущего шага, и в дальнейшем прибавлять новые питчи уже к этому значению "до+остаток", а не к старой оригинальной ноте. и опять таки пока не изменится октава.
поубивал бы этих сегамегадрайверных создателей :)))) нафига козе боян с такими сложностями блин... так было просто тупо прибавлять значение питча через каждый делей 1, но неееет - надо было им добавить сложности с октавой блин :)
|
|
| |
r57shell | Дата: Воскресенье, 16.10.2016, 07:51 | Сообщение # 136 |
Сообщений: 632 Статус: Offline
| Цитата SeregaZ ( ) поубивал бы этих сегамегадрайверных создателей :)))) нафига козе боян с такими сложностями блин... так было просто тупо прибавлять значение питча через каждый делей 1, но неееет - надо было им добавить сложности с октавой блин :) Не знаю ничего, посмотрел в код, там хоть все 96 нот питчем/модуляцией тяни.
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Воскресенье, 16.10.2016, 22:31 | Сообщение # 137 |
Сообщений: 50 Статус: Offline
| не не :) там между октавами промежуток больше, как если бы к регистрам прибавлялось конвертированное значение питч. в итоге мой слайд играет не так, как гемский слайд. надо в функцию добавить четкое разделение по октавам. типа: начало до - 128 питч, конец си + 128 питч. и в случае когда нота + сумма питчей превышает эту си + 128, то делать перерасчет и остаток переносить в новую октаву к до - 128.
первое значение регистры А4А0, второе питч
у меня: $0BC5 0 $0C02 272 $0C43 544 $0C88 816 $0CD1 1088 $0D1F 1360 $0D72 1632
правильно: $0BC5 0 $0C01 272 $0C43 544 $0C87 816 $0CD1 1088 $128F 1360 <--- поменялась октава $12B9 1632
вот эту лабуду надо будет учитывать.Добавлено (16.10.2016, 22:02) --------------------------------------------- горд до усрачки :))))
Код Procedure.i GetOPNNote(Note.i, Pitch.w) Protected.d FreqHz, CurNote, PitchCoef Protected.i BlkNum, FNum, CurBlkNum PitchCoef = Pitch / 256 If PitchCoef < 1 And PitchCoef > -1 If PitchCoef < 0 And (Note = 12 Or Note = 24 Or Note = 36 Or Note = 48 Or Note = 60 Or Note = 72 Or Note = 84) Note = Note - 1 Pitch = 256 + Pitch ;(Pitch is a - value, so 256 + Pitch means 256 - Pitch) ret = GetOPNNote(Note, Pitch) Else CurNote = Note + Pitch / 256 FreqHz = 440 * Pow(2, (CurNote - 69) / 12) BlkNum = Note / 12 - 1 ; octave without pitch
If BlkNum < 0 BlkNum = 0 ElseIf BlkNum > 7 BlkNum = 7 EndIf FNum = Round((144 * FreqHz / 7670454) * Pow(2, 21 - BlkNum), #PB_Round_Nearest) If FNum < 0 FNum = 0 EndIf ;count main value ret = FNum + (BlkNum * $800) EndIf Else Note + Pitch / 256 Pitch - (Int(Pitch / 256) * 256) ret = GetOPNNote(Note, Pitch) EndIf ;set gems limit If ret > $3CBF ret = $3CBF ElseIf ret < $0142 ret = $0142 EndIf ProcedureReturn ret
EndProcedure
правда то разночтение $0C02 272 = $0C01 272 так и осталось :) пойду еще с буржуйским товарищем проконсультируюсь, мож подскажет где косяк с этой единичкой.
и кстати получается 95 нота это не лимит. ей можно питч прикрутить, тогда она еще выше подняться может.Добавлено (16.10.2016, 22:22) --------------------------------------------- и до -128 питч мысль не правильная. си +255 правильно, при си +256 надо переходить на дошные значения, а не прибавлять к си 256. то есть кароче до -1 это си + 255. уж извиняюсь за свой деревенский - французским не владею :) объясняю как сам понял. Добавлено (16.10.2016, 22:26) --------------------------------------------- аааааааааа вот она :))))) попалась стерва!
Код FNum = Round((144 * FreqHz / 7670454) * Pow(2, 21 - BlkNum), #PB_Round_Down);#PB_Round_Nearest) округлять вниз надо, тогда как в эмуляторе :))) лай ла ла ла лаДобавлено (16.10.2016, 22:31) --------------------------------------------- а нифига... теперь в других местах косяки полезли. значит округлять надо через мою хитрую процедуру со второго знака, встроенный видимо округляет по первому знаку. вспомнить теперь только надо где она...
|
|
| |
r57shell | Дата: Понедельник, 17.10.2016, 20:41 | Сообщение # 138 |
Сообщений: 632 Статус: Offline
| Слишком много ифов. Немножко теории: B регистр пихается степень двойки (Blocknum) и мультипликатор, так что из значения регистра в частоту считается просто: (2^Block) * FNum * C Где C это константа некоторая (скорость ямахи) Теперь, что касается музыки: частота = 2^( нота / 12 ) * C, а питч это просто дробная часть ноты, а C задаёт смещение нумерации нот. То есть, получается частота = 2^( (нота_целая_часть + нота_дробная_часть) / 12) * C = 2^( нота_целая_часть / 12 + нота_дробная_часть / 12) * C 2^( нота_целая_часть / 12) * 2^( нота_дробная_часть / 12) * C 2^( (октава * 12 + нота_внутри_октавы ) / 12 ) * 2^( нота_дробная_часть / 12) * C 2^октава * 2^( нота_внутри_октавы / 12 ) * 2^( нота_дробная_часть / 12) * C Cравниваем с (2^Block) * FNum * C получаем, что Block = нота / 12 = октава. Осталось FNum = 2^( нота_внутри_октавы / 12 ) * 2^( нота_дробная_часть / 12) * С/C Где C/C - отношение констант (масштабов). Но так как в z80 особо не повычисляешь, поэтому в гемсе забита таблица: table[нота] = 2^( нота_внутри_октавы / 12 ) * C/C И тогда надо ещё 2^( нота_дробная_часть / 12). Но возвести в дробную степень сложно. А тут получается 2^(0) диапазон 2^(1/12), то есть от 1 до 1.06. Но так как оно должно лежать между table[нота] и table[нота+1], сделано просто интерполяция между ними: FNum = table[нота] + (table[нота+1]-table[нота]) * нота_дробная часть.
Короче если хочешь получить FNum, Block как делает гемс, то просто:
Код GetFreq(note, pitch) { note_p = pitch / 256 pitch = pitch - note_p * 256 note = note + note_p if (note < 0) { pitch = 0; note = 0; } if (note > 95) { note = 95 pitch = 255 } Block = note / 12 note = note - Block * 12; a = table[note] b = table[note+1] FNum = a + ((b-a)*pitch)/256 } Такой псевдокод. Это всё целые деления (с округлением вниз).
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Понедельник, 17.10.2016, 22:22 | Сообщение # 139 |
Сообщений: 50 Статус: Offline
| в моем случае тогда можно еще оптимизировать:
Код if (note < 0) elseif (note > 95) endif
но не суть, все равно твоя система не совсем верная :) с 0 до $C - правильно (это я пока без питча), но потом нота $D = нота $0 почему-то. note = note - Block * 12 то есть получается в таблице должно быть всего 12 нот? и вокруг них все должно крутится? я думал таблица должна быть от 0 до $60 (точнее $5F + 256 питч) вот если снести эту note = note - Block * 12 - то вроде хорошо.
а второй момент - мои где много иф, а точнее где я все ноты До проверяю - это неспроста :) поскольку между Си и До гораздо бОльшее значение, нежели между До и Ре скажем или Ля и Си. вот с минусом например: моя процедура: GetOPNNote($18, -272) = $04BB твоя процедура: GetFreq($18, -272) = $0463 хотя я еще в гемсе не смотрел... чтоб точно знать какое должно быть правильное значение :)Добавлено (17.10.2016, 22:22) --------------------------------------------- таблица для чистоты эксперимента:
Код table[0] = $0142 table[1] = $0155 table[2] = $0169 table[3] = $017F table[4] = $0196 table[5] = $01AE table[6] = $01C7 table[7] = $01E2 table[8] = $01FF table[9] = $021D table[10] = $023E table[11] = $0260 table[12] = $0284 table[13] = $02AA table[14] = $02D3 table[15] = $02FE table[16] = $032B table[17] = $035B table[18] = $038E table[19] = $03C5 table[20] = $03FE table[21] = $043B table[22] = $047B table[23] = $04BF table[24] = $0A84 table[25] = $0AAA table[26] = $0AD3 table[27] = $0AFE table[28] = $0B2B table[29] = $0B5B table[30] = $0B8E table[31] = $0BC5 table[32] = $0BFE table[33] = $0C3B table[34] = $0C7B table[35] = $0CBF table[36] = $1284 table[37] = $12AA table[38] = $12D3 table[39] = $12FE table[40] = $132B table[41] = $135B table[42] = $138E table[43] = $13C5 table[44] = $13FE table[45] = $143B table[46] = $147B table[47] = $14BF table[48] = $1A84 table[49] = $1AAA table[50] = $1AD3 table[51] = $1AFE table[52] = $1B2B table[53] = $1B5B table[54] = $1B8E table[55] = $1BC5 table[56] = $1BFE table[57] = $1C3B table[58] = $1C7B table[59] = $1CBF table[60] = $2284 table[61] = $22AA table[62] = $22D3 table[63] = $22FE table[64] = $232B table[65] = $235B table[66] = $238E table[67] = $23C5 table[68] = $23FE table[69] = $243B table[70] = $247B table[71] = $24BF table[72] = $2A84 table[73] = $2AAA table[74] = $2AD3 table[75] = $2AFE table[76] = $2B2B table[77] = $2B5B table[78] = $2B8E table[79] = $2BC5 table[80] = $2BFE table[81] = $2C3B table[82] = $2C7B table[83] = $2CBF table[84] = $3284 table[85] = $32AA table[86] = $32D3 table[87] = $32FE table[88] = $332B table[89] = $335B table[90] = $338E table[91] = $33C5 table[92] = $33FE table[93] = $343B table[94] = $347B table[95] = $34BF table[96] = $3A84
|
|
| |
r57shell | Дата: Понедельник, 17.10.2016, 22:42 | Сообщение # 140 |
Сообщений: 632 Статус: Offline
| Цитата SeregaZ ( ) то есть получается в таблице должно быть всего 12 нот? 13, так как используется 11+1 (следующая после Си)
Цитата SeregaZ ( ) вот с минусом например: Я гемс описал, как я сказал, нет возможности питчи считать точно. Потому сделан такой финт. А вообще, тогда всё просто, нужно просто table [note]* pow(2, pitch/(256*12)); Но сделано не так. Таблица гемса это 12-23 значения в твоей таблице, и 12-е 1288, или $508.
добавь в код после деления на 256 такое:
Код if (pitch < 0) { note_p = note_p - 1; pitch = pitch + 256; } Это надо чтобы питч был всегда положительным
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Понедельник, 17.10.2016, 23:28 | Сообщение # 141 |
Сообщений: 50 Статус: Offline
| но вдруг питч будет гораааздо больше чем 256? -1000 например :) тогда надо рипит запускать:
Код if (pitch < 0) repeat note_p = note_p - 1; pitch = pitch + 256; until pitch >= 0
Сообщение отредактировал SeregaZ - Понедельник, 17.10.2016, 23:29 |
|
| |
r57shell | Дата: Понедельник, 17.10.2016, 23:42 | Сообщение # 142 |
Сообщений: 632 Статус: Offline
| Там одного раза достаточно, из-за предыдущей манипуляции.
Примеры: GETFREQ( $20, $1234) = $22DB GETFREQ( $20, -$1234) = $0ACA Должно так получатся.
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Вторник, 18.10.2016, 23:50 | Сообщение # 143 |
Сообщений: 50 Статус: Offline
| что-то у меня не выходит. где-то я что-то пропустил. разве не должно быть какого-то умножения на октаву, после того как получено значение? а то опять таки повторюсь до 12 нот нормально, после они повторяются, хотя октава уже уехала. моя процедура так и показывает, как ты пример привел $22DB и $0ACA. это видимо не то сочетание параметров, где у меня ошибка на единицу :) но твою чот не вышло нифига запустить $02DB показывает - октава не учтена.
Код Global Dim table(12)
table(0) = $0284 table(1) = $02AA table(2) = $02D3 table(3) = $02FE table(4) = $032B table(5) = $035B table(6) = $038E table(7) = $03C5 table(8) = $03FE table(9) = $043B table(10) = $047B table(11) = $04BF table(12) = $0508
Procedure.i GetFreq(note.i, pitch.w) note_p = pitch / 256 If pitch < 0 note_p = note_p - 1; pitch = pitch + 256; EndIf pitch = pitch - note_p * 256 note = note + note_p If note < 0 pitch = 0; note = 0 ; ElseIf note > 95 note = 95 pitch = 255 EndIf Block = note / 12 note = note - Block * 12; a = table(note) b = table(note+1) FNum = a + ((b-a)*pitch)/256 ProcedureReturn FNum EndProcedure
Note = $20 Pitch.w = $1234 Debug RSet(Hex( GetFreq(Note, Pitch)), 4, "0") ; показыает как 02DB вместо 22DB
Добавлено (18.10.2016, 05:50) ---------------------------------------------
Код FNum = a + ((b-a)*pitch)/256 + Block * 2048 мож так? :)))) правда с минусом не то...Добавлено (18.10.2016, 05:59) --------------------------------------------- видимо нетуда я куда-то вот это вставил раз он с минусом не правильно считает:
Код if (pitch < 0) { note_p = note_p - 1; pitch = pitch + 256; } Добавлено (18.10.2016, 06:05) --------------------------------------------- вообще убрал этот момент, как ты изначально код предложил то теперь показывает как $0ACB та $20 нота и питч $1234, а должна $0ACA Добавлено (18.10.2016, 06:12) --------------------------------------------- хотя если спустить чуть ниже, то вроде получается нормально :) ни после деления, а после умножения на 256.
Код Procedure.i GetFreq(note.i, pitch.w) note_p = pitch / 256 pitch = pitch - note_p * 256 If pitch < 0 note_p = note_p - 1; pitch = pitch + 256; EndIf note = note + note_p If note < 0 pitch = 0; note = 0 ; ElseIf note > 95 note = 95 pitch = 255 EndIf Block = note / 12 note = note - Block * 12; a = table(note) b = table(note+1) FNum = a + ((b-a)*pitch)/256 + Block * 2048 ProcedureReturn FNum EndProcedure Добавлено (18.10.2016, 23:50) --------------------------------------------- так... 1. определение частоты и питча - есть (хотя у меня есть одна теория, которая по идее сломает правильность работы этой функции) 2. выставление инструмента в регистры - есть 3. контроль громкости - есть. (берем значение громкости из code файла, прибавляем 6, а после прибавляем это значение к тем операторам, которые соответствуют алгоритму, учитывая что 2 это на самом деле 3. но такое правило нужно только для алгоритма под номером 4, где 2 и 4 операторы используются, то есть 3 и 4 по очередности) 4. модуляция - есть
PSG часть. как объяснял ValleyBell процедура звука выглядит так:
Цитата It goes "Key On": 1. Attack Phase [volume up with Attack Rate until Attack Level], 2. Decay Phase [volume down with Decay Rate until Sustain Level], 3. Sustain Phase [volume down with SustainRate until 0] actually... no, the Sustain Rate is fixed to 0 in GEMS, so the volume stays at its level there.
Anywhere in this, a "Key Off" breaks into the 4. Release Phase [volume down with Release Rate until 0]
with "volume 0" I mean "silence" here, so for the PSG it's actually value $F
могу я надеятся, что все это безобразие расписано по отношению к 1 единичке времени, как delay 1? то есть по той-же схеме что модуляция работает? например Attack Level - я бы сказал что это кратковременная максимальная громкость ноты - равняется 10, а Attack Rate = 5, то тогда график должен строится типа такого: delay 1, громкость = 0, delay 1, громкость = 5, delay 1, громкость 10...
|
|
| |
r57shell | Дата: Среда, 19.10.2016, 03:50 | Сообщение # 144 |
Сообщений: 632 Статус: Offline
| Главное ты разобрался. Конечно же, я просто указал как посчитать Block и FNum - это два параметра, а как их упихать - сам. По поводу неточности в ACA - ты видать округляешь где-то не правильно. PSG от темпа не зависит, поэтому оно от 60 герц. То есть, один тик - 1/60 секунды (примерно, всё зависит от частоты экрана). Громкость там через умножение, и на PSG/DAC не влияет. И глобальное складывается с локальным.
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Четверг, 20.10.2016, 22:59 | Сообщение # 145 |
Сообщений: 50 Статус: Offline
| дошла очередь до PSG инструментов. так надеялся что там единичка времени для работы это delay 1, но вышло как ты сказал 1/60 секунды... то есть для PSG придется отдельный тред делать, где будет происходить расчет громкости для ноты согласно плану - инструменту.
вот стал смотреть в DOS версии, и сравнивать с результатами что выдает эмулятор. вначале разбираюсь вот с Attack Rate, это как бы первый параметр который используется. это получается как бы скорость взлета ноты от тишины - 15 до того значения, которое указано будет в Attack Level. значения могут быть от 0 до $1F(31), и $FF - 32 значение, там нет разгона и сразу выдает максимальную громкость. получается от 0 до 31 там у каждого значения своя таблица. например максимальная громкость 0 и тогда:
Код $1F - 31 - 14, 12, 10, 8, 6 4 2 0 0 $1B - 27 - 14, 12, 10, 9, 7, 5, 4, 2, 0, 0 $0A - 10 - 15, 14, 14, 13, 12, 12, 11, 10, 10, 9, 9, 8, 7, 7, 6, 5, 5, 4, 4, 3, 2, 2, 1, 0, 0, 0 (между каждым значением получается пауза 1/60 секунды) нет ли формулы? или придется для каждого значения таблицу расписывать? и я так полагаю что остальные параметры типа релиз рейт - примерно такая-же история с таблицей с плавным или не плавным затуханием громкостей?
Сообщение отредактировал SeregaZ - Четверг, 20.10.2016, 23:01 |
|
| |
r57shell | Дата: Пятница, 21.10.2016, 02:38 | Сообщение # 146 |
Сообщений: 632 Статус: Offline
| Начнём с того, что у PSG всего 16 уровней от 0 до F, и F - тишина. Для "пущей" плавности, и так как есть место, в гемсе хранится громкость от 00 до $FF то есть от 0 до 255. И старшие биты посылаются в PSG то есть 0 - громко, FF - тихо. Значения скоростей - все прибавляются/убавляются раз в 1/60. Например начиная с keyon, сначала FF потом убавление по attack_rate, потому что чем меньше - тем громче звук. Напоминаю, если сильно хотеть, можно такое настроить: https://www.youtube.com/watch?v=hDXsRWKaqGw
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Пятница, 21.10.2016, 03:58 | Сообщение # 147 |
Сообщений: 50 Статус: Offline
| ну значит таблицы вручную :) и согласно тестам получается для PSG лимит еще меньше, чем для FM. там не с 0 ноты начинается, с а 22 чтоль... от 0 до 21 там одно и то-же значение для ноты. и с питчем там не очень поиграешь. если низкие ноты там еще худо бедно между нотами есть куда развернутся, то на высоких нотах ступенек между нотами совсем мало. и я то не чисто гемс делаю, а на основе code файлов, что твой сплиттер делает и потом комбайн использует. у меня пока играет как дорожки идут по порядку - так и играет каждая дорожка в своем канале. до момента, где динамически каналы забиваются нотами и играют я еще не дошел :) там только как представлю... так сразу плохо становится. так что пока инструменты для PSG решил доделать - эта часть попроще будет. значения нот в таблицу уже вывел. теперь громкости для Attack Rate в таблицы внесу, после буду смотреть те два других рейта как там обстоит это формирование громкости во времени. но в целом пока вроде понятно. просто думал мож формулы готовые есть, чтоб не городить эти таблицы вручную...
|
|
| |
r57shell | Дата: Пятница, 21.10.2016, 04:11 | Сообщение # 148 |
Сообщений: 632 Статус: Offline
| Так я указал формулы, сложение и вычитание.
Мальчик, девочка... какая в жопу разница..
|
|
| |
SeregaZ | Дата: Пятница, 21.10.2016, 20:08 | Сообщение # 149 |
Сообщений: 50 Статус: Offline
| ну судя по тестам, то формула примерно такая: 256 / (attack rate * 15) и потом повторять это количество каждую громкость, перенося остаток на следующую: 256 / (10 * 15) = 1.7 1 раз 15, 0.7 + 1.7 = 2.4 2 раза 14, 0.4 + 1.7 = 2 раза 13 (хотя в оригинале там 1 раз 13)
не 100% точно, но думаю сойдет в качестве формула расчета :)
|
|
| |
r57shell | Дата: Суббота, 22.10.2016, 00:12 | Сообщение # 150 |
Сообщений: 632 Статус: Offline
| Не, фигню какую-то ты пишешь. Должно быть
Код function init() { level = $FF; } function update() { level = level + rate(state); // скорость функция от состояния. ... проверки на смену состояния (после атаки декей, потом сустейн, потом когда key off - релиз setchannelvolume(channel, level/16); }
Мальчик, девочка... какая в жопу разница..
|
|
| |
|