GP32 Ringbuffer Code Crashing


pea posted on Mar 16 2005 at 01:30 AM said:
I fixed it guys.

I'm almost ashamed to say this - it was so fundamental :(
The problem was that I had set all the compiler flags in a CFLAGS variable, but then never used it in the makefile, so it was compiling at the default settings! i.e. it wasn't even using -mtune=arm9tdmi

It plays with no crackling now (still using SAMPLEBUFFER1) and now I will try to use the original SAMPLEBUFFER0 code to see if that works ok too, and also try it at 44100 kHz.

EDIT: 44100 kHz is fine, but refuses to work with FRAMEBUFFER0 - crashes when writes to upper buffer

If you are using :
void gp_addRingsegment( u16 *add_buffer );

libmikmod must render its output to SAMPLEBUFFER1.
SAMPLEBUFFER0 is the real played ringloop. Modified by gp_addRingsegment.
 
Last edited by a moderator:
But don't do page flipping as these can wait for a screen refresh before they return and it'll skew your result.

Thanks Rich. Nothing going on while I play music at the moment, but I can add something in there (some Sin calc or something) Only problem is that when I update the ringbuffer with some more sample, it waits for the ringbuffer to enter the next segment, so that would skew the results too :) I will think of something for that.

If you are using :
void gp_addRingsegment( u16 *add_buffer );

libmikmod must render its output to SAMPLEBUFFER1.
SAMPLEBUFFER0 is the real played ringloop. Modified by gp_addRingsegment.

Hi Mr.Mirko - not sure what you mean :blink:

What I have done is altered your SDK (init1330.c) and recompiled it.

All the ringbuffer code used to refer to SAMPLEBUFFER0, and there was never any mention of SAMPLEBUFFER1 at all. All I did was search-and-replace all instances of SAMPLEBUFFER0 with SAMPLEBUFFER1, and changed one line of the code to allocate the correct amount of memory (SAMPLEBUFFER1 is half the size of SAMPLEBUFFER0).

Here are my new functions

Code:
void gp_clearRingbuffer() {
    int i;
    u16 *SEGMENT0 = (u16*)SAMPLEBUFFER1;
    for (i=0;i<(BSIZE)/2;i++) *SEGMENT0++ = 0;
}

// Init Sound, starts a Ringbuffer with 2 segments
// Ringbuffer is BSIZE (in bytes)
// One segement is BSIZE/2
void gp_initSound( int freq, int bit, int ringsize) {
     int sysfs=0;
     if (bit == 8) bit=0; else bit=1;
     if (ringsize > 1024*16) ringsize = 1024*16;
     BSIZE = ringsize; SEGMENTSIZE = ringsize/2;
     GpPcmStop();
     sysfs=InitIIS (gp_getPCLK(),freq,bit);
     Init1330( sysfs, iisbus,0);
     gp_clearRingbuffer();
     //gp_setMMU( SAMPLEBUFFER1, (SAMPLEBUFFER1+16384)-1, 0xFFA );  //no cache for samplebuffer
     gp_setMMU( SAMPLEBUFFER1, (SAMPLEBUFFER1+8192)-1, 0xFFA );  //no cache for samplebuffer
     gp_setMMU( UNCACHED4KB0 , (UNCACHED4KB0 +16384)-1, 0xFFA );  //no cache for extra_ram
     GpPcmPlay( (u16*)SAMPLEBUFFER1, BSIZE, 0, bit); // Loop endless
}

void gp_addRingsegment( u16 *add_buffer ) {
     int i;
     u16 *SEGMENT0 = (u16*)SAMPLEBUFFER1;
     u16 *SEGMENT1 = ((u16*)SAMPLEBUFFER1) + SEGMENTSIZE/2;   // ((short*)0xf000)+4 is exactly the same as ((short*)0xf000)[4]
     // detect playing segment
//gp_debug( 1, "addRS: get sample pos" );
     if ( gp_getSamplepos() > (u32)SEGMENT1 ) {  // we are in upper segment
//gp_debug( 1, "addRS: upper segment. fill buffer %d", SEGMENT0 );                       
       for (i=0;i<SEGMENTSIZE/2;i++) SEGMENT0[i] = add_buffer[i];  // fill lower segment
//gp_debug( 1, "addRS: wait for lower segment" ); 
       while (1) {  if (gp_getSamplepos() < (u32)SEGMENT1) break;  }    // wait reaches lower segment
     }
     else {
//gp_debug( 1, "addRS: lower segment. fill buffer %d", SEGMENT1 ); 
        for (i=0;i<SEGMENTSIZE/2;i++) SEGMENT1[i] = add_buffer[i]; // we are in lower segment, fill upper segment
//gp_debug( 1, "addRS: wait for upper segment" );
        while (1) {  if (gp_getSamplepos() > (u32)SEGMENT1) break;  }   // wait reaches upper segment
     }
}
 
Back
Top