Running out of channels (on GBA)
Re: Running out of channels (on GBA)
At least it seems I succeed in isolating the problem.
Scenario:
- we've got a soundbank with some XM modules and some SFX.
- there's always one module playing (looping).
- in any moment we have to stop that module and suddenly start playing another module.
- SFX (non-looping) can get triggered at any time.
well, if we don't trigger any SFX, we don't get any problem. If we trigger SFX, the problems begins. After some module restarting and SFX triggering, MaxMod 'chokes'... it sounds like it doesn't have enough free channels to play module instruments and/or reproduce SFX.
I'm preparing a small demo...
Scenario:
- we've got a soundbank with some XM modules and some SFX.
- there's always one module playing (looping).
- in any moment we have to stop that module and suddenly start playing another module.
- SFX (non-looping) can get triggered at any time.
well, if we don't trigger any SFX, we don't get any problem. If we trigger SFX, the problems begins. After some module restarting and SFX triggering, MaxMod 'chokes'... it sounds like it doesn't have enough free channels to play module instruments and/or reproduce SFX.
I'm preparing a small demo...
Re: Running out of channels (on GBA)
Here's the small test program.
If you keep on firing SFXs (shoulder keys) and while they're playing you restart the module (A or B keys) you'll see and hear that something is going wrong (on no$gba emulator too).
Full source (just few lines) it's right here:
If you keep on firing SFXs (shoulder keys) and while they're playing you restart the module (A or B keys) you'll see and hear that something is going wrong (on no$gba emulator too).
Full source (just few lines) it's right here:
Code: Select all
#include <gba_console.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <stdio.h>
// Maxmod library
#include <maxmod.h>
// MaxMod soundbank
#include "soundbank_bin.h"
#include "soundbank.h"
int main(void) {
// GBA: the vblank interrupt must be enabled for VBlankIntrWait() to work
// GBA: since the default dispatcher handles the bios flags no vblank handler is required
irqInit();
irqEnable(IRQ_VBLANK);
consoleDemoInit();
iprintf("\n Press A/B to restart MOD 1/2");
iprintf("\n Press L/R to trigger SFX 1/2");
// init MaxMod (with 12 channels)
mmInitDefault((mm_addr)soundbank_bin, 12);
mmStart(MOD_1,MM_PLAY_LOOP);
// main loop
while (1) {
mmFrame(); // Update Maxmod Frame
VBlankIntrWait(); // wait VBlank
scanKeys();
u32 keysD = keysDown();
if (keysD & KEY_A) {
mmStop();
mmStart(MOD_1,MM_PLAY_LOOP);
}
if (keysD & KEY_B) {
mmStop();
mmStart(MOD_2,MM_PLAY_LOOP);
}
if (keysD & KEY_L)
mmEffect(SFX_1);
if (keysD & KEY_R)
mmEffect(SFX_2);
// print mixing channels state
int i;
iprintf("\x1b[5;2HChannels = ");
for (i=0;i<12;i++) {
iprintf("%d",mmMixerChannelActive(i)?1:0);
if ((i&0x3)==3)
iprintf(" "); // some spacing
}
}
return 0;
}
Re: Running out of channels (on GBA)
Yesterday evening I noticed I can make the bug appear even without restarting the module... just triggering sound effects like crazy makes the program malfunctioning. So I bet the problem can be related to trying to use at a given moment more channels than those available.
The search goes on...
The search goes on...
Re: Running out of channels (on GBA)
Here's another test: no modules, just SFX. I reduced the channels to 6, to be able to fire enough SFX to saturate them. If you click shoulder buttons like crazy, after a while you'll see that some channels are stuck to 0. This means it's no longer able to use that channel.
Full source follows. Even shorter than the previous one.
Full source follows. Even shorter than the previous one.
Code: Select all
#include <gba_console.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <stdio.h>
// Maxmod library
#include <maxmod.h>
// MaxMod soundbank
#include "soundbank_bin.h"
#include "soundbank.h"
#define MAXMODCHN 6
int main(void) {
// GBA: the vblank interrupt must be enabled for VBlankIntrWait() to work
// GBA: since the default dispatcher handles the bios flags no vblank handler is required
irqInit();
irqEnable(IRQ_VBLANK);
consoleDemoInit();
iprintf("\n Press L/R to trigger SFX 1/2");
// init MaxMod (with MAXMODCHN channels)
mmInitDefault((mm_addr)soundbank_bin, MAXMODCHN);
// main loop
while (1) {
mmFrame(); // Update Maxmod Frame
VBlankIntrWait(); // wait VBlank
scanKeys();
u32 keysD = keysDown();
if (keysD & KEY_L)
mmEffect(SFX_1);
if (keysD & KEY_R)
mmEffect(SFX_2);
// print mixing channels state
int i;
iprintf("\x1b[5;2HChannels = ");
for (i=0;i<MAXMODCHN;i++) {
iprintf("%d",mmMixerChannelActive(i)?1:0);
if ((i&0x3)==3)
iprintf(" "); // some spacing
}
}
return 0;
}
Re: Running out of channels (on GBA)
One last test, I finally found out that the problem was related to firing two SFX at the same time. If you fire both effects (just press 'L' shoulder key) and you wait for them to release both channels, no problem. If you fire them again with a short to very short delay in between, you'll make one channel stuck.
eKid kindly provided me a quick fix, and it seems like it's working correctly. I guess there will soon be a public fix
Full source of test3, for those interested...
eKid kindly provided me a quick fix, and it seems like it's working correctly. I guess there will soon be a public fix
Full source of test3, for those interested...
Code: Select all
#include <gba_console.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <stdio.h>
// Maxmod library
#include <maxmod.h>
// MaxMod soundbank
#include "soundbank_bin.h"
#include "soundbank.h"
#define MAXMODCHN 12
int main(void) {
// GBA: the vblank interrupt must be enabled for VBlankIntrWait() to work
// GBA: since the default dispatcher handles the bios flags no vblank handler is required
irqInit();
irqEnable(IRQ_VBLANK);
consoleDemoInit();
iprintf("\n Press L to trigger SFX 1 + 2");
// init MaxMod (with MAXMODCHN channels)
mmInitDefault((mm_addr)soundbank_bin, MAXMODCHN);
// main loop
while (1) {
mmFrame(); // Update Maxmod Frame
VBlankIntrWait(); // wait VBlank
scanKeys();
u32 keysD = keysDown();
if (keysD & KEY_L) {
mmEffect(SFX_1);
mmEffect(SFX_2);
}
// print mixing channels state
int i;
iprintf("\x1b[5;2HChannels = ");
for (i=0;i<MAXMODCHN;i++) {
iprintf("%d",mmMixerChannelActive(i)?1:0);
if ((i&0x3)==3)
iprintf(" "); // some spacing
}
}
return 0;
}
Re: Running out of channels (on GBA)
FYI the correction that fixed the bug was:
in mm_effect.s (around line 230)
the 3rd line should be changed to
in mm_effect.s (around line 230)
Code: Select all
ldr r2, [r1]
orr r2, r3
str r3, [r1]
Code: Select all
str r2, [r1]
-
- Site Admin
- Posts: 1986
- Joined: Tue Aug 09, 2005 3:21 am
- Location: UK
- Contact:
Re: Running out of channels (on GBA)
Thanks for letting us know. That's now been fixed in the git repository - should be available with next release
Who is online
Users browsing this forum: No registered users and 2 guests