• Advertisement
Sign in to follow this  

SDL and Modplug sound artifacts

This topic is 3733 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

My sound engine is a software mixer for a number of running modplug modules, pushed through SDL. I ran into a clicking sounds that I can't seem to get rid of. Changing the buffer lengths changes the tempo of the click, so it's not a buffer underrun. The libraries are up to date (libmodplug 0.8.4 and SDL 1.2.12). And for some reason, the first active module channel is the one that experiences the clicks (so changing the playing module on that channel will still show clicks) I even tried switching it so sound effects play on that channel and the sound effects end up with the clicking. Any ideas? Here's the code.
void inm_audio_handler( void *p_udata, Uint8 *p_stream, int p_len )
{
  int i, j, e;
  signed int clip;
  int mods, samps;
  void * modbuffs[INM_MAX_SOUNDS];
  ModPlugFile * module;
  int bytes = g_inmgame->mixer.bytes_per_sample;
  int chans = g_inmgame->mixer.sdl_audio_spec->channels;
  int silence = g_inmgame->mixer.sdl_audio_spec->silence;

  if (!inm_audio_active) return;

  /* Clear list of samples playing. */
  for ( i=0; i<INM_MAX_SOUNDS; i++ )
    modbuffs = 0;

  /* Generate MOD buffer content. */
  mods = 0;
  switch (bytes)
  {
    case 1:
      for ( i=0; i<INM_MAX_SOUNDS; i++ )
      {
        Sint8 * modbuff = (Sint8 *) g_inmgame->sound.buffer;
        module = (ModPlugFile *) g_inmgame->sound.module;
        if ( ( g_inmgame->sound.paused==0 ) && ( modbuff ) && ( module ) )
        {
          modbuffs[mods] = (void *) modbuff;
          e = ModPlug_Read( module, modbuff, p_len );
          if ( e < p_len )
          {
            if ( g_inmgame->sound.looped )
            {
              ModPlug_Loopback( module );
              e += ModPlug_Read( module, modbuff+e, p_len-e );
            }
            if ( e < p_len )
            {
              g_inmgame->sound.paused = 1;
              memset( modbuff+e, 0, p_len-e );
            }
          }
          mods += 1;
        }
      }
      break;

    case 2:
      for ( i=0; i<INM_MAX_SOUNDS; i++ )
      {
        Sint16 * modbuff = (Sint16 *) g_inmgame->sound.buffer;
        module = (ModPlugFile *) g_inmgame->sound.module;
        if ( ( g_inmgame->sound.paused==0 ) && ( modbuff ) && ( module ) )
        {
          modbuffs[mods] = (void *) modbuff;
          e = ModPlug_Read( module, modbuff, p_len );
          if ( e < p_len )
          {
            if ( g_inmgame->sound.looped )
            {
              ModPlug_Loopback( module );
              e += ModPlug_Read( module, modbuff+e, p_len-e );
            }
            if ( e < p_len )
            {
              g_inmgame->sound.paused = 1;
              memset( modbuff+e, 0, p_len-e );
            }
          }
          mods += 1;
        }
      }
      break;
  }

  if ( chans > 0 )
  {
    switch (bytes)
    {
      case 1:
      {
        Sint8  * dst8buff;
        /* Mix samples into Stream */
        dst8buff = (Sint8 *) p_stream;
        samps = p_len;
        for ( i=0; i<samps; i++ )
        { 
          clip = silence;
          for ( j=0; j<mods; j++ )
          {
            clip += *(((Sint8 *)modbuffs[j])+i);
          }
          /* Perform clipping */
          if      (clip < S8CMIN) *dst8buff = S8CMIN;
          else if (clip > S8CMAX) *dst8buff = S8CMAX;
          else                    *dst8buff = clip;
          dst8buff++;
        }
      }
      break;

      case 2:
      {
        Sint16 * dst16buff;
        /* Mix samples into Stream */
        dst16buff = (Sint16 *) p_stream;
        samps = p_len / 2;
        for ( i=0; i<samps; i++ )
        { 
          clip = silence;
          for ( j=0; j<mods; j++ )
          {
            clip += *(((Sint16 *)modbuffs[j])+i);
          }
          /* Perform clipping */
          if      (clip < S16CMIN) *dst16buff = S16CMIN;
          else if (clip > S16CMAX) *dst16buff = S16CMAX;
          else                     *dst16buff = clip;
          dst16buff++;
        } 
      }
      break;
    }
  }
  else
  {
    /* Clear stream when no samples playing. */
    memset( p_stream, 0, p_len );
  }
}

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement