Running out of channels (on GBA)

sverx
Posts: 94
Joined: Wed Aug 12, 2009 2:56 pm
Location: github.com/sverx
Contact:

Re: Running out of channels (on GBA)

Post by sverx » Mon Jun 17, 2013 1:57 pm

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...

sverx
Posts: 94
Joined: Wed Aug 12, 2009 2:56 pm
Location: github.com/sverx
Contact:

Re: Running out of channels (on GBA)

Post by sverx » Mon Jun 17, 2013 4:33 pm

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:

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;
}

sverx
Posts: 94
Joined: Wed Aug 12, 2009 2:56 pm
Location: github.com/sverx
Contact:

Re: Running out of channels (on GBA)

Post by sverx » Thu Jun 20, 2013 8:45 am

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. :evil:

The search goes on...

sverx
Posts: 94
Joined: Wed Aug 12, 2009 2:56 pm
Location: github.com/sverx
Contact:

Re: Running out of channels (on GBA)

Post by sverx » Thu Jun 20, 2013 1:06 pm

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.

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;
}

sverx
Posts: 94
Joined: Wed Aug 12, 2009 2:56 pm
Location: github.com/sverx
Contact:

Re: Running out of channels (on GBA)

Post by sverx » Tue Jun 25, 2013 9:31 am

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... :roll:

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;
}

sverx
Posts: 94
Joined: Wed Aug 12, 2009 2:56 pm
Location: github.com/sverx
Contact:

Re: Running out of channels (on GBA)

Post by sverx » Thu Jul 11, 2013 3:16 pm

FYI the correction that fixed the bug was:

in mm_effect.s (around line 230)

Code: Select all

	ldr	r2, [r1]
	orr	r2, r3
	str	r3, [r1]
the 3rd line should be changed to

Code: Select all

	str	r2, [r1]
:)

WinterMute
Site Admin
Posts: 1845
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: Running out of channels (on GBA)

Post by WinterMute » Wed Sep 04, 2013 11:55 pm

Thanks for letting us know. That's now been fixed in the git repository - should be available with next release
Help keep devkitPro toolchains free, Donate today

Personal Blog

Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests