Gain,Volume Zipper Pop Suppression by Steady Zero Crossing Technique

This post is accompanied by a video hosted at http://youtu.be/FhjR1ArTgyg

This PDF says it all: zipper_gain_clicks

Baring in the mind that I have not yet controlled a strict frame rate in my program, my code looks something like this:

double Audio::calculate_linear_gain_from_db(double gain_db, double min_gain/*=-96.0*/)
{
  if (gain_db <= min_gain) return 0.0;  // -INF dB
  else return pow ( 10.0, (0.05 * gain_db) );
}

void Music_Player::apply_gain(sample_t* out, int count )
{
  double gain; 
  double direction;

  gain = Audio::calculate_linear_gain_from_db(gain_db, min_gain_db);
  for (int i=0; i < count; i += 1)
  {
    double newsamp = out[i];
    
    if (gain_has_changed)
    {
      direction = ((new_gain_db - gain_db > 0) ? +0.02 : -0.02);

      if ((newsamp <= 0.0 && out[i+1] > 0) || (newsamp >= 0.0 && out[i+1] < 0))
      {
        gain_db += direction;
        if ((direction > 0 && gain_db >= new_gain_db) || (direction < 0 && gain_db <= new_gain_db))
        {
          gain_db = new_gain_db;
          gain_has_changed=false;
        }
        gain = Audio::calculate_linear_gain_from_db(gain_db, min_gain_db);
        
      }
    }
    //DEBUGLOG("gain = %f\n", gain);
    newsamp *= gain;
    
    int io = round(newsamp);
    /*if (d > 32767)
    {
      d = 32767;
      //DEBUGLOG("+clip+!");
    }
    else if (d < -32768)
    {
      d = -32768;
      //DEBUGLOG("clip-!");
    }*/
    //CLAMP16(d);
    if ( (int16_t) io != io )
    {
    /*fprintf(stderr,"\t%d : ", io);*/
      io = (io >> 31) ^ 0x7FFF;
    /*fprintf(stderr,"\t%d\n", io);*/
    }
    out[i] = (sample_t)io;
  }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s