Jump to content
Tursi

VGM Compression Tool

Recommended Posts

More than a few months ago I started working on a tool to compress VGM music files, such as those found at http://www.smspower.org/, so they could be used on the TI. A few weeks ago, I finally had everything working to my satisfaction, and released it. Today I am also releasing a ColecoVision version of the playback code, as I also like to do Coleco work. :) The compressor itself runs as a Windows command-line application - I am still considering Linux, since it should port easily enough.

 

For those who want to get right to the important stuff, it's at http://harmlesslion.com/software/vgmcomp

 

The tool is capable of merging up to 16 VGM files into a single output file, applying a variety of tricks to pack it down. While not quite as tight as gzip, it's usually within 10%, and does not require a decompression buffer to play back. In addition, the player optionally supports 30hz playback instead of 60hz, and sound effects with priority (also optionally). The player code is written in C and compiles to under 1k of ROM, and uses from 120-220 bytes of RAM (depending on whether you have enabled the sound effect code). A sample app is available both in the full download, and as standalone at the above link. It is tested on hardware and in BlueMSX.

 

VGMs compatible with the Coleco can be sourced from the Master System, Game Gear, and of course other ColecoVision games (although I think Antarctic Adventure is the only Coleco VGM I ever saw). In addition, the tracker tool Mod2PSG2 can export VGM (although the website at www.kontechs.com seems to be down, there is this alternate http://www.smspower.org/Music/Mod2PSG2). Of course, I can also list my Protracker MOD converter at http://harmlesslion.com/software/modconvertpsg

  • Like 4

Share this post


Link to post
Share on other sites

Huh. You know, the old editor used to handle manual BBCode a lot better. ;) Sorry about the screwed up links, but, the important details came through.

Share this post


Link to post
Share on other sites

Ah thank you I have been struggling with conversion of sound to the Colecovision, especially since my original games did not include much sound and music in the first place (limited memory when developing on a SV-318 and a tape based compiler :)).

I am converting the player.c to asm at the moment, might take me a day or so - constantly get interrupted at the moment.

Share this post


Link to post
Share on other sites

I can't get anywhere with this unfortunately. I got it to compile but I just get an unuseable rom.

 

Is there a simple c file setup including all necessary files in one directory and a sample music clip that I can compile in SDCC 3.4. Once I can get a working basic file I can figure it out from there.

Share this post


Link to post
Share on other sites

Here's a simpler demo that doesn't do anything fancy except play one tune on a blank screen. Tested on SDCC 3.4 as requested. Self-contained, no libraries required.

 

(There are definitely too many files in the main download, I will need to clean that up a bit ;) ).

 

Just unzip and 'make' (assuming sdcc\bin is in your path).

 

snddemo.zip

Edited by Tursi

Share this post


Link to post
Share on other sites

Thanks again. I'm trying it. No luck so far though. I'm getting his message when I try to compile using scdd 3.4

 

Try to link project : snddemo
Multiple definition of gsinit
C:\Documents and Settings\gerry\Desktop\coleco compiler\snddemo>sdcc -mz80 --code-loc 0x8024 --data-loc 0x7000 --no-std-crt0 ../crtcv.rel ../cvlib.lib ../getput.lib ../comp.lib crt0.rel main.rel music.rel player.rel
?ASlink-Warning-Undefined Global '_nmi' referenced by module 'crt0'
C:\Documents and Settings\gerry\Desktop\coleco compiler\snddemo>objcopy --input-target=ihex --output-target=binary crtcv.ihx result.rom

Share this post


Link to post
Share on other sites

Why are crtcv.rel, cvlib.lib, getput.lib and comp.lib in that linker line? Also your code address is not correct for my crt0 (although that probably doesn't matter). Use the included Makefile rather than doing it by hand.

 

I must apologize, there is still a bug in here (but it should build and give you a black screen). In main.c you need to update the function nmi() - for some reason I didn't include the final version in the archive (probably because I was rushing to get it done). Change the nmi() function to look like this:

 

// NMI hook called by crt0.s (don't worry about this if you have a lib)
void my_nmi() 
{
	unsigned char x;
	// read the status register to clear the interrupt
	x = vdpaddr;
	
	// note with the cv library you'd have to call a function to set this
	// also note you should normally call ststop() or allstop() (if SFX are enabled)
	// before you set the hook. But for this simple demo, this will do, it might
	// just squawk a bit at startup.
	stplay();
}
(The only important new lines are the unsigned char x, and the x=vdpaddr - if you don't read the status register you never get more than the first interrupt).

 

Here's a log - fresh download of SDCC and this example (after fixing main.c as above) on a new computer. Note that all I typed to build it was "make", but to be clear, I also did a "dir" so you can see the folder, and manually set the path to include the SDCC tools. Whether you need to do that depends on your system, looks like you don't. :)

 

C:\new\sample>dir
 Volume in drive C is OSDisk
 Volume Serial Number is D822-D699

 Directory of C:\new\sample

06/17/2014  03:17 PM    <DIR>          .
06/17/2014  03:17 PM    <DIR>          ..
06/16/2014  01:27 PM             2,329 crt0.s
11/07/2011  06:45 PM            66,457 LETSPLAY.VGM
06/16/2014  02:21 PM            10,806 LETSPLAY.VGM.spf
06/16/2014  02:13 PM             1,520 main.c
06/16/2014  02:01 PM               689 Makefile
06/16/2014  02:22 PM            77,945 music.c
06/16/2014  01:20 PM            12,865 player.c
06/16/2014  01:20 PM             2,240 player.h
06/16/2014  02:27 PM               354 readme.txt
06/16/2014  02:22 PM            13,130 snddemo.rom
              10 File(s)        188,335 bytes
               2 Dir(s)  841,110,691,840 bytes free

C:\new\sample>path=c:\sdcc\bin;%path%

C:\new\sample>make
sdcc -mz80 -c "-I../../libti99" --std-sdcc99 --vc  main.c
sdcc -c player.c -mz80 -c "-I../../libti99" --std-sdcc99 --vc  -o player.rel
sdcc -c music.c -mz80 -c "-I../../libti99" --std-sdcc99 --vc  -o music.rel
sdasz80 -o crt0.rel crt0.s
sdcc -mz80 --no-std-crt0 --code-loc 0x8100 --data-loc 0x7000 "./crt0.rel" main.rel player.rel music.rel
sdobjcopy -R .sec5 -I ihex -O binary crt0.ihx snddemo.rom
Run snddemo.rom (I tested in BlueMSX).

 

After you verify it working, you only need to include player.c and player.h in your existing project, don't worry about the rest of my settings. But to compile this program, you do need to worry, as it's a complete program not using any external libs.

 

(I just noticed the "-I../../libti99" 's in the compilation lines -- that is definitely not needed, but it doesn't hurt anything. That folder doesn't even exist on the computer I just did this example on. ;) ) Likewise, the -vc switch is optional, it just formats the error messages. :)

Edited by Tursi

Share this post


Link to post
Share on other sites

Cool.

 

I was able to compile the working rom.

 

For some reason my system doesn't recognize "make". But what I did was enter the make lines you listed above line by line into the command prompt and after it completed each step it worked.

 

Thank you so much. I now need to try and convert a music file of my own into your demo and see if I can do that step.

Share this post


Link to post
Share on other sites

I have now managed to convert a different vgm file and successfully compiled it and it sounds great. Now I need to try to get it into my program and compile under SDCC 3.4

Share this post


Link to post
Share on other sites

Excellent, glad to hear you are making progress!

 

My "make" is probably coming out of Cygwin, then, if you don't have Cygwin installed, it's a handy way to get a lot of the GNU utilities. ;) (There are other, native ports, but Cygwin is handy to have).

 

For your program, you only need player.c and player.h, use "stinit" to start the playback, and call "stplay" every nmi, that should be all it takes!

Share this post


Link to post
Share on other sites

Yeah, it's very exciting. Can't make it work once I try to incorporate it into any other project yet though.

 

AS soon as I make any getput1 librairy calls the rom becomes a black screen when compiled.

 

Gonna keep at it. Could it be the crt0.s vs the crtcv.s file?

 

I don't know assembly language so I reply on the high level languages C etc.

Edited by digress

Share this post


Link to post
Share on other sites

Nah, my CRT0 is tuned for starting a megacart, and for the sample program I tuned it a bit to run with no libs, but it's not doing anything else that would make any difference. I don't know much Z80 asm either. ;)

 

I don't know getput1, but what happens if you run your program with player.c and player.h included, but stinit and stplay commented out? That way you can rule out the player causing the issue (Although it doesn't touch VDP, but, it might eat a lot of your vblank if you are counting on that time.. I would do any NMI VDP operations first, and stplay last).

Share this post


Link to post
Share on other sites

Yeah, I've testing. The moment I include the player library it kills to compiled rom in SDCC with its default compiling.

 

I was able to use your command line sdcc compile options and get it to compile with your library and the getput library and coleco library and play the music but the moment I make a call to the getput1 library it kills the compiled rom. Any ideas what else I can try.

 

Thanks. It clearly plays the music perfectly. So I'm really interested in adding this nice option with full credit to my project. The music I hand coded is inadequate.

Share this post


Link to post
Share on other sites

You're going to have to share code, I think. The symptoms you describe don't make sense. Barring a compiler bug, simply including a module (and not calling any of its functions) should not break the rest of the code.

 

You can email me directly if you don't want to share here (tursi at harmlesslion.com)

Share this post


Link to post
Share on other sites

I sent you a small sample in the email which I was using to test bring the player.c into another getput sample.

 

Thanks.

 

 

You're going to have to share code, I think. The symptoms you describe don't make sense. Barring a compiler bug, simply including a module (and not calling any of its functions) should not break the rest of the code.

You can email me directly if you don't want to share here (tursi at harmlesslion.com)

Share this post


Link to post
Share on other sites

I haven't received anything yet.. check that it went to the right address?

Share this post


Link to post
Share on other sites

I checked, it seemed to send to the address above replaceing the @ symbol of course. Oh well , it doesn't matter. Here is the little sample;

sample


I can compile this as long as the player.c is not compiled along with it. If I rename player.ccc to player.c it doesn't work. I can attached the player.h header file and the compile will work but not the player.c

I noticed crt0.s is looking for _my_nmi as opposed to nmi in the crtcv.s . I tried putting in both but no success. I'm just guessing. I'm not sure.

I have compiled this using the cci2 inluding the crtcv.rel, getput and cvlib files options

Thanks for looking.

Share this post


Link to post
Share on other sites

When I run "result.rom" (having not built anything, just as in your zip file), I get a picture and music. (Running in Bluemsx). I guess that is the normal expected behavior.

 

There's no Makefile.. so I had to figure out the build myself... this is what I did:

 

C:\New\ex\10years>sdcc -c -mz80 -I".." cake.c
In file included from cake.c:7:
../coleco.h:2:1: warning: "/*" within comment
../coleco.h:3:1: warning: "/*" within comment
../coleco.h:4:1: warning: "/*" within comment
../coleco.h:5:1: warning: "/*" within comment
../coleco.h:6:1: warning: "/*" within comment
../coleco.h:7:1: warning: "/*" within comment
../coleco.h:8:1: warning: "/*" within comment
../coleco.h:9:1: warning: "/*" within comment
../coleco.h:10:1: warning: "/*" within comment

C:\New\ex\10years>sdcc -c -mz80 -I".." main.c
In file included from main.c:1:
../coleco.h:2:1: warning: "/*" within comment
../coleco.h:3:1: warning: "/*" within comment
../coleco.h:4:1: warning: "/*" within comment
../coleco.h:5:1: warning: "/*" within comment
../coleco.h:6:1: warning: "/*" within comment
../coleco.h:7:1: warning: "/*" within comment
../coleco.h:8:1: warning: "/*" within comment
../coleco.h:9:1: warning: "/*" within comment
../coleco.h:10:1: warning: "/*" within comment

C:\New\ex\10years>sdcc -c -mz80 -I".." sounds.c
In file included from sounds.c:1:
../coleco.h:2:1: warning: "/*" within comment
../coleco.h:3:1: warning: "/*" within comment
../coleco.h:4:1: warning: "/*" within comment
../coleco.h:5:1: warning: "/*" within comment
../coleco.h:6:1: warning: "/*" within comment
../coleco.h:7:1: warning: "/*" within comment
../coleco.h:8:1: warning: "/*" within comment
../coleco.h:9:1: warning: "/*" within comment
../coleco.h:10:1: warning: "/*" within comment

C:\New\ex\10years>sdcc -mz80 --no-std-crt0 --code-loc 0x8100 --data-loc 0x7000 -l"..\cvlib.lib" -l"..\comp.lib" -l"..\getput.lib" "..\crtcv.rel" cake.rel main.rel sounds.rel

C:\New\ex\10years>objcopy -I ihex -O binary crtcv.ihx test.rom

C:\New\ex\10years>
All those warnings in coleco.h really should be fixed.... it's not good to ignore warnings. :) Anyway, the above lines produced a working ROM, so I went ahead and added the player.

 

C:\New\ex\10years>sdcc -c -mz80 -I".." player.c

C:\New\ex\10years>sdcc -mz80 --no-std-crt0 --code-loc 0x8100 --data-loc 0x7000 -l"..\cvlib.lib" -l"..\comp.lib" -l"..\getput.lib" "..\crtcv.rel" cake.rel main.rel sounds.rel player.rel

C:\New\ex\10years>objcopy -I ihex -O binary crtcv.ihx test2.rom

C:\New\ex\10years>
And as you noted, this suddenly produced a ROM that didn't even start!!

 

However! I have the answer (although I need to look deeper into why it's a problem, I just assumed it was the new compiler as the older SDCC did not do this. Knowing that it's triggered by player.c, I can look into it deeper.)

 

Anyway, the problem is that the linker includes the RAM zero init area, which screws up the offset. We just need to drop that section when we do the objcopy line:

 

C:\New\ex\10years>objcopy -I ihex -O binary -R .sec5 crtcv.ihx test2.rom

C:\New\ex\10years>
With that, the ROM now works! thanks for your patience helping to understand this. :)

Share this post


Link to post
Share on other sites

awesome. I wish I could try it out right now. Later today when I have some time. I'll let you know if I can get it as well.

Share this post


Link to post
Share on other sites

Ok I got a little further. I got a working compile with the graphics on screen and the music playing from your library. Music sounds great before I bring in the getput libraries but Music is distorted for some reason though after I attached the getput library.

 

I attached 2 files. 1 without any getput libraries attached and the same file after I got the libraries attached and graphics on screen.

 

same music file other wise.

 

http://www.eriscreations.com/downloads/test2.zip

Edited by digress

Share this post


Link to post
Share on other sites

Sounds like something else is writing to the sound chip and muting the audio. I'd take a closer look at what the libraries you are adding did. Are you still activating the BIOS music player, for instance?

Share this post


Link to post
Share on other sites

I got it!

 

It's now working with graphics and sprites & the music is working . After trying a bunch of different things...I'm not %100 sure what I did different as I changed too many things at once.

 

seems the main thing was to put in a delay(1) and have the stplay in my main loop rather the the nmi routine.

 

Now I'm going to try it in the full game seem if I can get the whole package at once working.

Share this post


Link to post
Share on other sites

edit. I realize it should be in the nmi routine and this was just a backwards way of getting it to work. So I'm leaving it in the nmi routine but at least I know it works.

Share this post


Link to post
Share on other sites

Excellent, congrats!

 

It doesn't matter if it's called from the NMI itself, it's only the timing that matters. :)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...