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 > Playing Notes?

#61681 - hello world - Tue Nov 22, 2005 5:37 pm

Hi, I was wondering if it is possible to play a sound at a certain pitch for a certain amount of time (if you could give me an example i would be grateful). If possible it would also be helpful if you could explain it fully, since i am very new to Gameboy Advance developement.
Thanks.

#61683 - thegamefreak0134 - Tue Nov 22, 2005 6:11 pm

Well obviously it's possible, or there wouldn't be any music in games, now would there? There are many ways to get this done, actually. There are the 4 GB channels used by the old GB and GBC games that can all play notes (save for the 4th, which is noise.), and then there are the 2 direct sound channels which can take any samples you provide them. Coupled with a mixer (either one you write or one you get from someone else) these can be used to play any sound imaginable, including what you're talking about.

I recommend posting specifically what you need soundwise, as it will be easier to determine a proper solution. But yes, it IS possible.
_________________
What if the hokey-pokey really is what it's all about?

[url=http:/www.darknovagames.com/index.php?action=recruit&clanid=1]Support Zeta on DarkNova![/url]

#61688 - hello world - Tue Nov 22, 2005 6:54 pm

An example of what i need, could be summed up by "monophonic ringtone" but if possible i would have two playing at the same time.

#61696 - tepples - Tue Nov 22, 2005 7:55 pm

So you want to make NES/GBC style music. Here are the steps to get started:
  1. Read everything at The Audio Advance that pertains to the tone generators.
  2. Figure out how to play a single tone on channel 1 and how to silence it.
  3. Figure out how to play a single tone on channel 2 and how to silence it.
  4. Read about musical tuning systems including equal temperament and MIDI note numbers.
  5. Construct a lookup table mapping MIDI note numbers 36 through 99 (the usable range of tone generators) to period values. Middle C is note 60; 36 through 99 represent the usable range of the tone generators.
  6. Create a table of note numbers that represent a melody. Loop through this table and play the rests and notes on each channel as you see them.

_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#61795 - hello world - Wed Nov 23, 2005 5:10 pm

No offence, but I have no idea what you are talking about. Isn't there a simple way to play a sound at a definable pitch & for a certain time?

#61796 - kusma - Wed Nov 23, 2005 5:19 pm

read the specs and wisdom will come to you.

#61799 - hello world - Wed Nov 23, 2005 6:01 pm

