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 > Direct sound problem (Turning DMA off)

#11601 - DennisBor - Mon Oct 13, 2003 4:43 pm

At the moment, I'm trying to get direct sound to work on the GBA. Well, it works... half :). My sample plays just the way it should, but when it's finished I get noise, infinite...

I already know what the problem is. After the soundtrack is finished playing, the DMA channel should be turned of. Manually turning it off after playing the soundtrack works, but that's not the way it should work.

I suppose I need some counter, counting every played sample and if the counter has reached it's limit (end of the soundtrack, total # of samples of the soundtrack) it calls an function DMA.TurnOff().

Here's my code (don't know if you need it though)

gba.cpp

Code:

/**
 * Setup direct sound using the given parameters
 *
 * @param         Parameters            the parameters from which to
 *                                 set up directsound
 */
void CSound::SetDirectSound(unsigned short Parameters)
{
   // set the direct sound control bits (memory address 0x04000082)
   *(unsigned short*)DirectSoundControl = Parameters;
}

/**
 * Enable the GBA's sound system
 */
void CSound::Enable()
{
   // set bit 7 of the sound memory address 0x04000084 (32-bit value) to 1
   *(unsigned long*)0x04000084 = 0x00000080;
}

/**
 * Start the Direct Sound
 *
 * @param         Frequency            sound sample frequency, eg: 22050
 *
 *               Wavedata            pointer to the wave data
 */
void CSound::Start(int Frequency, signed char* Wavedata)
{
   // set the DMA channel 1 address
   *(unsigned long*)DMA1SourceAddrLow = (unsigned long)Wavedata;

   //set the destination address to fifo a address
   *(unsigned long*)DMA1DestAddrLow = FIFOChannelALow;

   *(unsigned long*)DMA1ControlLow = EnableDMA | StartOnEmptyFIFO | WordDMA | DMARepeat;

   *(unsigned long*)IRQMasterEnable = 1;
   *(unsigned short*)IRQEnable = IRQTimer1;

   // set the timer 1 countdown
//   *(unsigned long*)Timer1Count = 65531;
   //*(unsigned short*)Timer1 = EnableTimer  | TimerOverflow;

   *(unsigned short*)Timer0Count = (0xFFFF - 16777216 / Frequency);
   *(unsigned short*)Timer0 = EnableTimer;

}


main.cpp

Code:

#include "gba.h"
#include "gba.cpp"
#include "music.h"

/**
 * Our main function
 */
int main()
{
   // initialize the GBA class
   GBA myGBA;

   // set the Direct Sound Parameters
   myGBA.Sound.SetDirectSound(SoundOutputRatio100 |
      DirectSoundAOutputRatio100 |
      DirectSoundAOutputBoth |
      DirectSoundATimer0 |
      DirectSoundAFIFOReset);
   
   // turn the sound chip on
   myGBA.Sound.Enable();

   // start the soundtrack (at 22050 kHz)
   myGBA.Sound.Start(22050, myMusic.Data);

   // game loop
   while(1)
   {
      // has the start button been pressed?
      if (myGBA.Input.KeyPressed(KeypadStart))
      {
         // turn off the sound DMA channel (1)
         DMA.TurnOff(Channel1);
      }
   }

   return 0;
}


I really hope you guys can help me out![/code]
_________________
I rather have a compiler than a girl... A compiler isn't complaining all the time!

#11603 - sajiimori - Mon Oct 13, 2003 5:36 pm

Quote:

I rather have a compiler than a girl... A compiler isn't complaining all the time!

What compiler do you use??

Code:

byte a, b;
a = b + 1;

Error: cannot implicitly convert 'int' to 'byte'

Code:

void f() { g(); }
void g() { puts("blah"); }

Warning: 'g' was previously declared to return 'int'

Code:

std::vector<std::vector<int>> x;

Error: You want to shift what to the right?  Are you stupid?