Before I hit the bricks I made a little bit of progress. I discovered links apparently has 33 language translations for the menus baked right into the executable, just like the font system. I removed all but English and French for a 500K RAM savings at runtime and a 100K savings on the jffs. Not too shabby. I also devised a simple way of loading one or more of the excised translations at runtime from a shared lib using dlopen, but didn't code it up yet,
Anyhow, this put my free space on the jffs right up around a megabyte. Sweet! So I pressed ahead and cut ties with the internal font, roughed in a ttf system based on the plan9 varfont patch, and found myself with a "tiny" 500K upxed links executable that promptly segfaulted. Aargh! So close. I bet if I swapped out the openssl bloat for the tiny matrix ssl library I could get it down around 300K. Of course, it doesn't work right now. There's probably some residual piece of the old font system poking at random memory through a bad pointer that I forgot to prune out. I'll get it, but i need to step away for a moment.
Maybe some relaxing music might get me back into the swing of things? Well, actually this has been bugging me since the sound system in my fceu build didn't quite work. I decided to try and port the SDL Drum Toy to get a better idea of how game sound is accomplished. So I shrunk up the interface from 640x480 to 320x240 for the zipit and gave it a spin.
When I commented out the DrumToy FM synth code, the tracks played at full speed, albeit with only the 4 digital drum sounds. So I thought maybe if I converted the FM synthesized voices to digital samples on startup then I could play the full musical track. I allocated a generous 2 seconds worth of samples to each synth voice and suddenly it was taking 3 minutes to bring up the main screen. That's not so good. I also botched the formula because the sampled FM synth notes were pure noise. But at least the tracks were now playing at full speed. So instead of synthesizing I borrowed the samples from the NDS bliptracker and used them to replace six of the synthesized voices in the demo1 track. It sounded weird, but it worked. It looks like you can probably make full use of all 16 voices in the DrumToy if you can find 12 more decent mono .wav files.
This music stuff is kinda fun so I may tinker with it some more, until I feel like taking on the segfault. There must be some simple integer only synth code out there somewhere, right? Didn't we have different notes on the PC speaker way back when DOS ran off a flippy floppy? I may even have a 5 inch floppy in the attic with that sort of code on it. Too bad I got nothing to read it.
I see there's quite a bit of sample code here. And this has some fast integer sine functions, with arm assembler code! Just what the doctor ordered. The DrumToy FM synth boils down to a few floating point multiplies and two sine calls per sample. If I can just convert it all to fixed point, that function might just do the trick.
There's also an interesting thread on MilkyTracker at the dingoo forum. Hmm...
Since I don't particularly like the dpad "mouse", I thought it might be a good idea to try and dig up something mouseless. I ran a search for ncurses trackers, but most of that stuff appeared to be rather old. I built the ancient funktrackerGOLD and managed to play it's example songs, but it reqires an 80 character wide terminal, which forced me to load this nearly unreadable Atari font.
I've spent some time in the DrumToy code and made a little bit of progress. The integer sine functions seem to work ok. It can now synthesize the 12 FM notes on the fly, which is pretty cool. The small errors introduced by the integer math may be changing the tone of the notes somewhat, but it's hard to tell because I've found a bigger problem. The tempo isn't working right on the zipit. At some point I noticed the 4 wav sounds seemed to stutter and hang around too long, which got me looking at the code for maintaining the tempo. It's starting to look like the DrumToy was programmed with a fairly powerful PC in mind.
I'm not sure exactly where the tempo problem originates, but I suspect there's too much wasteful math happening in some of the inner code loops where it should just be moving data out to the audio device. I did some experiments with reducing the graphics overhead and that quickened the tempo quite a bit, but still not quite up to full speed. I also did an experiment with no notes playing, not even the wav notes, and it still failed to keep up with the expected 120 beats per minute. That should never happen. So I've gotta fix this before I go back and attempt to smooth out the FM sounds by tweaking the location of the decimal point in the integer math.
Heh. Apparently there was some more sneaky floating point math (that I completely missed) in the saturation_process function. I commented that out and now it runs at the correct speed. So it's back to tweaking the integer math in the FM synthesis code. Gotta find me a few more bits of precision for those low, low notes in the demo1 track.
Actually all of the integer math notes were sounding a bit flat, even to my tin ear. What's up with that? I dug up a cheap guitar tuner gizmo and verified it. They are indeed flat. Whereas the tuner says the floating point math is generating the true notes. Hmm, maybe I should go back to double precision floats for the initial frequency calculations, and save the integer math for the runtime sample generation? Or maybe the integer sine function loses precision as the number of cycles increases? I don't know, so I think I'll go back and retest it with some additional (more realistic) sample points.
I solved the problem with the flat notes. It was accumulating errors in the integer math, which pushed all the frequencies off by a few cycles per second. Now it sounds halfway decent, and the guitar tuner gives it the thumbs up too. It still needs lotsa work with the location of the decimal point in all of the integer multiplies. I think there are parts of the code where I'm down to a single bit of precision -- the sign bit -- but it's only supposed to be a "toy", right? So it'll have to do for now.
Here's a nice blurry video. Enjoy.
Here's some DrumToy executables for IZ2S and OpenWRT, with the integer FM synthesis source code included.
And here's a milkytracker package for IZ2S.