VGM structure by simple words (noob's investigation)
Technical discussion which is not directly related to VGM files. Talk about Hardware and Software.
Moderator: Staff
yes, it just give one smd proccesor, even no second - noise sound cpu. but for my case no need full vgm features, just sega's 2612. i want to make converter from any vgm sega music to gems. now it just gems game to gems game compatibility... (you can see it in dune, where play battletech song, Jim, Comixzone and other gems song, but awesome music for example Rock n Roll Racing, or Alien 3 now cant used for it. so i want to try make it.)
so player part still not finish. i am not understand how to set ValleyBell OPN.dll play samples... not by PlayDACSample procedure, but cpu registers. what sequence of commands must be?
1. DAC Enable:
OPN_Write(0, $2B, $80)
2. cycle:
For i = addresofsample to addresofsample + samplesize
OPN_Write(0, $2A, ReadByte(i))
DelayMicroSeconds(45)
Next
but it get nothing. silence. if add before it some like this: OPN_Write(0, $28, $F0) - it get some scratch sound, but not sample data is correct, i am sure - becouse if i set this data to PlayDACSample it play fine. and my plan was use this PlayDACSample, but ValleyBell says it get some "wait" effect, so song will be play a little wrong. that is why i am already a few days kick my head on monitor for get info how to make this cpu play samples... i read a few times documentation http://www.smspower.org/maxim/Documents/YM2612#reg2b , but didnt understand what he want from me (((...
so player part still not finish. i am not understand how to set ValleyBell OPN.dll play samples... not by PlayDACSample procedure, but cpu registers. what sequence of commands must be?
1. DAC Enable:
OPN_Write(0, $2B, $80)
2. cycle:
For i = addresofsample to addresofsample + samplesize
OPN_Write(0, $2A, ReadByte(i))
DelayMicroSeconds(45)
Next
but it get nothing. silence. if add before it some like this: OPN_Write(0, $28, $F0) - it get some scratch sound, but not sample data is correct, i am sure - becouse if i set this data to PlayDACSample it play fine. and my plan was use this PlayDACSample, but ValleyBell says it get some "wait" effect, so song will be play a little wrong. that is why i am already a few days kick my head on monitor for get info how to make this cpu play samples... i read a few times documentation http://www.smspower.org/maxim/Documents/YM2612#reg2b , but didnt understand what he want from me (((...
again i am a little stuck... prelude:
this theory correct? so my question is why my case is works a conversely?
PlayDACSample(0, 10k, Adress, 6000) play fine
PlayDACSample(0, 10k, Adress, 10000) play is eat by middle
how it can be? by hear in winamp that sample definitly is 10k. 6k is too low sound. and 6k must be longer, but it plays fine. shorter 10k is eat.
it was manual setup of frequence as i hear. but it need to programm count frequence. so i make some collection of pauses and x8n command. then i need to count frequence. as far i remember:
filesize / frequence = time of playing song in secunds.
so frequence is:
filesize / time = frequence
i have only summ of pauses. but one pause it is... 1s/44100hz (44100 it is frequence of vgm files. it means in 1 sec vgm cycle make 44100 actions).
1s/44100 = 0.000 022 675736961
millisec microsec even i dont know what it is...
so summofpauses need to * 0.000022675736961
then we come to:
filesize / (summofpauses * 0.000022675736961) = frequence of sample
(i think i am as always some do is wrong... i am dumbass, remember? i hope some god father will say how to count it sure)
so my case value was 12 300 - sounds of sample is right, as winamp play, but it eat my samples!!!!1111oneone only 6 000 is nice, not eat, but is sounds much lower, than winamp do... so i am still "want to belive" and "truth is out there"...
this theory correct? so my question is why my case is works a conversely?
PlayDACSample(0, 10k, Adress, 6000) play fine
PlayDACSample(0, 10k, Adress, 10000) play is eat by middle
how it can be? by hear in winamp that sample definitly is 10k. 6k is too low sound. and 6k must be longer, but it plays fine. shorter 10k is eat.
it was manual setup of frequence as i hear. but it need to programm count frequence. so i make some collection of pauses and x8n command. then i need to count frequence. as far i remember:
filesize / frequence = time of playing song in secunds.
so frequence is:
filesize / time = frequence
i have only summ of pauses. but one pause it is... 1s/44100hz (44100 it is frequence of vgm files. it means in 1 sec vgm cycle make 44100 actions).
1s/44100 = 0.000 022 675736961
millisec microsec even i dont know what it is...
so summofpauses need to * 0.000022675736961
then we come to:
filesize / (summofpauses * 0.000022675736961) = frequence of sample
(i think i am as always some do is wrong... i am dumbass, remember? i hope some god father will say how to count it sure)
so my case value was 12 300 - sounds of sample is right, as winamp play, but it eat my samples!!!!1111oneone only 6 000 is nice, not eat, but is sounds much lower, than winamp do... so i am still "want to belive" and "truth is out there"...
and this stuped piano hiding in bushes was found:
in my case samples starts only after xE0 command. and plays, until x8n comes. but this place have DAC disabled and no new xE0 for start new sample. so my sample shutdown. but it is interesting - with 6k frequency it have no stop play is continue. but 10k is interrupt. maybe to much data is lost with 10k and PlayDACSample decides to turn off this concert...
it means need to monitoring this x8n more, and restart sounds sample after DAC disables... this 2A unsupport is killing me... so many problem...
in my case samples starts only after xE0 command. and plays, until x8n comes. but this place have DAC disabled and no new xE0 for start new sample. so my sample shutdown. but it is interesting - with 6k frequency it have no stop play is continue. but 10k is interrupt. maybe to much data is lost with 10k and PlayDACSample decides to turn off this concert...
it means need to monitoring this x8n more, and restart sounds sample after DAC disables... this 2A unsupport is killing me... so many problem...
as requared i make short code for illustration of it:
and attach exe file. lesson third snare! by VGM it is kick + snare doubled sample as one. but this second part PlayDac is eat. and eat when 10k or 12k. when 6k - no eat and PlayDac work fine. so it means PlayDac have some cache... with 10k PlayDac work very fast and this cache is ends. with 6k this cache not depleted and play is continue after DAC Disable and Enable.
ops... attach not want to sends.
https://www.dropbox.com/s/wbfg6bcsf94gzcc/demo.zip?dl=1
Code: Select all
Enumeration
#Window
#Play
#Play6000
EndEnumeration
DataSection
StartVGMFile:
IncludeBinary "E:\SHORT.vgm"
EndOfVGMFile:
EndDataSection
OPNhdll = OpenLibrary(0, "OPN_DLL.dll")
If OPNhdll
Prototype OpenDriver(int.i)
Prototype CloseDriver()
Prototype OPNWrite(int.i,int2.i,int3.i)
Prototype OPNPlayDACSample(chip.i, size.i, *Data, freq.i)
Global OpenOPNDriver.OpenDriver = GetFunction(0, "OpenOPNDriver")
Global CloseOPNDriver.CloseDriver = GetFunction(0, "CloseOPNDriver")
Global OPN_Write.OPNWrite = GetFunction(0, "OPN_Write")
Global PlayDACSample.OPNPlayDACSample = GetFunction(0, "PlayDACSample")
Else
;error
End
EndIf
Structure VGMFSt
type.i
reg.a
val.a
pause.u
samplenum.a
sampleadress.i
samplesize.i
summofpauses.i
EndStructure
Global Dim VGMARR.VGMFSt(0)
Global autofreq = 1
; shutdown sound procedure when track is done, or stop by button
Procedure EndOfPlay(sh.i)
OPN_Write(0, $2B, $00) ; Disable Dac
; probably RR param need to high level for shutdown
OPN_Write(0, $80 + sh, $0F)
OPN_Write(0, $81 + sh, $0F)
OPN_Write(0, $82 + sh, $0F)
OPN_Write(0, $84 + sh, $0F)
OPN_Write(0, $85 + sh, $0F)
OPN_Write(0, $86 + sh, $0F)
OPN_Write(0, $88 + sh, $0F)
OPN_Write(0, $89 + sh, $0F)
OPN_Write(0, $8A + sh, $0F)
OPN_Write(0, $8C + sh, $0F)
OPN_Write(0, $8D + sh, $0F)
OPN_Write(0, $8E + sh, $0F)
If sh = 0
OPN_Write(0, $28, $00) ; turn off
OPN_Write(0, $28, $01)
OPN_Write(0, $28, $02)
Else
OPN_Write(0, $28, $04)
OPN_Write(0, $28, $05)
OPN_Write(0, $28, $06)
EndIf
EndProcedure
; procedure work in another thread
Procedure ReadAndPlay(*Value)
;get vgm adress without head
ot = ?StartVGMFile + 64
do = ?EndOfVGMFile
; reset main array
Dim VGMARR(0)
Number.a = 0
WavAddres = 0
Arrayind = 0
samplecoordinates = -1
; cycle of reading
For i = ot To do
; Reads an ascii character (1 byte) from the specified memory address.
Number = PeekA(i)
Select Number
Case $67 ; wav data block adress
; Reads an integer (4 bytes in 32-bit executable, 8 bytes in 64-bit executable) number from the specified memory address.
WavDataSize = PeekI(i + 3)
; get this adress in mem
WavAddres = i + 7
; jump reads to end of wav data block
i + 6 + WavDataSize
Case $52
VGMARR(Arrayind)\type = 1
VGMARR(Arrayind)\reg = PeekA(i+1) ; get register
VGMARR(Arrayind)\val = PeekA(i+2) ; get value of register
; temporaly make ignore $2A. maybe somewhen i fix it to right
If VGMARR(Arrayind)\reg <> $2A
Arrayind + 1
ReDim VGMARR(Arrayind) ; +1 to array size
EndIf
i+2 ; make jump to next pointer
Case $53
VGMARR(Arrayind)\type = 2
VGMARR(Arrayind)\reg = PeekA(i+1)
VGMARR(Arrayind)\val = PeekA(i+2)
Arrayind + 1
ReDim VGMARR(Arrayind)
i+2
Case $61 ; $61 - can range from 0 to 65535 (approx 1.49 seconds)
VGMARR(Arrayind)\type = 3
VGMARR(Arrayind)\pause = PeekU(i + 1)
; it is not very correct... but if i will have working $2A - it will no need this.
If flagpausehunt
VGMARR(numforsizecount)\summofpauses + VGMARR(Arrayind)\pause
flagpausehunt = 0
EndIf
Arrayind + 1
ReDim VGMARR(Arrayind)
i+2
Case $70 To $7F ; wait n+1 samples, n can range from 0 to 15.
VGMARR(Arrayind)\type = 3
VGMARR(Arrayind)\pause = ((Number - $70) + 1)
If flagpausehunt
VGMARR(numforsizecount)\summofpauses + VGMARR(Arrayind)\pause
flagpausehunt = 0
EndIf
Arrayind + 1
ReDim VGMARR(Arrayind)
Case $E0 ; 0xE0 dddddddd seek to offset dddddddd (Intel byte order) in PCM data bank
; prepear adress for next 0x8n
samplecoordinates = PeekI(i + 1)
samplecoordinates = WavAddres + samplecoordinates
; jump to next command
i + 4
Case $80 To $8F
If samplecoordinates > -1
VGMARR(Arrayind)\type = 4
VGMARR(Arrayind)\sampleadress = samplecoordinates
VGMARR(Arrayind)\summofpauses = 0
numforsizecount = Arrayind ; remember array position for count size and freq
Arrayind + 1
ReDim VGMARR(Arrayind)
samplecoordinates = -1 ; no need more, just for once work per sample
EndIf
; start collect size per each 0x8n
VGMARR(numforsizecount)\samplesize = VGMARR(numforsizecount)\samplesize + 1
flagpausehunt = 1 ; flag for start collect pauses too
; get n - as pause, and remember it, if exists
If Number > $80
VGMARR(Arrayind)\type = 3
VGMARR(Arrayind)\pause = (Number - $80)
VGMARR(numforsizecount)\summofpauses + VGMARR(Arrayind)\pause
Arrayind + 1
ReDim VGMARR(Arrayind)
EndIf
Case $4F ; 0x4F dd Game Gear PSG stereo, write dd to port 0x06 ; dune with samples
; ignore until ValleyBell add support SN76489/SN76496 to OPN.dll :)))))))
i + 1
Case $50 ; 0x50 dd PSG (SN76489/SN76496) write value dd ; dune with samples
; again ignore and jump far
i + 1
Case $62 ; wait 735 samples (60th of a second), a shortcut for 0x61 0xdf 0x02 ; Lego Tune
VGMARR(Arrayind)\type = 3
VGMARR(Arrayind)\pause = 735
If flagpausehunt
VGMARR(numforsizecount)\summofpauses + VGMARR(Arrayind)\pause
flagpausehunt = 0
EndIf
Arrayind + 1
ReDim VGMARR(Arrayind)
Case $63 ; wait 882 samples (50th of a second), a shortcut For 0x61 0x72 0x03
VGMARR(Arrayind)\type = 3
VGMARR(Arrayind)\pause = 882
If flagpausehunt
VGMARR(numforsizecount)\summofpauses + VGMARR(Arrayind)\pause
flagpausehunt = 0
EndIf
Arrayind + 1
ReDim VGMARR(Arrayind)
Case $66 ; end of sound
Break
EndSelect
Next
; it is for organization of pauses less, than millisec
PlayedTicks.i = 0
PlayedUS.i = 0
CurrentUS.i = 0
StartMS.i = ElapsedMilliseconds()
; cycle of playing
For i = 0 To ArraySize(VGMARR())-1
Select VGMARR(i)\type
Case 1
OPN_Write(0, VGMARR(i)\reg, VGMARR(i)\val)
Case 2
; probably cpu have some command with $53, but no need +256... now i set for all +256
tmp = VGMARR(i)\reg+256
OPN_Write(0, tmp, VGMARR(i)\val)
Case 3
; that cursed pause...
PlayedTicks + VGMARR(i)\pause
PlayedUS = PlayedTicks * 22.675736961 ;(this 22 - As 1s/44100hz. and 22 it means microsec)
While (CurrentUS < PlayedUS)
Delay(1)
CurrentUS.i = (ElapsedMilliseconds() - StartMS) * 1000
Wend
Case 4
If autofreq = 1
; count frequency
freq = VGMARR(i)\samplesize / (VGMARR(i)\summofpauses * 0.000022675736961)
PlayDACSample(0, VGMARR(i)\samplesize, VGMARR(i)\sampleadress, freq)
Else
PlayDACSample(0, VGMARR(i)\samplesize, VGMARR(i)\sampleadress, 6000)
EndIf
EndSelect
Next
; shutdown of sound
EndOfPlay(0)
EndOfPlay(256)
; enable plays button
DisableGadget(#Play, 0)
DisableGadget(#Play6000, 0)
EndProcedure
OpenOPNDriver(1)
If OpenWindow(#Window, 100, 100, 300, 100, "play", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
ButtonGadget(#Play, 10, 10, 200, 30, "play auto freq")
ButtonGadget(#Play6000, 10, 50, 200, 30, "play 6k freq")
OPN_Write(0, $2B, $80)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #Play
DisableGadget(#Play, 1) ; disable for avoid double press button
DisableGadget(#Play6000, 1)
autofreq = 1
CreateThread(@ReadAndPlay(), 1)
Case #Play6000
DisableGadget(#Play, 1)
DisableGadget(#Play6000, 1)
autofreq = 0
CreateThread(@ReadAndPlay(), 1)
EndSelect
Case #PB_Event_CloseWindow
stopflag = 1
Quit = 1
EndSelect
Until Quit = 1
CloseOPNDriver()
CloseLibrary(0)
EndIf
ops... attach not want to sends.
https://www.dropbox.com/s/wbfg6bcsf94gzcc/demo.zip?dl=1
solution still "is out there" who is C-programmer? any idea what need fix in this code for avoid that sample eating on middle? as ValleyBell say DAC Disable command must just make silence for PlayDACSample, not stop. but practice shows it is stops.
what for this MulDivRoundU(0x10000, TempDAC->Frequency, SampleRate) - 0x10000 - it is can be cach? what will happen if this param set to bigger value? and i thought this function must have For cycle some like this:
For i = 0 to samplesize
OPN_Write(0, $2A, ReadByte(adressofsample+i))
Pause(22microsec)
Next
flowchart
Code: Select all
#define MulDivRoundU(Mul1, Mul2, Div) (UINT32)( ((UINT64)Mul1 * Mul2 + Div / 2) / Div)
void OPNAPI PlayDACSample(UINT8 ChipID, UINT32 DataSize, const UINT8* Data, UINT32 SmplFreq)
{
DAC_STATE* TempDAC;
if (ChipID >= OPN_CHIPS)
return;
EnterCriticalSection(&write_sect);
TempDAC = &DACState[ChipID];
TempDAC->DataSize = DataSize;
TempDAC->Data = Data;
if (SmplFreq)
TempDAC->Frequency = SmplFreq;
TempDAC->Delta = MulDivRoundU(0x10000, TempDAC->Frequency, SampleRate);
TempDAC->SmplPos = 0x00;
// Resume Stream
NullSamples = 0;
PauseStream(false);
LeaveCriticalSection(&write_sect);
return;
}
For i = 0 to samplesize
OPN_Write(0, $2A, ReadByte(adressofsample+i))
Pause(22microsec)
Next
flowchart
- ValleyBell Offline
- Posts: 4784
- Joined: 2011-12-01, 20:20:07
- Location: Germany
For reference, I posted DACTest_OnOnly.vgz in IRC to allow you to bug-test your player.
If I inject the VGM into the player, everything plays at the wrong frequency due to a bug in the sample detection. (And this is the main problem, no matter what you think. Fix this and everything else will magically work.)
Bonus: DACTest_OnOff.vgz - same file, but the DAC is disabled after the last data byte (every the sound) is sent and enabled when it starts playing a new sound.
You should notice that the amount of time the DAC is not muted in the last VGM matches the time it takes to play a sound in Winamp.
The PlayDACSample function just streams the DAC data to the YM2612 chip at whatever frequency you tell it. It doesn't care about DAC enable/disable and will continue to stream even if the DAC is disabled/muted. (because that's what actual sound drivers would do)
Bonus 2: the SMPS file (Sonic 1 format) that I made and recorded above
If I inject the VGM into the player, everything plays at the wrong frequency due to a bug in the sample detection. (And this is the main problem, no matter what you think. Fix this and everything else will magically work.)
Bonus: DACTest_OnOff.vgz - same file, but the DAC is disabled after the last data byte (every the sound) is sent and enabled when it starts playing a new sound.
You should notice that the amount of time the DAC is not muted in the last VGM matches the time it takes to play a sound in Winamp.
The PlayDACSample function just streams the DAC data to the YM2612 chip at whatever frequency you tell it. It doesn't care about DAC enable/disable and will continue to stream even if the DAC is disabled/muted. (because that's what actual sound drivers would do)
Bonus 2: the SMPS file (Sonic 1 format) that I made and recorded above
resume:
SeregaZ_DACTest.vgm - wrong start time of samples, wrong frequency - plays slow, but play full length of sample - no eat and it is main thing.
SeregaZ_DACTest_OnOff.vgm - eat samples. a loooot of eat and probably wrong start time of this samples who was eat, but main thing - it is eat samples.
so my first problem is this eating. not wrong start play time, not frequency - becouse they wrong only for your test song and i can fix it... probably... for Alien it is even no need fix - it is ok and frequency and start play time. only eating is main problem.
as you can se Disable DAC is shutdown of sound, what was start by PlayDAC procedure. and it is not wrong staring time fault - because Alien have correct starting time of sample. it is PlayDAC procedure. and evedence of it - you can see stright line of silence. even it is a fault of wrong time - some of piece anyway must be seen on audio log. some part of sample anyway must be hear in place, where they have intersection - but none. it means it is not starting time problem. it is PlayDac procedure.
SeregaZ_DACTest.vgm - wrong start time of samples, wrong frequency - plays slow, but play full length of sample - no eat and it is main thing.
SeregaZ_DACTest_OnOff.vgm - eat samples. a loooot of eat and probably wrong start time of this samples who was eat, but main thing - it is eat samples.
so my first problem is this eating. not wrong start play time, not frequency - becouse they wrong only for your test song and i can fix it... probably... for Alien it is even no need fix - it is ok and frequency and start play time. only eating is main problem.
as you can se Disable DAC is shutdown of sound, what was start by PlayDAC procedure. and it is not wrong staring time fault - because Alien have correct starting time of sample. it is PlayDAC procedure. and evedence of it - you can see stright line of silence. even it is a fault of wrong time - some of piece anyway must be seen on audio log. some part of sample anyway must be hear in place, where they have intersection - but none. it means it is not starting time problem. it is PlayDac procedure.
my investigation desides to move sample-question into long box.
now i think time to start make table of register values for notes A0 and A4 for all notes. then, when i will get this value from vgm file - just check my table for get note value and then count of pitch. i think it will be problem to see difference where need to use pitch effect without stop note command, and where is stop note command and start new one. will see...
for vgm convert case (as you know gems have 1/24 note as minimum, vgm have almost no limit for size) i think will need two thread for process. one is read&play, second is a timer, that was make some tik in repeat and read register, what set vgm file. every tik = 1 delay for gems.
at the begin i think i will work only with nosamples vgm songs. it is more easy now then i will return to that my cursed of samples playing and new part - samples converting.
that is some demo: http://www.emu-land.net/forum/index.php ... ach=159838 rom for sega mega drive emulator. just press "A" for play pitch was made only ones, and wrong, it have 3 track, not 5 as original, no have loops, and it is eat last one note but anyway it is coooooool it is not vgm-2-gems, but by use a tonns of difference programm, but now time is come for making direct convert vgm-2-gems (oooops! vgm-2-code-2-gems )
by my plan it will be a path for making convert any vgm-smd songs from database to Dune (or another gems-using games)
now i think time to start make table of register values for notes A0 and A4 for all notes. then, when i will get this value from vgm file - just check my table for get note value and then count of pitch. i think it will be problem to see difference where need to use pitch effect without stop note command, and where is stop note command and start new one. will see...
for vgm convert case (as you know gems have 1/24 note as minimum, vgm have almost no limit for size) i think will need two thread for process. one is read&play, second is a timer, that was make some tik in repeat and read register, what set vgm file. every tik = 1 delay for gems.
at the begin i think i will work only with nosamples vgm songs. it is more easy now then i will return to that my cursed of samples playing and new part - samples converting.
that is some demo: http://www.emu-land.net/forum/index.php ... ach=159838 rom for sega mega drive emulator. just press "A" for play pitch was made only ones, and wrong, it have 3 track, not 5 as original, no have loops, and it is eat last one note but anyway it is coooooool it is not vgm-2-gems, but by use a tonns of difference programm, but now time is come for making direct convert vgm-2-gems (oooops! vgm-2-code-2-gems )
by my plan it will be a path for making convert any vgm-smd songs from database to Dune (or another gems-using games)
i am start rewrite whole project again and at begin i make some registers monitor. it is eat cpu, becouse it need to refresh 6 listicongadget. maybe later i find some solution for that.
and it have grafic monitor too. but same problem with cpu eating make this monitor not fine
i take another track. RRR song it too hard for my test. this slide... i hate this slide so i get some song without slide. but it have samples. probably i will need to get another song again. i need song without slide and without samples.
slide is a stuped system with pitch parameter - i am still not done that well.
samples - i have no idea yet how to get length in "delay" for gems.
then next small problem - when you choice channel - anothers channels still hear... a lower, but still hear. i will think about it too.
and i didnt plug function, that can count and export instruments from track. becouse, as you can see in sample-track, it have 6 channel for samples. A6+256 and A2+256 registers is 0, but LRAmFm is change per track a few times. so my system can think it is a few new instruments.
and one more - this track have some scratch before start. it is mistake of creators of vgm file of this song?
and it have grafic monitor too. but same problem with cpu eating make this monitor not fine
i take another track. RRR song it too hard for my test. this slide... i hate this slide so i get some song without slide. but it have samples. probably i will need to get another song again. i need song without slide and without samples.
slide is a stuped system with pitch parameter - i am still not done that well.
samples - i have no idea yet how to get length in "delay" for gems.
then next small problem - when you choice channel - anothers channels still hear... a lower, but still hear. i will think about it too.
and i didnt plug function, that can count and export instruments from track. becouse, as you can see in sample-track, it have 6 channel for samples. A6+256 and A2+256 registers is 0, but LRAmFm is change per track a few times. so my system can think it is a few new instruments.
and one more - this track have some scratch before start. it is mistake of creators of vgm file of this song?
- Attachments
-
- demo.zip
- pres load, and wait
- (165.63 KiB) Downloaded 274 times
full day i am fight with backconvert function idea was get $A4 and $A0 registers value and convert it into note and pitch values.
so by this simple convert you can see result as i check by GYM logs - GEMS set register same value as VGM do.
at the middle of song come asynchronously and it was only 2 channels from 6 original... but i am still work on it
(old attachment was delete, new one is a bottom:))
so by this simple convert you can see result as i check by GYM logs - GEMS set register same value as VGM do.
at the middle of song come asynchronously and it was only 2 channels from 6 original... but i am still work on it
(old attachment was delete, new one is a bottom:))
Last edited by SeregaZ on 2016-09-07, 22:03:49, edited 1 time in total.
so my investigation comes to much far i am already have:
correct instruments
correct volume
almost correct notes (i mean 100% same as VGM have. i just need to fill special table of values $A0 for 100%)
almost synchronously (this system probably i will need to remake - becouse now it no slide support)
so slides left and samples. and SN76489 (i have no any idea about this SN76489:)).
with samples i need in some re-sampling procedures for bass.dll. second day no hepl at bass.dll forum (( idea was make correct re-sample for samples, becouse my system count as 15-20k frequency for samples. i need 10.4k as max. i want to save as 15-20k sounds, but use 10.4 for it. no slow\low sound.
correct instruments
correct volume
almost correct notes (i mean 100% same as VGM have. i just need to fill special table of values $A0 for 100%)
almost synchronously (this system probably i will need to remake - becouse now it no slide support)
so slides left and samples. and SN76489 (i have no any idea about this SN76489:)).
with samples i need in some re-sampling procedures for bass.dll. second day no hepl at bass.dll forum (( idea was make correct re-sample for samples, becouse my system count as 15-20k frequency for samples. i need 10.4k as max. i want to save as 15-20k sounds, but use 10.4 for it. no slow\low sound.
- Attachments
-
- Player.zip
- synchronously + volume (both was made by 1 click:))
- (10.58 KiB) Downloaded 273 times
first wav support. but i will make second one - more smart. i mean will try it have too difficult algorithm. i mean user can hear 3 drums, but real it is one drum, with 3 different frequency. so i need to somehow explain for my programm what she must do it need some kind of borders for frequency.
https://www.youtube.com/watch?v=v81qVqbz8nY
https://www.youtube.com/watch?v=v81qVqbz8nY
i have this ValleyBell's function:
we convert it into my language for convert code file note values into registers. until now it work fine. but now i have problem with a pitches. it count uncorrect and have limit.
GetOPNNote($13+12, 1667) it shows $FFF. any higher pitch will return same $FFF. can this part of function be wrong?
i remove it, and add check at the end of function:
$34BF - it is 95 note - hieghest note of GEMS... ops... 95 + 12 probably... will need to test and change this limit but idea was correct?
if yes - limit is fixed. now uncorrect pitch counting:
GetOPNNote($13+12, 272) shows as $0C43, but GEMS with this 272 pitch shows as $0C01.
then i change this part code 128 to 256
GetOPNNote($13+12, 272) start shows $0C02 almost! this idea is correct?
Code: Select all
Private Function GetOPNNote(ByVal Note As Byte, ByVal Pitch As Integer) As Integer
Dim FreqHz As Double
Dim BlkNum As Integer
Dim FNum As Double
Dim CurNote As Double
CurNote = Note + Pitch / 128#
FreqHz = 440# * 2# ^ ((CurNote - 69) / 12#)
' must be Note, not CurNote, to avoid changing octaves
BlkNum = (Note \ 12) - 1
If BlkNum < &H0 Then
BlkNum = &H0
ElseIf BlkNum > &H7 Then
BlkNum = &H7
End If
'FNum = (144 * FreqHz * 2 ^ 20 / 7670454) / 2 ^ (BlkNum - 1)
FNum = (144 * FreqHz / 7670454) * 2 ^ (21 - BlkNum)
FNum = Int(FNum + 0.5)
If FNum < 0 Then
FNum = 0
ElseIf FNum > &H7FF Then
FNum = &H7FF
End If
GetOPNNote = FNum Or BlkNum * &H800
End Function
GetOPNNote($13+12, 1667) it shows $FFF. any higher pitch will return same $FFF. can this part of function be wrong?
Code: Select all
ElseIf FNum > &H7FF Then
FNum = &H7FF
End If
Code: Select all
ret = FNum | (BlkNum * $800)
If ret > $34BF
ret = $34BF
EndIf
ProcedureReturn ret
if yes - limit is fixed. now uncorrect pitch counting:
GetOPNNote($13+12, 272) shows as $0C43, but GEMS with this 272 pitch shows as $0C01.
then i change this part code 128 to 256
Code: Select all
CurNote = Note + Pitch / 256