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

midi

开发平台:

C/C++

  1. /* FluidSynth - A Software Synthesizer
  2.  *
  3.  * Copyright (C) 2003  Peter Hanappe and others.
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Library General Public License
  7.  * as published by the Free Software Foundation; either version 2 of
  8.  * the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Library General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Library General Public
  16.  * License along with this library; if not, write to the Free
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18.  * 02111-1307, USA
  19.  */
  20. #include "fluid_lash.h"
  21. #include "fluid_synth.h"
  22. #include <unistd.h> /* for usleep() */
  23. #include <sys/types.h>
  24. #include <signal.h>
  25. #include <string.h>
  26. #include <errno.h>
  27. #include <pthread.h>
  28. static void fluid_lash_save (fluid_synth_t * synth);
  29. static void fluid_lash_load (fluid_synth_t * synth, const char * filename);
  30. static void *fluid_lash_run (void * data);
  31. /*
  32.  * lash client - this symbol needs to be in the library else
  33.  * all clients would need a fluid_lash_client symbol.
  34.  */
  35. #ifdef HAVE_LASH
  36. lash_client_t * fluid_lash_client;
  37. #else
  38. cca_client_t * fluid_lash_client;
  39. #endif
  40. static pthread_t fluid_lash_thread;
  41. #ifdef HAVE_LASH
  42. fluid_lash_args_t *
  43. fluid_lash_extract_args (int * pargc, char *** pargv)
  44. {
  45.   return lash_extract_args (pargc, pargv);
  46. }
  47. int
  48. fluid_lash_connect (fluid_lash_args_t * args)
  49. {
  50.   fluid_lash_client = lash_init (args, PACKAGE, LASH_Config_Data_Set | LASH_Terminal, LASH_PROTOCOL (2,0));
  51.   return fluid_lash_client && lash_enabled (fluid_lash_client);
  52. }
  53. void
  54. fluid_lash_create_thread (fluid_synth_t * synth)
  55. {
  56.   pthread_create (&fluid_lash_thread, NULL, fluid_lash_run, synth);
  57. }
  58. static void
  59. fluid_lash_save (fluid_synth_t * synth)
  60. {
  61.   int i;
  62.   int sfcount;
  63.   fluid_sfont_t * sfont;
  64.   lash_config_t * config;
  65.   char num[32];
  66.   sfcount = fluid_synth_sfcount (synth);
  67.   config = lash_config_new ();
  68.   lash_config_set_key (config, "soundfont count");
  69.   lash_config_set_value_int (config, sfcount);
  70.   lash_send_config (fluid_lash_client, config);
  71.   for (i = sfcount - 1; i >= 0; i--)
  72.     {
  73.       sfont = fluid_synth_get_sfont (synth, i);
  74.       config = lash_config_new ();
  75.       sprintf (num, "%d", i);
  76.       lash_config_set_key (config, num);
  77.       lash_config_set_value_string (config, sfont->get_name (sfont));
  78.       lash_send_config (fluid_lash_client, config);
  79.     }
  80. }
  81. static void
  82. fluid_lash_load (fluid_synth_t * synth, const char * filename)
  83. {
  84.   fluid_synth_sfload (synth, filename, 1);
  85. }
  86. static void *
  87. fluid_lash_run (void * data)
  88. {
  89.   lash_event_t * event;
  90.   lash_config_t * config;
  91.   fluid_synth_t * synth;
  92.   int done = 0;
  93.   int err;
  94.   int pending_restores = 0;
  95.   synth = (fluid_synth_t *) data;
  96.   while (!done)
  97.     {
  98.       while ( (event = lash_get_event (fluid_lash_client)) )
  99.         {
  100.           switch (lash_event_get_type (event))
  101.             {
  102.             case LASH_Save_Data_Set:
  103.               fluid_lash_save (synth);
  104.               lash_send_event (fluid_lash_client, event);
  105.               break;
  106.             case LASH_Restore_Data_Set:
  107.               lash_event_destroy (event);
  108.               break;
  109.             case LASH_Quit:
  110.       err = kill (getpid(), SIGQUIT);
  111.       if (err)
  112. fprintf (stderr, "%s: error sending signal: %s",
  113.  __FUNCTION__, strerror (errno));
  114.       lash_event_destroy (event);
  115.       done = 1;
  116.       break;
  117.     case LASH_Server_Lost:
  118.       lash_event_destroy (event);
  119.       done = 1;
  120.       break;
  121.             default:
  122.               fprintf (stderr, "Received unknown LASH event of type %dn", lash_event_get_type (event));
  123.       lash_event_destroy (event);
  124.       break;
  125.             }
  126.         }
  127.       while ( (config = lash_get_config (fluid_lash_client)) )
  128.         {
  129.   if (strcmp (lash_config_get_key (config), "soundfont count") == 0)
  130.       pending_restores = lash_config_get_value_int (config);
  131.   else
  132.     {
  133.               fluid_lash_load (synth, lash_config_get_value_string (config));
  134.       pending_restores--;
  135.     }
  136.           lash_config_destroy (config);
  137.   if (!pending_restores)
  138.     {
  139.       event = lash_event_new_with_type (LASH_Restore_Data_Set);
  140.       lash_send_event (fluid_lash_client, event);
  141.     }
  142.         }
  143.       usleep (10000);
  144.     }
  145.   return NULL;
  146. }
  147. #else /* deprecated LADCCA support, will remove someday */
  148. fluid_lash_args_t *
  149. fluid_lash_extract_args (int * pargc, char *** pargv)
  150. {
  151.   return cca_extract_args (pargc, pargv);
  152. }
  153. int
  154. fluid_lash_connect (fluid_lash_args_t * args)
  155. {
  156.   fluid_lash_client = cca_init (args, PACKAGE, CCA_Config_Data_Set | CCA_Terminal, CCA_PROTOCOL (2,0));
  157.   return fluid_lash_client && cca_enabled (fluid_lash_client);
  158. }
  159. void
  160. fluid_lash_create_thread (fluid_synth_t * synth)
  161. {
  162.   pthread_create (&fluid_lash_thread, NULL, fluid_lash_run, synth);
  163. }
  164. static void
  165. fluid_lash_save (fluid_synth_t * synth)
  166. {
  167.   int i;
  168.   int sfcount;
  169.   fluid_sfont_t * sfont;
  170.   cca_config_t * config;
  171.   char num[32];
  172.   sfcount = fluid_synth_sfcount (synth);
  173.   config = cca_config_new ();
  174.   cca_config_set_key (config, "soundfont count");
  175.   cca_config_set_value_int (config, sfcount);
  176.   cca_send_config (fluid_lash_client, config);
  177.   for (i = sfcount - 1; i >= 0; i--)
  178.     {
  179.       sfont = fluid_synth_get_sfont (synth, i);
  180.       config = cca_config_new ();
  181.       sprintf (num, "%d", i);
  182.       cca_config_set_key (config, num);
  183.       cca_config_set_value_string (config, sfont->get_name (sfont));
  184.       cca_send_config (fluid_lash_client, config);
  185.     }
  186. }
  187. static void
  188. fluid_lash_load (fluid_synth_t * synth, const char * filename)
  189. {
  190.   fluid_synth_sfload (synth, filename, 1);
  191. }
  192. /* LADCCA thread */
  193. static void *
  194. fluid_lash_run (void * data)
  195. {
  196.   cca_event_t * event;
  197.   cca_config_t * config;
  198.   fluid_synth_t * synth;
  199.   int done = 0;
  200.   int err;
  201.   int pending_restores = 0;
  202.   synth = (fluid_synth_t *) data;
  203.   while (!done)
  204.     {
  205.       while ( (event = cca_get_event (fluid_lash_client)) )
  206.         {
  207.           switch (cca_event_get_type (event))
  208.             {
  209.             case CCA_Save_Data_Set:
  210.               fluid_lash_save (synth);
  211.               cca_send_event (fluid_lash_client, event);
  212.               break;
  213.             case CCA_Restore_Data_Set:
  214.               cca_event_destroy (event);
  215.               break;
  216.             case CCA_Quit:
  217.       err = kill (getpid(), SIGQUIT);
  218.       if (err)
  219. fprintf (stderr, "%s: error sending signal: %s",
  220.  __FUNCTION__, strerror (errno));
  221.       cca_event_destroy (event);
  222.       done = 1;
  223.       break;
  224.     case CCA_Server_Lost:
  225.       cca_event_destroy (event);
  226.       done = 1;
  227.       break;
  228.             default:
  229.               fprintf (stderr, "Received unknown LADCCA event of type %dn", cca_event_get_type (event));
  230.       cca_event_destroy (event);
  231.       break;
  232.             }
  233.         }
  234.       while ( (config = cca_get_config (fluid_lash_client)) )
  235.         {
  236.   if (strcmp (cca_config_get_key (config), "soundfont count") == 0)
  237.       pending_restores = cca_config_get_value_int (config);
  238.   else
  239.     {
  240.               fluid_lash_load (synth, cca_config_get_value_string (config));
  241.       pending_restores--;
  242.     }
  243.           cca_config_destroy (config);
  244.   if (!pending_restores)
  245.     {
  246.       event = cca_event_new_with_type (CCA_Restore_Data_Set);
  247.       cca_send_event (fluid_lash_client, event);
  248.     }
  249.         }
  250.       usleep (10000);
  251.     }
  252.   return NULL;
  253. }
  254. #endif /* #if HAVE_LASH   #else */