Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - PSGlib 'official' topic [was: "Music engines"]

Reply to topic Goto page Previous  1, 2, 3, 4, 5  Next
Author Message
  • Joined: 04 Nov 2004
  • Posts: 273
Reply with quote
Post Posted: Wed Feb 26, 2014 1:30 pm
Basic Huffman needs one bit per tree node. You can use multiple bits if you want to have it faster, but you'll need a data structure that is tricky to build and it needs a lot of memory if you want many bits.
  View user's profile Send private message Visit poster's website
  • Joined: 08 Dec 2013
  • Posts: 200
Reply with quote
Post Posted: Wed Feb 26, 2014 2:49 pm
use lookup tables and perhaps even a pre-prepared dictionary in ROM -- if the engine, LUTs and pre-compiled dictionary take up 1 bank in page 0 then page 1 can be the bank with the current song and page 2 the bank with the current SFX.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Feb 26, 2014 4:47 pm
Maxim wrote
[...]traversing a Huffman tree you only want one at a time anyway, don't you? (It's a few years since I implemented such a thing.) Using add a, a you get optimal performance (for the Z80) of four cycles.


Right. But I also have to read again about Huffman trees :|

Kroc wrote
if the engine, LUTs and pre-compiled dictionary take up 1 bank in page 0 then page 1 can be the bank with the current song and page 2 the bank with the current SFX.


Gosh! I actually was hoping in something smaller (and I'm also planning to make some changes to the sources so that I could eventually use the same page for song and SFX, switching banks if needed)
  View user's profile Send private message Visit poster's website
  • Joined: 08 Dec 2013
  • Posts: 200
Reply with quote
Post Posted: Wed Feb 26, 2014 5:51 pm
Size is not the problem to be worried about! Compression and efficiency are.

In the Commodore 64 scene they manage a lot of the tricks they do with offline computation. A program on the PC spends hours, sometimes even days computing everything into simple data that the C64 only need read, look up and act upon without it having to do any of the work.

When a game is being assembled on the PC, you know *exactly* what music and SFX will be going into the ROM, you don't need to be generic -- you can on-demand customise the engine to suit the data; i.e. compute the compression tables and LUTs on the PC so that the playback engine on the SMS only needs to look up a value and act upon it in the 'dumbest' fashion possible. This is the answer to solving both speed and compression factor with the downside of using more ROM space (up to 16KB), which is not much of a problem when it comes to homebrew as we can easily create 512KB, 1MB or even 4MB cartridge images.

Edit: Think of Page 1 as a "window" into any bank containing music data and Page 2 as another "window" for SFX even though both could be looking at the same bank. The point is that this way, the engine can play music & SFX at the same time regardless if they are in the same bank or not!
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Feb 27, 2014 9:18 am
Kroc wrote
Size is not the problem to be worried about! Compression and efficiency are.


Yes, I know, I just meant to say that I'd like to have a small/simple and fast code because I don't want it to take too much, especially in CPU horsepower percentage (actually I never see my code eating more than 9% CPU while playing both background music and a SFX).

About Huffman: I made a quick test using this online tool.
The results are that this compression would shave off about 40% of the original size, while the compression I'm using is already shaving almost 50% with that same test file (the biggest in the Sonic 1 collection)

I guess I'll keep the current method, at the moment. But I'm keeping some good cards hidden in the case I really need to shave some more ;)
  View user's profile Send private message Visit poster's website
  • Joined: 04 Nov 2004
  • Posts: 273
Reply with quote
Post Posted: Thu Feb 27, 2014 11:20 pm
I thought the idea was to combine both. :)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Feb 28, 2014 8:30 am
Wouldn't that be seriously overkilling?

edit: a quick test with that same online tool said that Huffman compression on my already compressed file would shave off another 25% (no longer 40% of course). I wonder if it's worth.
  View user's profile Send private message Visit poster's website
  • Joined: 08 Dec 2013
  • Posts: 200
Reply with quote
Post Posted: Fri Feb 28, 2014 11:42 am
sverx wrote
I'd like to have a small/simple and fast code because I don't want it to take too much, especially in CPU horsepower percentage


Apologies, you misunderstand me -- if you want a fast and simple decoder then having lookup tables and/or a precalculated dictionary (or 'decompression map') will greatly simplify the amount of cycles the decoder needs to spend on decompression.

I.e. - you could have a complex 4 KB decoder that runs twice as slow as a 2 KB decoder that has 14 KB of ROM-based precalculated lookups.

My point is that it isn't a problem to spend 16 KB on the playback engine (even though only ~ 2KB might be Z80 code) in the name of speed and efficiency; I can spare 3 banks for music stuff.
  View user's profile Send private message Visit poster's website
  • Joined: 04 Nov 2004
  • Posts: 273
Reply with quote
Post Posted: Fri Feb 28, 2014 12:30 pm
Yes, you're right, it would be overkilling probably. It could work though for a title screen with just a still picture.

And yes, you can spend lots of space in a homebrew program to make it faster. It's a little unfair compared to old programs on expensive cartridges, but otherwise I see no problem.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Feb 28, 2014 12:40 pm
Kroc wrote
if you want a fast and simple decoder then having lookup tables and/or a precalculated dictionary (or 'decompression map') will greatly simplify the amount of cycles the decoder needs to spend on decompression.


True, indeed. I was comparing it to the actual code, which has no lookup tables or dictionaries because it doesn't need them... of course because it isn't doing anything complex. If I switch on a more complex compression I would surely use some more ROM instead of making the code more CPU intensive, of course!

Thanks!
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Mar 03, 2014 3:45 pm
just renamed this to PSGlib. Better :)
  View user's profile Send private message Visit poster's website
  • Joined: 08 Dec 2013
  • Posts: 200
Reply with quote
Post Posted: Mon Mar 03, 2014 5:12 pm
Cool. Will be keeping an eye on this for potential future use / integration with OZ80.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Apr 2011
  • Posts: 250
  • Location: Netherlands
Reply with quote
Post Posted: Thu Mar 13, 2014 9:30 pm
So. How is everything going with the project?

I managed myself to get pretty far with the replayer from my tracker.
In the video below you can see the replayer in action on an MSX. So I'd expect it to run faster on an SMS (no wait states!).

I was wondering how much faster will the PSGlib replayer be in comparison with my video?


.be
purple lines: PSG update
blue lines: Music data process
yellow lines: Generating PSG values (instruments, efffects etc).

green lines: Unrelated. This is the screen update.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Mar 14, 2014 8:42 am
Nice work, Zipper!
I don't know how to compare the speed of my PSGlib on the SMS to the speed of your replay lib on MSX, really... the only thing I could clock myself (on MEKA) is that playing a tune and firing SFX like crazy I could not take more than 24 scanlines, which means less than 10% (also, this is info is outdated actually because I didn't check again after all the changes I've made recently...)
  View user's profile Send private message Visit poster's website
  • Joined: 06 Apr 2011
  • Posts: 250
  • Location: Netherlands
Reply with quote
Post Posted: Fri Mar 14, 2014 10:06 am
Thanks,
24 scanlines max is fast! My version seems to use a little less than the double amount at max peak.

I'll try to port my code to SMS in the next few weeks (+adding sfx support) to see how it performs on real SMS HW.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Mar 14, 2014 12:39 pm
Zipper wrote
24 scanlines max is fast!


Well, it does very few things... it just pushes PSG data to the PSG chip, saves some data to 'mix' music and SFX and little less so I think it's even too much ;)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Mar 18, 2014 8:54 am
It doesn't matter how hard I try, I still can't make it work 100% properly in every situation, so I guess there's something I miss.
In the docs I've read that the PSG chip tones are affected by every write (upper or lower part). Ok, this makes sense to me. The real question is: is the internal counter reset each time I write, so that if I keep on writing the same tone data to a sound channel every frame I would in fact disturb proper sound generation?
Thanks very much, I'm quite lost... :|
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14690
  • Location: London
Reply with quote
Post Posted: Tue Mar 18, 2014 8:57 am
No, the tone register is only read when the counter expires and the flip flop flips. Noise resets the LFSR on write.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Mar 18, 2014 9:08 am
Ah! I was suspecting that. Now the plot thickens. :|
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14690
  • Location: London
