Четверг, 19.10.2017, 21:47
Вы вошли как Гость | Группа "Гости" | RSS

.
 
 
Главная Регистрация Вход
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 5 из 6«123456»
Модератор форума: Nemesis_c 
Форум » Elektropage.ru » Other » GEMS sound driver research (копипаста с соникретро)
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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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 10 01 00

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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: 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


 
Сообщений: 631
Статус: Offline
 

Не, фигню какую-то ты пишешь. Должно быть

Код
function init()
{
  level = $FF;
}
function update()
{
  level = level + rate(state); // скорость функция от состояния.
  ... проверки на смену состояния (после атаки декей, потом сустейн, потом когда key off - релиз
  setchannelvolume(channel, level/16);
}


Мальчик, девочка... какая в жопу разница..
 
Форум » Elektropage.ru » Other » GEMS sound driver research (копипаста с соникретро)
Страница 5 из 6«123456»
Поиск:


Select language:
English
French
German
Portuguese
Chinese
Nemesis_c, r57shell, Smoke, Lipetsk, GoodBye (aka vfiuchcikicshuusrch) & Segaman © 2017
Хостинг от uCoz