Sound on DS can make you scratch your head sometimes. Here is a more technical approach.
As you want to play raw sound, that means each piece of sound would use exactly one out the 16 DS audio channels. The channels's id is told by the return value of NF_PlayRawSound, which internally calls the libnds function
soundPlaySample.
Now, take a look at
SOUNDxCNT register, where you replace "x" with the channel id previously obtained. It is a 32-bit register which contains useful playback data such as the volume, pan, loop, and last but not least, the
state of the channel. Bit 31 of SOUNDxCNT is set to 1 if the sound is playing, and 0 if it is not.
Therefore, the strategy would be something like this:
C++:
int nf_slot_id = /*some value of choice*/;
NF_LoadRawSound("my_sound", nf_slot_id, my_freq, my_format);
bool loop = false;
int channel_id = NF_PlayRawSound(nf_slot_id, my_volume, my_pan, loop, 0);
if(!sound_playing(channel_id))
{
// sound has stopped, do something...
}
////////////////////////////////////////////////////////
bool sound_playing(int channel_id)
{
// get bit31 of the word at 40004x0h, x=channel id
return (0x04000400 | (channel_id<<4)) & 0x80000000;
}
However, this solution raises even more questions related to the DS low-level behavior. libnds defines the 40004x0h registers as volatile (meaning the system can change them without programmer's knowledge). It is also defined as part of the ARM7 binary, not ARM9 (which exaplains the "ugly" way of accessing it in the above code). My attempt of reading the sound reister always returned 0 (you can also try it for yourself and hope for the best), and it seems like the 0x04xxxxxx memory region is different for the ARM9 and ARM7. With the emulator's memory viewer, you can see that on ARM7, the sound register is indeed something like 0xD0400040, while ending the sound changes it to 0x50400040 (note the bit 31 being reset to 0). Therefore, this is worse than I initially imagined. You may need a FIFO to have the ARM7 communicate the sound state to the ARM9 and then the problem is solved.
PS: There is an even simpler method which requires DS timers. It is as follows:
- you have to know the sound duration beforehand, assuming you don't change the playback frequency in the middle of the sound
- start both the sound and the timer
- when timer exceeds the sound's duration, it means the sound has finished, unload the sound, stop the timer and make the code your dreams become reality.
Related on how to use the timer, also check
this post and
libnds documentation.
You may need to be very patient to solve sound issues on NDS, I truly hope maybe someone in the future will come up with smarter and easier tricks to achieve the same thing.
Good luck! Please keep us updated with your work!