Since the release of the Palm Tungsten T, Palm Inc handhelds have the capability to play back WAV files(aka sampled sound). I have recently implemented such a sound routine and found an interesting twist(due to MemGluePtrNew not working)…and felt like sharing it with you!

Essentially, sampled sound works by repeatedly calling a function and requesting that it outs wave data into a buffer, from where it is then played. The main problem here is that the callback must execute quickly and should not loose any data(frame skipping). “Wrapping around” the end of a RAM buffer can be tedious both code and performance-wise, but the Palm OS has a little-úsed but very useful feature called a file stream.

The function below is called to start the music:

void startBGM()
{
//Check if data really is UINT8
MemHandle r0,r1,r2,r3;
void *me;

//Make buffer
r0=DmGetResource(wavRsrcType,1000);
r1=DmGetResource(wavRsrcType,1001);
r2=DmGetResource(wavRsrcType,1002);
r3=DmGetResource(wavRsrcType,1003);
sounddata.stream=FileOpen(0,BGM_STREAM_NAME,NULL,NULL,fileModeReadWrite|fileModeTemporary,NULL);

//Write to buffer
me=MemHandleLock(r0);
FileWrite(sounddata.stream,me,MemHandleSize(r0),1,NULL);
MemHandleUnlock(r0);
me=MemHandleLock(r1);
FileWrite(sounddata.stream,me,MemHandleSize(r1),1,NULL);
MemHandleUnlock(r1);
me=MemHandleLock(r2);
FileWrite(sounddata.stream,me,MemHandleSize(r2),1,NULL);
MemHandleUnlock(r2);
me=MemHandleLock(r3);
FileWrite(sounddata.stream,me,MemHandleSize(r3),1,NULL);
MemHandleUnlock(r3);

FileFlush(sounddata.stream);
FileRewind(sounddata.stream);

DmReleaseResource(r0);
DmReleaseResource(r1);
DmReleaseResource(r2);
DmReleaseResource(r3);

//Start stream
SndStreamCreate (&stream,sndOutput,BGM_SAMPLERATE,sndUInt8,sndMono,SndStreamBufferCallbackFunc,&sounddata,BGM_BUFFERSIZE_FRAMES,false);
SndStreamStart(stream);
}

Essentially, it creates a new file stream, opens each of the “bits” of sound in the application database, and puts it all together into the file stream. It then creates a new stream and starts it. BTW, FileWrite’s documentation in PODS is wrong…but more on that later.

The music gets ended by this call:

void stopBGM()
{
SndStreamStop(stream);
SndStreamDelete(stream);
//Clean up buffer
FileClose(sounddata.stream);
}

This first stops and deletes the stream, and afterwards cleans up the buffer.

Last but not least, here’s the callback and the global data struct:

typedef struct{
//Contains all data that the sound stream callback needs
UInt32 framesdone;//aka where to start copying
FileHand stream;
}sounddatat;

static Err SndStreamBufferCallbackFunc (void *userDataP, SndStreamRef stream, void *bufferP, UInt32 frameCount)
{//NO GLOBALS!!!!
//Write data from buffer
UInt32 err;
sounddatat *sounddata=userDataP;
err=FileRead(sounddata->stream,bufferP,1,frameCount,NULL);
if(err!=frameCount)
{
FileRewind(sounddata->stream);
FileRead(sounddata->stream,bufferP+err,1,frameCount-err,NULL);
}
}

The sounddatat type gets passed to the callback each time the sound manager needs data. It contains all information needed to generate the next block of data. The err!= filecount bit of code is used to determine if we “ran over the end” of the file stream…if we did, the stream is rewinded and reading commences once again from the beginning to fill the buffer up completely.

What do you think?

Related posts:

  1. malloc and free for Palm OS
  2. Globals in DAs
  3. Chronology of Palm Music
  4. Detecting color screens programatically
  5. Implementing a Software UART

2 Responses to “Implementing background music for Palm OS games”

  1. Nice! This will come in handy. I have been putting off implementing sound in wifight for too long. I need to read up on the file streaming functions I guess.

  2. Hi Brennan,
    all you need is right above!

    Best regards
    Tam Hanna

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe without commenting

© 2013 TamsPalm - the Palm OS / web OS Blog Suffusion theme by Sayontan Sinha