gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Sound playing problem

#146222 - Echo49 - Fri Nov 30, 2007 9:01 pm

I'm trying to make a double buffer sound playing routine which I intend to use with libfat to stream sound from my flashcart. The problem is that whenever I use my own transferSound() routine to send the data, every so often I miss 3 seconds of music. However, it works fine with the playSound() function from sound.c. My transferSound() function is identical to playSound() except that it allows me to specify which one of the 16 places to insert the data into. Any idea why this is happening?

Also, any recommendations as to the size of the buffers, and is there any way to sync the music properly? At the moment it's lagging by about 5 samples every second, hence the SYNC_CORRECTION define.

Code:

#include "music_raw.h"

#define SYNC_CORRECTION 5

u8* buffer;
u8* backbuffer;
bool fill;

// this will always point to the sound data
TransferSoundData soundb = {
   NULL,
   11025,
   11025,
   127,
   64,
   1
};

TransferSound Snd;
void transferSound(u8 slot, TransferSoundData* sdata)
{
   Snd.count += 1;
   memcpy(&Snd.data[slot], sdata, sizeof(TransferSoundData));
   DC_FlushRange(&Snd, sizeof(TransferSound));
   IPC->soundData = &Snd;
}

void timerHandler()
{
   // send data to ARM7 to play
   soundb.data = buffer;
   transferSound(0, &soundb);
   // tell backbuffer to fill
   fill = true;
}

int main(void) {

   powerON(POWER_ALL);
   
   irqInit();
   irqEnable(IRQ_VBLANK | IRQ_TIMER0);
   irqSet(IRQ_TIMER0, timerHandler);
   
   lcdMainOnBottom();
   
   consoleDemoInit();
   
   buffer = (u8*)malloc(11025*sizeof(u8));
   backbuffer = (u8*)malloc(11025*sizeof(u8));
   
   TIMER0_DATA = TIMER_FREQ_1024(1);   
   TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1024 | TIMER_IRQ_REQ;   
      
   u32 i;
   u32 pos = 0;
   
   fill = true;
      
   while(true) {
   
      Snd.count = 0;
      
      if (fill) {
         // fill backbuffer
         for (i=0; i<(11025); i++)
         {
            backbuffer[i] = music_raw[pos+i];
         }
         pos += 11025 + SYNC_CORRECTION;
         fill = false;
         // swap buffers
         u8* temp = buffer;
         buffer = backbuffer;
         backbuffer = temp;
      }
      
      swiWaitForVBlank();
   }

   return 0;
}