fluid_chorus.c
上传用户:tjmskj2
上传日期:2020-08-17
资源大小:577k
文件大小:16k
源码类别:

midi

开发平台:

C/C++

  1. /*
  2.  * August 24, 1998
  3.  * Copyright (C) 1998 Juergen Mueller And Sundry Contributors
  4.  * This source code is freely redistributable and may be used for
  5.  * any purpose.  This copyright notice must be maintained.
  6.  * Juergen Mueller And Sundry Contributors are not responsible for
  7.  * the consequences of using this software.
  8.  */
  9. /*
  10.   CHANGES
  11.   - Adapted for fluidsynth, Peter Hanappe, March 2002
  12.   - Variable delay line implementation using bandlimited
  13.     interpolation, code reorganization: Markus Nentwig May 2002
  14.  */
  15. /*
  16.  *  Chorus effect.
  17.  *
  18.  * Flow diagram scheme for n delays ( 1 <= n <= MAX_CHORUS ):
  19.  *
  20.  *        * gain-in                                           ___
  21.  * ibuff -----+--------------------------------------------->|   |
  22.  *            |      _________                               |   |
  23.  *            |     |         |                   * level 1  |   |
  24.  *            +---->| delay 1 |----------------------------->|   |
  25.  *            |     |_________|                              |   |
  26.  *            |        /|                                   |   |
  27.  *            :         |                                    |   |
  28.  *            : +-----------------+   +--------------+       | + |
  29.  *            : | Delay control 1 |<--| mod. speed 1 |       |   |
  30.  *            : +-----------------+   +--------------+       |   |
  31.  *            |      _________                               |   |
  32.  *            |     |         |                   * level n  |   |
  33.  *            +---->| delay n |----------------------------->|   |
  34.  *                  |_________|                              |   |
  35.  *                     /|                                   |___|
  36.  *                      |                                      |
  37.  *              +-----------------+   +--------------+         | * gain-out
  38.  *              | Delay control n |<--| mod. speed n |         |
  39.  *              +-----------------+   +--------------+         +----->obuff
  40.  *
  41.  *
  42.  * The delay i is controlled by a sine or triangle modulation i ( 1 <= i <= n).
  43.  *
  44.  * The delay of each block is modulated between 0..depth ms
  45.  *
  46.  */
  47. /* Variable delay line implementation
  48.  * ==================================
  49.  *
  50.  * The modulated delay needs the value of the delayed signal between
  51.  * samples.  A lowpass filter is used to obtain intermediate values
  52.  * between samples (bandlimited interpolation).  The sample pulse
  53.  * train is convoluted with the impulse response of the low pass
  54.  * filter (sinc function).  To make it work with a small number of
  55.  * samples, the sinc function is windowed (Hamming window).
  56.  *
  57.  */
  58. #include "fluid_chorus.h"
  59. #include "fluid_sys.h"
  60. #define MAX_CHORUS 99
  61. #define MAX_DELAY 100
  62. #define MAX_DEPTH 10
  63. #define MIN_SPEED_HZ 0.29
  64. #define MAX_SPEED_HZ    5
  65. /* Length of one delay line in samples:
  66.  * Set through MAX_SAMPLES_LN2.
  67.  * For example:
  68.  * MAX_SAMPLES_LN2=12
  69.  * => MAX_SAMPLES=pow(2,12)=4096
  70.  * => MAX_SAMPLES_ANDMASK=4095
  71.  */
  72. #define MAX_SAMPLES_LN2 12
  73. #define MAX_SAMPLES (1 << (MAX_SAMPLES_LN2-1))
  74. #define MAX_SAMPLES_ANDMASK (MAX_SAMPLES-1)
  75. /* Interpolate how many steps between samples? Must be power of two
  76.    For example: 8 => use a resolution of 256 steps between any two
  77.    samples
  78. */
  79. #define INTERPOLATION_SUBSAMPLES_LN2 8
  80. #define INTERPOLATION_SUBSAMPLES (1 << (INTERPOLATION_SUBSAMPLES_LN2-1))
  81. #define INTERPOLATION_SUBSAMPLES_ANDMASK (INTERPOLATION_SUBSAMPLES-1)
  82. /* Use how many samples for interpolation? Must be odd.  '7' sounds
  83.    relatively clean, when listening to the modulated delay signal
  84.    alone.  For a demo on aliasing try '1' With '3', the aliasing is
  85.    still quite pronounced for some input frequencies
  86. */
  87. #define INTERPOLATION_SAMPLES 5
  88. /* Private data for SKEL file */
  89. struct _fluid_chorus_t {
  90.   int type;
  91.   fluid_real_t depth_ms;
  92.   fluid_real_t level;
  93.   fluid_real_t speed_Hz;
  94.   int number_blocks;
  95.   fluid_real_t *chorusbuf;
  96.   int counter;
  97.   long phase[MAX_CHORUS];
  98.   long modulation_period_samples;
  99.   int *lookup_tab;
  100.   fluid_real_t sample_rate;
  101.   /* sinc lookup table */
  102.   fluid_real_t sinc_table[INTERPOLATION_SAMPLES][INTERPOLATION_SUBSAMPLES];
  103. };
  104. static void fluid_chorus_triangle(int *buf, int len, int depth);
  105. static void fluid_chorus_sine(int *buf, int len, int depth);
  106. fluid_chorus_t*
  107. new_fluid_chorus(fluid_real_t sample_rate)
  108. {
  109.   int i; int ii;
  110.   fluid_chorus_t* chorus;
  111.   chorus = FLUID_NEW(fluid_chorus_t);
  112.   if (chorus == NULL) {
  113.     fluid_log(FLUID_PANIC, "chorus: Out of memory");
  114.     return NULL;
  115.   }
  116.   FLUID_MEMSET(chorus, 0, sizeof(fluid_chorus_t));
  117.   chorus->sample_rate = sample_rate;
  118.   /* Lookup table for the SI function (impulse response of an ideal low pass) */
  119.   /* i: Offset in terms of whole samples */
  120.   for (i = 0; i < INTERPOLATION_SAMPLES; i++){
  121.     /* ii: Offset in terms of fractional samples ('subsamples') */
  122.     for (ii = 0; ii < INTERPOLATION_SUBSAMPLES; ii++){
  123.       /* Move the origin into the center of the table */
  124.       double i_shifted = ((double) i- ((double) INTERPOLATION_SAMPLES) / 2.
  125.   + (double) ii / (double) INTERPOLATION_SUBSAMPLES);
  126.       if (fabs(i_shifted) < 0.000001) {
  127. /* sinc(0) cannot be calculated straightforward (limit needed
  128.    for 0/0) */
  129. chorus->sinc_table[i][ii] = (fluid_real_t)1.;
  130.       } else {
  131. chorus->sinc_table[i][ii] = (fluid_real_t)sin(i_shifted * M_PI) / (M_PI * i_shifted);
  132. /* Hamming window */
  133. chorus->sinc_table[i][ii] *= (fluid_real_t)0.5 * (1.0 + cos(2.0 * M_PI * i_shifted / (fluid_real_t)INTERPOLATION_SAMPLES));
  134.       };
  135.     };
  136.   };
  137.   /* allocate lookup tables */
  138.   chorus->lookup_tab = FLUID_ARRAY(int, (int) (chorus->sample_rate / MIN_SPEED_HZ));
  139.   if (chorus->lookup_tab == NULL) {
  140.     fluid_log(FLUID_PANIC, "chorus: Out of memory");
  141.     goto error_recovery;
  142.   }
  143.   /* allocate sample buffer */
  144.   chorus->chorusbuf = FLUID_ARRAY(fluid_real_t, MAX_SAMPLES);
  145.   if (chorus->chorusbuf == NULL) {
  146.     fluid_log(FLUID_PANIC, "chorus: Out of memory");
  147.     goto error_recovery;
  148.   }
  149.   if (fluid_chorus_init(chorus) != FLUID_OK){
  150.     goto error_recovery;
  151.   };
  152.   return chorus;
  153.  error_recovery:
  154.   delete_fluid_chorus(chorus);
  155.   return NULL;
  156. }
  157. void
  158. delete_fluid_chorus(fluid_chorus_t* chorus)
  159. {
  160.   if (chorus == NULL) {
  161.     return;
  162.   }
  163.   if (chorus->chorusbuf != NULL) {
  164.     FLUID_FREE(chorus->chorusbuf);
  165.   }
  166.   if (chorus->lookup_tab != NULL) {
  167.     FLUID_FREE(chorus->lookup_tab);
  168.   }
  169.   FLUID_FREE(chorus);
  170. }
  171. int
  172. fluid_chorus_init(fluid_chorus_t* chorus)
  173. {
  174.   int i;
  175.   for (i = 0; i < MAX_SAMPLES; i++) {
  176.     chorus->chorusbuf[i] = 0.0;
  177.   }
  178.   /* initialize the chorus with the default settings */
  179.   fluid_chorus_set (chorus, FLUID_CHORUS_SET_ALL, FLUID_CHORUS_DEFAULT_N,
  180.                     FLUID_CHORUS_DEFAULT_LEVEL, FLUID_CHORUS_DEFAULT_SPEED,
  181.                     FLUID_CHORUS_DEFAULT_DEPTH, FLUID_CHORUS_MOD_SINE);
  182.   return FLUID_OK;
  183. }
  184. void
  185. fluid_chorus_reset(fluid_chorus_t* chorus)
  186. {
  187.   fluid_chorus_init(chorus);
  188. }
  189. /**
  190.  * Set one or more chorus parameters.
  191.  * @param chorus Chorus instance
  192.  * @param set Flags indicating which chorus parameters to set (#fluid_chorus_set_t)
  193.  * @param nr Chorus voice count (0-99, CPU time consumption proportional to
  194.  *   this value)
  195.  * @param level Chorus level (0.0-1.0)
  196.  * @param speed Chorus speed in Hz (0.29-5.0)
  197.  * @param depth_ms Chorus depth (max value depends on synth sample rate,
  198.  *   0.0-21.0 is safe for sample rate values up to 96KHz)
  199.  * @param type Chorus waveform type (#fluid_chorus_mod)
  200.  */
  201. void
  202. fluid_chorus_set(fluid_chorus_t* chorus, int set, int nr, float level,
  203.                  float speed, float depth_ms, int type)
  204. {
  205.   int modulation_depth_samples;
  206.   int i;
  207.   if (set & FLUID_CHORUS_SET_NR) chorus->number_blocks = nr;
  208.   if (set & FLUID_CHORUS_SET_LEVEL) chorus->level = level;    
  209.   if (set & FLUID_CHORUS_SET_SPEED) chorus->speed_Hz = speed;
  210.   if (set & FLUID_CHORUS_SET_DEPTH) chorus->depth_ms = depth_ms;
  211.   if (set & FLUID_CHORUS_SET_TYPE) chorus->type = type;
  212.   if (chorus->number_blocks < 0) {
  213.     fluid_log(FLUID_WARN, "chorus: number blocks must be >=0! Setting value to 0.");
  214.     chorus->number_blocks = 0;
  215.   } else if (chorus->number_blocks > MAX_CHORUS) {
  216.     fluid_log(FLUID_WARN, "chorus: number blocks larger than max. allowed! Setting value to %d.",
  217.      MAX_CHORUS);
  218.     chorus->number_blocks = MAX_CHORUS;
  219.   }
  220.   if (chorus->speed_Hz < MIN_SPEED_HZ) {
  221.     fluid_log(FLUID_WARN, "chorus: speed is too low (min %f)! Setting value to min.",
  222.      (double) MIN_SPEED_HZ);
  223.     chorus->speed_Hz = MIN_SPEED_HZ;
  224.   } else if (chorus->speed_Hz > MAX_SPEED_HZ) {
  225.     fluid_log(FLUID_WARN, "chorus: speed must be below %f Hz! Setting value to max.",
  226.      (double) MAX_SPEED_HZ);
  227.     chorus->speed_Hz = MAX_SPEED_HZ;
  228.   }
  229.   if (chorus->depth_ms < 0.0) {
  230.     fluid_log(FLUID_WARN, "chorus: depth must be positive! Setting value to 0.");
  231.     chorus->depth_ms = 0.0;
  232.   }
  233.   /* Depth: Check for too high value through modulation_depth_samples. */
  234.   if (chorus->level < 0.0) {
  235.     fluid_log(FLUID_WARN, "chorus: level must be positive! Setting value to 0.");
  236.     chorus->level = 0.0;
  237.   } else if (chorus->level > 10) {
  238.     fluid_log(FLUID_WARN, "chorus: level must be < 10. A reasonable level is << 1! "
  239.      "Setting it to 0.1.");
  240.     chorus->level = 0.1;
  241.   }
  242.   /* The modulating LFO goes through a full period every x samples: */
  243.   chorus->modulation_period_samples = chorus->sample_rate / chorus->speed_Hz;
  244.   /* The variation in delay time is x: */
  245.   modulation_depth_samples = (int)
  246.     (chorus->depth_ms / 1000.0  /* convert modulation depth in ms to s*/
  247.      * chorus->sample_rate);
  248.   if (modulation_depth_samples > MAX_SAMPLES) {
  249.     fluid_log(FLUID_WARN, "chorus: Too high depth. Setting it to max (%d).", MAX_SAMPLES);
  250.     modulation_depth_samples = MAX_SAMPLES;
  251.   }
  252.   /* initialize LFO table */
  253.   if (chorus->type == FLUID_CHORUS_MOD_SINE) {
  254.     fluid_chorus_sine(chorus->lookup_tab, chorus->modulation_period_samples,
  255.      modulation_depth_samples);
  256.   } else if (chorus->type == FLUID_CHORUS_MOD_TRIANGLE) {
  257.     fluid_chorus_triangle(chorus->lookup_tab, chorus->modulation_period_samples,
  258.  modulation_depth_samples);
  259.   } else {
  260.     fluid_log(FLUID_WARN, "chorus: Unknown modulation type. Using sinewave.");
  261.     chorus->type = FLUID_CHORUS_MOD_SINE;
  262.     fluid_chorus_sine(chorus->lookup_tab, chorus->modulation_period_samples,
  263.      modulation_depth_samples);
  264.   }
  265.   for (i = 0; i < chorus->number_blocks; i++) {
  266.     /* Set the phase of the chorus blocks equally spaced */
  267.     chorus->phase[i] = (int) ((double) chorus->modulation_period_samples
  268.       * (double) i / (double) chorus->number_blocks);
  269.   }
  270.   /* Start of the circular buffer */
  271.   chorus->counter = 0;
  272. }
  273. void fluid_chorus_processmix(fluid_chorus_t* chorus, fluid_real_t *in,
  274.     fluid_real_t *left_out, fluid_real_t *right_out)
  275. {
  276.   int sample_index;
  277.   int i;
  278.   fluid_real_t d_in, d_out;
  279.   for (sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++) {
  280.     d_in = in[sample_index];
  281.     d_out = 0.0f;
  282. # if 0
  283.     /* Debug: Listen to the chorus signal only */
  284.     left_out[sample_index]=0;
  285.     right_out[sample_index]=0;
  286. #endif
  287.     /* Write the current sample into the circular buffer */
  288.     chorus->chorusbuf[chorus->counter] = d_in;
  289.     for (i = 0; i < chorus->number_blocks; i++) {
  290.       int ii;
  291.       /* Calculate the delay in subsamples for the delay line of chorus block nr. */
  292.       /* The value in the lookup table is so, that this expression
  293.        * will always be positive.  It will always include a number of
  294.        * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to
  295.        * remain positive at all times. */
  296.       int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter
  297.     - chorus->lookup_tab[chorus->phase[i]]);
  298.       int pos_samples = pos_subsamples/INTERPOLATION_SUBSAMPLES;
  299.       /* modulo divide by INTERPOLATION_SUBSAMPLES */
  300.       pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK;
  301.       for (ii = 0; ii < INTERPOLATION_SAMPLES; ii++){
  302. /* Add the delayed signal to the chorus sum d_out Note: The
  303.  * delay in the delay line moves backwards for increasing
  304.  * delay!*/
  305. /* The & in chorusbuf[...] is equivalent to a division modulo
  306.    MAX_SAMPLES, only faster. */
  307. d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK]
  308.   * chorus->sinc_table[ii][pos_subsamples];
  309. pos_samples--;
  310.       };
  311.       /* Cycle the phase of the modulating LFO */
  312.       chorus->phase[i]++;
  313.       chorus->phase[i] %= (chorus->modulation_period_samples);
  314.     } /* foreach chorus block */
  315.     d_out *= chorus->level;
  316.     /* Add the chorus sum d_out to output */
  317.     left_out[sample_index] += d_out;
  318.     right_out[sample_index] += d_out;
  319.     /* Move forward in circular buffer */
  320.     chorus->counter++;
  321.     chorus->counter %= MAX_SAMPLES;
  322.   } /* foreach sample */
  323. }
  324. /* Duplication of code ... (replaces sample data instead of mixing) */
  325. void fluid_chorus_processreplace(fluid_chorus_t* chorus, fluid_real_t *in,
  326. fluid_real_t *left_out, fluid_real_t *right_out)
  327. {
  328.   int sample_index;
  329.   int i;
  330.   fluid_real_t d_in, d_out;
  331.   for (sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++) {
  332.     d_in = in[sample_index];
  333.     d_out = 0.0f;
  334. # if 0
  335.     /* Debug: Listen to the chorus signal only */
  336.     left_out[sample_index]=0;
  337.     right_out[sample_index]=0;
  338. #endif
  339.     /* Write the current sample into the circular buffer */
  340.     chorus->chorusbuf[chorus->counter] = d_in;
  341.     for (i = 0; i < chorus->number_blocks; i++) {
  342.       int ii;
  343.       /* Calculate the delay in subsamples for the delay line of chorus block nr. */
  344.       /* The value in the lookup table is so, that this expression
  345.        * will always be positive.  It will always include a number of
  346.        * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to
  347.        * remain positive at all times. */
  348.       int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter
  349.     - chorus->lookup_tab[chorus->phase[i]]);
  350.       int pos_samples = pos_subsamples / INTERPOLATION_SUBSAMPLES;
  351.       /* modulo divide by INTERPOLATION_SUBSAMPLES */
  352.       pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK;
  353.       for (ii = 0; ii < INTERPOLATION_SAMPLES; ii++){
  354. /* Add the delayed signal to the chorus sum d_out Note: The
  355.  * delay in the delay line moves backwards for increasing
  356.  * delay!*/
  357. /* The & in chorusbuf[...] is equivalent to a division modulo
  358.    MAX_SAMPLES, only faster. */
  359. d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK]
  360.   * chorus->sinc_table[ii][pos_subsamples];
  361. pos_samples--;
  362.       };
  363.       /* Cycle the phase of the modulating LFO */
  364.       chorus->phase[i]++;
  365.       chorus->phase[i] %= (chorus->modulation_period_samples);
  366.     } /* foreach chorus block */
  367.     d_out *= chorus->level;
  368.     /* Store the chorus sum d_out to output */
  369.     left_out[sample_index] = d_out;
  370.     right_out[sample_index] = d_out;
  371.     /* Move forward in circular buffer */
  372.     chorus->counter++;
  373.     chorus->counter %= MAX_SAMPLES;
  374.   } /* foreach sample */
  375. }
  376. /* Purpose:
  377.  *
  378.  * Calculates a modulation waveform (sine) Its value ( modulo
  379.  * MAXSAMPLES) varies between 0 and depth*INTERPOLATION_SUBSAMPLES.
  380.  * Its period length is len.  The waveform data will be used modulo
  381.  * MAXSAMPLES only.  Since MAXSAMPLES is substracted from the waveform
  382.  * a couple of times here, the resulting (current position in
  383.  * buffer)-(waveform sample) will always be positive.
  384.  */
  385. static void
  386. fluid_chorus_sine(int *buf, int len, int depth)
  387. {
  388.   int i;
  389.   double val;
  390.   for (i = 0; i < len; i++) {
  391.     val = sin((double) i / (double)len * 2.0 * M_PI);
  392.     buf[i] = (int) ((1.0 + val) * (double) depth / 2.0 * (double) INTERPOLATION_SUBSAMPLES);
  393.     buf[i] -= 3* MAX_SAMPLES * INTERPOLATION_SUBSAMPLES;
  394.     //    printf("%i %in",i,buf[i]);
  395.   }
  396. }
  397. /* Purpose:
  398.  * Calculates a modulation waveform (triangle)
  399.  * See fluid_chorus_sine for comments.
  400.  */
  401. static void
  402. fluid_chorus_triangle(int *buf, int len, int depth)
  403. {
  404.   int i=0;
  405.   int ii=len-1;
  406.   double val;
  407.   double val2;
  408.   while (i <= ii){
  409.     val = i * 2.0 / len * (double)depth * (double) INTERPOLATION_SUBSAMPLES;
  410.     val2= (int) (val + 0.5) - 3 * MAX_SAMPLES * INTERPOLATION_SUBSAMPLES;
  411.     buf[i++] = (int) val2;
  412.     buf[ii--] = (int) val2;
  413.   }
  414. }