Noob's investigation of VGM and DMF and SMD audio drivers
Re: Noob's investigation of VGM
I added the GGStereoWrite procedure to set what channel where to play.
If you want to try, update also the code part that takes care of the windows waveout since it renders stereo samples now.
If you want to try, update also the code part that takes care of the windows waveout since it renders stereo samples now.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
-
- Enthusiast
- Posts: 619
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Noob's investigation of VGM
and i am not get that - you are already make support for second chip? i need + 256 for second chip?2016-09-22 02:23:20 ValleyBell about PCM on the PSG - rarely anyone uses it
2016-09-22 02:23:59 ValleyBell and I don't think there is any game that combines music and PCM.
2016-09-22 02:24:19 ValleyBell i.e. you either get music on the PSG - *or* you get PCM voice samples
2016-09-22 02:25:11 ValleyBell (at least that's the case for Master System/Game Gear - MD games usually don't bother with PCM on the PSG at all due to the YM2612 DAC, but of course there is that one exception)
Code: Select all
Case $30 ; 0x50 dd PSG (SN76489/SN76496) write value dd ;
i + 1
PSGvalue = PeekA(i)
VGMARR(Arrayind)\type = 6
VGMARR(Arrayind)\val = PSGvalue + 256
Arrayind + 1
1 - chip bit
1111 - L side of 0, 1, 2, 3 channels
1111 - R side of 0, 1, 2, 3
same for write?
i make this + 256... bit it start sound some strange
i am go to eat something, then return and make this code with checkboxes for channels.
Re: Noob's investigation of VGM
Yes, that should work for both GGStereoWrite and Write (hopefully)SeregaZ wrote:and i am not get that - you are already make support for second chip? i need + 256 for second chip?
But you also have to enable the second chip if you want to use it by setting a clock value with bit 30 set, like this ...
Code: Select all
Clock($40000000 | 3579545)
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
-
- Enthusiast
- Posts: 619
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Noob's investigation of VGM
dont understand how to make this second chip work...
https://www.dropbox.com/s/wtf69je6goi1e ... t.zip?dl=1 (i attach zlib - stole code from one topic at this forum )
and i attach Rydeen.vgz - when you start song, it sound tone "tone tone tone", but original it is train "noise noise noise". when you wait until train sound will come - reopen that track, from this moment this starts "tone tone" is change into "noise" as they must be. i dont know where my mistake or not my? )))
and stereo command not full for window part - i mean now when you load song - it turnon all by default. VGM can turn off some channel, but window will still have switchers on checkbox - i am not go into stereo function and not make change for changing state of checkboxes functional.
https://www.dropbox.com/s/wtf69je6goi1e ... t.zip?dl=1 (i attach zlib - stole code from one topic at this forum )
and i attach Rydeen.vgz - when you start song, it sound tone "tone tone tone", but original it is train "noise noise noise". when you wait until train sound will come - reopen that track, from this moment this starts "tone tone" is change into "noise" as they must be. i dont know where my mistake or not my? )))
and stereo command not full for window part - i mean now when you load song - it turnon all by default. VGM can turn off some channel, but window will still have switchers on checkbox - i am not go into stereo function and not make change for changing state of checkboxes functional.
-
- Enthusiast
- Posts: 619
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Noob's investigation of VGM
one my mistake is captured
now channels is shutdown fine, but second chip play some wrong anyway. it have some gaps. probably that clock i set incorrect...
it was val.a - but need val.uStructure VGMFSt
type.i
reg.a
val.u...
now channels is shutdown fine, but second chip play some wrong anyway. it have some gaps. probably that clock i set incorrect...
Code: Select all
;Clock(3579545)
Clock($40000000 | 3579545)
Re: Noob's investigation of VGM
I think it has to do with the initial state of the chip. It was very hard to spot the problem. It might be fixed now (updated version).SeregaZ wrote:and i attach Rydeen.vgz - when you start song, it sound tone "tone tone tone", but original it is train "noise noise noise". when you wait until train sound will come - reopen that track, from this moment this starts "tone tone" is change into "noise" as they must be. i dont know where my mistake or not my? )))
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
-
- Enthusiast
- Posts: 619
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Noob's investigation of VGM
about "spot" - maybe it is connected with noise channel, where 3 or 7 value means get frequency from 2 channel. but system think, if 2 channel have some value - it need to play. but volume at this moment must be 15 = silence for second channel.
did you fix my val.a into val.u and hear how it plays? i hear gaps, when shutdown all channels for 1 chip. 2 chip play with this gaps. how to i need set correct clock? probably i set it at wrong place...
did you fix my val.a into val.u and hear how it plays? i hear gaps, when shutdown all channels for 1 chip. 2 chip play with this gaps. how to i need set correct clock? probably i set it at wrong place...
Re: Noob's investigation of VGM
I tried. I don't know what you think is wrong.SeregaZ wrote:did you fix my val.a into val.u and hear how it plays? i hear gaps, when shutdown all channels for 1 chip. 2 chip play with this gaps. how to i need set correct clock? probably i set it at wrong place...
It sounds kind of okay to me
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
-
- Enthusiast
- Posts: 619
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Noob's investigation of VGM
did you shutdown first chip? unicode and thread safe?
Re: Noob's investigation of VGM
Your picture doesn't show but yes, I did ran it in unicode and thread safe mode.SeregaZ wrote:did you shutdown first chip? unicode and thread safe?
I posted a little modified version of my module but I don't think that will make the difference when it comes to what you are talking about.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
-
- Enthusiast
- Posts: 619
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Noob's investigation of VGM
now plays fine no gaps. but... i can hear difference sound at 2 channel of 2 chip. winamp play is a little lower i think. more deeper sound. i am not sure - maybe all track have different high, but this 2 channel of 2 chip i can hear it more clear. maybe this formula is count wrong?
one more - what do you think, if PSG_Init() command will have a few params?
PSG_Init(chip1freq.i, chip2freq.i=0)
when you set only one freq - system know, that he must play only 1 chip, if both params turn on - use both. or even that way:
PSG_Init(#PAL) or PSG_Init(#NTSC) or PSG_Init(#PAL, #PAL) or PSG_Init(#NTSC, #NTSC)
where:
#NTSC = 3579545
#PAL = 3546893
i set start play position, and turn on only that 2 channel for 2 chip. and you need change path to your file in: XIncludeFile "SN76489 module.pb" (in that file both your parts of code core and window part)
ops. it cant be constant. VGM have different values, not exactly NTSC of PAL values. probably it will need to set by VGM's, not by Init command.
for that train track it is 1077741824
Code: Select all
Input clock (Hz) (3579545)
Frequency (Hz) = ----------------------------------
2 x register value x divider (16)
PSG_Init(chip1freq.i, chip2freq.i=0)
when you set only one freq - system know, that he must play only 1 chip, if both params turn on - use both. or even that way:
PSG_Init(#PAL) or PSG_Init(#NTSC) or PSG_Init(#PAL, #PAL) or PSG_Init(#NTSC, #NTSC)
where:
#NTSC = 3579545
#PAL = 3546893
i set start play position, and turn on only that 2 channel for 2 chip. and you need change path to your file in: XIncludeFile "SN76489 module.pb" (in that file both your parts of code core and window part)
Code: Select all
;{
ProgName.s=GetFilePart(ProgramFilename())
a = CreateSemaphore_(#Null,0,1,@ProgName)
If a<>0 And GetLastError_()=#ERROR_ALREADY_EXISTS
CloseHandle_(a)
End
EndIf
;}
Enumeration
#Window
#PathString
#OpenButton
#File
#Text
#Fr01
#Fr02
#Ch1R
#Ch2R
#Ch3R
#Ch4R
#Ch1L
#Ch2L
#Ch3L
#Ch4L
#Ch1R2
#Ch2R2
#Ch3R2
#Ch4R2
#Ch1L2
#Ch2L2
#Ch3L2
#Ch4L2
#Play
#Stop
#From
EndEnumeration
XIncludeFile "SN76489 module.pb"
Structure VGMFSt
type.i
reg.a
val.u
pause.u
samplenum.a
sampleadress.i
samplesize.i
summofpauses.i
EndStructure
Global Dim VGMARR.VGMFSt(0)
Global TormozFlag = 1
Global PlThr
;{
Macro SetBit(Var, Bit)
Var | (Bit)
EndMacro
Macro ClearBit(Var, Bit)
Var & (~(Bit))
EndMacro
Macro TestBit(Var, Bit)
Bool(Var & (Bit))
EndMacro
Macro NumToBit(Num)
(1<<(Num))
EndMacro
Macro GetBits(Var, StartPos, EndPos)
((Var>>(StartPos))&(NumToBit((EndPos)-(StartPos)+1)-1))
EndMacro
;}
Procedure Play(*Value)
PlayedTicks.i = 0
PlayedUS.i = 0
CurrentUS.i = 0
StartMS.i = ElapsedMilliseconds()
start = Val(GetGadgetText(#From))
For i = start To ArraySize(VGMARR())-1
Select VGMARR(i)\type
Case 3 ; pauses
PlayedTicks + VGMARR(i)\pause
PlayedUS = PlayedTicks * 22.675736961;90.702947844;22.675736961
While (CurrentUS < PlayedUS)
Delay(1)
CurrentUS.i = (ElapsedMilliseconds() - StartMS) * 1000
Wend
Case 5 ; PSG
Write(VGMARR(i)\val)
;Case 6 ; PSG
; ;Write(VGMARR(i)\val) ;Write2?
; ;Write(VGMARR(i)\val)
Case 7 ; stereo flags
GGStereoWrite(VGMARR(i)\val)
EndSelect
If TormozFlag
Break
EndIf
Next
;silence when stop
Write(%10011111)
Write(%10111111)
Write(%11011111)
Write(%11111111)
Write(%110011111)
Write(%110111111)
Write(%111011111)
Write(%111111111)
EndProcedure
Procedure ParsePlay(*FileMem)
memsize = MemorySize(*FileMem)
o.l = PeekL(*FileMem+$0C)
Clock(o) ; set clock per track. idk will it make effect, or not...
Debug "frequency is " + Str(o)
;get version of vgm. ugly code? :)))
ver$ = ""
tmp = PeekA(*FileMem + 11)
ver$ = Str(GetBits(tmp, 4, 7))
ver$ + Str(GetBits(tmp, 0, 3))
tmp = PeekA(*FileMem + 10)
ver$ + Str(GetBits(tmp, 4, 7))
ver$ + Str(GetBits(tmp, 0, 3))
tmp = PeekA(*FileMem + 9)
ver$ + Str(GetBits(tmp, 4, 7))
ver$ + Str(GetBits(tmp, 0, 3))
tmp = PeekA(*FileMem + 8)
ver$ + Str(GetBits(tmp, 4, 7))
ver$ + Str(GetBits(tmp, 0, 3))
If Val(ver$) < 151
ot = *FileMem + 64 ; 64 - it is vgm header. no need it yet
Else
ot = *FileMem + 256
EndIf
do = *FileMem + memsize
; create array with size as filesize. array will get less size, than file, but it is ok
Dim VGMARR(memsize)
Number.a = 0
PSGvalue.a
Arrayind = 0
For i = ot To do
Number = PeekA(i)
Select Number
Case $67 ; 0x67 0x66 tt ss ss ss ss (data)
; it is big wav data block
; get size of wav data block
WavDataSize = PeekI(i + 3)
; get adress of wav data block
WavAddres = i + 7
; jump to end of wav data block
i + 6 + WavDataSize
Case $52 ; $52 - register +0
i+2
Case $53 ; $53 - register +256
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)
If flagpausehunt
VGMARR(numforsizecount)\summofpauses + VGMARR(Arrayind)\pause
flagpausehunt = 0
EndIf
Arrayind + 1
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
Case $E0 ; 0xE0 dddddddd seek to offset dddddddd (Intel byte order) in PCM data bank
;jump far
i + 4
Case $80 To $8F
flagpausehunt = 1
If Number > $80
VGMARR(Arrayind)\type = 3
VGMARR(Arrayind)\pause = (Number - $80)
VGMARR(numforsizecount)\summofpauses + VGMARR(Arrayind)\pause
Arrayind + 1
EndIf
Case $4F ; 0x4F dd Game Gear PSG stereo, write dd to port 0x06 ; dune with samples
i + 1
PSGvalue = PeekA(i)
VGMARR(Arrayind)\type = 7
VGMARR(Arrayind)\val = PSGvalue
Arrayind + 1
Case $3F ; 0x4F dd Game Gear PSG stereo, write dd to port 0x06 ; dune with samples
i + 1
PSGvalue = PeekA(i)
VGMARR(Arrayind)\type = 7
VGMARR(Arrayind)\val = PSGvalue + 256
Arrayind + 1
;MAIN COMMAND :))
Case $50 ; 0x50 dd PSG (SN76489/SN76496) write value dd ; dune with samples
i + 1
PSGvalue = PeekA(i)
VGMARR(Arrayind)\type = 5
VGMARR(Arrayind)\val = PSGvalue
Arrayind + 1
Case $30 ; 0x50 dd PSG (SN76489/SN76496) write value dd ; dune with samples
i + 1
PSGvalue = PeekA(i)
VGMARR(Arrayind)\type = 5
VGMARR(Arrayind)\val = PSGvalue + 256
Arrayind + 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
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
Case $66 ; end of sound
Debug "end"
Break
Default
;Debug "unknown command " + Hex(Number)
EndSelect
If TormozFlag
Break
EndIf
Next
If TormozFlag = 0
Play(0)
EndIf
EndProcedure
#ENABLE_GZIP = 16
; #ZLIB_VERSION = "1.2.8"
#Z_NULL = 0
#Z_OK = 0
#Z_STREAM_END = 1
#Z_FINISH = 4
#Z_BLOCK = 5
Structure Z_STREAM
*next_in.Byte
avail_in.l
total_in.l
*next_out.Byte
avail_out.l
total_out.l
*msg.Byte
*state
zalloc.l
zfree.l
opaque.l
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
PB_Alignment1.b[4]
CompilerEndIf
data_type.i
adler.l
reserved.l
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
PB_Alignment2.b[8]
CompilerEndIf
EndStructure
ImportC "zlib.lib"
zlibVersion()
inflateInit2_(*strm, windowBits.i, Version.s, strm_size)
inflate(*strm, flush.i)
inflateEnd(*strm)
deflateInit2_(*strm, level.i, method.i, windowBits.i, memlevel.i, strategy.i, Version.s, strm_size)
deflateBound(*strm, sourceLen.l)
deflate(*strm, flush.i)
deflateEnd(*strm)
EndImport : Global ZLIB_VERSION$ = PeekS(zlibVersion(), -1, #PB_Ascii)
Procedure InflatePayload(*TmpMem, windowBits.i, size.i)
Debug "запустилось"
LengthToRead = MemorySize(*TmpMem)
LengthToWrite = size;FileSize("1test.dds")
*MemoryID = AllocateMemory(LengthToWrite)
strm.Z_STREAM
strm\next_in = *TmpMem
strm\avail_in = LengthToRead
strm\next_out = *MemoryID
strm\avail_out = LengthToWrite
strm\zalloc = #Z_NULL
strm\zfree = #Z_NULL
strm\opaque = #Z_NULL
inflateInit2_(@strm, windowBits, ZLIB_VERSION$, SizeOf(Z_STREAM))
inflate(@strm, #Z_FINISH)
inflateEnd(@strm)
ProcedureReturn *MemoryID
EndProcedure
If OpenWindow(#Window, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
StringGadget(#PathString, 10, 20, 120, 20, "", #PB_String_ReadOnly)
ButtonGadget(#OpenButton, 130, 20, 50, 20, "open")
TextGadget(#Text, 10, 40, 170, 90, "WARNING! see what chips was used by this VGM. it plays only one SN76489. YM2612 is ignored. any VGM with other chips can crash programm.")
StringGadget(#From, 10, 120, 65, 20, "550")
GadgetToolTip(#From, "starts from...")
ButtonGadget(#Play, 80, 120, 50, 20, "play")
ButtonGadget(#Stop, 135, 120, 50, 20, "stop")
FrameGadget(#Fr01, 1, 158, 93, 97, "1 chip")
FrameGadget(#Fr02, 95, 158, 93, 97, "2 chip")
CheckBoxGadget(#Ch1L, 5, 170, 70, 20, "L 1Ch R")
CheckBoxGadget(#Ch2L, 5, 190, 70, 20, "L 2Ch R")
CheckBoxGadget(#Ch3L, 5, 210, 70, 20, "L 3Ch R")
CheckBoxGadget(#Ch4L, 5, 230, 70, 20, "L 4Ch R")
CheckBoxGadget(#Ch1R, 75, 170, 16, 20, "")
CheckBoxGadget(#Ch2R, 75, 190, 16, 20, "")
CheckBoxGadget(#Ch3R, 75, 210, 16, 20, "")
CheckBoxGadget(#Ch4R, 75, 230, 16, 20, "")
CheckBoxGadget(#Ch1L2, 100, 170, 70, 20, "L 1Ch R")
CheckBoxGadget(#Ch2L2, 100, 190, 70, 20, "L 2Ch R")
CheckBoxGadget(#Ch3L2, 100, 210, 70, 20, "L 3Ch R")
CheckBoxGadget(#Ch4L2, 100, 230, 70, 20, "L 4Ch R")
CheckBoxGadget(#Ch1R2, 170, 170, 16, 20, "")
CheckBoxGadget(#Ch2R2, 170, 190, 16, 20, "")
CheckBoxGadget(#Ch3R2, 170, 210, 16, 20, "")
CheckBoxGadget(#Ch4R2, 170, 230, 16, 20, "")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
;- Event
Case #OpenButton
If File$
StandardFile$ = GetPathPart(File$)
Else
StandardFile$ = "C:\" ;GetPathPart(ProgramFilename()); ; initial path + file
EndIf
Pattern$ = "VGM files (*.vgm)|*.vgm;*.vgz;";*.vgz|" ; set first pattern (index = 0)
Pattern = 0 ; use the second of the five possible patterns as standard
; Now we open a filerequester, you can change the pattern and will get the index after closing
File$ = OpenFileRequester("Please choose file to load", StandardFile$, Pattern$, Pattern)
If File$
;For i = #Ch1R To #Ch4L2
; SetGadgetState(i, 1)
;Next
;GGStereoWrite(255)
;GGStereoWrite(255 + 256)
SetGadgetState(#Ch2R2, 1)
SetGadgetState(#Ch2L2, 1)
GGStereoWrite(0)
GGStereoWrite(34 + 256)
TormozFlag = 1
If IsThread(PlThr)
WaitThread(PlThr)
EndIf
SetGadgetText(#PathString, File$)
If ReadFile(#File, File$)
If *MemoryID
FreeMemory(*MemoryID)
*MemoryID = 0
EndIf
length = Lof(#File)
If ReadByte(#File) = $56 And ReadByte(#File) = $67 And ReadByte(#File) = $6D
;unpacked VGM
Debug "unpacked"
*MemoryID = AllocateMemory(length) ; allocate the needed memory
If *MemoryID
FileSeek(#File, 0)
ReadData(#File, *MemoryID, length) ; read all data into the memory block
EndIf
Else
Debug "packed"
;get size unpacked
FileSeek(#File, length - 4)
unpsz = ReadLong(#File)
If *TmpMem
FreeMemory(*TmpMem)
*TmpMem = 0
EndIf
*TmpMem = AllocateMemory(length) ; allocate the needed memory
If *TmpMem
FileSeek(#File, 0)
ReadData(#File, *TmpMem, length) ; read all data into the memory block
*MemoryID = InflatePayload(*TmpMem, #ENABLE_GZIP, unpsz) ;unpack
EndIf
EndIf
CloseFile(#File)
TormozFlag = 0
If *MemoryID
PlThr = CreateThread(@ParsePlay(), *MemoryID)
Else
MessageRequester("error", "cant read file")
EndIf
EndIf
EndIf
Case #Ch1R To #Ch4L
forstereo = 0
For i = #Ch1R To #Ch4L
value = GetGadgetState(i)
If value
SetBit(forstereo, NumToBit(i-#Ch1R))
Else
ClearBit(forstereo, NumToBit(i-#Ch1R))
EndIf
Next
GGStereoWrite(forstereo)
Case #Ch1R2 To #Ch4L2
forstereo = 0
For i = #Ch1R2 To #Ch4L2
value = GetGadgetState(i)
If value
SetBit(forstereo, NumToBit(i-#Ch1R2))
Else
ClearBit(forstereo, NumToBit(i-#Ch1R2))
EndIf
Next
GGStereoWrite(forstereo + 256)
Case #Play
If *MemoryID
TormozFlag = 1
If IsThread(PlThr)
WaitThread(PlThr)
EndIf
TormozFlag = 0
PlThr = CreateThread(@Play(), *MemoryID)
EndIf
Case #Stop
TormozFlag = 1
EndSelect
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Quit = 1
EndIf
End
for that train track it is 1077741824
-
- Enthusiast
- Posts: 619
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Noob's investigation of VGM
1077741824 - $40000000 = 4 000 000 = that is problem. winamp cheating. he play 4 000 000 as 3 579 545. that is why winamp plays lower, than we have.
i have cursed this vgm.
i have cursed this vgm.
2016-09-24 02:40:31 ValleyBell Super Locomotive is a completely different story from "normal" Dual-PSG VGMs
2016-09-24 02:41:00 ValleyBell It uses the VGM's extra header to emulate one PSG chip at 4 MHz and another one at 2 MHz.
-
- Enthusiast
- Posts: 619
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Noob's investigation of VGM
i am not understand how to get that extra header value.
and how change main header size. basic it is 256, but sience 1.70 version of VGM it can be variable becouse this extra header.
and how change main header size. basic it is 256, but sience 1.70 version of VGM it can be variable becouse this extra header.
Header Size is the size of the extra header. It has to be 4 or larger, depending in the needed offsets.
Then there are two offsets that point to extra header data for:
additional Chip Clocks for second chips
user-defined chip volumes
Chip Clock Header
1 byte - Entry Count (chips with extra clocks) [5 bytes - List Entry 1] [5 bytes - List Entry 2] ...
Each list entry has the format: 1 byte - Chip ID (chip order follows the header) 4 bytes - clock for second chip of the type above
Chip Volume Header
1 byte - Entry Count (chips with user-defined volumes) [4 bytes - List Entry 1] [4 bytes - List Entry 2] ...
Each list entry has the format: 1 byte - Chip ID (chip order follows the header)
Re: Noob's investigation of VGM
I had to rewrite a lot to implement the ability to set a different frequency for both chips.
Hopefully everything still works.
I'll look into the VGM file format.
Hopefully everything still works.
I'll look into the VGM file format.
Last edited by wilbert on Wed May 31, 2017 2:58 pm, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: Noob's investigation of VGM
Excuse me but ...
If I got it right, this is all about controlling Texas and Yamaha sound-chips ?
How do you send PB-code to these ?
Wherein are they placed ?
Is that VGM format limited to these two (older) chips ?
Thanks.
If I got it right, this is all about controlling Texas and Yamaha sound-chips ?
How do you send PB-code to these ?
Wherein are they placed ?
Is that VGM format limited to these two (older) chips ?
Thanks.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.