Tuesday, April 23, 2013

Stuck on Segfault

This time I really and truly wanted to get a links browser build running on the zipit with ttf fonts instead of the fuzzy built-in fonts.  Unfortunately a nasty segfault halted my forward progress like a brick wall.  I swear I'm almost there.  Really.  But apparently not in the mood for a serious debugging  effort.

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.
Heh.  It sounded even crappier than the Super Mario sound running in fceu on the zipit.  But I stuck with it and learned a few things.  Notably, the first 4 sounds in all of the sample music tracks appear to be loaded from .wav files, and work just fine.  The other 12 sounds are typically synthesized at runtime to create an octave of notes, or a few chords.  These FM synthesized notes are generated on the fly at runtime, but about 10 times too slowly for actual use due to the lack of a floating point unit in the zipit processor.   I think this is basically the problem with the fceu sound code.  It can't create sounds fast enough to use them in a timely manner on the zipit hardware.

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...

Yeah, so that turned out to be a relatively easy build for the zipit.  It takes almost 30 seconds to load, but seems to work ok.  However it requires the z2mouse which makes it somewhat cumbersome to use.  I might take a look at the keybinding code someday to make it easier to control.  Although I'm not sure how much I can do.  It seems to have a function for every single key on a full PC keyboard.  So any sort of "fix" would just be a trade off for a slightly more usable set of keys.

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.
It also sounds like the music is being played underwater.  Is that really the way 8bits used to sound?  No, it's not.  Turns out the mixer code in funktracker uses doubles.  The individual instruments actually sound just fine when played manually via the the single octave on the z row of the keyboard.  I did some experiments reshaping the display for a bigger font, and fixed some nasty stack overrun bugs caused by string overflows.  I'd say this has promise, if I can convert the mixer code to integers.


Update: 

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.

Update 2: 

 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.

Update 3:

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.

drumtoy-fm-iz2s.zip
drumtoy-fm-wrt.tgz
drumtoy-fm-wrt-bleeding-edge.tgz

And here's a milkytracker package for IZ2S.


The openwrt package should have shown up in the nightly builds by now.  It's in mozzwald's repo but not yet in the chainxor repo, which probably calculates "nightly" in Australian.

4 comments:

  1. I have renewed ebindkeys-z2mouse-iz2s.zip (04-16-2011) in the goodibag, the file was corrupted.
    Milkytracker reminds me my old Amigas ! We can find mods to play and to play with at
    http://modarchive.org/

    ReplyDelete
  2. I missed out on the entire Amiga scene. IBM cleverly locked me into the PC architecture when they financed a new building at CMU in exchange for a requirement that all of the CS students must obtain a Mellon Bank credit card and purchase an expensive IBM PC with it at a 20% interest rate. By the time I got out from under that loan I already had kids, so my first audio hardware was the Disney Sound Source instead of the more stylish Amiga.

    I'm trying to make up for lost time now, prowling around various chiptunes sites like woolyss.com and http://shiru.untergrund.net/1bit to see what I missed.

    ReplyDelete
  3. Maybe this will help. I found, playing with Milkytracker, that the Z2mouse makes conflict with my sd card, if i extract and reinsert it with z2mouse enabled, it will not be recognized, or with errors, or rarely readonly. I'm not good enough to draw any conclusion.

    ReplyDelete
  4. That's scary. I haven't seen that behavior yet myself, but I'll watch out for it. I already dislike the fake mouse driver, and this just reinforces my opinion.

    I'll have to see if I can somehow make milkytracker completely useable with the keyboard commands. Meanwhile I have funktracker mostly patched up for the smaller zipit screen, and it only uses the keyboard.

    ReplyDelete