GP2X Sound Mixing Routines


slygamer

Active Member
Joined
Sep 19, 2005
Messages
795
Location
Brisbane, Australia
Website
Visit site
Does anyone have any sound mixing routines they would like to share? I've got a sound mixing routine, but it's nothing special. Does the job, but that's about it.

Note that I know zero ARM assembler, so I would not have the faintest clue about how to rewrite my current C implementation in assembler.

Any tips, tricks or hints on writing sound mixing routines that you may have?
 
Does anyone have any sound mixing routines they would like to share? I've got a sound mixing routine, but it's nothing special. Does the job, but that's about it.

Note that I know zero ARM assembler, so I would not have the faintest clue about how to rewrite my current C implementation in assembler.

Any tips, tricks or hints on writing sound mixing routines that you may have?

Don't use floatpoints when targeting Arm in gp2x.

You might use bit shifting instead of divide when summing. The panning (at 6dB steps but it can be enough) also can be achievied this way.

For a sample rate conversion... this is big topic. Linear interpolation should be enough for a device like gp2x.

You know probably all this already...
 
Last edited by a moderator:
This is my current attempt at a mixer. It doesn't handle overflow or underflow at all, which I could better handle by pre-mixing into a 32bit buffer then copying to the output buffer with clamping as Mr Spiv does.

Code:
void gp2x_audio_mix(s16 *buffer, int samples)
{
  pthread_mutex_lock(&mutex);
  // Clear the buffer
  memset(buffer, 0, samples * sizeof(s16) * 2);
  // Get the first sound in our currently-playing list
  gp2x_sound_t **sound = (gp2x_sound_t **)gp2x_ptrlist_begin(&sounds);
  while (*sound)
  {
    s16 *buf = buffer;
    s16 sample;
    int sam = samples;

    if ((*sound)->sample->flags & GP2X_SAMPLE_FLAG_STEREO)
    {
      // Mixing a stereo sample into a stereo buffer
      while (sam-- && (*sound)->position < (*sound)->sample->samples)
      {
        sample = (*sound)->sample->data[(*sound)->position++];
        *buf++ += sample; //Left channel
        sample = (*sound)->sample->data[(*sound)->position++];
        *buf++ += sample; //Right channel
      }
    }
    else
    {
      // Mixing a mono sample into a stereo buffer
      while (sam-- && (*sound)->position < (*sound)->sample->samples)
      {
        sample = (*sound)->sample->data[(*sound)->position++];
        *buf++ += sample; //Left channel
        *buf++ += sample; //Right channel
      }
    }

    if ((*sound)->position >= (*sound)->sample->samples)
    {
      // NULL any reference to this sound handle
      if ((*sound)->handle)
        *(*sound)->handle = NULL;
      // Remove this sound from the currently-playing list
      gp2x_ptrlist_destroy(&sounds, (void **)sound);
    }

    ++sound;
  }
  pthread_mutex_unlock(&mutex);
}

My next task is to better handle latency. At the moment, it won't start playing a sound until the next buffer is filled, which is a noticeable delay after triggering the sound.
 
Back
Top