Update Fluidsynth to 2.0.1
[ardour.git] / libs / fluidsynth / src / fluid_chorus.c
index 4bead5ce2d9d407c5861ea4fc02046989ed71337..83a88d3826c85f5a47b126ac5c657b8160291491 100644 (file)
@@ -1,13 +1,25 @@
-/*
- * August 24, 1998
- * Copyright (C) 1998 Juergen Mueller And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose.  This copyright notice must be maintained.
- * Juergen Mueller And Sundry Contributors are not responsible for
- * the consequences of using this software.
+/* FluidSynth - A Software Synthesizer
+ *
+ * Copyright (C) 2003  Peter Hanappe, Markus Nentwig and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
  */
 
 /*
+  based on a chrous implementation made by Juergen Mueller And Sundry Contributors in 1998
 
   CHANGES
 
@@ -78,8 +90,8 @@
  * Set through MAX_SAMPLES_LN2.
  * For example:
  * MAX_SAMPLES_LN2=12
- * => MAX_SAMPLES=pow(2,12)=4096
- * => MAX_SAMPLES_ANDMASK=4095
+ * => MAX_SAMPLES=pow(2,12-1)=2048
+ * => MAX_SAMPLES_ANDMASK=2047
  */
 #define MAX_SAMPLES_LN2 12
 
 #define INTERPOLATION_SAMPLES 5
 
 /* Private data for SKEL file */
-struct _fluid_chorus_t {
-  int type;
-  fluid_real_t depth_ms;
-  fluid_real_t level;
-  fluid_real_t speed_Hz;
-  int number_blocks;
-
-  fluid_real_t *chorusbuf;
-  int counter;
-  long phase[MAX_CHORUS];
-  long modulation_period_samples;
-  int *lookup_tab;
-  fluid_real_t sample_rate;
-
-  /* sinc lookup table */
-  fluid_real_t sinc_table[INTERPOLATION_SAMPLES][INTERPOLATION_SUBSAMPLES];
+struct _fluid_chorus_t
+{
+    int type;
+    fluid_real_t depth_ms;
+    fluid_real_t level;
+    fluid_real_t speed_Hz;
+    int number_blocks;
+
+    fluid_real_t *chorusbuf;
+    int counter;
+    long phase[MAX_CHORUS];
+    long modulation_period_samples;
+    int *lookup_tab;
+    fluid_real_t sample_rate;
+
+    /* sinc lookup table */
+    fluid_real_t sinc_table[INTERPOLATION_SAMPLES][INTERPOLATION_SUBSAMPLES];
 };
 
 static void fluid_chorus_triangle(int *buf, int len, int depth);
 static void fluid_chorus_sine(int *buf, int len, int depth);
 
 
-fluid_chorus_t*
+fluid_chorus_t *
 new_fluid_chorus(fluid_real_t sample_rate)
 {
-  int i; int ii;
-  fluid_chorus_t* chorus;
-
-  chorus = FLUID_NEW(fluid_chorus_t);
-  if (chorus == NULL) {
-    fluid_log(FLUID_PANIC, "chorus: Out of memory");
-    return NULL;
-  }
+    int i;
+    int ii;
+    fluid_chorus_t *chorus;
+
+    chorus = FLUID_NEW(fluid_chorus_t);
+
+    if(chorus == NULL)
+    {
+        FLUID_LOG(FLUID_PANIC, "chorus: Out of memory");
+        return NULL;
+    }
+
+    FLUID_MEMSET(chorus, 0, sizeof(fluid_chorus_t));
+
+    chorus->sample_rate = sample_rate;
+
+    /* Lookup table for the SI function (impulse response of an ideal low pass) */
+
+    /* i: Offset in terms of whole samples */
+    for(i = 0; i < INTERPOLATION_SAMPLES; i++)
+    {
+
+        /* ii: Offset in terms of fractional samples ('subsamples') */
+        for(ii = 0; ii < INTERPOLATION_SUBSAMPLES; ii++)
+        {
+            /* Move the origin into the center of the table */
+            double i_shifted = ((double) i - ((double) INTERPOLATION_SAMPLES) / 2.
+                                + (double) ii / (double) INTERPOLATION_SUBSAMPLES);
+
+            if(fabs(i_shifted) < 0.000001)
+            {
+                /* sinc(0) cannot be calculated straightforward (limit needed
+                   for 0/0) */
+                chorus->sinc_table[i][ii] = (fluid_real_t)1.;
+
+            }
+            else
+            {
+                chorus->sinc_table[i][ii] = (fluid_real_t)sin(i_shifted * M_PI) / (M_PI * i_shifted);
+                /* Hamming window */
+                chorus->sinc_table[i][ii] *= (fluid_real_t)0.5 * (1.0 + cos(2.0 * M_PI * i_shifted / (fluid_real_t)INTERPOLATION_SAMPLES));
+            };
+        };
+    };
 
-  FLUID_MEMSET(chorus, 0, sizeof(fluid_chorus_t));
+    /* allocate lookup tables */
+    chorus->lookup_tab = FLUID_ARRAY(int, (int)(chorus->sample_rate / MIN_SPEED_HZ));
 
-  chorus->sample_rate = sample_rate;
+    if(chorus->lookup_tab == NULL)
+    {
+        FLUID_LOG(FLUID_PANIC, "chorus: Out of memory");
+        goto error_recovery;
+    }
 
-  /* Lookup table for the SI function (impulse response of an ideal low pass) */
+    /* allocate sample buffer */
 
-  /* i: Offset in terms of whole samples */
-  for (i = 0; i < INTERPOLATION_SAMPLES; i++){
+    chorus->chorusbuf = FLUID_ARRAY(fluid_real_t, MAX_SAMPLES);
 
-    /* ii: Offset in terms of fractional samples ('subsamples') */
-    for (ii = 0; ii < INTERPOLATION_SUBSAMPLES; ii++){
-      /* Move the origin into the center of the table */
-      double i_shifted = ((double) i- ((double) INTERPOLATION_SAMPLES) / 2.
-                         + (double) ii / (double) INTERPOLATION_SUBSAMPLES);
-      if (fabs(i_shifted) < 0.000001) {
-       /* sinc(0) cannot be calculated straightforward (limit needed
-          for 0/0) */
-       chorus->sinc_table[i][ii] = (fluid_real_t)1.;
+    if(chorus->chorusbuf == NULL)
+    {
+        FLUID_LOG(FLUID_PANIC, "chorus: Out of memory");
+        goto error_recovery;
+    }
 
-      } else {
-       chorus->sinc_table[i][ii] = (fluid_real_t)sin(i_shifted * M_PI) / (M_PI * i_shifted);
-       /* Hamming window */
-       chorus->sinc_table[i][ii] *= (fluid_real_t)0.5 * (1.0 + cos(2.0 * M_PI * i_shifted / (fluid_real_t)INTERPOLATION_SAMPLES));
-      };
+    if(fluid_chorus_init(chorus) != FLUID_OK)
+    {
+        goto error_recovery;
     };
-  };
-
-  /* allocate lookup tables */
-  chorus->lookup_tab = FLUID_ARRAY(int, (int) (chorus->sample_rate / MIN_SPEED_HZ));
-  if (chorus->lookup_tab == NULL) {
-    fluid_log(FLUID_PANIC, "chorus: Out of memory");
-    goto error_recovery;
-  }
-
-  /* allocate sample buffer */
-
-  chorus->chorusbuf = FLUID_ARRAY(fluid_real_t, MAX_SAMPLES);
-  if (chorus->chorusbuf == NULL) {
-    fluid_log(FLUID_PANIC, "chorus: Out of memory");
-    goto error_recovery;
-  }
 
-  if (fluid_chorus_init(chorus) != FLUID_OK){
-    goto error_recovery;
-  };
+    return chorus;
 
-  return chorus;
+error_recovery:
+    delete_fluid_chorus(chorus);
 
- error_recovery:
-  delete_fluid_chorus(chorus);
-  return NULL;
+    return NULL;
 }
 
 void
-delete_fluid_chorus(fluid_chorus_tchorus)
+delete_fluid_chorus(fluid_chorus_t *chorus)
 {
-  if (chorus == NULL) {
-    return;
-  }
+    fluid_return_if_fail(chorus != NULL);
 
-  if (chorus->chorusbuf != NULL) {
     FLUID_FREE(chorus->chorusbuf);
-  }
-
-  if (chorus->lookup_tab != NULL) {
     FLUID_FREE(chorus->lookup_tab);
-  }
-
-  FLUID_FREE(chorus);
+    FLUID_FREE(chorus);
 }
 
 int
-fluid_chorus_init(fluid_chorus_tchorus)
+fluid_chorus_init(fluid_chorus_t *chorus)
 {
-  int i;
+    int i;
 
-  for (i = 0; i < MAX_SAMPLES; i++) {
-    chorus->chorusbuf[i] = 0.0;
-  }
+    for(i = 0; i < MAX_SAMPLES; i++)
+    {
+        chorus->chorusbuf[i] = 0.0;
+    }
 
-  /* initialize the chorus with the default settings */
-  fluid_chorus_set (chorus, FLUID_CHORUS_SET_ALL, FLUID_CHORUS_DEFAULT_N,
-                    FLUID_CHORUS_DEFAULT_LEVEL, FLUID_CHORUS_DEFAULT_SPEED,
-                    FLUID_CHORUS_DEFAULT_DEPTH, FLUID_CHORUS_MOD_SINE);
-  return FLUID_OK;
+    return FLUID_OK;
 }
 
 void
-fluid_chorus_reset(fluid_chorus_tchorus)
+fluid_chorus_reset(fluid_chorus_t *chorus)
 {
-  fluid_chorus_init(chorus);
+    fluid_chorus_init(chorus);
 }
 
 /**
@@ -243,223 +260,272 @@ fluid_chorus_reset(fluid_chorus_t* chorus)
  * @param type Chorus waveform type (#fluid_chorus_mod)
  */
 void
-fluid_chorus_set(fluid_chorus_t* chorus, int set, int nr, float level,
-                 float speed, float depth_ms, int type)
+fluid_chorus_set(fluid_chorus_t *chorus, int set, int nr, fluid_real_t level,
+                 fluid_real_t speed, fluid_real_t depth_ms, int type)
 {
-  int modulation_depth_samples;
-  int i;
-
-  if (set & FLUID_CHORUS_SET_NR) chorus->number_blocks = nr;
-  if (set & FLUID_CHORUS_SET_LEVEL) chorus->level = level;
-  if (set & FLUID_CHORUS_SET_SPEED) chorus->speed_Hz = speed;
-  if (set & FLUID_CHORUS_SET_DEPTH) chorus->depth_ms = depth_ms;
-  if (set & FLUID_CHORUS_SET_TYPE) chorus->type = type;
-
-  if (chorus->number_blocks < 0) {
-    fluid_log(FLUID_WARN, "chorus: number blocks must be >=0! Setting value to 0.");
-    chorus->number_blocks = 0;
-  } else if (chorus->number_blocks > MAX_CHORUS) {
-    fluid_log(FLUID_WARN, "chorus: number blocks larger than max. allowed! Setting value to %d.",
-            MAX_CHORUS);
-    chorus->number_blocks = MAX_CHORUS;
-  }
-
-  if (chorus->speed_Hz < MIN_SPEED_HZ) {
-    fluid_log(FLUID_WARN, "chorus: speed is too low (min %f)! Setting value to min.",
-            (double) MIN_SPEED_HZ);
-    chorus->speed_Hz = MIN_SPEED_HZ;
-  } else if (chorus->speed_Hz > MAX_SPEED_HZ) {
-    fluid_log(FLUID_WARN, "chorus: speed must be below %f Hz! Setting value to max.",
-            (double) MAX_SPEED_HZ);
-    chorus->speed_Hz = MAX_SPEED_HZ;
-  }
-
-  if (chorus->depth_ms < 0.0) {
-    fluid_log(FLUID_WARN, "chorus: depth must be positive! Setting value to 0.");
-    chorus->depth_ms = 0.0;
-  }
-  /* Depth: Check for too high value through modulation_depth_samples. */
-
-  if (chorus->level < 0.0) {
-    fluid_log(FLUID_WARN, "chorus: level must be positive! Setting value to 0.");
-    chorus->level = 0.0;
-  } else if (chorus->level > 10) {
-    fluid_log(FLUID_WARN, "chorus: level must be < 10. A reasonable level is << 1! "
-            "Setting it to 0.1.");
-    chorus->level = 0.1;
-  }
-
-  /* The modulating LFO goes through a full period every x samples: */
-  chorus->modulation_period_samples = chorus->sample_rate / chorus->speed_Hz;
-
-  /* The variation in delay time is x: */
-  modulation_depth_samples = (int)
-    (chorus->depth_ms / 1000.0  /* convert modulation depth in ms to s*/
-     * chorus->sample_rate);
-
-  if (modulation_depth_samples > MAX_SAMPLES) {
-    fluid_log(FLUID_WARN, "chorus: Too high depth. Setting it to max (%d).", MAX_SAMPLES);
-    modulation_depth_samples = MAX_SAMPLES;
-  }
-
-  /* initialize LFO table */
-  if (chorus->type == FLUID_CHORUS_MOD_SINE) {
-    fluid_chorus_sine(chorus->lookup_tab, chorus->modulation_period_samples,
-                    modulation_depth_samples);
-  } else if (chorus->type == FLUID_CHORUS_MOD_TRIANGLE) {
-    fluid_chorus_triangle(chorus->lookup_tab, chorus->modulation_period_samples,
-                        modulation_depth_samples);
-  } else {
-    fluid_log(FLUID_WARN, "chorus: Unknown modulation type. Using sinewave.");
-    chorus->type = FLUID_CHORUS_MOD_SINE;
-    fluid_chorus_sine(chorus->lookup_tab, chorus->modulation_period_samples,
-                    modulation_depth_samples);
-  }
-
-  for (i = 0; i < chorus->number_blocks; i++) {
-    /* Set the phase of the chorus blocks equally spaced */
-    chorus->phase[i] = (int) ((double) chorus->modulation_period_samples
-                             * (double) i / (double) chorus->number_blocks);
-  }
-
-  /* Start of the circular buffer */
-  chorus->counter = 0;
+    int modulation_depth_samples;
+    int i;
+
+    if(set & FLUID_CHORUS_SET_NR)
+    {
+        chorus->number_blocks = nr;
+    }
+
+    if(set & FLUID_CHORUS_SET_LEVEL)
+    {
+        chorus->level = level;
+    }
+
+    if(set & FLUID_CHORUS_SET_SPEED)
+    {
+        chorus->speed_Hz = speed;
+    }
+
+    if(set & FLUID_CHORUS_SET_DEPTH)
+    {
+        chorus->depth_ms = depth_ms;
+    }
+
+    if(set & FLUID_CHORUS_SET_TYPE)
+    {
+        chorus->type = type;
+    }
+
+    if(chorus->number_blocks < 0)
+    {
+        FLUID_LOG(FLUID_WARN, "chorus: number blocks must be >=0! Setting value to 0.");
+        chorus->number_blocks = 0;
+    }
+    else if(chorus->number_blocks > MAX_CHORUS)
+    {
+        FLUID_LOG(FLUID_WARN, "chorus: number blocks larger than max. allowed! Setting value to %d.",
+                  MAX_CHORUS);
+        chorus->number_blocks = MAX_CHORUS;
+    }
+
+    if(chorus->speed_Hz < MIN_SPEED_HZ)
+    {
+        FLUID_LOG(FLUID_WARN, "chorus: speed is too low (min %f)! Setting value to min.",
+                  (double) MIN_SPEED_HZ);
+        chorus->speed_Hz = MIN_SPEED_HZ;
+    }
+    else if(chorus->speed_Hz > MAX_SPEED_HZ)
+    {
+        FLUID_LOG(FLUID_WARN, "chorus: speed must be below %f Hz! Setting value to max.",
+                  (double) MAX_SPEED_HZ);
+        chorus->speed_Hz = MAX_SPEED_HZ;
+    }
+
+    if(chorus->depth_ms < 0.0)
+    {
+        FLUID_LOG(FLUID_WARN, "chorus: depth must be positive! Setting value to 0.");
+        chorus->depth_ms = 0.0;
+    }
+
+    /* Depth: Check for too high value through modulation_depth_samples. */
+
+    if(chorus->level < 0.0)
+    {
+        FLUID_LOG(FLUID_WARN, "chorus: level must be positive! Setting value to 0.");
+        chorus->level = 0.0;
+    }
+    else if(chorus->level > 10)
+    {
+        FLUID_LOG(FLUID_WARN, "chorus: level must be < 10. A reasonable level is << 1! "
+                  "Setting it to 0.1.");
+        chorus->level = 0.1;
+    }
+
+    /* The modulating LFO goes through a full period every x samples: */
+    chorus->modulation_period_samples = chorus->sample_rate / chorus->speed_Hz;
+
+    /* The variation in delay time is x: */
+    modulation_depth_samples = (int)
+                               (chorus->depth_ms / 1000.0  /* convert modulation depth in ms to s*/
+                                * chorus->sample_rate);
+
+    if(modulation_depth_samples > MAX_SAMPLES)
+    {
+        FLUID_LOG(FLUID_WARN, "chorus: Too high depth. Setting it to max (%d).", MAX_SAMPLES);
+        modulation_depth_samples = MAX_SAMPLES;
+        // set depth to maximum to avoid spamming console with above warning
+        chorus->depth_ms = (modulation_depth_samples * 1000) / chorus->sample_rate;
+    }
+
+    /* initialize LFO table */
+    switch(chorus->type)
+    {
+    default:
+        FLUID_LOG(FLUID_WARN, "chorus: Unknown modulation type. Using sinewave.");
+        chorus->type = FLUID_CHORUS_MOD_SINE;
+        /* fall-through */
+        
+    case FLUID_CHORUS_MOD_SINE:
+        fluid_chorus_sine(chorus->lookup_tab, chorus->modulation_period_samples,
+                          modulation_depth_samples);
+        break;
+
+    case FLUID_CHORUS_MOD_TRIANGLE:
+        fluid_chorus_triangle(chorus->lookup_tab, chorus->modulation_period_samples,
+                              modulation_depth_samples);
+        break;
+    }
+
+    for(i = 0; i < chorus->number_blocks; i++)
+    {
+        /* Set the phase of the chorus blocks equally spaced */
+        chorus->phase[i] = (int)((double) chorus->modulation_period_samples
+                                 * (double) i / (double) chorus->number_blocks);
+    }
+
+    /* Start of the circular buffer */
+    chorus->counter = 0;
 }
 
 
-void fluid_chorus_processmix(fluid_chorus_tchorus, fluid_real_t *in,
-                           fluid_real_t *left_out, fluid_real_t *right_out)
+void fluid_chorus_processmix(fluid_chorus_t *chorus, fluid_real_t *in,
+                             fluid_real_t *left_out, fluid_real_t *right_out)
 {
-  int sample_index;
-  int i;
-  fluid_real_t d_in, d_out;
+    int sample_index;
+    int i;
+    fluid_real_t d_in, d_out;
 
-  for (sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++) {
+    for(sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++)
+    {
 
-    d_in = in[sample_index];
-    d_out = 0.0f;
+        d_in = in[sample_index];
+        d_out = 0.0f;
 
 # if 0
-    /* Debug: Listen to the chorus signal only */
-    left_out[sample_index]=0;
-    right_out[sample_index]=0;
+        /* Debug: Listen to the chorus signal only */
+        left_out[sample_index] = 0;
+        right_out[sample_index] = 0;
 #endif
 
-    /* Write the current sample into the circular buffer */
-    chorus->chorusbuf[chorus->counter] = d_in;
+        /* Write the current sample into the circular buffer */
+        chorus->chorusbuf[chorus->counter] = d_in;
 
-    for (i = 0; i < chorus->number_blocks; i++) {
-      int ii;
-      /* Calculate the delay in subsamples for the delay line of chorus block nr. */
+        for(i = 0; i < chorus->number_blocks; i++)
+        {
+            int ii;
+            /* Calculate the delay in subsamples for the delay line of chorus block nr. */
 
-      /* The value in the lookup table is so, that this expression
-       * will always be positive.  It will always include a number of
-       * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to
-       * remain positive at all times. */
-      int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter
-                           - chorus->lookup_tab[chorus->phase[i]]);
+            /* The value in the lookup table is so, that this expression
+             * will always be positive.  It will always include a number of
+             * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to
+             * remain positive at all times. */
+            int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter
+                                  - chorus->lookup_tab[chorus->phase[i]]);
 
-      int pos_samples = pos_subsamples/INTERPOLATION_SUBSAMPLES;
+            int pos_samples = pos_subsamples / INTERPOLATION_SUBSAMPLES;
 
-      /* modulo divide by INTERPOLATION_SUBSAMPLES */
-      pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK;
+            /* modulo divide by INTERPOLATION_SUBSAMPLES */
+            pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK;
 
-      for (ii = 0; ii < INTERPOLATION_SAMPLES; ii++){
-       /* Add the delayed signal to the chorus sum d_out Note: The
-        * delay in the delay line moves backwards for increasing
-        * delay!*/
+            for(ii = 0; ii < INTERPOLATION_SAMPLES; ii++)
+            {
+                /* Add the delayed signal to the chorus sum d_out Note: The
+                 * delay in the delay line moves backwards for increasing
+                 * delay!*/
 
-       /* The & in chorusbuf[...] is equivalent to a division modulo
-          MAX_SAMPLES, only faster. */
-       d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK]
-         * chorus->sinc_table[ii][pos_subsamples];
+                /* The & in chorusbuf[...] is equivalent to a division modulo
+                   MAX_SAMPLES, only faster. */
+                d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK]
+                         * chorus->sinc_table[ii][pos_subsamples];
 
-       pos_samples--;
-      };
-      /* Cycle the phase of the modulating LFO */
-      chorus->phase[i]++;
-      chorus->phase[i] %= (chorus->modulation_period_samples);
-    } /* foreach chorus block */
+                pos_samples--;
+            };
 
-    d_out *= chorus->level;
+            /* Cycle the phase of the modulating LFO */
+            chorus->phase[i]++;
 
-    /* Add the chorus sum d_out to output */
-    left_out[sample_index] += d_out;
-    right_out[sample_index] += d_out;
+            chorus->phase[i] %= (chorus->modulation_period_samples);
+        } /* foreach chorus block */
 
-    /* Move forward in circular buffer */
-    chorus->counter++;
-    chorus->counter %= MAX_SAMPLES;
+        d_out *= chorus->level;
 
-  } /* foreach sample */
+        /* Add the chorus sum d_out to output */
+        left_out[sample_index] += d_out;
+        right_out[sample_index] += d_out;
+
+        /* Move forward in circular buffer */
+        chorus->counter++;
+        chorus->counter %= MAX_SAMPLES;
+
+    } /* foreach sample */
 }
 
 /* Duplication of code ... (replaces sample data instead of mixing) */
-void fluid_chorus_processreplace(fluid_chorus_tchorus, fluid_real_t *in,
-                               fluid_real_t *left_out, fluid_real_t *right_out)
+void fluid_chorus_processreplace(fluid_chorus_t *chorus, fluid_real_t *in,
+                                 fluid_real_t *left_out, fluid_real_t *right_out)
 {
-  int sample_index;
-  int i;
-  fluid_real_t d_in, d_out;
+    int sample_index;
+    int i;
+    fluid_real_t d_in, d_out;
 
-  for (sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++) {
+    for(sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++)
+    {
 
-    d_in = in[sample_index];
-    d_out = 0.0f;
+        d_in = in[sample_index];
+        d_out = 0.0f;
 
 # if 0
-    /* Debug: Listen to the chorus signal only */
-    left_out[sample_index]=0;
-    right_out[sample_index]=0;
+        /* Debug: Listen to the chorus signal only */
+        left_out[sample_index] = 0;
+        right_out[sample_index] = 0;
 #endif
 
-    /* Write the current sample into the circular buffer */
-    chorus->chorusbuf[chorus->counter] = d_in;
+        /* Write the current sample into the circular buffer */
+        chorus->chorusbuf[chorus->counter] = d_in;
+
+        for(i = 0; i < chorus->number_blocks; i++)
+        {
+            int ii;
+            /* Calculate the delay in subsamples for the delay line of chorus block nr. */
+
+            /* The value in the lookup table is so, that this expression
+             * will always be positive.  It will always include a number of
+             * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to
+             * remain positive at all times. */
+            int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter
+                                  - chorus->lookup_tab[chorus->phase[i]]);
 
-    for (i = 0; i < chorus->number_blocks; i++) {
-      int ii;
-      /* Calculate the delay in subsamples for the delay line of chorus block nr. */
+            int pos_samples = pos_subsamples / INTERPOLATION_SUBSAMPLES;
 
-      /* The value in the lookup table is so, that this expression
-       * will always be positive.  It will always include a number of
-       * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to
-       * remain positive at all times. */
-      int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter
-                           - chorus->lookup_tab[chorus->phase[i]]);
+            /* modulo divide by INTERPOLATION_SUBSAMPLES */
+            pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK;
 
-      int pos_samples = pos_subsamples / INTERPOLATION_SUBSAMPLES;
+            for(ii = 0; ii < INTERPOLATION_SAMPLES; ii++)
+            {
+                /* Add the delayed signal to the chorus sum d_out Note: The
+                 * delay in the delay line moves backwards for increasing
+                 * delay!*/
 
-      /* modulo divide by INTERPOLATION_SUBSAMPLES */
-      pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK;
+                /* The & in chorusbuf[...] is equivalent to a division modulo
+                   MAX_SAMPLES, only faster. */
+                d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK]
+                         * chorus->sinc_table[ii][pos_subsamples];
 
-      for (ii = 0; ii < INTERPOLATION_SAMPLES; ii++){
-       /* Add the delayed signal to the chorus sum d_out Note: The
-        * delay in the delay line moves backwards for increasing
-        * delay!*/
+                pos_samples--;
+            };
 
-       /* The & in chorusbuf[...] is equivalent to a division modulo
-          MAX_SAMPLES, only faster. */
-       d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK]
-         * chorus->sinc_table[ii][pos_subsamples];
+            /* Cycle the phase of the modulating LFO */
+            chorus->phase[i]++;
 
-       pos_samples--;
-      };
-      /* Cycle the phase of the modulating LFO */
-      chorus->phase[i]++;
-      chorus->phase[i] %= (chorus->modulation_period_samples);
-    } /* foreach chorus block */
+            chorus->phase[i] %= (chorus->modulation_period_samples);
+        } /* foreach chorus block */
 
-    d_out *= chorus->level;
+        d_out *= chorus->level;
 
-    /* Store the chorus sum d_out to output */
-    left_out[sample_index] = d_out;
-    right_out[sample_index] = d_out;
+        /* Store the chorus sum d_out to output */
+        left_out[sample_index] = d_out;
+        right_out[sample_index] = d_out;
 
-    /* Move forward in circular buffer */
-    chorus->counter++;
-    chorus->counter %= MAX_SAMPLES;
+        /* Move forward in circular buffer */
+        chorus->counter++;
+        chorus->counter %= MAX_SAMPLES;
 
-  } /* foreach sample */
+    } /* foreach sample */
 }
 
 /* Purpose:
@@ -474,15 +540,25 @@ void fluid_chorus_processreplace(fluid_chorus_t* chorus, fluid_real_t *in,
 static void
 fluid_chorus_sine(int *buf, int len, int depth)
 {
-  int i;
-  double val;
-
-  for (i = 0; i < len; i++) {
-    val = sin((double) i / (double)len * 2.0 * M_PI);
-    buf[i] = (int) ((1.0 + val) * (double) depth / 2.0 * (double) INTERPOLATION_SUBSAMPLES);
-    buf[i] -= 3* MAX_SAMPLES * INTERPOLATION_SUBSAMPLES;
-    //    printf("%i %i\n",i,buf[i]);
-  }
+    int i;
+    double angle, incr, mult;
+
+    /* Pre-calculate increment between angles. */
+    incr = (2. * M_PI) / (double)len;
+
+    /* Pre-calculate 'depth' multiplier. */
+    mult = (double) depth / 2.0 * (double) INTERPOLATION_SUBSAMPLES;
+
+    /* Initialize to zero degrees. */
+    angle = 0.;
+
+    /* Build sine modulation waveform */
+    for(i = 0; i < len; i++)
+    {
+        buf[i] = (int)((1. + sin(angle)) * mult) - 3 * MAX_SAMPLES * INTERPOLATION_SUBSAMPLES;
+
+        angle += incr;
+    }
 }
 
 /* Purpose:
@@ -492,15 +568,26 @@ fluid_chorus_sine(int *buf, int len, int depth)
 static void
 fluid_chorus_triangle(int *buf, int len, int depth)
 {
-  int i=0;
-  int ii=len-1;
-  double val;
-  double val2;
-
-  while (i <= ii){
-    val = i * 2.0 / len * (double)depth * (double) INTERPOLATION_SUBSAMPLES;
-    val2= (int) (val + 0.5) - 3 * MAX_SAMPLES * INTERPOLATION_SUBSAMPLES;
-    buf[i++] = (int) val2;
-    buf[ii--] = (int) val2;
-  }
+    int *il = buf;
+    int *ir = buf + len - 1;
+    int ival;
+    double val, incr;
+
+    /* Pre-calculate increment for the ramp. */
+    incr = 2.0 / len * (double)depth * (double) INTERPOLATION_SUBSAMPLES;
+
+    /* Initialize first value */
+    val = 0. - 3. * MAX_SAMPLES * INTERPOLATION_SUBSAMPLES;
+
+    /* Build triangular modulation waveform */
+    while(il <= ir)
+    {
+        /* Assume 'val' to be always negative for rounding mode */
+        ival = (int)(val - 0.5);
+
+        *il++ = ival;
+        *ir-- = ival;
+
+        val += incr;
+    }
 }