Reply with quote
Post Posted: Tue Mar 18, 2014 10:06 am
If your engine outputs exactly the writes in the VGM data, and no more, then you should be able to log a VGM, optimise to standardise the writes, and then compare to see where any divergence happens.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Mar 18, 2014 10:29 am
No, currently my engine is issuing additional writes, and I'm working to eliminate them (and I hope this time it will work). After that, if there will still be differences, I'll try comparing the logged VGM byte per byte. Well... hopefully not!
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14690
  • Location: London
Reply with quote
Post Posted: Tue Mar 18, 2014 1:22 pm
Actually, VGM optimisation works by removing unnecessary writes (those that make no difference to the sound) so even with the extra ones, log a VGM, optimise and compare to the original (maybe by conversion to text and then diffing) and you should see where they diverge.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Mar 18, 2014 1:36 pm
I'm rewriting part of the engine (and a small part of the converter) and now it seems to work pretty well.
I'm just curious about the VGM optimizer: does it make each frame so that it starts with a latch command or not? It seems so already but maybe I've just been lucky...

edit: also, what tool(s) could I use to create SFX? Using Mod2PSG2 or DefleMask for those it's a pain... :|
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14690
  • Location: London
Reply with quote
Post Posted: Tue Mar 18, 2014 4:19 pm
Ripping SFX from games with sound tests is an option.

A VGM optimiser can do anything it likes so long as the sound is not affected. Re-using a latch might cause trouble in some replayers so it's best avoided, even if it works on a real chip.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Mar 18, 2014 4:48 pm
Sorry, I meant the VGMTool you made, when you use the 'Optimize' button. In the optimized VGM, each frame starts with a latch... is it the default or just a coincidence?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14690
  • Location: London
Reply with quote
Post Posted: Tue Mar 18, 2014 7:12 pm
I write out only fully formed commands, so you won't see a data byte after a pause.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Mar 19, 2014 8:38 am
OK, that's the reason why my converter tool didn't find any (and I will keep that in place so that the conversion would generate a valid output also with unoptimized VGMs)
  View user's profile Send private message Visit poster's website
  • Joined: 06 Apr 2011
  • Posts: 250
  • Location: Netherlands
Reply with quote
Post Posted: Tue May 06, 2014 8:22 am
Any updates on the music engine?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue May 06, 2014 8:57 am
Although I can't assure you it's 100% bug free, I'm currently using the latest version released with no problems. So if you want to use it too, please do it :)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon May 12, 2014 8:45 am
OK, I spoke too soon.
Friday I noticed a nasty effect when playing a SFX on PSG channel 2 (only) that disrupted the tune playing on PSG channel 3.
It wasn't until few minutes ago I could find the bug... so I'll be running some tests today (hopefully) and commit changes to github ASAP.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed May 14, 2014 9:38 am
v0.9.91 released. Now it works as it never did :D
  View user's profile Send private message Visit poster's website
  • Joined: 01 Feb 2014
  • Posts: 849
Reply with quote
Post Posted: Sat Jul 19, 2014 6:19 am
I've integrated PSGlib into my game project and can report that it works beautifully. It's really a fantastic solution for handling music and SFX.

One minor niggle, though, is that sometimes a short SFX when fired cancels an ongoing longer one, which sounds a little odd, because one would naturally expect to hear the end of the longer SFX when the shorter one is done. I suppose implementing that would make things to complicated, though, and it really isn't much of an issue.


Slightly off-topic: When I put in a music track I had done in MOD2PSG2, I was shocked to see it fill almost a whole bank. What used to be a Psgmod of about 3 KB turned into a 43 KB monster of a VGM which then in turn could be shrunk again (through PSG conversion and compression) to about 15 KB of data.

While this is not a problem per se, as it's unlikely that I'll run out of ROM space even with multiple songs in the game, it does limit the possible length of the tracks and it's something I'll have to keep in mind when composing. After all, the track in question was just 1:45 long.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Jul 28, 2014 8:15 am
Have you optimized the VGM using Maxim's VGM tool already?
I believe its size is due to the vibrato/tremolo you give to the instruments, all these turns into PSG commands to change freq/volume...
  View user's profile Send private message Visit poster's website
  • Joined: 01 Feb 2014
  • Posts: 849
