#106868 - HyperHacker - Tue Oct 24, 2006 8:15 am
Just figured I'd post this because sound documentation seems to be quite scarce. This explains how to play a tone of a specific frequency. The idea here is rather than generating a sample or loading it from a file, you do it like you would on old consoles and just choose the frequency and manually start and stop playback. This is good for things like emulation of said consoles.
First you turn sound on:
For the most part you can keep the volume at max (127) as the DS provides a hardware volume control. Software volume control might be useful for environment effects or something. I'm not sure if the DS can play loud enough sounds to damage its speakers, but be sensible.
You're supposed to wait 15 milliseconds before playing sound after turning it on. DS runs at 60FPS so one frame will take about 16ms; call swiWaitForVBlank() twice just to be safe (lest you call right before VBlank and end up only delaying 1ms). You have to have the VBlank interrupt enabled for this, which you should know how to do already.
Once you've done that you just choose your frequency, channel volume, pan, and wave duty and start the sound:
Simple breakdown of these values:
SOUND_FREQ(DesiredFrequency << 3) should be obvious. Your frequency needs to be multiplied by 8; you can left-shift by 3 as I've done here to accomplish the same but faster.
SOUND_VOL(127) sets the individual channel volume; again, no real reason to reduce it in a simple demo app.
SOUND_PAN(64) centers the sound. 0 would make it entirely on the left speaker, 127 entirely on the right.
SOUND_FORMAT_PSG enables the Programmable Sound Generator, which tells the DS we're doing choose-a-frequency-and-go sounds rather than playing actual sound samples in memory. There's probably a term for that but I can't think of one.
SCHANNEL_ENABLE, of course, turns the channel on.
libnds doesn't appear to have a wave duty macro, but you can add one:
#define SCHANNEL_WAVEDUTY(n) (n << 24)
Various documents list completely different information for the wave duty values. The most reasonable I've seen is GBATek's: 0=12.5%..6=87.5%, 7=silence.
Finally, note that you can only do this on channels 8 through 13. You can also generate white noise using PSG on channels 14 and 15.
_________________
I'm a PSP hacker now, but I still <3 DS.
First you turn sound on:
Code: |
SOUND_CR = SOUND_VOL(127) | SOUND_ENABLE; |
For the most part you can keep the volume at max (127) as the DS provides a hardware volume control. Software volume control might be useful for environment effects or something. I'm not sure if the DS can play loud enough sounds to damage its speakers, but be sensible.
You're supposed to wait 15 milliseconds before playing sound after turning it on. DS runs at 60FPS so one frame will take about 16ms; call swiWaitForVBlank() twice just to be safe (lest you call right before VBlank and end up only delaying 1ms). You have to have the VBlank interrupt enabled for this, which you should know how to do already.
Once you've done that you just choose your frequency, channel volume, pan, and wave duty and start the sound:
Code: |
SCHANNEL_TIMER(8) = SOUND_FREQ(DesiredFrequency << 3);
SCHANNEL_CR(8) = SOUND_VOL(127) | SOUND_PAN(64) | SCHANNEL_WAVEDUTY(6) | SOUND_FORMAT_PSG | SCHANNEL_ENABLE; |
Simple breakdown of these values:
SOUND_FREQ(DesiredFrequency << 3) should be obvious. Your frequency needs to be multiplied by 8; you can left-shift by 3 as I've done here to accomplish the same but faster.
SOUND_VOL(127) sets the individual channel volume; again, no real reason to reduce it in a simple demo app.
SOUND_PAN(64) centers the sound. 0 would make it entirely on the left speaker, 127 entirely on the right.
SOUND_FORMAT_PSG enables the Programmable Sound Generator, which tells the DS we're doing choose-a-frequency-and-go sounds rather than playing actual sound samples in memory. There's probably a term for that but I can't think of one.
SCHANNEL_ENABLE, of course, turns the channel on.
libnds doesn't appear to have a wave duty macro, but you can add one:
#define SCHANNEL_WAVEDUTY(n) (n << 24)
Various documents list completely different information for the wave duty values. The most reasonable I've seen is GBATek's: 0=12.5%..6=87.5%, 7=silence.
Finally, note that you can only do this on channels 8 through 13. You can also generate white noise using PSG on channels 14 and 15.
_________________
I'm a PSP hacker now, but I still <3 DS.