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

midi

开发平台:

C/C++

  1. /* Init dither table */
  2. static void 
  3. init_dither(void)
  4. {
  5.   float d, dp;
  6.   int c, i;
  7.   for (c = 0; c < DITHER_CHANNELS; c++) {
  8.     dp = 0;
  9.     for (i = 0; i < DITHER_SIZE-1; i++) {
  10.       d = rand() / (float)RAND_MAX - 0.5f;
  11.       rand_table[c][i] = d - dp;
  12.       dp = d;
  13.     }
  14.     rand_table[c][DITHER_SIZE-1] = 0 - dp;
  15.   }
  16. }
  17. /* A portable replacement for roundf(), seems it may actually be faster too! */
  18. static inline int
  19. roundi (float x)
  20. {
  21.   if (x >= 0.0f)
  22.     return (int)(x+0.5f);
  23.   else
  24.     return (int)(x-0.5f);
  25. }
  26. /**
  27.  * Synthesize a block of 16 bit audio samples to audio buffers.
  28.  * @param synth FluidSynth instance
  29.  * @param len Count of audio frames to synthesize
  30.  * @param lout Array of 16 bit words to store left channel of audio
  31.  * @param loff Offset index in 'lout' for first sample
  32.  * @param lincr Increment between samples stored to 'lout'
  33.  * @param rout Array of 16 bit words to store right channel of audio
  34.  * @param roff Offset index in 'rout' for first sample
  35.  * @param rincr Increment between samples stored to 'rout'
  36.  * @return FLUID_OK on success, FLUID_FAIL otherwise
  37.  *
  38.  * Useful for storing interleaved stereo (lout = rout, loff = 0, roff = 1,
  39.  * lincr = 2, rincr = 2).
  40.  *
  41.  * NOTE: Should only be called from synthesis thread.
  42.  * NOTE: Dithering is performed when converting from internal floating point to
  43.  * 16 bit audio.
  44.  */
  45. int
  46. fluid_synth_write_s16(fluid_synth_t* synth, int len,
  47.                       void* lout, int loff, int lincr,
  48.                       void* rout, int roff, int rincr)
  49. {
  50.   int i, j, k, cur;
  51.   signed short* left_out = (signed short*) lout;
  52.   signed short* right_out = (signed short*) rout;
  53.   fluid_real_t* left_in = synth->left_buf[0];
  54.   fluid_real_t* right_in = synth->right_buf[0];
  55.   fluid_real_t left_sample;
  56.   fluid_real_t right_sample;
  57.   double time = fluid_utime();
  58.   int di = synth->dither_index;
  59.   double prof_ref_on_block;
  60.   float cpu_load;
  61.   fluid_profile_ref_var (prof_ref);
  62.   cur = synth->cur;
  63.   for (i = 0, j = loff, k = roff; i < len; i++, cur++, j += lincr, k += rincr) {
  64.     /* fill up the buffers as needed */
  65.     if (cur == FLUID_BUFSIZE) {
  66.       prof_ref_on_block = fluid_profile_ref();
  67.       fluid_synth_one_block(synth, 0);
  68.       cur = 0;
  69.       fluid_profile(FLUID_PROF_ONE_BLOCK, prof_ref_on_block);
  70.     }
  71.     left_sample = roundi (left_in[cur] * 32766.0f + rand_table[0][di]);
  72.     right_sample = roundi (right_in[cur] * 32766.0f + rand_table[1][di]);
  73.     di++;
  74.     if (di >= DITHER_SIZE) di = 0;
  75.     /* digital clipping */
  76.     if (left_sample > 32767.0f) left_sample = 32767.0f;
  77.     if (left_sample < -32768.0f) left_sample = -32768.0f;
  78.     if (right_sample > 32767.0f) right_sample = 32767.0f;
  79.     if (right_sample < -32768.0f) right_sample = -32768.0f;
  80.     left_out[j] = (signed short) left_sample;
  81.     right_out[k] = (signed short) right_sample;
  82.   }
  83.   synth->cur = cur;
  84.   synth->dither_index = di; /* keep dither buffer continous */
  85.   fluid_profile(FLUID_PROF_WRITE_S16, prof_ref);
  86.   time = fluid_utime() - time;
  87.   cpu_load = 0.5 * (synth->cpu_load + time * synth->sample_rate / len / 10000.0);
  88.   fluid_atomic_float_set (&synth->cpu_load, cpu_load);
  89.   return 0;
  90. }
  91. /**
  92.  * Converts stereo floating point sample data to signed 16 bit data with dithering.
  93.  * @param dither_index Pointer to an integer which should be initialized to 0
  94.  *   before the first call and passed unmodified to additional calls which are
  95.  *   part of the same synthesis output.
  96.  * @param len Length in frames to convert
  97.  * @param lin Buffer of left audio samples to convert from
  98.  * @param rin Buffer of right audio samples to convert from
  99.  * @param lout Array of 16 bit words to store left channel of audio
  100.  * @param loff Offset index in 'lout' for first sample
  101.  * @param lincr Increment between samples stored to 'lout'
  102.  * @param rout Array of 16 bit words to store right channel of audio
  103.  * @param roff Offset index in 'rout' for first sample
  104.  * @param rincr Increment between samples stored to 'rout'
  105.  *
  106.  * NOTE: Currently private to libfluidsynth.
  107.  */
  108. void
  109. fluid_synth_dither_s16(int *dither_index, int len, float* lin, float* rin,
  110.        void* lout, int loff, int lincr,
  111.        void* rout, int roff, int rincr)
  112. {
  113.   int i, j, k;
  114.   signed short* left_out = (signed short*) lout;
  115.   signed short* right_out = (signed short*) rout;
  116.   fluid_real_t left_sample;
  117.   fluid_real_t right_sample;
  118.   int di = *dither_index;
  119.   fluid_profile_ref_var (prof_ref);
  120.   for (i = 0, j = loff, k = roff; i < len; i++, j += lincr, k += rincr) {
  121.     left_sample = roundi (lin[i] * 32766.0f + rand_table[0][di]);
  122.     right_sample = roundi (rin[i] * 32766.0f + rand_table[1][di]);
  123.     di++;
  124.     if (di >= DITHER_SIZE) di = 0;
  125.     /* digital clipping */
  126.     if (left_sample > 32767.0f) left_sample = 32767.0f;
  127.     if (left_sample < -32768.0f) left_sample = -32768.0f;
  128.     if (right_sample > 32767.0f) right_sample = 32767.0f;
  129.     if (right_sample < -32768.0f) right_sample = -32768.0f;
  130.     left_out[j] = (signed short) left_sample;
  131.     right_out[k] = (signed short) right_sample;
  132.   }
  133.   *dither_index = di; /* keep dither buffer continous */
  134.   fluid_profile(FLUID_PROF_WRITE_S16, prof_ref);
  135. }
  136. /*
  137.  * Process a single block (FLUID_BUFSIZE) of audio.
  138.  */
  139. static int
  140. fluid_synth_one_block(fluid_synth_t* synth, int do_not_mix_fx_to_out)
  141. {
  142.   fluid_real_t local_voice_buf[FLUID_BUFSIZE];
  143.   int i, auchan, start_index, voice_index;
  144.   fluid_voice_t* voice;
  145.   fluid_real_t* left_buf;
  146.   fluid_real_t* right_buf;
  147.   fluid_real_t* reverb_buf;
  148.   fluid_real_t* chorus_buf;
  149.   int byte_size = FLUID_BUFSIZE * sizeof(fluid_real_t);
  150.   int count;
  151.   fluid_profile_ref_var (prof_ref);
  152.   /* Assign ID of synthesis thread */
  153.   synth->synth_thread_id = fluid_thread_get_id ();
  154.   fluid_check_fpe("??? Just starting up ???");
  155.   fluid_sample_timer_process(synth);
  156.   fluid_check_fpe("fluid_sample_timer_process");
  157.   /* Process queued events */
  158.   for (i = 0; i < FLUID_MAX_EVENT_QUEUES; i++)
  159.   {
  160.     if (synth->queues[i])
  161.       fluid_synth_process_event_queue_LOCAL (synth, synth->queues[i]);
  162.     else break;         /* First NULL ends the array (values are never set to NULL) */
  163.   }
  164.   /* clean the audio buffers */
  165.   for (i = 0; i < synth->nbuf; i++) {
  166.     FLUID_MEMSET(synth->left_buf[i], 0, byte_size);
  167.     FLUID_MEMSET(synth->right_buf[i], 0, byte_size);
  168.   }
  169.   for (i = 0; i < synth->effects_channels; i++) {
  170.     FLUID_MEMSET(synth->fx_left_buf[i], 0, byte_size);
  171.     FLUID_MEMSET(synth->fx_right_buf[i], 0, byte_size);
  172.   }
  173.   /* Set up the reverb / chorus buffers only, when the effect is
  174.    * enabled on synth level.  Nonexisting buffers are detected in the
  175.    * DSP loop. Not sending the reverb / chorus signal saves some time
  176.    * in that case. */
  177.   reverb_buf = synth->with_reverb ? synth->fx_left_buf[SYNTH_REVERB_CHANNEL] : NULL;
  178.   chorus_buf = synth->with_chorus ? synth->fx_left_buf[SYNTH_CHORUS_CHANNEL] : NULL;
  179.   fluid_profile(FLUID_PROF_ONE_BLOCK_CLEAR, prof_ref);
  180.   if (synth->cores > 1)
  181.   {
  182.     /* Look for first active voice to process */
  183.     for (voice_index = 0; voice_index < synth->polyphony; voice_index++)
  184.     {
  185.       voice = synth->voice[voice_index];
  186.       if (_PLAYING (voice)) break;
  187.     }
  188.     /* Was there a voice to process? */
  189.     if (voice_index < synth->polyphony)
  190.     {
  191.       fluid_cond_mutex_lock (synth->core_mutex);       /* ++ Lock core variables */
  192.       synth->core_voice_index = voice_index + 1;       /* Set the next core_voice_index */
  193.       /* Tell the other core threads that there is work to do */
  194.       synth->core_work = TRUE;
  195.       synth->core_waiting_for_last = FALSE;
  196.       fluid_cond_broadcast (synth->core_cond);
  197.       fluid_cond_mutex_unlock (synth->core_mutex);       /* -- Unlock core variables */
  198.       while (TRUE)
  199.       {
  200. got_voice:      /* We got a voice to process */
  201.         count = fluid_voice_write (voice, &synth->core_bufs[voice_index * FLUID_BUFSIZE]);
  202.         if (count > 0) synth->core_voice_processed[voice_index] = voice;
  203.         /* Look for next active voice to process (in a lock free manner) */
  204.         do
  205.         {
  206.           voice_index = fluid_atomic_int_get (&synth->core_voice_index);
  207.           for (start_index = voice_index; voice_index < synth->polyphony; voice_index++)
  208.           {
  209.             voice = synth->voice[voice_index];
  210.             if (_PLAYING (voice))
  211.             {
  212.               if (fluid_atomic_int_compare_and_exchange (&synth->core_voice_index,
  213.                                                          start_index, voice_index + 1))
  214.                 goto got_voice;
  215.               break;    /* compare and exchange failed (another thread grabbed the voice first) */
  216.             }
  217.           }
  218.         }
  219.         while (voice_index < synth->polyphony);
  220.         /* No more voices to process */
  221.         fluid_cond_mutex_lock (synth->core_mutex);       /* ++ Lock core variables */
  222.         synth->core_work = FALSE;
  223.         /* If there are still other core threads in progress, wait for last one */
  224.         if (synth->core_inprogress > 0)
  225.         {
  226.           synth->core_waiting_for_last = TRUE;
  227.           while (synth->core_inprogress > 0)
  228.             fluid_cond_wait (synth->core_wait_last_cond, synth->core_mutex);
  229.         }
  230.         fluid_cond_mutex_unlock (synth->core_mutex);     /* -- Unlock core variables */
  231.         break;        /* We're done */
  232.       }         /* while (TRUE) - Process voices loop */
  233.       /* Mix all voices */
  234.       for (i = 0; i < synth->polyphony; i++)
  235.       {
  236.         voice = synth->core_voice_processed[i];
  237.         if (!voice) continue;
  238.         synth->core_voice_processed[i] = NULL;
  239.         auchan = fluid_channel_get_num (fluid_voice_get_channel (voice));
  240.         auchan %= synth->audio_groups;
  241.         left_buf = synth->left_buf[auchan];
  242.         right_buf = synth->right_buf[auchan];
  243.         fluid_voice_mix (voice, left_buf, right_buf, reverb_buf, chorus_buf);
  244.       }       /* while (TRUE) - Mix processed voices loop */
  245.     }   /* if (i < synth->polyphony) - Are there any voices to process? */
  246.   }
  247.   else          /* synth->cores < 1 - Not multi-core enabled */
  248.   {
  249.     /* call all playing synthesis processes */
  250.     for (i = 0; i < synth->polyphony; i++) {
  251.       fluid_profile_ref_var (prof_ref_voice);
  252.       voice = synth->voice[i];
  253.       if (!_PLAYING(voice)) continue;
  254.       /* The output associated with a MIDI channel is wrapped around
  255.        * using the number of audio groups as modulo divider.  This is
  256.        * typically the number of output channels on the 'sound card',
  257.        * as long as the LADSPA Fx unit is not used. In case of LADSPA
  258.        * unit, think of it as subgroups on a mixer.
  259.        *
  260.        * For example: Assume that the number of groups is set to 2.
  261.        * Then MIDI channel 1, 3, 5, 7 etc. go to output 1, channels 2,
  262.        * 4, 6, 8 etc to output 2.  Or assume 3 groups: Then MIDI
  263.        * channels 1, 4, 7, 10 etc go to output 1; 2, 5, 8, 11 etc to
  264.        * output 2, 3, 6, 9, 12 etc to output 3.
  265.        */
  266.       auchan = fluid_channel_get_num(fluid_voice_get_channel(voice));
  267.       auchan %= synth->audio_groups;
  268.       left_buf = synth->left_buf[auchan];
  269.       right_buf = synth->right_buf[auchan];
  270.       fluid_voice_write (voice, local_voice_buf);
  271.       fluid_voice_mix (voice, left_buf, right_buf, reverb_buf, chorus_buf);
  272.       fluid_profile (FLUID_PROF_ONE_BLOCK_VOICE, prof_ref_voice);
  273.     }
  274.   }
  275.   fluid_check_fpe("Synthesis processes");
  276.   fluid_profile(FLUID_PROF_ONE_BLOCK_VOICES, prof_ref);
  277.   /* if multi channel output, don't mix the output of the chorus and
  278.      reverb in the final output. The effects outputs are send
  279.      separately. */
  280.   if (do_not_mix_fx_to_out) {
  281.     /* send to reverb */
  282.     if (reverb_buf) {
  283.       fluid_revmodel_processreplace(synth->reverb, reverb_buf,
  284.    synth->fx_left_buf[SYNTH_REVERB_CHANNEL],
  285.    synth->fx_right_buf[SYNTH_REVERB_CHANNEL]);
  286.       fluid_check_fpe("Reverb");
  287.     }
  288.     fluid_profile(FLUID_PROF_ONE_BLOCK_REVERB, prof_ref);
  289.     /* send to chorus */
  290.     if (chorus_buf) {
  291.       fluid_chorus_processreplace(synth->chorus, chorus_buf,
  292.  synth->fx_left_buf[SYNTH_CHORUS_CHANNEL],
  293.          synth->fx_right_buf[SYNTH_CHORUS_CHANNEL]);
  294.       fluid_check_fpe("Chorus");
  295.     }
  296.   } else {
  297.     /* send to reverb */
  298.     if (reverb_buf) {
  299.       fluid_revmodel_processmix(synth->reverb, reverb_buf,
  300.        synth->left_buf[0], synth->right_buf[0]);
  301.       fluid_check_fpe("Reverb");
  302.     }
  303.     fluid_profile(FLUID_PROF_ONE_BLOCK_REVERB, prof_ref);
  304.     /* send to chorus */
  305.     if (chorus_buf) {
  306.       fluid_chorus_processmix(synth->chorus, chorus_buf,
  307.      synth->left_buf[0], synth->right_buf[0]);
  308.       fluid_check_fpe("Chorus");
  309.     }
  310.   }
  311.   fluid_profile(FLUID_PROF_ONE_BLOCK_CHORUS, prof_ref);
  312. #ifdef LADSPA
  313.   /* Run the signal through the LADSPA Fx unit */
  314.   fluid_LADSPA_run(synth->LADSPA_FxUnit, synth->left_buf, synth->right_buf, synth->fx_left_buf, synth->fx_right_buf);
  315.   fluid_check_fpe("LADSPA");
  316. #endif
  317.   /* Signal return queue thread if there are any events pending */
  318.   if (fluid_atomic_int_get (&synth->return_queue->count) > 0)
  319.     fluid_cond_signal (synth->return_queue_cond);
  320.   synth->ticks += FLUID_BUFSIZE;
  321.   /* Testcase, that provokes a denormal floating point error */
  322. #if 0
  323.   {float num=1;while (num != 0){num*=0.5;};};
  324. #endif
  325.   fluid_check_fpe("??? Remainder of synth_one_block ???");
  326.   return 0;
  327. }
  328. /* Core thread function (processes voices in parallel to primary synthesis thread) */
  329. static void
  330. fluid_synth_core_thread_func (void* data)
  331. {
  332.   fluid_synth_t *synth = data;
  333.   fluid_voice_t *voice;
  334.   int i, count, start_index;
  335.   /* We do this, rather than adding an "if (first_run)" statement to the while loop */
  336.   fluid_cond_mutex_lock (synth->core_mutex);       /* ++ Lock core variables */
  337.   synth->core_inprogress++;
  338.   fluid_cond_mutex_unlock (synth->core_mutex);     /* -- Unlock core variables */
  339.   /* Loop until delete_fluid_synth() kills off core threads */
  340.   while (synth->cores_active)
  341.   {
  342.     fluid_cond_mutex_lock (synth->core_mutex);       /* ++ Lock core variables */
  343.     synth->core_inprogress--;
  344.     /* Wakeup primary synthesis thread if it is waiting for last and we are it */
  345.     if (synth->core_waiting_for_last && synth->core_inprogress == 0)
  346.       fluid_cond_signal (synth->core_wait_last_cond);
  347.     /* Wait until there is core work */
  348.     while (!synth->core_work && synth->cores_active)
  349.       fluid_cond_wait (synth->core_cond, synth->core_mutex);
  350.     if (!synth->cores_active)
  351.     {
  352.       fluid_cond_mutex_unlock (synth->core_mutex);   /* -- Unlock core variables */
  353.       break;
  354.     }
  355.     synth->core_inprogress++;
  356.     fluid_cond_mutex_unlock (synth->core_mutex);     /* -- Unlock core variables */
  357.     /* Voice processing loop (lock free) */
  358.     while (TRUE)
  359.     {
  360.       /* Look for next active voice to process (in a lock free manner) */
  361.       do
  362.       {
  363.         i = fluid_atomic_int_get (&synth->core_voice_index);
  364.         for (start_index = i; i < synth->polyphony; i++)
  365.         {
  366.           voice = synth->voice[i];
  367.           if (_PLAYING (voice))
  368.           {
  369.             if (fluid_atomic_int_compare_and_exchange (&synth->core_voice_index,
  370.                                                        start_index, i + 1))
  371.               goto got_voice;
  372.             break;    /* compare and exchange failed (another thread grabbed the voice first) */
  373.           }
  374.         }
  375.       }
  376.       while (i < synth->polyphony);
  377.       /* No more voices to process */
  378.       fluid_atomic_int_set (&synth->core_voice_index, synth->polyphony);
  379.       fluid_atomic_int_set (&synth->core_work, FALSE);
  380.       break;
  381. got_voice:
  382.       /* Synthesize the voice */
  383.       count = fluid_voice_write (voice, &synth->core_bufs[i * FLUID_BUFSIZE]);
  384.       /* Assign the processed voice to the same voicebuf index (if there was any audio) */
  385.       if (count > 0) synth->core_voice_processed[i] = voice;
  386.     }           /* while (TRUE) - Lock free voice processing loop */
  387.   }     /* while (synth->cores_active) */
  388. }
  389. /* Process events in an event queue */
  390. static FLUID_INLINE void
  391. fluid_synth_process_event_queue_LOCAL (fluid_synth_t *synth,
  392.                                        fluid_event_queue_t *queue)
  393. {
  394.   fluid_event_queue_elem_t *event;
  395.   while ((event = fluid_event_queue_get_outptr (queue)))
  396.   {
  397.     switch (event->type)
  398.     {
  399.     case FLUID_EVENT_QUEUE_ELEM_MIDI:
  400.       switch (event->midi.type)
  401.       {
  402.         case NOTE_ON:
  403.           fluid_synth_noteon_LOCAL (synth, event->midi.channel,
  404.                                     event->midi.param1, event->midi.param2);
  405.           break;
  406.         case NOTE_OFF:
  407.           fluid_synth_noteoff_LOCAL (synth, event->midi.channel,
  408.                                      event->midi.param1);
  409.           break;
  410.         case CONTROL_CHANGE:
  411.           fluid_synth_cc_LOCAL (synth, event->midi.channel, event->midi.param1);
  412.           break;
  413.         case MIDI_SYSTEM_RESET:
  414.           fluid_synth_system_reset_LOCAL (synth);
  415.           break;
  416.         case CHANNEL_PRESSURE:
  417.           fluid_synth_update_channel_pressure_LOCAL (synth, event->midi.channel);
  418.           break;
  419.         case PITCH_BEND:
  420.           fluid_synth_update_pitch_bend_LOCAL (synth, event->midi.channel);
  421.           break;
  422.         case RPN_LSB:
  423.           switch (event->midi.param1)
  424.           {
  425.             case RPN_PITCH_BEND_RANGE:
  426.               fluid_synth_update_pitch_wheel_sens_LOCAL (synth, event->midi.channel);
  427.               break;
  428.           }
  429.           break;
  430.       }
  431.       break;
  432.     case FLUID_EVENT_QUEUE_ELEM_UPDATE_GAIN:
  433.       fluid_synth_update_gain_LOCAL (synth);
  434.       break;
  435.     case FLUID_EVENT_QUEUE_ELEM_POLYPHONY:
  436.       fluid_synth_update_polyphony_LOCAL (synth);
  437.       break;
  438.     case FLUID_EVENT_QUEUE_ELEM_GEN:
  439.       fluid_synth_set_gen_LOCAL (synth, event->gen.channel, event->gen.param,
  440.                                  event->gen.value, event->gen.absolute);
  441.       break;
  442.     case FLUID_EVENT_QUEUE_ELEM_PRESET:
  443.       fluid_channel_set_preset (synth->channel[event->preset.channel],
  444.                                 event->preset.preset);
  445.       break;
  446.     case FLUID_EVENT_QUEUE_ELEM_STOP_VOICES:
  447.       fluid_synth_stop_LOCAL (synth, event->ival);
  448.       break;
  449.     case FLUID_EVENT_QUEUE_ELEM_SET_TUNING:
  450.       fluid_synth_set_tuning_LOCAL (synth, event->set_tuning.channel,
  451.                                     event->set_tuning.tuning, event->set_tuning.apply);
  452.       break;
  453.     case FLUID_EVENT_QUEUE_ELEM_REPL_TUNING:
  454.       fluid_synth_replace_tuning_LOCAL (synth, event->repl_tuning.old_tuning,
  455.                                         event->repl_tuning.new_tuning,
  456.                                         event->repl_tuning.apply, TRUE);
  457.       break;
  458.     }
  459.     fluid_event_queue_next_outptr (queue);
  460.   }
  461. }
  462. /* Selects a voice for killing. */
  463. static fluid_voice_t*
  464. fluid_synth_free_voice_by_kill_LOCAL(fluid_synth_t* synth)
  465. {
  466.   int i;
  467.   fluid_real_t best_prio = 999999.;
  468.   fluid_real_t this_voice_prio;
  469.   fluid_voice_t* voice;
  470.   int best_voice_index=-1;
  471.   for (i = 0; i < synth->polyphony; i++) {
  472.     voice = synth->voice[i];
  473.     /* safeguard against an available voice. */
  474.     if (_AVAILABLE(voice)) {
  475.       return voice;
  476.     }
  477.     /* Determine, how 'important' a voice is.
  478.      * Start with an arbitrary number */
  479.     this_voice_prio = 10000.;
  480.     /* Is this voice on the drum channel?
  481.      * Then it is very important.
  482.      * Also, forget about the released-note condition:
  483.      * Typically, drum notes are triggered only very briefly, they run most
  484.      * of the time in release phase.
  485.      */
  486.     if (voice->chan == 9){
  487.       this_voice_prio += 4000;
  488.     } else if (_RELEASED(voice)){
  489.       /* The key for this voice has been released. Consider it much less important
  490.        * than a voice, which is still held.
  491.        */
  492.       this_voice_prio -= 2000.;
  493.     }
  494.     if (_SUSTAINED(voice)){
  495.       /* The sustain pedal is held down on this channel.
  496.        * Consider it less important than non-sustained channels.
  497.        * This decision is somehow subjective. But usually the sustain pedal
  498.        * is used to play 'more-voices-than-fingers', so it shouldn't hurt
  499.        * if we kill one voice.
  500.        */
  501.       this_voice_prio -= 1000;
  502.     }
  503.     /* We are not enthusiastic about releasing voices, which have just been started.
  504.      * Otherwise hitting a chord may result in killing notes belonging to that very same
  505.      * chord.
  506.      * So subtract the age of the voice from the priority - an older voice is just a little
  507.      * bit less important than a younger voice.
  508.      * This is a number between roughly 0 and 100.*/
  509.     this_voice_prio -= (synth->noteid - fluid_voice_get_id(voice));
  510.     /* take a rough estimate of loudness into account. Louder voices are more important. */
  511.     if (voice->volenv_section > FLUID_VOICE_ENVATTACK){
  512.       this_voice_prio += voice->volenv_val * 1000.;
  513.     } else {
  514.       this_voice_prio += voice->volenv_data[FLUID_VOICE_ENVATTACK].max * 1000.;
  515.     }
  516.     /* check if this voice has less priority than the previous candidate. */
  517.     if (this_voice_prio < best_prio)
  518.       best_voice_index = i,
  519.       best_prio = this_voice_prio;
  520.   }
  521.   if (best_voice_index < 0) {
  522.     return NULL;
  523.   }
  524.   voice = synth->voice[best_voice_index];
  525.   fluid_voice_off(voice);
  526.   return voice;
  527. }
  528. /**
  529.  * Allocate a synthesis voice.
  530.  * @param synth FluidSynth instance
  531.  * @param sample Sample to assign to the voice
  532.  * @param chan MIDI channel number (0 to MIDI channel count - 1)
  533.  * @param key MIDI note number for the voice (0-127)
  534.  * @param vel MIDI velocity for the voice (0-127)
  535.  * @return Allocated synthesis voice or NULL on error
  536.  *
  537.  * This function is called by a SoundFont's preset in response to a noteon event.
  538.  * The returned voice comes with default modulators and generators.
  539.  * A single noteon event may create any number of voices, when the preset is layered.
  540.  *
  541.  * NOTE: Should only be called from within synthesis thread, which includes
  542.  * SoundFont loader preset noteon method.
  543.  */
  544. fluid_voice_t*
  545. fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, int chan, int key, int vel)
  546. {
  547.   int i, k;
  548.   fluid_voice_t* voice = NULL;
  549.   fluid_channel_t* channel = NULL;
  550.   fluid_return_val_if_fail (synth != NULL, NULL);
  551.   fluid_return_val_if_fail (sample != NULL, NULL);
  552.   fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, NULL);
  553.   fluid_return_val_if_fail (fluid_synth_is_synth_thread (synth), NULL);
  554.   /* check if there's an available synthesis process */
  555.   for (i = 0; i < synth->polyphony; i++) {
  556.     if (_AVAILABLE(synth->voice[i])) {
  557.       voice = synth->voice[i];
  558.       break;
  559.     }
  560.   }
  561.   /* No success yet? Then stop a running voice. */
  562.   if (voice == NULL) {
  563.     voice = fluid_synth_free_voice_by_kill_LOCAL(synth);
  564.   }
  565.   if (voice == NULL) {
  566.     FLUID_LOG(FLUID_WARN, "Failed to allocate a synthesis process. (chan=%d,key=%d)", chan, key);
  567.     return NULL;
  568.   }
  569.   if (synth->verbose) {
  570.     k = 0;
  571.     for (i = 0; i < synth->polyphony; i++) {
  572.       if (!_AVAILABLE(synth->voice[i])) {
  573. k++;
  574.       }
  575.     }
  576.     FLUID_LOG(FLUID_INFO, "noteont%dt%dt%dt%05dt%.3ft%.3ft%.3ft%d",
  577.      chan, key, vel, synth->storeid,
  578.      (float) synth->ticks / 44100.0f,
  579.      (fluid_curtime() - synth->start) / 1000.0f,
  580.      0.0f,
  581.      k);
  582.   }
  583.   if (chan >= 0) {
  584.   channel = synth->channel[chan];
  585.   }
  586.   if (fluid_voice_init (voice, sample, channel, key, vel,
  587.                         synth->storeid, synth->ticks,
  588.                         fluid_atomic_float_get (&synth->gain)) != FLUID_OK) {
  589.     FLUID_LOG(FLUID_WARN, "Failed to initialize voice");
  590.     return NULL;
  591.   }
  592.   /* add the default modulators to the synthesis process. */
  593.   fluid_voice_add_mod(voice, &default_vel2att_mod, FLUID_VOICE_DEFAULT);    /* SF2.01 $8.4.1  */
  594.   fluid_voice_add_mod(voice, &default_vel2filter_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.2  */
  595.   fluid_voice_add_mod(voice, &default_at2viblfo_mod, FLUID_VOICE_DEFAULT);  /* SF2.01 $8.4.3  */
  596.   fluid_voice_add_mod(voice, &default_mod2viblfo_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.4  */
  597.   fluid_voice_add_mod(voice, &default_att_mod, FLUID_VOICE_DEFAULT);        /* SF2.01 $8.4.5  */
  598.   fluid_voice_add_mod(voice, &default_pan_mod, FLUID_VOICE_DEFAULT);        /* SF2.01 $8.4.6  */
  599.   fluid_voice_add_mod(voice, &default_expr_mod, FLUID_VOICE_DEFAULT);       /* SF2.01 $8.4.7  */
  600.   fluid_voice_add_mod(voice, &default_reverb_mod, FLUID_VOICE_DEFAULT);     /* SF2.01 $8.4.8  */
  601.   fluid_voice_add_mod(voice, &default_chorus_mod, FLUID_VOICE_DEFAULT);     /* SF2.01 $8.4.9  */
  602.   fluid_voice_add_mod(voice, &default_pitch_bend_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.10 */
  603.   return voice;
  604. }
  605. /* Kill all voices on a given channel, which have the same exclusive class
  606.  * generator as new_voice.
  607.  */
  608. static void
  609. fluid_synth_kill_by_exclusive_class_LOCAL(fluid_synth_t* synth,
  610.                                           fluid_voice_t* new_voice)
  611. {
  612.   int excl_class = _GEN(new_voice,GEN_EXCLUSIVECLASS);
  613.   fluid_voice_t* existing_voice;
  614.   int i;
  615.   /* Excl. class 0: No exclusive class */
  616.   if (excl_class == 0) return;
  617.   /* Kill all notes on the same channel with the same exclusive class */
  618.   for (i = 0; i < synth->polyphony; i++) {
  619.     existing_voice = synth->voice[i];
  620.     /* If voice is playing, on the same channel, has same exclusive
  621.      * class and is not part of the same noteon event (voice group), then kill it */
  622.     if (_PLAYING(existing_voice)
  623.         && existing_voice->chan == new_voice->chan
  624.         && (int)_GEN (existing_voice, GEN_EXCLUSIVECLASS) == excl_class
  625.         && fluid_voice_get_id (existing_voice) != fluid_voice_get_id(new_voice))
  626.       fluid_voice_kill_excl(existing_voice);
  627.   }
  628. }
  629. /**
  630.  * Activate a voice previously allocated with fluid_synth_alloc_voice().
  631.  * @param synth FluidSynth instance
  632.  * @param voice Voice to activate
  633.  *
  634.  * This function is called by a SoundFont's preset in response to a noteon
  635.  * event.  Exclusive classes are processed here.
  636.  *
  637.  * NOTE: Should only be called from within synthesis thread, which includes
  638.  * SoundFont loader preset noteon method.
  639.  */
  640. void
  641. fluid_synth_start_voice(fluid_synth_t* synth, fluid_voice_t* voice)
  642. {
  643.   fluid_return_if_fail (synth != NULL);
  644.   fluid_return_if_fail (voice != NULL);
  645.   fluid_return_if_fail (fluid_synth_is_synth_thread (synth));
  646.   /* Find the exclusive class of this voice. If set, kill all voices
  647.    * that match the exclusive class and are younger than the first
  648.    * voice process created by this noteon event. */
  649.   fluid_synth_kill_by_exclusive_class_LOCAL(synth, voice);
  650.   fluid_voice_start(voice);     /* Start the new voice */
  651. }
  652. /**
  653.  * Add a SoundFont loader interface.
  654.  * @param synth FluidSynth instance
  655.  * @param loader Loader API structure, used directly and should remain allocated
  656.  *   as long as the synth instance is used.
  657.  *
  658.  * SoundFont loaders are used to add custom instrument loading to FluidSynth.
  659.  * The caller supplied functions for loading files, allocating presets,
  660.  * retrieving information on them and synthesizing note-on events.  Using this
  661.  * method even non SoundFont instruments can be synthesized, although limited
  662.  * to the SoundFont synthesis model.
  663.  *
  664.  * NOTE: Should only be called before any SoundFont files are loaded.
  665.  */
  666. void
  667. fluid_synth_add_sfloader(fluid_synth_t* synth, fluid_sfloader_t* loader)
  668. {
  669.   gboolean sfont_already_loaded;
  670.   fluid_return_if_fail (synth != NULL);
  671.   fluid_return_if_fail (loader != NULL);
  672.   sfont_already_loaded = synth->sfont_info != NULL;
  673.   fluid_return_if_fail (!sfont_already_loaded);
  674.   fluid_rec_mutex_lock (synth->mutex);
  675.   synth->loaders = fluid_list_prepend(synth->loaders, loader);
  676.   fluid_rec_mutex_unlock (synth->mutex);
  677. }
  678. /**
  679.  * Load a SoundFont file (filename is interpreted by SoundFont loaders).
  680.  * The newly loaded SoundFont will be put on top of the SoundFont
  681.  * stack. Presets are searched starting from the SoundFont on the
  682.  * top of the stack, working the way down the stack until a preset is found.
  683.  *
  684.  * @param synth SoundFont instance
  685.  * @param filename File to load
  686.  * @param reset_presets TRUE to re-assign presets for all MIDI channels
  687.  * @return SoundFont ID on success, FLUID_FAILED on error
  688.  */
  689. int
  690. fluid_synth_sfload(fluid_synth_t* synth, const char* filename, int reset_presets)
  691. {
  692.   fluid_sfont_info_t *sfont_info;
  693.   fluid_sfont_t *sfont;
  694.   fluid_list_t *list;
  695.   fluid_sfloader_t *loader;
  696.   unsigned int sfont_id;
  697.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  698.   fluid_return_val_if_fail (filename != NULL, FLUID_FAILED);
  699.   /* MT NOTE: Loaders list should not change. */
  700.   for (list = synth->loaders; list; list = fluid_list_next(list)) {
  701.     loader = (fluid_sfloader_t*) fluid_list_get(list);
  702.     sfont = fluid_sfloader_load(loader, filename);
  703.     if (sfont != NULL) {
  704.       sfont_info = new_fluid_sfont_info (synth, sfont);
  705.       if (!sfont_info)
  706.       {
  707.         delete_fluid_sfont (sfont_info->sfont);         /* FIXME - Shouldn't fail right? - JG */
  708.         return FLUID_FAILED;
  709.       }
  710.       fluid_rec_mutex_lock (synth->mutex);  /* ++ Lock sfont_id and sfont list */
  711.       sfont->id = sfont_id = ++synth->sfont_id;
  712.       synth->sfont_info = fluid_list_prepend(synth->sfont_info, sfont_info);   /* prepend to list */
  713.       fluid_hashtable_insert (synth->sfont_hash, sfont, sfont_info);       /* Hash sfont->sfont_info */
  714.       fluid_rec_mutex_unlock (synth->mutex);        /* -- unlock */
  715.       /* reset the presets for all channels if requested */
  716.       if (reset_presets) fluid_synth_program_reset(synth);
  717.       return (int)sfont_id;
  718.     }
  719.   }
  720.   FLUID_LOG(FLUID_ERR, "Failed to load SoundFont "%s"", filename);
  721.   return FLUID_FAILED;
  722. }
  723. /* Create a new SoundFont info structure, free with FLUID_FREE */
  724. static fluid_sfont_info_t *
  725. new_fluid_sfont_info (fluid_synth_t *synth, fluid_sfont_t *sfont)
  726. {
  727.   fluid_sfont_info_t *sfont_info;
  728.   sfont_info = FLUID_NEW (fluid_sfont_info_t);
  729.   if (!sfont_info)
  730.   {
  731.     FLUID_LOG(FLUID_ERR, "Out of memory");
  732.     return NULL;
  733.   }
  734.   sfont_info->sfont = sfont;
  735.   sfont_info->synth = synth;
  736.   sfont_info->refcount = 1;     /* Start with refcount of 1 for owning synth */
  737.   sfont_info->bankofs = 0;
  738.   return (sfont_info);
  739. }
  740. /**
  741.  * Unload a SoundFont.
  742.  * @param synth SoundFont instance
  743.  * @param id ID of SoundFont to unload
  744.  * @param reset_presets TRUE to re-assign presets for all MIDI channels
  745.  * @return FLUID_OK on success, FLUID_FAILED on error
  746.  */
  747. int
  748. fluid_synth_sfunload(fluid_synth_t* synth, unsigned int id, int reset_presets)
  749. {
  750.   fluid_sfont_info_t *sfont_info = NULL;
  751.   fluid_list_t *list;
  752.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  753.   /* remove the SoundFont from the list */
  754.   fluid_rec_mutex_lock (synth->mutex);  /* ++ Lock sfont list */
  755.   for (list = synth->sfont_info; list; list = fluid_list_next(list)) {
  756.     sfont_info = (fluid_sfont_info_t*) fluid_list_get(list);
  757.     if (fluid_sfont_get_id (sfont_info->sfont) == id)
  758.     {
  759.       synth->sfont_info = fluid_list_remove (synth->sfont_info, sfont_info);
  760.       break;
  761.     }
  762.   }
  763.   fluid_rec_mutex_unlock (synth->mutex);        /* -- unlock */
  764.   if (!list) {
  765.     FLUID_LOG(FLUID_ERR, "No SoundFont with id = %d", id);
  766.     return FLUID_FAILED;
  767.   }
  768.   /* reset the presets for all channels (SoundFont will be freed when there are no more references) */
  769.   if (reset_presets) fluid_synth_program_reset (synth);
  770.   else fluid_synth_update_presets (synth);
  771.   /* -- Remove synth->sfont_info list's reference to SoundFont */
  772.   fluid_synth_sfont_unref (synth, sfont_info->sfont);
  773.   return FLUID_OK;
  774. }
  775. /* Unref a SoundFont and destroy if no more references */
  776. static void
  777. fluid_synth_sfont_unref (fluid_synth_t *synth, fluid_sfont_t *sfont)
  778. {
  779.   fluid_sfont_info_t *sfont_info;
  780.   int refcount = 0;
  781.   
  782.   fluid_rec_mutex_lock (synth->mutex);      /* ++ Lock sfont_hash */
  783.   sfont_info = fluid_hashtable_lookup (synth->sfont_hash, sfont);
  784.   if (sfont_info)
  785.   {
  786.     sfont_info->refcount--;             /* -- Remove the sfont_info list's reference */
  787.     refcount = sfont_info->refcount;
  788.     if (refcount == 0)    /* Remove SoundFont from hash if no more references */
  789.       fluid_hashtable_remove (synth->sfont_hash, sfont_info->sfont);
  790.   }
  791.   fluid_rec_mutex_unlock (synth->mutex);    /* -- Unlock sfont_hash */
  792.   fluid_return_if_fail (sfont_info != NULL);    /* Shouldn't happen, programming error if so */
  793.   if (refcount == 0)                    /* No more references? - Attempt delete */
  794.   {
  795.     if (delete_fluid_sfont (sfont_info->sfont) == 0)    /* SoundFont loader can block SoundFont unload */
  796.     {
  797.       FLUID_FREE (sfont_info);
  798.       FLUID_LOG (FLUID_DBG, "Unloaded SoundFont");
  799.     } /* spin off a timer thread to unload the sfont later (SoundFont loader blocked unload) */
  800.     else new_fluid_timer (100, fluid_synth_sfunload_callback, sfont_info, TRUE, TRUE, FALSE);    
  801.   }
  802. }
  803. /* Callback to continually attempt to unload a SoundFont,
  804.  * only if a SoundFont loader blocked the unload operation */
  805. static int
  806. fluid_synth_sfunload_callback(void* data, unsigned int msec)
  807. {
  808.   fluid_sfont_info_t *sfont_info = (fluid_sfont_info_t *)data;
  809.   if (delete_fluid_sfont (sfont_info->sfont) == 0)
  810.   {
  811.     FLUID_FREE (sfont_info);
  812.     FLUID_LOG (FLUID_DBG, "Unloaded SoundFont");
  813.     return FALSE;
  814.   }
  815.   else return TRUE;
  816. }
  817. /**
  818.  * Reload a SoundFont.  The SoundFont retains its ID and index on the SoundFont stack.
  819.  * @param synth SoundFont instance
  820.  * @param id ID of SoundFont to reload
  821.  * @return SoundFont ID on success, FLUID_FAILED on error
  822.  */
  823. int
  824. fluid_synth_sfreload(fluid_synth_t* synth, unsigned int id)
  825. {
  826.   char filename[1024];
  827.   fluid_sfont_info_t *sfont_info, *old_sfont_info;
  828.   fluid_sfont_t* sfont;
  829.   fluid_sfloader_t* loader;
  830.   fluid_list_t *list;
  831.   int index;
  832.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  833.   fluid_rec_mutex_lock (synth->mutex);      /* ++ lock sfont list */
  834.   /* Search for SoundFont and get its index */
  835.   for (list = synth->sfont_info, index = 0; list; list = fluid_list_next (list), index++) {
  836.     old_sfont_info = (fluid_sfont_info_t *)fluid_list_get (list);
  837.     if (fluid_sfont_get_id (old_sfont_info->sfont) == id) break;
  838.   }
  839.   if (!list) {
  840.     fluid_rec_mutex_unlock (synth->mutex);      /* -- unlock */
  841.     FLUID_LOG(FLUID_ERR, "No SoundFont with id = %d", id);
  842.     return FLUID_FAILED;
  843.   }
  844.   /* keep a copy of the SoundFont's filename */
  845.   FLUID_STRCPY (filename, fluid_sfont_get_name (old_sfont_info->sfont));
  846.   fluid_rec_mutex_unlock (synth->mutex);    /* -- unlock */
  847.   if (fluid_synth_sfunload (synth, id, FALSE) != FLUID_OK)
  848.     return FLUID_FAILED;
  849.   /* MT Note: SoundFont loader list will not change */
  850.   for (list = synth->loaders; list; list = fluid_list_next(list)) {
  851.     loader = (fluid_sfloader_t*) fluid_list_get(list);
  852.     sfont = fluid_sfloader_load(loader, filename);
  853.     if (sfont != NULL) {
  854.       sfont->id = id;
  855.       sfont_info = new_fluid_sfont_info (synth, sfont);
  856.       if (!sfont_info)
  857.       {
  858.         delete_fluid_sfont (sfont_info->sfont);         /* FIXME - Shouldn't fail right? - JG */
  859.         return FLUID_FAILED;
  860.       }
  861.       fluid_rec_mutex_lock (synth->mutex);  /* ++ Lock sfont list */
  862.       synth->sfont_info = fluid_list_insert_at(synth->sfont_info, index, sfont_info);  /* insert the sfont at the same index */
  863.       fluid_hashtable_insert (synth->sfont_hash, sfont, sfont_info);       /* Hash sfont->sfont_info */
  864.       fluid_rec_mutex_unlock (synth->mutex);        /* -- unlock */
  865.       /* reset the presets for all channels */
  866.       fluid_synth_update_presets(synth);
  867.       return sfont->id;
  868.     }
  869.   }
  870.   FLUID_LOG(FLUID_ERR, "Failed to load SoundFont "%s"", filename);
  871.   return FLUID_FAILED;
  872. }
  873. /**
  874.  * Add a SoundFont.  The SoundFont will be added to the top of the SoundFont stack.
  875.  * @param synth FluidSynth instance
  876.  * @param sfont SoundFont to add
  877.  * @return New assigned SoundFont ID or FLUID_FAILED on error
  878.  */
  879. int
  880. fluid_synth_add_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont)
  881. {
  882.   fluid_sfont_info_t *sfont_info;
  883.   unsigned int sfont_id;
  884.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  885.   fluid_return_val_if_fail (sfont != NULL, FLUID_FAILED);
  886.   sfont_info = new_fluid_sfont_info (synth, sfont);
  887.   if (!sfont_info) return (FLUID_FAILED);
  888.   fluid_rec_mutex_lock (synth->mutex);      /* ++ lock sfont_id and sfont_info list */
  889.   sfont->id = sfont_id = ++synth->sfont_id;
  890.   synth->sfont_info = fluid_list_prepend (synth->sfont_info, sfont_info);       /* prepend to list */
  891.   fluid_hashtable_insert (synth->sfont_hash, sfont, sfont_info);   /* Hash sfont->sfont_info */
  892.   fluid_rec_mutex_unlock (synth->mutex);    /* -- unlock */
  893.   /* reset the presets for all channels */
  894.   fluid_synth_program_reset (synth);
  895.   return sfont_id;
  896. }
  897. /**
  898.  * Remove a SoundFont from the SoundFont stack without deleting it.
  899.  * @param synth FluidSynth instance
  900.  * @param sfont SoundFont to remove
  901.  *
  902.  * SoundFont is not freed and is left as the responsibility of the caller.
  903.  *
  904.  * NOTE: The SoundFont should only be freed after there are no presets
  905.  *   referencing it.  This can only be ensured by the SoundFont loader and
  906.  *   therefore this function should not normally be used.
  907.  */
  908. void
  909. fluid_synth_remove_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont)
  910. {
  911.   fluid_sfont_info_t *sfont_info;
  912.   fluid_list_t *list;
  913.   fluid_return_if_fail (synth != NULL);
  914.   fluid_return_if_fail (sfont != NULL);
  915.   /* remove the SoundFont from the list */
  916.   fluid_rec_mutex_lock (synth->mutex);  /* ++ Lock sfont_info list */
  917.   for (list = synth->sfont_info; list; list = fluid_list_next(list)) {
  918.     sfont_info = (fluid_sfont_info_t*) fluid_list_get(list);
  919.     if (sfont_info->sfont == sfont)
  920.     {
  921.       synth->sfont_info = fluid_list_remove (synth->sfont_info, sfont_info);
  922.       /* Remove from SoundFont hash regardless of refcount (SoundFont delete is up to caller) */
  923.       fluid_hashtable_remove (synth->sfont_hash, sfont_info->sfont);
  924.       break;
  925.     }
  926.   }
  927.   fluid_rec_mutex_unlock (synth->mutex);        /* -- unlock */
  928.   /* reset the presets for all channels */
  929.   fluid_synth_program_reset (synth);
  930. }
  931. /**
  932.  * Count number of loaded SoundFont files.
  933.  * @param synth FluidSynth instance
  934.  * @return Count of loaded SoundFont files.
  935.  */
  936. int
  937. fluid_synth_sfcount(fluid_synth_t* synth)
  938. {
  939.   int count;
  940.   
  941.   fluid_return_val_if_fail (synth != NULL, 0);
  942.   fluid_rec_mutex_lock (synth->mutex);      /* ++ lock sfont_info list */
  943.   count = fluid_list_size (synth->sfont_info);
  944.   fluid_rec_mutex_unlock (synth->mutex);      /* -- unlock */
  945.   return count;
  946. }
  947. /**
  948.  * Get SoundFont by index.
  949.  * @param synth FluidSynth instance
  950.  * @param num SoundFont index on the stack (starting from 0 for top of stack).
  951.  * @return SoundFont instance or NULL if invalid index
  952.  *
  953.  * NOTE: Caller should be certain that SoundFont is not deleted (unloaded) for
  954.  * the duration of use of the returned pointer.
  955.  */
  956. fluid_sfont_t *
  957. fluid_synth_get_sfont(fluid_synth_t* synth, unsigned int num)
  958. {
  959.   fluid_sfont_t *sfont = NULL;
  960.   fluid_list_t *list;
  961.   fluid_return_val_if_fail (synth != NULL, NULL);
  962.   fluid_rec_mutex_lock (synth->mutex);      /* ++ lock sfont list */
  963.   list = fluid_list_nth (synth->sfont_info, num);
  964.   if (list) sfont = ((fluid_sfont_info_t *)fluid_list_get (list))->sfont;
  965.   fluid_rec_mutex_unlock (synth->mutex);      /* -- unlock */
  966.   return sfont;
  967. }
  968. /**
  969.  * Get SoundFont by ID.
  970.  * @param synth FluidSynth instance
  971.  * @param id SoundFont ID
  972.  * @return SoundFont instance or NULL if invalid ID
  973.  *
  974.  * NOTE: Caller should be certain that SoundFont is not deleted (unloaded) for
  975.  * the duration of use of the returned pointer.
  976.  */
  977. fluid_sfont_t *
  978. fluid_synth_get_sfont_by_id(fluid_synth_t* synth, unsigned int id)
  979. {
  980.   fluid_sfont_t* sfont = NULL;
  981.   fluid_list_t* list;
  982.   fluid_return_val_if_fail (synth != NULL, NULL);
  983.   fluid_rec_mutex_lock (synth->mutex);      /* ++ lock sfont_info list */
  984.   for (list = synth->sfont_info; list; list = fluid_list_next(list)) {
  985.     sfont = ((fluid_sfont_info_t *)fluid_list_get (list))->sfont;
  986.     if (fluid_sfont_get_id (sfont) == id)
  987.       break;
  988.   }
  989.   fluid_rec_mutex_unlock (synth->mutex);      /* -- unlock */
  990.   return list ? sfont : NULL;
  991. }
  992. /**
  993.  * Get SoundFont by name.
  994.  * @param synth FluidSynth instance
  995.  * @param name Name of SoundFont
  996.  * @return SoundFont instance or NULL if invalid name
  997.  * @since 1.1.0
  998.  *
  999.  * NOTE: Caller should be certain that SoundFont is not deleted (unloaded) for
  1000.  * the duration of use of the returned pointer.
  1001.  */
  1002. fluid_sfont_t *
  1003. fluid_synth_get_sfont_by_name(fluid_synth_t* synth, const char *name)
  1004. {
  1005.   fluid_sfont_t* sfont = NULL;
  1006.   fluid_list_t* list;
  1007.   fluid_return_val_if_fail (synth != NULL, NULL);
  1008.   fluid_return_val_if_fail (name != NULL, NULL);
  1009.   fluid_rec_mutex_lock (synth->mutex);      /* ++ lock */
  1010.   for (list = synth->sfont_info; list; list = fluid_list_next(list)) {
  1011.     sfont = ((fluid_sfont_info_t *)fluid_list_get (list))->sfont;
  1012.     if (FLUID_STRCMP(fluid_sfont_get_name(sfont), name) == 0)
  1013.       break;
  1014.   }
  1015.   fluid_rec_mutex_unlock (synth->mutex);      /* -- unlock */
  1016.   return list ? sfont : NULL;
  1017. }
  1018. /**
  1019.  * Get active preset on a MIDI channel.
  1020.  * @param synth FluidSynth instance
  1021.  * @param chan MIDI channel number (0 to MIDI channel count - 1)
  1022.  * @return Preset or NULL if no preset active on channel
  1023.  * @deprecated fluid_synth_get_channel_info() should replace most use cases.
  1024.  *
  1025.  * NOTE: Should only be called from within synthesis thread, which includes
  1026.  * SoundFont loader preset noteon methods.  Not thread safe otherwise.
  1027.  */
  1028. fluid_preset_t *
  1029. fluid_synth_get_channel_preset(fluid_synth_t* synth, int chan)
  1030. {
  1031.   fluid_channel_t *channel;
  1032.   fluid_return_val_if_fail (synth != NULL, NULL);
  1033.   fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, NULL);
  1034.   channel = synth->channel[chan];
  1035.   return fluid_atomic_pointer_get (&channel->shadow_preset);
  1036. }
  1037. /**
  1038.  * Get information on the currently selected preset on a MIDI channel.
  1039.  * @param synth FluidSynth instance
  1040.  * @param chan MIDI channel number (0 to MIDI channel count - 1)
  1041.  * @param info Caller supplied structure to fill with preset information
  1042.  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
  1043.  * @since 1.1.1
  1044.  */
  1045. int
  1046. fluid_synth_get_channel_info (fluid_synth_t *synth, int chan,
  1047.                               fluid_synth_channel_info_t *info)
  1048. {
  1049.   fluid_channel_t *channel;
  1050.   fluid_preset_t *preset;
  1051.   char *name;
  1052.   if (info)
  1053.   {
  1054.     info->assigned = FALSE;
  1055.     info->name[0] = '';
  1056.   }
  1057.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  1058.   fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
  1059.   fluid_return_val_if_fail (info != NULL, FLUID_FAILED);
  1060.   /* Lock mutex to ensure preset doesn't get deleted, while working on it */
  1061.   fluid_rec_mutex_lock (synth->mutex);
  1062.   channel = synth->channel[chan];
  1063.   preset = fluid_atomic_pointer_get (&channel->shadow_preset);
  1064.   if (preset)
  1065.   {
  1066.     info->assigned = TRUE;
  1067.     name = fluid_preset_get_name (preset);
  1068.     if (name)
  1069.     {
  1070.       strncpy (info->name, name, FLUID_SYNTH_CHANNEL_INFO_NAME_SIZE);
  1071.       info->name[FLUID_SYNTH_CHANNEL_INFO_NAME_SIZE - 1] = '';
  1072.     }
  1073.     else info->name[0] = '';
  1074.     info->sfont_id = preset->sfont->id;
  1075.     info->bank = fluid_preset_get_banknum (preset);
  1076.     info->program = fluid_preset_get_num (preset);
  1077.   }
  1078.   else
  1079.   {
  1080.     info->assigned = FALSE;
  1081.     fluid_channel_get_sfont_bank_prog (channel, &info->sfont_id, &info->bank, &info->program);
  1082.     info->name[0] = '';
  1083.   }
  1084.   fluid_rec_mutex_unlock (synth->mutex);
  1085.   return FLUID_OK;
  1086. }
  1087. /**
  1088.  * Get list of voices.
  1089.  * @param synth FluidSynth instance
  1090.  * @param buf Array to store voices to (NULL terminated if not filled completely)
  1091.  * @param bufsize Count of indexes in buf
  1092.  * @param id Voice ID to search for or < 0 to return list of all playing voices
  1093.  *
  1094.  * NOTE: Should only be called from within synthesis thread, which includes
  1095.  * SoundFont loader preset noteon methods.  Voices are only guaranteed to remain
  1096.  * unchanged until next synthesis process iteration.
  1097.  */
  1098. void
  1099. fluid_synth_get_voicelist(fluid_synth_t* synth, fluid_voice_t* buf[], int bufsize,
  1100.                           int id)
  1101. {
  1102.   int count = 0;
  1103.   int i;
  1104.   fluid_return_if_fail (synth != NULL);
  1105.   fluid_return_if_fail (buf != NULL);
  1106.   for (i = 0; i < synth->polyphony && count < bufsize; i++) {
  1107.     fluid_voice_t* voice = synth->voice[i];
  1108.     if (_PLAYING(voice) && (id < 0 || (int)voice->id == id))
  1109.       buf[count++] = voice;
  1110.   }
  1111.   if (count < bufsize) buf[count] = NULL;
  1112. }
  1113. /**
  1114.  * Enable or disable reverb effect.
  1115.  * @param synth FluidSynth instance
  1116.  * @param on TRUE to enable reverb, FALSE to disable
  1117.  */
  1118. void
  1119. fluid_synth_set_reverb_on(fluid_synth_t* synth, int on)
  1120. {
  1121.   fluid_return_if_fail (synth != NULL);
  1122.   fluid_atomic_int_set (&synth->with_reverb, on != 0);
  1123. }
  1124. /**
  1125.  * Activate a reverb preset.
  1126.  * @param synth FluidSynth instance
  1127.  * @param num Reverb preset number
  1128.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1129.  *
  1130.  * NOTE: Currently private to libfluidsynth.
  1131.  */
  1132. int
  1133. fluid_synth_set_reverb_preset(fluid_synth_t* synth, int num)
  1134. {
  1135.   int i = 0;
  1136.   while (revmodel_preset[i].name != NULL) {
  1137.     if (i == num) {
  1138.       fluid_synth_set_reverb (synth, revmodel_preset[i].roomsize,
  1139.                               revmodel_preset[i].damp, revmodel_preset[i].width,
  1140.                               revmodel_preset[i].level);
  1141.       return FLUID_OK;
  1142.     }
  1143.     i++;
  1144.   }
  1145.   return FLUID_FAILED;
  1146. }
  1147. /**
  1148.  * Set reverb parameters.
  1149.  * @param synth FluidSynth instance
  1150.  * @param roomsize Reverb room size value (0.0-1.2)
  1151.  * @param damping Reverb damping value (0.0-1.0)
  1152.  * @param width Reverb width value (0.0-100.0)
  1153.  * @param level Reverb level value (0.0-1.0)
  1154.  *
  1155.  * NOTE: Not realtime safe and therefore should not be called from synthesis
  1156.  * context at the risk of stalling audio output.
  1157.  */
  1158. void
  1159. fluid_synth_set_reverb(fluid_synth_t* synth, double roomsize, double damping,
  1160.                        double width, double level)
  1161. {
  1162.   fluid_synth_set_reverb_full (synth, FLUID_REVMODEL_SET_ALL,
  1163.                                roomsize, damping, width, level);
  1164. }
  1165. /**
  1166.  * Set one or more reverb parameters.
  1167.  * @param synth FluidSynth instance
  1168.  * @param set Flags indicating which parameters should be set (#fluid_revmodel_set_t)
  1169.  * @param roomsize Reverb room size value (0.0-1.2)
  1170.  * @param damping Reverb damping value (0.0-1.0)
  1171.  * @param width Reverb width value (0.0-100.0)
  1172.  * @param level Reverb level value (0.0-1.0)
  1173.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1174.  *
  1175.  * NOTE: Not realtime safe and therefore should not be called from synthesis
  1176.  * context at the risk of stalling audio output.
  1177.  */
  1178. int
  1179. fluid_synth_set_reverb_full(fluid_synth_t* synth, int set, double roomsize,
  1180.                             double damping, double width, double level)
  1181. {
  1182.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  1183.   if (!(set & FLUID_REVMODEL_SET_ALL))
  1184.     set = FLUID_REVMODEL_SET_ALL; 
  1185.   /* Synth shadow values are set here so that they will be returned if querried */
  1186.   fluid_rec_mutex_lock (synth->mutex);      /* ++ Lock reverb */
  1187.   if (set & FLUID_REVMODEL_SET_ROOMSIZE)
  1188.     fluid_atomic_float_set (&synth->reverb_roomsize, roomsize);
  1189.   if (set & FLUID_REVMODEL_SET_DAMPING)
  1190.     fluid_atomic_float_set (&synth->reverb_damping, damping);
  1191.   if (set & FLUID_REVMODEL_SET_WIDTH)
  1192.     fluid_atomic_float_set (&synth->reverb_width, width);
  1193.   if (set & FLUID_REVMODEL_SET_LEVEL)
  1194.     fluid_atomic_float_set (&synth->reverb_level, level);
  1195.   fluid_revmodel_set (synth->reverb, set, roomsize, damping, width, level);
  1196.   fluid_rec_mutex_unlock (synth->mutex);    /* -- Unlock reverb */
  1197.   return FLUID_OK;
  1198. }
  1199. /**
  1200.  * Get reverb room size.
  1201.  * @param synth FluidSynth instance
  1202.  * @return Reverb room size (0.0-1.2)
  1203.  */
  1204. double
  1205. fluid_synth_get_reverb_roomsize(fluid_synth_t* synth)
  1206. {
  1207.   fluid_return_val_if_fail (synth != NULL, 0.0);
  1208.   return fluid_atomic_float_get (&synth->reverb_roomsize);
  1209. }
  1210. /**
  1211.  * Get reverb damping.
  1212.  * @param synth FluidSynth instance
  1213.  * @return Reverb damping value (0.0-1.0)
  1214.  */
  1215. double
  1216. fluid_synth_get_reverb_damp(fluid_synth_t* synth)
  1217. {
  1218.   fluid_return_val_if_fail (synth != NULL, 0.0);
  1219.   return fluid_atomic_float_get (&synth->reverb_damping);
  1220. }
  1221. /**
  1222.  * Get reverb level.
  1223.  * @param synth FluidSynth instance
  1224.  * @return Reverb level value (0.0-1.0)
  1225.  */
  1226. double
  1227. fluid_synth_get_reverb_level(fluid_synth_t* synth)
  1228. {
  1229.   fluid_return_val_if_fail (synth != NULL, 0.0);
  1230.   return fluid_atomic_float_get (&synth->reverb_level);
  1231. }
  1232. /**
  1233.  * Get reverb width.
  1234.  * @param synth FluidSynth instance
  1235.  * @return Reverb width value (0.0-100.0)
  1236.  */
  1237. double
  1238. fluid_synth_get_reverb_width(fluid_synth_t* synth)
  1239. {
  1240.   fluid_return_val_if_fail (synth != NULL, 0.0);
  1241.   return fluid_atomic_float_get (&synth->reverb_width);
  1242. }
  1243. /**
  1244.  * Enable or disable chorus effect.
  1245.  * @param synth FluidSynth instance
  1246.  * @param on TRUE to enable chorus, FALSE to disable
  1247.  */
  1248. void 
  1249. fluid_synth_set_chorus_on(fluid_synth_t* synth, int on)
  1250. {
  1251.   fluid_return_if_fail (synth != NULL);
  1252.   fluid_atomic_int_set (&synth->with_chorus, on != 0);
  1253. }
  1254. /**
  1255.  * Set chorus parameters.
  1256.  * @param synth FluidSynth instance
  1257.  * @param nr Chorus voice count (0-99, CPU time consumption proportional to
  1258.  *   this value)
  1259.  * @param level Chorus level (0.0-1.0)
  1260.  * @param speed Chorus speed in Hz (0.29-5.0)
  1261.  * @param depth_ms Chorus depth (max value depends on synth sample rate,
  1262.  *   0.0-21.0 is safe for sample rate values up to 96KHz)
  1263.  * @param type Chorus waveform type (#fluid_chorus_mod)
  1264.  *
  1265.  * NOTE: Not realtime safe and therefore should not be called from synthesis
  1266.  * context at the risk of stalling audio output.
  1267.  */
  1268. void
  1269. fluid_synth_set_chorus(fluid_synth_t* synth, int nr, double level,
  1270.                        double speed, double depth_ms, int type)
  1271. {
  1272.   fluid_synth_set_chorus_full (synth, FLUID_CHORUS_SET_ALL, nr, level, speed,
  1273.                                depth_ms, type);
  1274. }
  1275. /**
  1276.  * Set one or more chorus parameters.
  1277.  * @param synth FluidSynth instance
  1278.  * @param set Flags indicating which chorus parameters to set (#fluid_chorus_set_t)
  1279.  * @param nr Chorus voice count (0-99, CPU time consumption proportional to
  1280.  *   this value)
  1281.  * @param level Chorus level (0.0-1.0)
  1282.  * @param speed Chorus speed in Hz (0.29-5.0)
  1283.  * @param depth_ms Chorus depth (max value depends on synth sample rate,
  1284.  *   0.0-21.0 is safe for sample rate values up to 96KHz)
  1285.  * @param type Chorus waveform type (#fluid_chorus_mod)
  1286.  *
  1287.  * NOTE: Not realtime safe and therefore should not be called from synthesis
  1288.  * context at the risk of stalling audio output.
  1289.  */
  1290. int
  1291. fluid_synth_set_chorus_full(fluid_synth_t* synth, int set, int nr, double level,
  1292.                             double speed, double depth_ms, int type)
  1293. {
  1294.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  1295.   if (!(set & FLUID_CHORUS_SET_ALL))
  1296.     set = FLUID_CHORUS_SET_ALL;
  1297.   /* Synth shadow values are set here so that they will be returned if querried */
  1298.   fluid_rec_mutex_lock (synth->mutex);      /* ++ Lock chorus */
  1299.   if (set & FLUID_CHORUS_SET_NR)
  1300.     fluid_atomic_int_set (&synth->chorus_nr, nr);
  1301.   if (set & FLUID_CHORUS_SET_LEVEL)
  1302.     fluid_atomic_float_set (&synth->chorus_level, level);
  1303.   if (set & FLUID_CHORUS_SET_SPEED)
  1304.     fluid_atomic_float_set (&synth->chorus_speed, speed);
  1305.   if (set & FLUID_CHORUS_SET_DEPTH)
  1306.     fluid_atomic_float_set (&synth->chorus_depth, depth_ms);
  1307.   if (set & FLUID_CHORUS_SET_TYPE)
  1308.     fluid_atomic_int_set (&synth->chorus_type, type);
  1309.   fluid_chorus_set (synth->chorus, set, nr, level, speed, depth_ms, type);
  1310.   fluid_rec_mutex_unlock (synth->mutex);    /* -- Unlock chorus */
  1311.   return FLUID_OK;
  1312. }
  1313. /**
  1314.  * Get chorus voice number (delay line count) value.
  1315.  * @param synth FluidSynth instance
  1316.  * @return Chorus voice count (0-99)
  1317.  */
  1318. int
  1319. fluid_synth_get_chorus_nr(fluid_synth_t* synth)
  1320. {
  1321.   fluid_return_val_if_fail (synth != NULL, 0.0);
  1322.   return fluid_atomic_int_get (&synth->chorus_nr);
  1323. }
  1324. /**
  1325.  * Get chorus level.
  1326.  * @param synth FluidSynth instance
  1327.  * @return Chorus level value (0.0-10.0)
  1328.  */
  1329. double
  1330. fluid_synth_get_chorus_level(fluid_synth_t* synth)
  1331. {
  1332.   fluid_return_val_if_fail (synth != NULL, 0.0);
  1333.   return fluid_atomic_float_get (&synth->chorus_level);
  1334. }
  1335. /**
  1336.  * Get chorus speed in Hz.
  1337.  * @param synth FluidSynth instance
  1338.  * @return Chorus speed in Hz (0.29-5.0)
  1339.  */
  1340. double
  1341. fluid_synth_get_chorus_speed_Hz(fluid_synth_t* synth)
  1342. {
  1343.   fluid_return_val_if_fail (synth != NULL, 0.0);
  1344.   return fluid_atomic_float_get (&synth->chorus_speed);
  1345. }
  1346. /**
  1347.  * Get chorus depth.
  1348.  * @param synth FluidSynth instance
  1349.  * @return Chorus depth
  1350.  */
  1351. double
  1352. fluid_synth_get_chorus_depth_ms(fluid_synth_t* synth)
  1353. {
  1354.   fluid_return_val_if_fail (synth != NULL, 0.0);
  1355.   return fluid_atomic_float_get (&synth->chorus_depth);
  1356. }
  1357. /**
  1358.  * Get chorus waveform type.
  1359.  * @param synth FluidSynth instance
  1360.  * @return Chorus waveform type (#fluid_chorus_mod)
  1361.  */
  1362. int
  1363. fluid_synth_get_chorus_type(fluid_synth_t* synth)
  1364. {
  1365.   fluid_return_val_if_fail (synth != NULL, 0.0);
  1366.   return fluid_atomic_int_get (&synth->chorus_type);
  1367. }
  1368. /*
  1369.  * If the same note is hit twice on the same channel, then the older
  1370.  * voice process is advanced to the release stage.  Using a mechanical
  1371.  * MIDI controller, the only way this can happen is when the sustain
  1372.  * pedal is held.  In this case the behaviour implemented here is
  1373.  * natural for many instruments.  Note: One noteon event can trigger
  1374.  * several voice processes, for example a stereo sample.  Don't
  1375.  * release those...
  1376.  */
  1377. static void
  1378. fluid_synth_release_voice_on_same_note_LOCAL(fluid_synth_t* synth, int chan,
  1379.                                              int key)
  1380. {
  1381.   int i;
  1382.   fluid_voice_t* voice;
  1383.   for (i = 0; i < synth->polyphony; i++) {
  1384.     voice = synth->voice[i];
  1385.     if (_PLAYING(voice)
  1386. && (voice->chan == chan)
  1387. && (voice->key == key)
  1388. && (fluid_voice_get_id(voice) != synth->noteid)) {
  1389.       fluid_voice_noteoff(voice);
  1390.     }
  1391.   }
  1392. }
  1393. /**
  1394.  * Set synthesis interpolation method on one or all MIDI channels.
  1395.  * @param synth FluidSynth instance
  1396.  * @param chan MIDI channel to set interpolation method on or -1 for all channels
  1397.  * @param interp_method Interpolation method (#fluid_interp)
  1398.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1399.  */
  1400. int
  1401. fluid_synth_set_interp_method(fluid_synth_t* synth, int chan, int interp_method)
  1402. {
  1403.   int i;
  1404.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  1405.   if (synth->channel[0] == NULL) {
  1406.     FLUID_LOG (FLUID_ERR, "Channels don't exist (yet)!");
  1407.     return FLUID_FAILED;
  1408.   }
  1409.   for (i = 0; i < synth->midi_channels; i++) {
  1410.     if (chan < 0 || fluid_channel_get_num(synth->channel[i]) == chan)
  1411.       fluid_channel_set_interp_method(synth->channel[i], interp_method);
  1412.   }
  1413.   return FLUID_OK;
  1414. };
  1415. /**
  1416.  * Get the total count of MIDI channels.
  1417.  * @param synth FluidSynth instance
  1418.  * @return Count of MIDI channels
  1419.  */
  1420. int
  1421. fluid_synth_count_midi_channels(fluid_synth_t* synth)
  1422. {
  1423.   fluid_return_val_if_fail (synth != NULL, 0);
  1424.   return synth->midi_channels;
  1425. }
  1426. /**
  1427.  * Get the total count of audio channels.
  1428.  * @param synth FluidSynth instance
  1429.  * @return Count of audio channel stereo pairs (1 = 2 channels, 2 = 4, etc)
  1430.  */
  1431. int
  1432. fluid_synth_count_audio_channels(fluid_synth_t* synth)
  1433. {
  1434.   fluid_return_val_if_fail (synth != NULL, 0);
  1435.   return synth->audio_channels;
  1436. }
  1437. /**
  1438.  * Get the total number of allocated audio channels.  Usually identical to the
  1439.  * number of audio channels.  Can be employed by LADSPA effects subsystem.
  1440.  *
  1441.  * @param synth FluidSynth instance
  1442.  * @return Count of audio group stereo pairs (1 = 2 channels, 2 = 4, etc)
  1443.  */
  1444. int
  1445. fluid_synth_count_audio_groups(fluid_synth_t* synth)
  1446. {
  1447.   fluid_return_val_if_fail (synth != NULL, 0);
  1448.   return synth->audio_groups;
  1449. }
  1450. /**
  1451.  * Get the total number of allocated effects channels.
  1452.  * @param synth FluidSynth instance
  1453.  * @return Count of allocated effects channels
  1454.  */
  1455. int
  1456. fluid_synth_count_effects_channels(fluid_synth_t* synth)
  1457. {
  1458.   fluid_return_val_if_fail (synth != NULL, 0);
  1459.   return synth->effects_channels;
  1460. }
  1461. /**
  1462.  * Get the synth CPU load value.
  1463.  * @param synth FluidSynth instance
  1464.  * @return Estimated CPU load value in percent (0-100)
  1465.  */
  1466. double
  1467. fluid_synth_get_cpu_load(fluid_synth_t* synth)
  1468. {
  1469.   fluid_return_val_if_fail (synth != NULL, 0);
  1470.   return fluid_atomic_float_get (&synth->cpu_load);
  1471. }
  1472. /* Get tuning for a given bank:program */
  1473. static fluid_tuning_t *
  1474. fluid_synth_get_tuning(fluid_synth_t* synth, int bank, int prog)
  1475. {
  1476.   if ((synth->tuning == NULL) ||
  1477.       (synth->tuning[bank] == NULL) ||
  1478.       (synth->tuning[bank][prog] == NULL))
  1479.     return NULL;
  1480.   return synth->tuning[bank][prog];
  1481. }
  1482. /* Replace tuning on a given bank:program (need not already exist).
  1483.  * Synth mutex should already be locked by caller. */
  1484. static int
  1485. fluid_synth_replace_tuning_LOCK (fluid_synth_t* synth, fluid_tuning_t *tuning,
  1486.                                  int bank, int prog, int apply)
  1487. {
  1488.   fluid_tuning_t *old_tuning;
  1489.   fluid_event_queue_t *queue;
  1490.   fluid_event_queue_elem_t *event;
  1491.   if (synth->tuning == NULL) {
  1492.     synth->tuning = FLUID_ARRAY(fluid_tuning_t**, 128);
  1493.     if (synth->tuning == NULL) {
  1494.       FLUID_LOG(FLUID_PANIC, "Out of memory");
  1495.       return FLUID_FAILED;
  1496.     }
  1497.     FLUID_MEMSET(synth->tuning, 0, 128 * sizeof(fluid_tuning_t**));
  1498.   }
  1499.   if (synth->tuning[bank] == NULL) {
  1500.     synth->tuning[bank] = FLUID_ARRAY(fluid_tuning_t*, 128);
  1501.     if (synth->tuning[bank] == NULL) {
  1502.       FLUID_LOG(FLUID_PANIC, "Out of memory");
  1503.       return FLUID_FAILED;
  1504.     }
  1505.     FLUID_MEMSET(synth->tuning[bank], 0, 128 * sizeof(fluid_tuning_t*));
  1506.   }
  1507.   old_tuning = synth->tuning[bank][prog];
  1508.   synth->tuning[bank][prog] = tuning;
  1509.   if (old_tuning) {
  1510.     if (!fluid_tuning_unref (old_tuning, 1))     /* -- unref old tuning */
  1511.     { /* Replace old tuning if present */
  1512.       if (fluid_synth_should_queue (synth))
  1513.       {
  1514.         event = fluid_synth_get_event_elem (synth, &queue);
  1515.         if (event)
  1516.         {
  1517.           fluid_tuning_ref (tuning);    /* ++ ref new tuning for event */
  1518.           event->type = FLUID_EVENT_QUEUE_ELEM_REPL_TUNING;
  1519.           event->repl_tuning.apply = apply;
  1520.           event->repl_tuning.old_tuning = old_tuning;
  1521.           event->repl_tuning.new_tuning = tuning;
  1522.           fluid_event_queue_next_inptr (queue);
  1523.         }
  1524.       }
  1525.       else fluid_synth_replace_tuning_LOCAL (synth, old_tuning, tuning, apply, FALSE);
  1526.     }
  1527.   }
  1528.   return FLUID_OK;
  1529. }
  1530. /* Replace a tuning with a new one in all MIDI channels.  new_tuning can be
  1531.  * NULL, in which case channels are reset to default equal tempered scale. */
  1532. static void
  1533. fluid_synth_replace_tuning_LOCAL (fluid_synth_t *synth, fluid_tuning_t *old_tuning,
  1534.                                   fluid_tuning_t *new_tuning, int apply, int unref_new)
  1535. {
  1536.   fluid_event_queue_elem_t *event;
  1537.   fluid_channel_t *channel;
  1538.   int old_tuning_unref = 0;
  1539.   int i;
  1540.   for (i = 0; i < synth->midi_channels; i++)
  1541.   {
  1542.     channel = synth->channel[i];
  1543.     if (fluid_channel_get_tuning (channel) == old_tuning)
  1544.     {
  1545.       old_tuning_unref++;
  1546.       if (new_tuning) fluid_tuning_ref (new_tuning);    /* ++ ref new tuning for channel */
  1547.       fluid_channel_set_tuning (channel, new_tuning);
  1548.       if (apply) fluid_synth_update_voice_tuning_LOCAL (synth, channel);
  1549.     }
  1550.   }
  1551.   /* Send unref old tuning event if any unrefs */
  1552.   if (old_tuning_unref > 0)
  1553.   {
  1554.     event = fluid_event_queue_get_inptr (synth->return_queue);
  1555.     if (event)
  1556.     {
  1557.       event->type = FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING;
  1558.       event->unref_tuning.tuning = old_tuning;
  1559.       event->unref_tuning.count = old_tuning_unref;
  1560.       fluid_event_queue_next_inptr (synth->return_queue);
  1561.     }
  1562.     else
  1563.     { /* Just unref it in synthesis thread if queue is full */
  1564.       fluid_tuning_unref (old_tuning, old_tuning_unref);
  1565.       FLUID_LOG (FLUID_ERR, "Synth return event queue full");
  1566.     }
  1567.   }
  1568.   if (!unref_new || !new_tuning) return;
  1569.   /* Send new tuning unref if requested (for replace queue event for example) */
  1570.   event = fluid_event_queue_get_inptr (synth->return_queue);
  1571.   if (event)
  1572.   {
  1573.     event->type = FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING;
  1574.     event->unref_tuning.tuning = new_tuning;
  1575.     event->unref_tuning.count = 1;
  1576.     fluid_event_queue_next_inptr (synth->return_queue);
  1577.   }
  1578.   else
  1579.   { /* Just unref it in synthesis thread if queue is full */
  1580.     fluid_tuning_unref (new_tuning, 1);
  1581.     FLUID_LOG (FLUID_ERR, "Synth return event queue full");
  1582.   }
  1583. }
  1584. /* Update voice tunings in realtime */
  1585. static void
  1586. fluid_synth_update_voice_tuning_LOCAL (fluid_synth_t *synth, fluid_channel_t *channel)
  1587. {
  1588.   fluid_voice_t *voice;
  1589.   int i;
  1590.   for (i = 0; i < synth->polyphony; i++)
  1591.   {
  1592.     voice = synth->voice[i];
  1593.     if (_ON (voice) && (voice->channel == channel))
  1594.     {
  1595.       fluid_voice_calculate_gen_pitch (voice);
  1596.       fluid_voice_update_param (voice, GEN_PITCH);
  1597.     }
  1598.   }
  1599. }
  1600. /**
  1601.  * Set the tuning of the entire MIDI note scale.
  1602.  * @param synth FluidSynth instance
  1603.  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
  1604.  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
  1605.  * @param name Label name for this tuning
  1606.  * @param pitch Array of pitch values (length of 128, each value is number of
  1607.  *   cents, for example normally note 0 is 0.0, 1 is 100.0, 60 is 6000.0, etc).
  1608.  *   Pass NULL to create a well-tempered (normal) scale.
  1609.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1610.  *
  1611.  * NOTE: Tuning is not applied in realtime to existing notes of the replaced
  1612.  * tuning (if any), use fluid_synth_activate_key_tuning() instead to specify
  1613.  * this behavior.
  1614.  */
  1615. int
  1616. fluid_synth_create_key_tuning(fluid_synth_t* synth, int bank, int prog,
  1617.                               const char* name, const double* pitch)
  1618. {
  1619.   return fluid_synth_activate_key_tuning (synth, bank, prog, name, pitch, FALSE);
  1620. }
  1621. /**
  1622.  * Set the tuning of the entire MIDI note scale.
  1623.  * @param synth FluidSynth instance
  1624.  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
  1625.  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
  1626.  * @param name Label name for this tuning
  1627.  * @param pitch Array of pitch values (length of 128, each value is number of
  1628.  *   cents, for example normally note 0 is 0.0, 1 is 100.0, 60 is 6000.0, etc).
  1629.  *   Pass NULL to create a well-tempered (normal) scale.
  1630.  * @param apply TRUE to apply new tuning in realtime to existing notes which
  1631.  *   are using the replaced tuning (if any), FALSE otherwise
  1632.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1633.  * @since 1.1.0
  1634.  */
  1635. int
  1636. fluid_synth_activate_key_tuning(fluid_synth_t* synth, int bank, int prog,
  1637.                                 const char* name, const double* pitch, int apply)
  1638. {
  1639.   fluid_tuning_t* tuning;
  1640.   int retval = FLUID_OK;
  1641.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  1642.   fluid_return_val_if_fail (bank >= 0 && bank < 128, FLUID_FAILED);
  1643.   fluid_return_val_if_fail (prog >= 0 && prog < 128, FLUID_FAILED);
  1644.   fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
  1645.   fluid_rec_mutex_lock (synth->mutex);      /* ++ Lock tunings */
  1646.   tuning = new_fluid_tuning (name, bank, prog);
  1647.   if (tuning)
  1648.   {
  1649.     if (pitch) fluid_tuning_set_all (tuning, pitch);
  1650.     retval = fluid_synth_replace_tuning_LOCK (synth, tuning, bank, prog, apply);
  1651.     if (retval == FLUID_FAILED) fluid_tuning_unref (tuning, 1);
  1652.   }
  1653.   else retval = FLUID_FAILED;
  1654.   fluid_rec_mutex_unlock (synth->mutex);    /* -- Unlock tunings */
  1655.   return retval;
  1656. }
  1657. /**
  1658.  * Apply an octave tuning to every octave in the MIDI note scale.
  1659.  * @param synth FluidSynth instance
  1660.  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
  1661.  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
  1662.  * @param name Label name for this tuning
  1663.  * @param pitch Array of pitch values (length of 12 for each note of an octave
  1664.  *   starting at note C, values are number of offset cents to add to the normal
  1665.  *   tuning amount)
  1666.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1667.  *
  1668.  * NOTE: Tuning is not applied in realtime to existing notes of the replaced
  1669.  * tuning (if any), use fluid_synth_activate_octave_tuning() instead to specify
  1670.  * this behavior.
  1671.  */
  1672. int
  1673. fluid_synth_create_octave_tuning(fluid_synth_t* synth, int bank, int prog,
  1674.                                  const char* name, const double* pitch)
  1675. {
  1676.   return fluid_synth_activate_octave_tuning (synth, bank, prog, name, pitch, FALSE);
  1677. }
  1678. /**
  1679.  * Activate an octave tuning on every octave in the MIDI note scale.
  1680.  * @param synth FluidSynth instance
  1681.  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
  1682.  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
  1683.  * @param name Label name for this tuning
  1684.  * @param pitch Array of pitch values (length of 12 for each note of an octave
  1685.  *   starting at note C, values are number of offset cents to add to the normal
  1686.  *   tuning amount)
  1687.  * @param apply TRUE to apply new tuning in realtime to existing notes which
  1688.  *   are using the replaced tuning (if any), FALSE otherwise
  1689.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1690.  * @since 1.1.0
  1691.  */
  1692. int
  1693. fluid_synth_activate_octave_tuning(fluid_synth_t* synth, int bank, int prog,
  1694.                                    const char* name, const double* pitch, int apply)
  1695. {
  1696.   fluid_tuning_t* tuning;
  1697.   int retval = FLUID_OK;
  1698.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  1699.   fluid_return_val_if_fail (bank >= 0 && bank < 128, FLUID_FAILED);
  1700.   fluid_return_val_if_fail (prog >= 0 && prog < 128, FLUID_FAILED);
  1701.   fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
  1702.   fluid_return_val_if_fail (pitch != NULL, FLUID_FAILED);
  1703.   fluid_rec_mutex_lock (synth->mutex);      /* ++ Lock tunings */
  1704.   tuning = new_fluid_tuning (name, bank, prog);
  1705.   if (tuning)
  1706.   {
  1707.     fluid_tuning_set_octave (tuning, pitch);
  1708.     retval = fluid_synth_replace_tuning_LOCK (synth, tuning, bank, prog, apply);
  1709.     if (retval == FLUID_FAILED) fluid_tuning_unref (tuning, 1);
  1710.   }
  1711.   else retval = FLUID_FAILED;
  1712.   fluid_rec_mutex_unlock (synth->mutex);    /* -- Unlock tunings */
  1713.   return retval;
  1714. }
  1715. /**
  1716.  * Set tuning values for one or more MIDI notes for an existing tuning.
  1717.  * @param synth FluidSynth instance
  1718.  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
  1719.  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
  1720.  * @param len Number of MIDI notes to assign
  1721.  * @param key Array of MIDI key numbers (length of 'len', values 0-127)
  1722.  * @param pitch Array of pitch values (length of 'len', values are number of
  1723.  *   cents from MIDI note 0)
  1724.  * @param apply TRUE to apply tuning change in realtime to existing notes using
  1725.  *   the specified tuning, FALSE otherwise
  1726.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1727.  *
  1728.  * NOTE: Prior to version 1.1.0 it was an error to specify a tuning that didn't
  1729.  * already exist.  Starting with 1.1.0, the default equal tempered scale will be
  1730.  * used as a basis, if no tuning exists for the given bank and prog.
  1731.  */
  1732. int
  1733. fluid_synth_tune_notes(fluid_synth_t* synth, int bank, int prog,
  1734.                        int len, const int *key, const double* pitch, int apply)
  1735. {
  1736.   fluid_tuning_t* old_tuning, *new_tuning;
  1737.   int retval = FLUID_OK;
  1738.   int i;
  1739.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  1740.   fluid_return_val_if_fail (bank >= 0 && bank < 128, FLUID_FAILED);
  1741.   fluid_return_val_if_fail (prog >= 0 && prog < 128, FLUID_FAILED);
  1742.   fluid_return_val_if_fail (len > 0, FLUID_FAILED);
  1743.   fluid_return_val_if_fail (key != NULL, FLUID_FAILED);
  1744.   fluid_return_val_if_fail (pitch != NULL, FLUID_FAILED);
  1745.   fluid_rec_mutex_lock (synth->mutex);      /* ++ Lock tunings */
  1746.   old_tuning = fluid_synth_get_tuning (synth, bank, prog);
  1747.   if (old_tuning)
  1748.     new_tuning = fluid_tuning_duplicate (old_tuning);
  1749.   else new_tuning = new_fluid_tuning ("Unnamed", bank, prog);
  1750.   if (new_tuning)
  1751.   {
  1752.     for (i = 0; i < len; i++)
  1753.       fluid_tuning_set_pitch (new_tuning, key[i], pitch[i]);
  1754.     retval = fluid_synth_replace_tuning_LOCK (synth, new_tuning, bank, prog, apply);
  1755.     if (retval == FLUID_FAILED) fluid_tuning_unref (new_tuning, 1);
  1756.   }
  1757.   else retval = FLUID_FAILED;
  1758.   fluid_rec_mutex_unlock (synth->mutex);    /* -- Unlock tunings */
  1759.   return retval;
  1760. }
  1761. /**
  1762.  * Select a tuning scale on a MIDI channel.
  1763.  * @param synth FluidSynth instance
  1764.  * @param chan MIDI channel number (0 to MIDI channel count - 1)
  1765.  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
  1766.  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
  1767.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1768.  *
  1769.  * NOTE: This function does NOT activate tuning in realtime, use
  1770.  * fluid_synth_activate_tuning() instead to specify whether tuning change
  1771.  * should cause existing notes to update.
  1772.  *
  1773.  * NOTE: Prior to version 1.1.0 it was an error to select a tuning that didn't
  1774.  * already exist.  Starting with 1.1.0, a default equal tempered scale will be
  1775.  * created, if no tuning exists for the given bank and prog.
  1776.  */
  1777. int
  1778. fluid_synth_select_tuning(fluid_synth_t* synth, int chan, int bank, int prog)
  1779. {
  1780.   return fluid_synth_activate_tuning (synth, chan, bank, prog, FALSE);
  1781. }
  1782. /**
  1783.  * Activate a tuning scale on a MIDI channel.
  1784.  * @param synth FluidSynth instance
  1785.  * @param chan MIDI channel number (0 to MIDI channel count - 1)
  1786.  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
  1787.  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
  1788.  * @param apply TRUE to apply tuning change to active notes, FALSE otherwise
  1789.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1790.  * @since 1.1.0
  1791.  *
  1792.  * NOTE: A default equal tempered scale will be created, if no tuning exists
  1793.  * on the given bank and prog.
  1794.  */
  1795. int
  1796. fluid_synth_activate_tuning(fluid_synth_t* synth, int chan, int bank, int prog,
  1797.                             int apply)
  1798. {
  1799.   fluid_event_queue_elem_t *event;
  1800.   fluid_event_queue_t *queue;
  1801.   fluid_tuning_t* tuning;
  1802.   int retval = FLUID_OK;
  1803.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  1804.   fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
  1805.   fluid_return_val_if_fail (bank >= 0 && bank < 128, FLUID_FAILED);
  1806.   fluid_return_val_if_fail (prog >= 0 && prog < 128, FLUID_FAILED);
  1807.   fluid_rec_mutex_lock (synth->mutex);      /* ++ Lock tunings */
  1808.   tuning = fluid_synth_get_tuning (synth, bank, prog);
  1809.  /* If no tuning exists, create a new default tuning.  We do this, so that
  1810.   * it can be replaced later, if any changes are made. */
  1811.   if (!tuning)
  1812.   {
  1813.     tuning = new_fluid_tuning ("Unnamed", bank, prog);
  1814.     if (tuning) fluid_synth_replace_tuning_LOCK (synth, tuning, bank, prog, FALSE);
  1815.   }
  1816.   if (tuning) fluid_tuning_ref (tuning);  /* ++ ref for outside of lock */
  1817.   fluid_rec_mutex_unlock (synth->mutex);      /* -- Unlock tunings */
  1818.   if (!tuning) return (FLUID_FAILED);
  1819.   if (fluid_synth_should_queue (synth))
  1820.   {
  1821.     event = fluid_synth_get_event_elem (synth, &queue);
  1822.     if (event)
  1823.     {
  1824.       fluid_tuning_ref (tuning);    /* ++ ref new tuning for event */
  1825.       event->type = FLUID_EVENT_QUEUE_ELEM_SET_TUNING;
  1826.       event->set_tuning.apply = apply;
  1827.       event->set_tuning.channel = chan;
  1828.       event->set_tuning.tuning = tuning;
  1829.       fluid_event_queue_next_inptr (queue);
  1830.     }
  1831.     else retval = FLUID_FAILED;
  1832.   }
  1833.   else
  1834.   {
  1835.     fluid_tuning_ref (tuning);    /* ++ ref new tuning for following function */
  1836.     retval = fluid_synth_set_tuning_LOCAL (synth, chan, tuning, apply);
  1837.   }
  1838.   fluid_tuning_unref (tuning, 1);   /* -- unref for outside of lock */
  1839.   return retval;
  1840. }
  1841. /* Local synthesis thread set tuning function (takes over tuning reference) */
  1842. static int
  1843. fluid_synth_set_tuning_LOCAL (fluid_synth_t *synth, int chan,
  1844.                               fluid_tuning_t *tuning, int apply)
  1845. {
  1846.   fluid_event_queue_elem_t *event;
  1847.   fluid_tuning_t *old_tuning;
  1848.   fluid_channel_t *channel;
  1849.   channel = synth->channel[chan];
  1850.   old_tuning = fluid_channel_get_tuning (channel);
  1851.   fluid_channel_set_tuning (channel, tuning);   /* !! Takes over callers reference */
  1852.   if (apply) fluid_synth_update_voice_tuning_LOCAL (synth, channel);
  1853.   /* Send unref old tuning event */
  1854.   if (old_tuning)
  1855.   {
  1856.     event = fluid_event_queue_get_inptr (synth->return_queue);
  1857.     if (event)
  1858.     {
  1859.       event->type = FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING;
  1860.       event->unref_tuning.tuning = old_tuning;
  1861.       event->unref_tuning.count = 1;
  1862.       fluid_event_queue_next_inptr (synth->return_queue);
  1863.     }
  1864.     else
  1865.     { /* Just unref it in synthesis thread if queue is full */
  1866.       fluid_tuning_unref (old_tuning, 1);
  1867.       FLUID_LOG (FLUID_ERR, "Synth return event queue full");
  1868.     }
  1869.   }
  1870.   return FLUID_OK;
  1871. }
  1872. /**
  1873.  * Clear tuning scale on a MIDI channel (set it to the default well-tempered scale).
  1874.  * @param synth FluidSynth instance
  1875.  * @param chan MIDI channel number (0 to MIDI channel count - 1)
  1876.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1877.  *
  1878.  * NOTE: This function does NOT activate tuning change in realtime, use
  1879.  * fluid_synth_deactivate_tuning() instead to specify whether tuning change
  1880.  * should cause existing notes to update.
  1881.  */
  1882. int
  1883. fluid_synth_reset_tuning(fluid_synth_t* synth, int chan)
  1884. {
  1885.   return fluid_synth_deactivate_tuning (synth, chan, FALSE);
  1886. }
  1887. /**
  1888.  * Clear tuning scale on a MIDI channel (use default equal tempered scale).
  1889.  * @param synth FluidSynth instance
  1890.  * @param chan MIDI channel number (0 to MIDI channel count - 1)
  1891.  * @param apply TRUE to apply tuning change to active notes, FALSE otherwise
  1892.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  1893.  * @since 1.1.0
  1894.  */
  1895. int
  1896. fluid_synth_deactivate_tuning(fluid_synth_t* synth, int chan, int apply)
  1897. {
  1898.   fluid_event_queue_elem_t *event;
  1899.   fluid_event_queue_t *queue;
  1900.   int retval = FLUID_OK;
  1901.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  1902.   fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
  1903.   if (fluid_synth_should_queue (synth))
  1904.   {
  1905.     event = fluid_synth_get_event_elem (synth, &queue);
  1906.     if (event)
  1907.     {
  1908.       event->type = FLUID_EVENT_QUEUE_ELEM_SET_TUNING;
  1909.       event->set_tuning.apply = apply;
  1910.       event->set_tuning.channel = chan;
  1911.       event->set_tuning.tuning = NULL;
  1912.       fluid_event_queue_next_inptr (queue);
  1913.     }
  1914.     else retval = FLUID_FAILED;
  1915.   }
  1916.   else retval = fluid_synth_set_tuning_LOCAL (synth, chan, NULL, apply);
  1917.   return retval;
  1918. }
  1919. /**
  1920.  * Start tuning iteration.
  1921.  * @param synth FluidSynth instance
  1922.  */
  1923. void
  1924. fluid_synth_tuning_iteration_start(fluid_synth_t* synth)
  1925. {
  1926.   fluid_return_if_fail (synth != NULL);
  1927.   fluid_private_set (synth->tuning_iter, FLUID_INT_TO_POINTER (0), NULL);
  1928. }
  1929. /**
  1930.  * Advance to next tuning.
  1931.  * @param synth FluidSynth instance
  1932.  * @param bank Location to store MIDI bank number of next tuning scale
  1933.  * @param prog Location to store MIDI program number of next tuning scale
  1934.  * @return 1 if tuning iteration advanced, 0 if no more tunings
  1935.  */
  1936. int
  1937. fluid_synth_tuning_iteration_next(fluid_synth_t* synth, int* bank, int* prog)
  1938. {
  1939.   void *pval;
  1940.   int b = 0, p = 0;
  1941.   fluid_return_val_if_fail (synth != NULL, 0);
  1942.   fluid_return_val_if_fail (bank != NULL, 0);
  1943.   fluid_return_val_if_fail (prog != NULL, 0);
  1944.   /* Current tuning iteration stored as: bank << 8 | program */
  1945.   pval = fluid_private_get (synth->tuning_iter);
  1946.   p = FLUID_POINTER_TO_INT (pval);
  1947.   b = (p >> 8) & 0xFF;
  1948.   p &= 0xFF;
  1949.   fluid_rec_mutex_lock (synth->mutex);      /* ++ lock tunings */
  1950.   if (!synth->tuning)
  1951.   {
  1952.     fluid_rec_mutex_unlock (synth->mutex);    /* -- unlock tunings */
  1953.     return 0;
  1954.   }
  1955.   for (; b < 128; b++, p = 0)
  1956.   {
  1957.     if (synth->tuning[b] == NULL) continue;
  1958.     for (; p < 128; p++)
  1959.     {
  1960.       if (synth->tuning[b][p] == NULL) continue;
  1961.       *bank = b;
  1962.       *prog = p;
  1963.       if (p < 127) fluid_private_set (synth->tuning_iter,
  1964.                                       FLUID_INT_TO_POINTER (b << 8 | (p + 1)), NULL);
  1965.       else fluid_private_set (synth->tuning_iter,
  1966.                               FLUID_INT_TO_POINTER ((b + 1) << 8), NULL);
  1967.       fluid_rec_mutex_unlock (synth->mutex);    /* -- unlock tunings */
  1968.       return 1;
  1969.     }
  1970.   }
  1971.   fluid_rec_mutex_unlock (synth->mutex);    /* -- unlock tunings */
  1972.   return 0;
  1973. }
  1974. /**
  1975.  * Get the entire note tuning for a given MIDI bank and program.
  1976.  * @param synth FluidSynth instance
  1977.  * @param bank MIDI bank number of tuning
  1978.  * @param prog MIDI program number of tuning
  1979.  * @param name Location to store tuning name or NULL to ignore
  1980.  * @param len Maximum number of chars to store to 'name' (including NULL byte)
  1981.  * @param pitch Array to store tuning scale to or NULL to ignore (len of 128)
  1982.  * @return FLUID_OK if matching tuning was found, FLUID_FAILED otherwise
  1983.  */
  1984. int
  1985. fluid_synth_tuning_dump(fluid_synth_t* synth, int bank, int prog,
  1986.                         char* name, int len, double* pitch)
  1987. {
  1988.   fluid_tuning_t* tuning;
  1989.   fluid_rec_mutex_lock (synth->mutex);      /* ++ lock tunings */
  1990.   tuning = fluid_synth_get_tuning (synth, bank, prog);
  1991.   if (tuning)
  1992.   {
  1993.     if (name)
  1994.     {
  1995.       snprintf (name, len - 1, "%s", fluid_tuning_get_name (tuning));
  1996.       name[len - 1] = 0;  /* make sure the string is null terminated */
  1997.     }
  1998.     if (pitch)
  1999.       FLUID_MEMCPY (pitch, fluid_tuning_get_all (tuning), 128 * sizeof (double));
  2000.   }
  2001.   fluid_rec_mutex_unlock (synth->mutex);    /* unlock tunings */
  2002.   return tuning ? FLUID_OK : FLUID_FAILED;
  2003. }
  2004. /**
  2005.  * Get settings assigned to a synth.
  2006.  * @param synth FluidSynth instance
  2007.  * @return FluidSynth settings which are assigned to the synth
  2008.  */
  2009. fluid_settings_t *
  2010. fluid_synth_get_settings(fluid_synth_t* synth)
  2011. {
  2012.   fluid_return_val_if_fail (synth != NULL, NULL);
  2013.   return synth->settings;
  2014. }
  2015. /**
  2016.  * Convenience function to set a string setting of a synth.
  2017.  * @param synth FluidSynth instance
  2018.  * @param name Name of setting parameter
  2019.  * @param str Value to assign to the setting
  2020.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2021.  */
  2022. int
  2023. fluid_synth_setstr(fluid_synth_t* synth, const char* name, const char* str)
  2024. {
  2025.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2026.   fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
  2027.   return fluid_settings_setstr(synth->settings, name, str);
  2028. }
  2029. /**
  2030.  * Convenience function to duplicate a string setting of a synth.
  2031.  * @param synth FluidSynth instance
  2032.  * @param name Name of setting parameter
  2033.  * @param str Location to store a pointer to the newly allocated string value
  2034.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2035.  *
  2036.  * The returned string is owned by the caller and should be freed with free()
  2037.  * when finished with it.
  2038.  */
  2039. int
  2040. fluid_synth_dupstr(fluid_synth_t* synth, const char* name, char** str)
  2041. {
  2042.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2043.   fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
  2044.   fluid_return_val_if_fail (str != NULL, FLUID_FAILED);
  2045.   return fluid_settings_dupstr(synth->settings, name, str);
  2046. }
  2047. /**
  2048.  * Convenience function to set a floating point setting of a synth.
  2049.  * @param synth FluidSynth instance
  2050.  * @param name Name of setting parameter
  2051.  * @param val Value to assign to the setting
  2052.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2053.  */
  2054. int
  2055. fluid_synth_setnum(fluid_synth_t* synth, const char* name, double val)
  2056. {
  2057.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2058.   fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
  2059.   return fluid_settings_setnum(synth->settings, name, val);
  2060. }
  2061. /**
  2062.  * Convenience function to get a floating point setting of a synth.
  2063.  * @param synth FluidSynth instance
  2064.  * @param name Name of setting parameter
  2065.  * @param val Location to store the current value of the setting
  2066.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2067.  */
  2068. int
  2069. fluid_synth_getnum(fluid_synth_t* synth, const char* name, double* val)
  2070. {
  2071.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2072.   fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
  2073.   return fluid_settings_getnum(synth->settings, name, val);
  2074. }
  2075. /**
  2076.  * Convenience function to set an integer setting of a synth.
  2077.  * @param synth FluidSynth instance
  2078.  * @param name Name of setting parameter
  2079.  * @param val Value to assign to the setting
  2080.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2081.  */
  2082. int
  2083. fluid_synth_setint(fluid_synth_t* synth, const char* name, int val)
  2084. {
  2085.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2086.   fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
  2087.   return fluid_settings_setint(synth->settings, name, val);
  2088. }
  2089. /**
  2090.  * Convenience function to get an integer setting of a synth.
  2091.  * @param synth FluidSynth instance
  2092.  * @param name Name of setting parameter
  2093.  * @param val Location to store the current value of the setting
  2094.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2095.  */
  2096. int
  2097. fluid_synth_getint(fluid_synth_t* synth, const char* name, int* val)
  2098. {
  2099.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2100.   fluid_return_val_if_fail (name != NULL, FLUID_FAILED);
  2101.   return fluid_settings_getint(synth->settings, name, val);
  2102. }
  2103. /**
  2104.  * Set a SoundFont generator (effect) value on a MIDI channel in real-time.
  2105.  * @param synth FluidSynth instance
  2106.  * @param chan MIDI channel number (0 to MIDI channel count - 1)
  2107.  * @param param SoundFont generator ID (#fluid_gen_type)
  2108.  * @param value Offset generator value to assign to the MIDI channel
  2109.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2110.  *
  2111.  * Parameter numbers and ranges are described in the SoundFont 2.01
  2112.  * specification PDF, paragraph 8.1.3, page 48.  See #fluid_gen_type.
  2113.  */
  2114. int
  2115. fluid_synth_set_gen(fluid_synth_t* synth, int chan, int param, float value)
  2116. {
  2117.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2118.   fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
  2119.   fluid_return_val_if_fail (param >= 0 && param < GEN_LAST, FLUID_FAILED);
  2120.   if (fluid_synth_should_queue (synth))
  2121.     return fluid_synth_queue_gen_event (synth, chan, param, value, FALSE);
  2122.   else fluid_synth_set_gen_LOCAL (synth, chan, param, value, FALSE);
  2123.   return FLUID_OK;
  2124. }
  2125. /* Synthesis thread local set gen function */
  2126. static void
  2127. fluid_synth_set_gen_LOCAL (fluid_synth_t* synth, int chan, int param, float value,
  2128.                            int absolute)
  2129. {
  2130.   fluid_voice_t* voice;
  2131.   int i;
  2132.   fluid_channel_set_gen (synth->channel[chan], param, value, absolute);
  2133.   for (i = 0; i < synth->polyphony; i++) {
  2134.     voice = synth->voice[i];
  2135.     if (voice->chan == chan)
  2136.       fluid_voice_set_param (voice, param, value, absolute);
  2137.   }
  2138. }
  2139. /**
  2140.  * Set a SoundFont generator (effect) value on a MIDI channel in real-time.
  2141.  * @param synth FluidSynth instance
  2142.  * @param chan MIDI channel number (0 to MIDI channel count - 1)
  2143.  * @param param SoundFont generator ID (#fluid_gen_type)
  2144.  * @param value Offset or absolute generator value to assign to the MIDI channel
  2145.  * @param absolute 0 to assign a relative value, non-zero to assign an absolute value
  2146.  * @param normalized 0 if value is specified in the native units of the generator,
  2147.  *   non-zero to take the value as a 0.0-1.0 range and apply it to the valid
  2148.  *   generator effect range (scaled and shifted as necessary).
  2149.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2150.  * @since 1.1.0
  2151.  *
  2152.  * This function allows for setting all effect parameters in real time on a
  2153.  * MIDI channel.  Setting absolute to non-zero will cause the value to override
  2154.  * any generator values set in the instruments played on the MIDI channel.
  2155.  * See SoundFont 2.01 spec, paragraph 8.1.3, page 48 for details on SoundFont
  2156.  * generator parameters and valid ranges.
  2157.  */
  2158. int
  2159. fluid_synth_set_gen2(fluid_synth_t* synth, int chan, int param,
  2160.      float value, int absolute, int normalized)
  2161. {
  2162.   float v;
  2163.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2164.   fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
  2165.   fluid_return_val_if_fail (param >= 0 && param < GEN_LAST, FLUID_FAILED);
  2166.   v = normalized ? fluid_gen_scale(param, value) : value;
  2167.   if (fluid_synth_should_queue (synth))
  2168.     return (fluid_synth_queue_gen_event (synth, chan, param, v, absolute));
  2169.   else fluid_synth_set_gen_LOCAL (synth, chan, param, v, absolute);
  2170.   return FLUID_OK;
  2171. }
  2172. /**
  2173.  * Get generator value assigned to a MIDI channel.
  2174.  * @param synth FluidSynth instance
  2175.  * @param chan MIDI channel number (0 to MIDI channel count - 1)
  2176.  * @param param SoundFont generator ID (#fluid_gen_type)
  2177.  * @return Current generator value assigned to MIDI channel
  2178.  */
  2179. /* FIXME - Not currently SMP multi-thread safe (need atomic set/get of gen) */
  2180. float
  2181. fluid_synth_get_gen(fluid_synth_t* synth, int chan, int param)
  2182. {
  2183.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2184.   fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
  2185.   fluid_return_val_if_fail (param >= 0 && param < GEN_LAST, FLUID_FAILED);
  2186.   return fluid_channel_get_gen(synth->channel[chan], param);
  2187. }
  2188. /**
  2189.  * Assign a MIDI router to a synth.
  2190.  * @param synth FluidSynth instance
  2191.  * @param router MIDI router to assign to the synth
  2192.  *
  2193.  * NOTE: This should only be done once and prior to using the synth.
  2194.  */
  2195. void
  2196. fluid_synth_set_midi_router(fluid_synth_t* synth, fluid_midi_router_t* router)
  2197. {
  2198.   fluid_return_if_fail (synth != NULL);
  2199.   synth->midi_router = router;
  2200. };
  2201. /**
  2202.  * Handle MIDI event from MIDI router, used as a callback function.
  2203.  * @param data FluidSynth instance
  2204.  * @param event MIDI event to handle
  2205.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2206.  */
  2207. int
  2208. fluid_synth_handle_midi_event(void* data, fluid_midi_event_t* event)
  2209. {
  2210.   fluid_synth_t* synth = (fluid_synth_t*) data;
  2211.   int type = fluid_midi_event_get_type(event);
  2212.   int chan = fluid_midi_event_get_channel(event);
  2213.   switch(type) {
  2214.       case NOTE_ON:
  2215. return fluid_synth_noteon(synth, chan,
  2216.                                   fluid_midi_event_get_key(event),
  2217.                                   fluid_midi_event_get_velocity(event));
  2218.       case NOTE_OFF:
  2219. return fluid_synth_noteoff(synth, chan, fluid_midi_event_get_key(event));
  2220.       case CONTROL_CHANGE:
  2221. return fluid_synth_cc(synth, chan,
  2222.                               fluid_midi_event_get_control(event),
  2223.                               fluid_midi_event_get_value(event));
  2224.       case PROGRAM_CHANGE:
  2225. return fluid_synth_program_change(synth, chan, fluid_midi_event_get_program(event));
  2226.       case CHANNEL_PRESSURE:
  2227. return fluid_synth_channel_pressure(synth, chan, fluid_midi_event_get_program(event));
  2228.       case PITCH_BEND:
  2229. return fluid_synth_pitch_bend(synth, chan, fluid_midi_event_get_pitch(event));
  2230.       case MIDI_SYSTEM_RESET:
  2231. return fluid_synth_system_reset(synth);
  2232.       case MIDI_SYSEX:
  2233.         return fluid_synth_sysex (synth, event->paramptr, event->param1, NULL, NULL, NULL, FALSE);
  2234.   }
  2235.   return FLUID_FAILED;
  2236. }
  2237. /**
  2238.  * Create and start voices using a preset and a MIDI note on event.
  2239.  * @param synth FluidSynth instance
  2240.  * @param id Voice group ID to use (can be used with fluid_synth_stop()).
  2241.  * @param preset Preset to synthesize
  2242.  * @param audio_chan Unused currently, set to 0
  2243.  * @param midi_chan MIDI channel number (0 to MIDI channel count - 1)
  2244.  * @param key MIDI note number (0-127)
  2245.  * @param vel MIDI velocity number (1-127)
  2246.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2247.  *
  2248.  * NOTE: Should only be called from within synthesis thread, which includes
  2249.  * SoundFont loader preset noteon method.
  2250.  */
  2251. int
  2252. fluid_synth_start(fluid_synth_t* synth, unsigned int id, fluid_preset_t* preset, 
  2253.   int audio_chan, int midi_chan, int key, int vel)
  2254. {
  2255.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2256.   fluid_return_val_if_fail (preset != NULL, FLUID_FAILED);
  2257.   fluid_return_val_if_fail (midi_chan >= 0 && midi_chan < synth->midi_channels, FLUID_FAILED);
  2258.   fluid_return_val_if_fail (key >= 0 && key <= 127, FLUID_FAILED);
  2259.   fluid_return_val_if_fail (vel >= 1 && vel <= 127, FLUID_FAILED);
  2260.   fluid_return_val_if_fail (fluid_synth_is_synth_thread (synth), FLUID_FAILED);
  2261.   synth->storeid = id;
  2262.   return fluid_preset_noteon (preset, synth, midi_chan, key, vel);
  2263. }
  2264. /**
  2265.  * Stop notes for a given note event voice ID.
  2266.  * @param synth FluidSynth instance
  2267.  * @param id Voice note event ID
  2268.  * @return FLUID_OK on success, FLUID_FAILED otherwise
  2269.  *
  2270.  * NOTE: In FluidSynth versions prior to 1.1.0 #FLUID_FAILED would be returned
  2271.  * if no matching voice note event ID was found.  Versions after 1.1.0 only
  2272.  * return #FLUID_FAILED if an error occurs.
  2273.  */
  2274. int
  2275. fluid_synth_stop(fluid_synth_t* synth, unsigned int id)
  2276. {
  2277.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2278.   if (fluid_synth_should_queue (synth))
  2279.     return fluid_synth_queue_int_event (synth, FLUID_EVENT_QUEUE_ELEM_STOP_VOICES, id);
  2280.   fluid_synth_stop_LOCAL (synth, id);
  2281.   return FLUID_OK;
  2282. }
  2283. /* Local synthesis thread variant of fluid_synth_stop */
  2284. static void
  2285. fluid_synth_stop_LOCAL (fluid_synth_t *synth, unsigned int id)
  2286. {
  2287.   fluid_voice_t* voice;
  2288.   int i;
  2289.   for (i = 0; i < synth->polyphony; i++) {
  2290.     voice = synth->voice[i];
  2291.     if (_ON(voice) && (fluid_voice_get_id (voice) == id))
  2292.       fluid_voice_noteoff(voice);
  2293.   }
  2294. }
  2295. /**
  2296.  * Offset the bank numbers of a loaded SoundFont.
  2297.  * @param synth FluidSynth instance
  2298.  * @param sfont_id ID of a loaded SoundFont
  2299.  * @param offset Bank offset value to apply to all instruments
  2300.  */
  2301. int
  2302. fluid_synth_set_bank_offset(fluid_synth_t* synth, int sfont_id, int offset)
  2303. {
  2304.   fluid_sfont_info_t *sfont_info;
  2305.   fluid_list_t *list;
  2306.   fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
  2307.   fluid_rec_mutex_lock (synth->mutex);      /* ++ lock sfont_info list */
  2308.   for (list = synth->sfont_info; list; list = fluid_list_next(list)) {
  2309.     sfont_info = (fluid_sfont_info_t *)fluid_list_get (list);
  2310.     if (fluid_sfont_get_id (sfont_info->sfont) == (unsigned int)sfont_id)
  2311.     {
  2312.       sfont_info->bankofs = offset;
  2313.       break;
  2314.     }
  2315.   }
  2316.   fluid_rec_mutex_unlock (synth->mutex);      /* -- unlock */
  2317.   if (!list)
  2318.   {
  2319.     FLUID_LOG (FLUID_ERR, "No SoundFont with id = %d", sfont_id);
  2320.     return FLUID_FAILED;
  2321.   }
  2322.   return FLUID_OK;
  2323. }
  2324. /**
  2325.  * Get bank offset of a loaded SoundFont.
  2326.  * @param synth FluidSynth instance
  2327.  * @param sfont_id ID of a loaded SoundFont
  2328.  * @return SoundFont bank offset value
  2329.  */
  2330. int
  2331. fluid_synth_get_bank_offset(fluid_synth_t* synth, int sfont_id)
  2332. {
  2333.   fluid_sfont_info_t *sfont_info;
  2334.   fluid_list_t *list;
  2335.   int offset = 0;
  2336.   fluid_return_val_if_fail (synth != NULL, 0);
  2337.   fluid_rec_mutex_lock (synth->mutex);      /* ++ lock sfont_info list */
  2338.   for (list = synth->sfont_info; list; list = fluid_list_next(list)) {
  2339.     sfont_info = (fluid_sfont_info_t *)fluid_list_get (list);
  2340.     if (fluid_sfont_get_id (sfont_info->sfont) == (unsigned int)sfont_id)
  2341.     {
  2342.       offset = sfont_info->bankofs;
  2343.       break;
  2344.     }
  2345.   }
  2346.   fluid_rec_mutex_unlock (synth->mutex);      /* -- unlock */
  2347.   if (!list)
  2348.   {
  2349.     FLUID_LOG (FLUID_ERR, "No SoundFont with id = %d", sfont_id);
  2350.     return 0;
  2351.   }
  2352.   return offset;
  2353. }