I've had a look and I can't make anything out, all I know is I need REG_SOUND1CNT_H & REG_SOUND1CNT_X , but I have no idea how to use them :-(.

#61801 - kusma - Wed Nov 23, 2005 7:03 pm

if you have no clue on how to write to hardware-registers, perhaps you should be asking in the Beginners-forum instead?

#define REG_SOUND1CNT_H (*((u16 volatile *)0x04000062))
REG_SOUND1CNT_H = some_value;

#61803 - poslundc - Wed Nov 23, 2005 7:26 pm

hello world wrote:
No offence, but I have no idea what you are talking about. Isn't there a simple way to play a sound at a definable pitch & for a certain time?


Depends what you consider to be simple, but if you think it's going to be something like "play(sound);" then the answer is no, there isn't.

This is GBA programming, not Visual Whatever or anything. Learn to crawl before you learn to walk, or you'll trip all over yourself.

Dan.

#61807 - keldon - Wed Nov 23, 2005 8:47 pm

Your answer is yes; there is a simple way to play a sound.

First get some code working that will produce a sound - any sound. Once you have done this then create code that will read out a sequence of notes and play them. Once you have done this everything else will become obvious.

The following sound table shows you what values will get you the correct frequencies to notes
http://devrs.com/gb/files/sndtab.html

The gameboy allows two sounds to be played simultaneously without any trouble.

Also you can use gbatek as your guide to answering these questions.
http://www.work.de/nocash/gbatek.htm
direct -link to sound-

#62245 - thegamefreak0134 - Mon Nov 28, 2005 6:14 pm

If you're still having issues, I recently got Krawall to work for my project. It's a bit of a hassle to set it up, but I can give you all the things you need to do for your project and give you an example, and even walk you through it if need be.

What this will do is let you create a blank .s3m file with the sounds (technically samples) you want to play. Then, simply call the krapSFX() thingy (can't remember off hand) with the name of your sample and you're good to go. Since you're not limited as to what you can include in a sample, you can very easily put like a square wave as a sample, which will sound like an old nokia phone.

As for dynamically changing the length of the playing sound, I believe you can set a loop property on the SFX, and then release the loop when the sound is done. However, I'll have to check my docs later to back that statement up.
_________________
What if the hokey-pokey really is what it's all about?

[url=http:/www.darknovagames.com/index.php?action=recruit&clanid=1]Support Zeta on DarkNova![/url]

#62796 - hello world - Mon Dec 05, 2005 8:03 pm

Basically, I've had a close look at the audio advance, and have found that I need channel 2, using the registers SOUNDCNT_L, SOUNDCNT_H, SOUNDCNT_X, SOUND2CNT_H and SOUND2CNT_L. I should be able to play a sound, but it doesn't work...
Here's my code:
Code:

int main()
{
SOUNDCNT_X = 0x80;
SOUNDCNT_L=0x2277;
SOUNDCNT_H = 2;
SOUND2CNT_L=0xf780;
SOUND2CNT_H=0x8400;
return 0;
}


By the way, I know that I haven't used the prefix "REG_"

#62797 - SittingDuck - Mon Dec 05, 2005 8:23 pm

You need to set up:
1. the correct timer at the correct rate (one that doesn't click and which is the correct sample rate, hard to find.)
2. DMA to transfer buffer contents into the FIFO buffer
3. Every VBlank point the DMA to one buffer and fill the other (double-buffering technique).

Note that you can't read from the FIFO register. The FIFO registers don't represent memory locations. Just write to them to output audio. (You don't need to - DMA will do it).

Just read some tutorials:

http://belogic.com/gba/
http://www.pineight.com/gba/samplerates/
http://deku.gbadev.org/program/sound1.html
http://user.chem.tue.nl/jakvijn/tonc/ <- look at DMA and timers

#62799 - keldon - Mon Dec 05, 2005 9:20 pm

Code:

   u16 ALLON = 1 << 7; // you had bit 8 set
   u16 leftVol = 7 << 4;
   u16 rightVol = 7;
   u16 enableFlags = (2 << 8)| (2<<12);
   u16 soundVol = 2; // max volume
   
   
   REG_SOUNDCNT_X = ALLON;
   REG_SOUNDCNT_H = soundVol;
   REG_SOUNDCNT_L=leftVol | rightVol| enableFlags;
   
   int  soundLen = 0; // 250 ms
   int patternDuty = 2 << 6;
   int envelopeStep = 7 << 8;
   int envelopeDir = 0; // decrease
   int initVol = 0xf << 12;
   
   REG_SOUND2CNT_L= soundLen | patternDuty | envelopeStep | envelopeDir | initVol;
   
   int frequency = 1500; // 64 hz
   int lenFlag = 0;
   int restart = 1 << 15;
   REG_SOUND2CNT_H= frequency | lenFlag | restart;
   // note that bits 11-13 are not used, and the 4 in ox8400 includes bit 11


I found that you had set a lot of bits which had no effect. Also I found that my include in DevkitPro (gba_sound.h) was incorrect - shown below.

Also check your defines
Code:
#define   REG_SOUNDCNT_L   (*((u16 volatile *) REG_BASE + 0x080))

Code:
#define   REG_SOUNDCNT_L   (*((u16 volatile *) (REG_BASE + 0x080)))

Check your defines. I know

#62877 - hello world - Tue Dec 06, 2005 5:51 pm

Thanks keldon, I can finally play a sound, I wonder why it didn't work before...

#62929 - keldon - Tue Dec 06, 2005 11:55 pm

You was not setting REG_SOUNDCNT_X properly. But I think it is good practise to do something similar to what I did in code - at least for your first time as you can easily spot errors in values. You can later wrap these into methods so that your code does not contain cryptic bitshifts.

#63010 - SittingDuck - Wed Dec 07, 2005 8:40 pm

keldon wrote:
You was not setting REG_SOUNDCNT_X properly.

You were...

#63013 - keldon - Wed Dec 07, 2005 8:51 pm

Quote:
You were...

Sorry; my mistake. I was counting bit 0 as bit 1

#63243 - SittingDuck - Sat Dec 10, 2005 12:59 pm

No, I was just correcting the grammar.