Reply with quote
Post Posted: Mon Jul 28, 2014 10:39 am
sverx wrote
Have you optimized the VGM using Maxim's VGM tool already?
I believe its size is due to the vibrato/tremolo you give to the instruments, all these turns into PSG commands to change freq/volume...

I suspected that might be it. Some of my instruments indeed use a lot of vibrato/tremolo. I did optimize the VGMs with VGMtool, but it doesn't seem to shave off more than a couple of bytes (not counting the compression to vgz).

Fortunately, I found that I don't really need tracks that are that long, as levels/environments (and with them the music) change so often that the tracks can be a lot shorter without feeling too repetitive. The already finished long track stays in for now, though. I have a part of the game in mind where it could be put to decent use.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Jul 29, 2014 9:00 am
Maxim wrote
I write out only fully formed commands, so you won't see a data byte after a pause.


Mmm... this also mean that there won't ever be any non-latch volume command, right? If this is true, then maybe I can try adding a master volume for the background music... mumble...
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14690
  • Location: London
Reply with quote
Post Posted: Tue Jul 29, 2014 10:38 am
Yes, that's right.

I think you should seriously try splitting the data into eight parallel streams (tone and volume for each channel), and maintain eight pointers through them. I suspect the LZ-style compression would then eat up lots of the tremolo and vibrato, compensating for the increased redundancy in timing data. Maybe just do a proof of concept to see how the data compresses, before writing the player...
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Jul 29, 2014 11:25 am
Actually I'm not really thinking about achieving a better compression ratio, I guess it's something not really necessary.
I'm just thinking that volume commands to the channels could be used to address a 16 bytes LUT of effective volumes instead of OUTing them directly to the PSG, so to add a Master Volume for the background tune...
I need to think a little more about it btw.
  View user's profile Send private message Visit poster's website
  • Joined: 16 Dec 2013
  • Posts: 69
Reply with quote
Post Posted: Sat Aug 02, 2014 8:06 pm
I placed PSGlib into my project, and it seems to work just fine, although Dega seems to have awful PSG support. Meh, can't be helped, I guess.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Aug 03, 2014 9:56 am
Let me know if you encounter something that's not working as expected :)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Aug 21, 2014 7:02 am
Kagesan wrote
Slightly off-topic: When I put in a music track I had done in MOD2PSG2, I was shocked to see it fill almost a whole bank. What used to be a Psgmod of about 3 KB turned into a 43 KB monster of a VGM which then in turn could be shrunk again (through PSG conversion and compression) to about 15 KB of data.


Yesterday I tried converting Shiru's example file (bundled with MOD2PSG2) 'run_under_fire.psgmod', which is 145KB. The exported VGM is 26KB, the converted (and compressed) psg file became 6,61KB... so I really can tell there's no connection between the source 'psgmod' file size and the resulting 'psgc' output...
  View user's profile Send private message Visit poster's website
  • Joined: 04 Nov 2004
  • Posts: 273
Reply with quote
Post Posted: Thu Aug 21, 2014 9:02 am
epsgmod file is around 2KB. (psgmod format is indeed not space-efficient, it didn't matter much for me.)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Aug 21, 2014 9:24 am
Oh, that's interesting. I thought it was a similar format...
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Aug 26, 2014 9:45 am
sverx wrote
[...] playing a tune and firing SFX like crazy I could not take more than 24 scanlines [...]


I just updated the library, now it takes up to 21 scanlines at most :)
(I was saving and reloading the pointer from RAM at each loop cycle, now I'm avoiding it since it was unnecessary)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Aug 27, 2014 3:03 pm
I wasn't very fond of the results I was getting during the tests these days, so I decided to investigate a bit more. The fact is I got a strange 'spike' in CPU performance with the music replay routine, so I went on checking my PSG test file with an hex editor... and I found a (rather small) bug in my conversion routine from VGM format. I fixed that a minute ago.

Unfortunately the problem remain, so I went on and found that there is a problem from the original VGM, which has been optimized using Maxim's VGMTool (because the way the file comes from DefleMask exporter is very unoptimized)

Analyzing the (optimized) file with VGMTool, at that point it appears this:

0x00000da9: 62       Wait:     735 samples (1/60s)      (total   376320 samples (0:08.53))
------- Loop point -------
0x00000daa: 4f ff    GG st:  012N012N
0x00000dac: 50 80    PSG:    Latch/data: Tone ch 0 -> 0x140 =   349.56 Hz =  F4   +2
0x00000dae: 50 14    PSG:    Data:       Tone ch 0 -> 0x140 =   349.56 Hz =  F4   +2
0x00000db0: 50 a0    PSG:    Latch/data: Tone ch 1 -> 0x0a0 =   699.13 Hz =  F5   +2
0x00000db2: 50 0a    PSG:    Data:       Tone ch 1 -> 0x0a0 =   699.13 Hz =  F5   +2
0x00000db4: 50 ca    PSG:    Latch/data: Tone ch 2 -> 0x05a =  1242.89 Hz = D#6   -2
0x00000db6: 50 05    PSG:    Data:       Tone ch 2 -> 0x05a =  1242.89 Hz = D#6   -2
0x00000db8: 50 e3    PSG:    Latch/data: Noise: synchronous, ch 2
0x00000dba: 50 9a    PSG:    Latch/data: Volume: ch 0 -> 0xa = 33%
0x00000dbc: 50 bc    PSG:    Latch/data: Volume: ch 1 -> 0xc = 20%
0x00000dbe: 50 df    PSG:    Latch/data: Volume: ch 2 -> 0xf = 0%
0x00000dc0: 50 f4    PSG:    Latch/data: Volume: ch 3 -> 0x4 = 73%
0x00000dc2: 50 8d    PSG:    Latch/data: Tone ch 0 -> 0x14d =   335.92 Hz =  E4  +33
0x00000dc4: 50 17    PSG:    Data:       Tone ch 0 -> 0x17d =   293.60 Hz =  D4   +0
0x00000dc6: 50 ad    PSG:    Latch/data: Tone ch 1 -> 0x0ad =   646.59 Hz =  E5  -34
0x00000dc8: 50 11    PSG:    Data:       Tone ch 1 -> 0x11d =   392.49 Hz =  G4   +2
0x00000dca: 50 cb    PSG:    Latch/data: Tone ch 2 -> 0x05b =  1229.23 Hz = D#6  -21
0x00000dcc: 50 23    PSG:    Data:       Tone ch 2 -> 0x23b =   195.90 Hz =  G3   -1
0x00000dce: 50 e6    PSG:    Latch/data: Noise: white, low (1747Hz)
0x00000dd0: 50 92    PSG:    Latch/data: Volume: ch 0 -> 0x2 = 86%
0x00000dd2: 50 b4    PSG:    Latch/data: Volume: ch 1 -> 0x4 = 73%
0x00000dd4: 50 d0    PSG:    Latch/data: Volume: ch 2 -> 0x0 = 100%
0x00000dd6: 50 f0    PSG:    Latch/data: Volume: ch 3 -> 0x0 = 100%
0x00000dd8: 62       Wait:     735 samples (1/60s)      (total   377055 samples (0:08.55))


which I believe it's wrong, as it's pushing 22 bytes to the same 11 PSG registers... or a pause in between got lost.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14690
  • Location: London
Reply with quote
Post Posted: Wed Aug 27, 2014 5:07 pm
Seems wrong. At the loop point it attempts to reset the state of every register (in order to make loops work nicely), but this ought to coalesce with any writes happening at that time. In many ways VGMTool is abandoned these days (I am unlikely to look at it again), so feel free to switch to the other VGM tools for the same purpose.

Ultimately, looping is a tricky problem - you need to jump from the end of the file to somewhere in the middle, but also reset the registers to the state they were in at that point without reference to any of the previous data (at playback time). It would probably make more sense to put the register dump at the end of the VGM file, so it isn't encountered on the first playthrough, and also to optimise it to only change those registers in the wrong state at the end of the file and not about to be changed by the writes at the loop point. However, this still means a lot of register writes when you do a loop.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Aug 28, 2014 9:43 am
I am trying ValleyBell's vgm_cmp but it seems to suffer of similar problems, albeit not at the loop point. So I tried passing the DefleMask generated VGM into VGMTool and then into vgm_cmp, but it didn't remove those unnecessary writes.
The other way around seems useless too.

I am wrong assuming that everything that gets written to the same PSG channel in the same frame is useless and can be removed?
Which other tools I could try using? I'd prefer not to have to code my own optimizer :|
  View user's profile Send private message Visit poster's website
  • Joined: 15 Sep 2009
  • Posts: 377
Reply with quote
Post Posted: Thu Aug 28, 2014 10:04 am
VGMTool's "optimise" function should remove multiple writes during the same frame. IIRC it takes a save state of every frames and just refreshes the registers that changed.

vgm_cmp intentionally doesn't remove multiple writes, because it can break FM playback and affect the noise generation slightly.
example: FM Key Off and On in the same frame restart the note.
If it would be reduced to Key On only, it won't restart the note, because the "off" trigger is missing.

For the PSG your assumption is right, btw. (There is a small exception for the noise channel, because Ex writes reset the noise generator, but that has only a small effect on the sound.)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Aug 28, 2014 11:03 am
So I don't get why vgm_cmp won't remove these double writes (to the PSG) that VGMTool optimizer leaves after the loop point, as shown in my yesterday post. :|

And those aren't the only ones left... for instance right at the beginning there's this:
VGM data:
0x00000040: 4f ff    GG st:  012N012N
0x00000042: 50 8d    PSG:    Latch/data: Tone ch 0 -> 0x00d =  8604.62 Hz =  C9  +47
0x00000044: 50 17    PSG:    Data:       Tone ch 0 -> 0x17d =   293.60 Hz =  D4   +0
0x00000046: 50 ae    PSG:    Latch/data: Tone ch 1 -> 0x00e =  7990.00 Hz =  B8  +19
0x00000048: 50 0b    PSG:    Data:       Tone ch 1 -> 0x0be =   588.74 Hz =  D5   +4
0x0000004a: 50 cb    PSG:    Latch/data: Tone ch 2 -> 0x00b = 10169.09 Hz = D#9  +37
0x0000004c: 50 23    PSG:    Data:       Tone ch 2 -> 0x23b =   195.90 Hz =  G3   -1
0x0000004e: 50 e6    PSG:    Latch/data: Noise: white, low (1747Hz)
0x00000050: 50 92    PSG:    Latch/data: Volume: ch 0 -> 0x2 = 86%
0x00000052: 50 b5    PSG:    Latch/data: Volume: ch 1 -> 0x5 = 66%
0x00000054: 50 d0    PSG:    Latch/data: Volume: ch 2 -> 0x0 = 100%
0x00000056: 50 f0    PSG:    Latch/data: Volume: ch 3 -> 0x0 = 100%
0x00000058: 50 93    PSG:    Latch/data: Volume: ch 0 -> 0x3 = 80%
0x0000005a: 62       Wait:     735 samples (1/60s)      (total      735 samples (0:00.02))


which means it's changing the volume for ch 0 twice :|
  View user's profile Send private message Visit poster's website
  • Joined: 15 Sep 2009
  • Posts: 377
Reply with quote
Post Posted: Thu Aug 28, 2014 12:35 pm
vgm_cmp doesn't remove any writes that would make a difference if they would be sent in two separate frames. So two volume changes, same frame or not, are not removed if they have a different volume level.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3763
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Aug 28, 2014 3:14 pm
OK, so I finally put this optimization into my converter.
No more CPU 'spikes' now (as it won't ever have to push more than 11 bytes to the PSG chip each frame) and the maximum time it takes now is 13 scanlines [15 if the file is using compression] :)
  View user's profile Send private message Visit poster's website
Reply to topic Goto page Previous  1, 2, 3, 4, 5  Next



Back to the top of this page

Back to SMS Power!