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.

Audio > DMA Sound Loop Works on emulator, & doesnt work in real

#4294 - rome - Wed Mar 26, 2003 6:52 pm

my GBA dma routine loop sound works perfectly in Virtual Game Boy emulator (sounds play in loop), but when i pass the rom to flash cartridge and play it on real GBA hardware, the sound runs and dont return the Cursor to play the same sound (loop the sound). can anyone help me?

Code:


void InterruptProcess(void)
{
    // timer 1 irq will be triggered when sound reaches the end
   if(REG_IF & INT_TIMER1)
   {
      // reset the sound source DMA transfer
      REG_DM1SAD   = (unsigned long)p_data;
   }
   REG_IF |= REG_IF;
}


int main (void)
{

  REG_INTERUPT = (u32)&InterruptProcess;

   // len keep the file size in bytes   
   len = GetFileSize(0);
   // p_data keep the pointer to data
   p_data = (char *)GetFileData(0);

    //play a mono sound at 16khz
//uses timer 0 as sampling rate source
//uses timer 1 to count the samples played in order to stop the sound
REG_SGCNT0_H=0x0b0F; //enable DS A&B + fifo reset + use timer0 + max volume to L and R
REG_SGCNT1=0x0080; //turn sound chip on

REG_DM1SAD=(unsigned long)p_data; //dma1 source
REG_DM1DAD=0x040000a0; //write to FIFO A address
REG_DM1CNT_H=0xB640; //DMA enabled + starton fifo req + 32 bit + repeat + increment source, leave dest (FIFO dest)

REG_TM1D=0xFFFF - len; //0xffff-the number of samples to play
REG_TM1CNT=0xC4;  // init timer cascade and generate irq

REG_IE=0x10; //enable irq for timer 1
REG_IME=1; //master enable interrupts

REG_TM0D=0xFBE8; //16khz playback freq
REG_TM0CNT=0x0080; //enable timer0 at 16 khz
   
while (1)
 {
 }
}

#4298 - tepples - Wed Mar 26, 2003 8:23 pm

The GBA hardware ignores writes to an active DMA channel. In order to reset DM1SAD on hardware, you have to first turn off the DMA channel, change the source address, and then turn the DMA channel back on.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#4299 - rome - Wed Mar 26, 2003 8:48 pm

oh yeah! great tip! thank you so much tepples!
now it works perfectly, in emulator and real GBA hardware

#9094 - Daikath - Mon Jul 28, 2003 1:29 pm

Ive got another problem, it works on an emulator (though not as it should do but thats not the most imprtant problem right now). but when I play it on the actual hardware it doesnt do anything.

This is my code
Code:
/ Sound.c AGBmain Entry point is contained here (main program loop)

#include <gba.h>
#include "soundregisters.h"
#include "stdlib.h"
extern const u8 sound[];

u16 counter;
void WaitforVsync()
{
  while (REG_VCOUNT != 160);
  while (REG_VCOUNT != 161);
   counter++;
   if (counter == 152)
   {
      counter = 0;
   }
}


void AgbMain(void)
{
   SetVideoMode(MODE1 | OBJ_ENABLE | OBJ_MAP_1D);
   REG_SOUNDCNT_L = 0;
   REG_SOUNDCNT_H = SND_OUTPUT_RATIO_100 |
                 DSA_OUTPUT_RATIO_100 |
                 DSA_OUTPUT_TO_BOTH |
                 DSA_TIMER0 |
                 DSA_FIFO_RESET;
   REG_SOUNDCNT_X = SND_ENABLED;
   
   
REG_DMA1SAD = (u32)(sound);
REG_DMA1DAD = (u32)REG_FIFO_A;
REG_DMA1CNT = ENABLE_DMA | START_ON_FIFO_EMPTY | WORD_DMA | DMA_REPEAT | 0x40;

   REG_TM0D   = TIMER_INTERVAL;
   REG_TM0CNT = TIMER_ENABLED;
   

   while(1)
   {
      
      WaitforVsync();
   }
}

//end of entry point



_________________
?There are no stupid questions but there are a LOT of inquisitive idiots.?

#9104 - DekuTree64 - Mon Jul 28, 2003 4:09 pm

Daikath wrote:
Code:
REG_DMA1DAD = (u32)REG_FIFO_A;

Should be
Code:
REG_DMA1DAD = (u32)& REG_FIFO_A;

I think that will fix it^^

EDIT: had to put a space betweer the & and the R, cause it turned into a trademark thing...
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku