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 23#include <unistd.h> /* for usleep() */ 24#include <sys/types.h> 25#include <signal.h> 26#include <string.h> 27#include <errno.h> 28#include <pthread.h> 29 30static void fluid_lash_save (fluid_synth_t * synth); 31static void fluid_lash_load (fluid_synth_t * synth, const char * filename); 32static void *fluid_lash_run (void * data); 33 34/* 35 * lash client - this symbol needs to be in the library else 36 * all clients would need a fluid_lash_client symbol. 37 */ 38#ifdef HAVE_LASH 39lash_client_t * fluid_lash_client; 40#else 41cca_client_t * fluid_lash_client; 42#endif 43 44static pthread_t fluid_lash_thread; 45 46 47#ifdef HAVE_LASH 48 49fluid_lash_args_t * 50fluid_lash_extract_args (int * pargc, char *** pargv) 51{ 52 return lash_extract_args (pargc, pargv); 53} 54 55int 56fluid_lash_connect (fluid_lash_args_t * args) 57{ 58 fluid_lash_client = lash_init (args, PACKAGE, LASH_Config_Data_Set | LASH_Terminal, LASH_PROTOCOL (2,0)); 59 return fluid_lash_client && lash_enabled (fluid_lash_client); 60} 61 62void 63fluid_lash_create_thread (fluid_synth_t * synth) 64{ 65 pthread_create (&fluid_lash_thread, NULL, fluid_lash_run, synth); 66} 67 68static void 69fluid_lash_save (fluid_synth_t * synth) 70{ 71 int i; 72 int sfcount; 73 fluid_sfont_t * sfont; 74 lash_config_t * config; 75 char num[32]; 76 77 sfcount = fluid_synth_sfcount (synth); 78 79 config = lash_config_new (); 80 lash_config_set_key (config, "soundfont count"); 81 lash_config_set_value_int (config, sfcount); 82 lash_send_config (fluid_lash_client, config); 83 84 for (i = sfcount - 1; i >= 0; i--) 85 { 86 sfont = fluid_synth_get_sfont (synth, i); 87 config = lash_config_new (); 88 89 sprintf (num, "%d", i); 90 91 lash_config_set_key (config, num); 92 lash_config_set_value_string (config, sfont->get_name (sfont)); 93 94 lash_send_config (fluid_lash_client, config); 95 } 96} 97 98static void 99fluid_lash_load (fluid_synth_t * synth, const char * filename) 100{ 101 fluid_synth_sfload (synth, filename, 1); 102} 103 104static void * 105fluid_lash_run (void * data) 106{ 107 lash_event_t * event; 108 lash_config_t * config; 109 fluid_synth_t * synth; 110 int done = 0; 111 int err; 112 int pending_restores = 0; 113 114 synth = (fluid_synth_t *) data; 115 116 while (!done) 117 { 118 while ( (event = lash_get_event (fluid_lash_client)) ) 119 { 120 switch (lash_event_get_type (event)) 121 { 122 case LASH_Save_Data_Set: 123 fluid_lash_save (synth); 124 lash_send_event (fluid_lash_client, event); 125 break; 126 case LASH_Restore_Data_Set: 127 lash_event_destroy (event); 128 break; 129 case LASH_Quit: 130 err = kill (getpid(), SIGQUIT); 131 if (err) 132 fprintf (stderr, "%s: error sending signal: %s", 133 __FUNCTION__, strerror (errno)); 134 lash_event_destroy (event); 135 done = 1; 136 break; 137 case LASH_Server_Lost: 138 lash_event_destroy (event); 139 done = 1; 140 break; 141 default: 142 fprintf (stderr, "Recieved unknown LASH event of type %d\n", lash_event_get_type (event)); 143 lash_event_destroy (event); 144 break; 145 } 146 } 147 148 while ( (config = lash_get_config (fluid_lash_client)) ) 149 { 150 if (strcmp (lash_config_get_key (config), "soundfont count") == 0) 151 pending_restores = lash_config_get_value_int (config); 152 else 153 { 154 fluid_lash_load (synth, lash_config_get_value_string (config)); 155 pending_restores--; 156 } 157 lash_config_destroy (config); 158 159 if (!pending_restores) 160 { 161 event = lash_event_new_with_type (LASH_Restore_Data_Set); 162 lash_send_event (fluid_lash_client, event); 163 } 164 } 165 166 usleep (10000); 167 } 168 169 return NULL; 170} 171 172 173#else /* depricated LADCCA support, will remove someday */ 174 175 176fluid_lash_args_t * 177fluid_lash_extract_args (int * pargc, char *** pargv) 178{ 179 return cca_extract_args (pargc, pargv); 180} 181 182int 183fluid_lash_connect (fluid_lash_args_t * args) 184{ 185 fluid_lash_client = cca_init (args, PACKAGE, CCA_Config_Data_Set | CCA_Terminal, CCA_PROTOCOL (2,0)); 186 return fluid_lash_client && cca_enabled (fluid_lash_client); 187} 188 189void 190fluid_lash_create_thread (fluid_synth_t * synth) 191{ 192 pthread_create (&fluid_lash_thread, NULL, fluid_lash_run, synth); 193} 194 195static void 196fluid_lash_save (fluid_synth_t * synth) 197{ 198 int i; 199 int sfcount; 200 fluid_sfont_t * sfont; 201 cca_config_t * config; 202 char num[32]; 203 204 sfcount = fluid_synth_sfcount (synth); 205 206 config = cca_config_new (); 207 cca_config_set_key (config, "soundfont count"); 208 cca_config_set_value_int (config, sfcount); 209 cca_send_config (fluid_lash_client, config); 210 211 for (i = sfcount - 1; i >= 0; i--) 212 { 213 sfont = fluid_synth_get_sfont (synth, i); 214 config = cca_config_new (); 215 216 sprintf (num, "%d", i); 217 218 cca_config_set_key (config, num); 219 cca_config_set_value_string (config, sfont->get_name (sfont)); 220 221 cca_send_config (fluid_lash_client, config); 222 } 223} 224 225static void 226fluid_lash_load (fluid_synth_t * synth, const char * filename) 227{ 228 fluid_synth_sfload (synth, filename, 1); 229} 230 231/* LADCCA thread */ 232static void * 233fluid_lash_run (void * data) 234{ 235 cca_event_t * event; 236 cca_config_t * config; 237 fluid_synth_t * synth; 238 int done = 0; 239 int err; 240 int pending_restores = 0; 241 242 synth = (fluid_synth_t *) data; 243 244 while (!done) 245 { 246 while ( (event = cca_get_event (fluid_lash_client)) ) 247 { 248 switch (cca_event_get_type (event)) 249 { 250 case CCA_Save_Data_Set: 251 fluid_lash_save (synth); 252 cca_send_event (fluid_lash_client, event); 253 break; 254 case CCA_Restore_Data_Set: 255 cca_event_destroy (event); 256 break; 257 case CCA_Quit: 258 err = kill (getpid(), SIGQUIT); 259 if (err) 260 fprintf (stderr, "%s: error sending signal: %s", 261 __FUNCTION__, strerror (errno)); 262 cca_event_destroy (event); 263 done = 1; 264 break; 265 case CCA_Server_Lost: 266 cca_event_destroy (event); 267 done = 1; 268 break; 269 default: 270 fprintf (stderr, "Recieved unknown LADCCA event of type %d\n", cca_event_get_type (event)); 271 cca_event_destroy (event); 272 break; 273 } 274 } 275 276 while ( (config = cca_get_config (fluid_lash_client)) ) 277 { 278 if (strcmp (cca_config_get_key (config), "soundfont count") == 0) 279 pending_restores = cca_config_get_value_int (config); 280 else 281 { 282 fluid_lash_load (synth, cca_config_get_value_string (config)); 283 pending_restores--; 284 } 285 cca_config_destroy (config); 286 287 if (!pending_restores) 288 { 289 event = cca_event_new_with_type (CCA_Restore_Data_Set); 290 cca_send_event (fluid_lash_client, event); 291 } 292 } 293 294 usleep (10000); 295 } 296 297 return NULL; 298} 299 300#endif /* #if HAVE_LASH #else */ 301