src/fluid_settings.c

00001 /* FluidSynth - A Software Synthesizer
00002  *
00003  * Copyright (C) 2003  Peter Hanappe and others.
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public License
00007  * as published by the Free Software Foundation; either version 2 of
00008  * the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public
00016  * License along with this library; if not, write to the Free
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018  * 02111-1307, USA
00019  */
00020 
00021 #include "fluidsynth_priv.h"
00022 #include "fluid_sys.h"
00023 #include "fluid_hash.h"
00024 #include "fluid_synth.h"
00025 #include "fluid_cmd.h"
00026 #include "fluid_adriver.h"
00027 #include "fluid_mdriver.h"
00028 #include "fluid_settings.h"
00029 
00030 /* maximum allowed components of a settings variable (separated by '.') */
00031 #define MAX_SETTINGS_TOKENS     8       /* currently only a max of 3 are used */
00032 #define MAX_SETTINGS_LABEL      256     /* max length of a settings variable label */
00033 
00034 static void fluid_settings_init(fluid_settings_t* settings);
00035 static void fluid_settings_hash_delete(void* value, int type);
00036 static int fluid_settings_tokenize(char* s, char *buf, char** ptr);
00037 
00038 
00039 typedef struct {
00040   char* value;
00041   char* def;
00042   int hints;
00043   fluid_list_t* options;
00044   fluid_str_update_t update;
00045   void* data;
00046 } fluid_str_setting_t;
00047 
00048 static fluid_str_setting_t*
00049 new_fluid_str_setting(char* value, char* def, int hints, fluid_str_update_t fun, void* data)
00050 {
00051   fluid_str_setting_t* str;
00052   str = FLUID_NEW(fluid_str_setting_t);
00053   str->value = value? FLUID_STRDUP(value) : NULL;
00054   str->def = def? FLUID_STRDUP(def) : NULL;
00055   str->hints = hints;
00056   str->options = NULL;
00057   str->update = fun;
00058   str->data = data;
00059   return str;
00060 }
00061 
00062 static void delete_fluid_str_setting(fluid_str_setting_t* str)
00063 {
00064   if (str) {
00065     if (str->value) {
00066       FLUID_FREE(str->value);
00067     }
00068     if (str->def) {
00069       FLUID_FREE(str->def);
00070     }
00071     if (str->options) {
00072       fluid_list_t* list = str->options;
00073 
00074       while (list) {
00075         FLUID_FREE (list->data);
00076         list = fluid_list_next(list);
00077       }
00078 
00079       delete_fluid_list(str->options);
00080     }
00081     FLUID_FREE(str);
00082   }
00083 }
00084 
00085 
00086 
00087 
00088 typedef struct {
00089   double value;
00090   double def;
00091   double min;
00092   double max;
00093   int hints;
00094   fluid_num_update_t update;
00095   void* data;
00096 } fluid_num_setting_t;
00097 
00098 
00099 static fluid_num_setting_t*
00100 new_fluid_num_setting(double min, double max, double def,
00101                      int hints, fluid_num_update_t fun, void* data)
00102 {
00103   fluid_num_setting_t* setting;
00104   setting = FLUID_NEW(fluid_num_setting_t);
00105   setting->value = def;
00106   setting->def = def;
00107   setting->min = min;
00108   setting->max = max;
00109   setting->hints = hints;
00110   setting->update = fun;
00111   setting->data = data;
00112   return setting;
00113 }
00114 
00115 static void delete_fluid_num_setting(fluid_num_setting_t* setting)
00116 {
00117   if (setting) {
00118      FLUID_FREE(setting);
00119   }
00120 }
00121 
00122 
00123 
00124 
00125 typedef struct {
00126   int value;
00127   int def;
00128   int min;
00129   int max;
00130   int hints;
00131   fluid_int_update_t update;
00132   void* data;
00133 } fluid_int_setting_t;
00134 
00135 
00136 static fluid_int_setting_t*
00137 new_fluid_int_setting(int min, int max, int def,
00138                      int hints, fluid_int_update_t fun, void* data)
00139 {
00140   fluid_int_setting_t* setting;
00141   setting = FLUID_NEW(fluid_int_setting_t);
00142   setting->value = def;
00143   setting->def = def;
00144   setting->min = min;
00145   setting->max = max;
00146   setting->hints = hints;
00147   setting->update = fun;
00148   setting->data = data;
00149   return setting;
00150 }
00151 
00152 static void delete_fluid_int_setting(fluid_int_setting_t* setting)
00153 {
00154   if (setting) {
00155      FLUID_FREE(setting);
00156   }
00157 }
00158 
00159 
00160 
00161 fluid_settings_t* new_fluid_settings()
00162 {
00163   fluid_settings_t* settings = new_fluid_hashtable(fluid_settings_hash_delete);
00164   if (settings == NULL) {
00165     return NULL;
00166   }
00167   fluid_settings_init(settings);
00168   return settings;
00169 }
00170 
00171 void delete_fluid_settings(fluid_settings_t* settings)
00172 {
00173   delete_fluid_hashtable(settings);
00174 }
00175 
00176 void fluid_settings_hash_delete(void* value, int type)
00177 {
00178   switch (type) {
00179   case FLUID_NUM_TYPE:
00180     delete_fluid_num_setting((fluid_num_setting_t*) value);
00181     break;
00182   case FLUID_INT_TYPE:
00183     delete_fluid_int_setting((fluid_int_setting_t*) value);
00184     break;
00185   case FLUID_STR_TYPE:
00186     delete_fluid_str_setting((fluid_str_setting_t*) value);
00187     break;
00188   case FLUID_SET_TYPE:
00189     delete_fluid_hashtable((fluid_hashtable_t*) value);
00190     break;
00191   }
00192 }
00193 
00194 void fluid_settings_init(fluid_settings_t* settings)
00195 {
00196   fluid_synth_settings(settings);
00197   fluid_shell_settings(settings);
00198   fluid_audio_driver_settings(settings);
00199   fluid_midi_driver_settings(settings);
00200 }
00201 
00202 static int fluid_settings_tokenize(char* s, char *buf, char** ptr)
00203 {
00204   char *tokstr, *tok;
00205   int n = 0;
00206 
00207   if (strlen (s) > MAX_SETTINGS_LABEL)
00208   {
00209     FLUID_LOG(FLUID_ERR, "Setting variable name exceeded max length of %d chars",
00210               MAX_SETTINGS_LABEL);
00211     return 0;
00212   }
00213 
00214   FLUID_STRCPY(buf, s); /* copy string to buffer, since it gets modified */
00215   tokstr = buf;
00216 
00217   while ((tok = fluid_strtok (&tokstr, ".")))
00218   {
00219     if (n > MAX_SETTINGS_TOKENS)
00220     {
00221       FLUID_LOG(FLUID_ERR, "Setting variable name exceeded max token count of %d",
00222                 MAX_SETTINGS_TOKENS);
00223       return 0;
00224     }
00225 
00226     ptr[n++] = tok;
00227   }
00228 
00229   return n;
00230 }
00231 
00233 static int fluid_settings_get(fluid_settings_t* settings,
00234                              char** name, int len,
00235                              void** value, int* type)
00236 {
00237   fluid_hashtable_t* table = settings;
00238   int t;
00239   void* v;
00240   int n;
00241 
00242   for (n = 0; n < len; n++) {
00243 
00244     if (table == NULL) {
00245       return 0;
00246     }
00247 
00248     if (!fluid_hashtable_lookup(table, name[n], &v, &t)) {
00249       return 0;
00250     }
00251 
00252     table = (t == FLUID_SET_TYPE)? (fluid_hashtable_t*) v : NULL;
00253   }
00254 
00255   if (value) {
00256     *value = v;
00257   }
00258 
00259   if (type) {
00260     *type = t;
00261   }
00262 
00263   return 1;
00264 }
00265 
00267 static int fluid_settings_set(fluid_settings_t* settings,
00268                              char** name, int len,
00269                              void* value, int type)
00270 {
00271   fluid_hashtable_t* table = settings;
00272   int t;
00273   void* v;
00274   int n, num = len - 1;
00275 
00276   for (n = 0; n < num; n++) {
00277 
00278     if (fluid_hashtable_lookup(table, name[n], &v, &t)) {
00279 
00280       if (t == FLUID_SET_TYPE) {
00281         table = (fluid_hashtable_t*) v;
00282       } else {
00283         /* path ends prematurely */
00284         FLUID_LOG(FLUID_WARN, "'%s' is not a node", name[n]);
00285         return 0;
00286       }
00287 
00288     } else {
00289       /* create a new node */
00290       fluid_hashtable_t* tmp;
00291       tmp = new_fluid_hashtable(fluid_settings_hash_delete);
00292       fluid_hashtable_insert(table, name[n], tmp, FLUID_SET_TYPE);
00293       table = tmp;
00294     }
00295   }
00296 
00297   fluid_hashtable_replace(table, name[num], value, type);
00298 
00299   return 1;
00300 }
00301 
00304 int fluid_settings_register_str(fluid_settings_t* settings, char* name, char* def, int hints,
00305                                fluid_str_update_t fun, void* data)
00306 {
00307   int type;
00308   void* value;
00309   char* tokens[MAX_SETTINGS_TOKENS];
00310   char buf[MAX_SETTINGS_LABEL+1];
00311   int ntokens;
00312   fluid_str_setting_t* setting;
00313 
00314   ntokens = fluid_settings_tokenize(name, buf, tokens);
00315 
00316   if (!fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00317     setting = new_fluid_str_setting(def, def, hints, fun, data);
00318     return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_STR_TYPE);
00319 
00320   } else {
00321     /* if variable already exists, don't change its value. */
00322     if (type == FLUID_STR_TYPE) {
00323       setting = (fluid_str_setting_t*) value;
00324       setting->update = fun;
00325       setting->data = data;
00326       setting->def = def? FLUID_STRDUP(def) : NULL;
00327       setting->hints = hints;
00328       return 1;
00329     } else {
00330       FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name);
00331       return 1;
00332     }
00333   }
00334 }
00335 
00338 int fluid_settings_register_num(fluid_settings_t* settings, char* name, double def,
00339                                double min, double max, int hints,
00340                                fluid_num_update_t fun, void* data)
00341 {
00342   int type;
00343   void* value;
00344   char* tokens[MAX_SETTINGS_TOKENS];
00345   char buf[MAX_SETTINGS_LABEL+1];
00346   int ntokens;
00347 
00348   ntokens = fluid_settings_tokenize(name, buf, tokens);
00349 
00350   if (!fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00351     /* insert a new setting */
00352     fluid_num_setting_t* setting;
00353     setting = new_fluid_num_setting(min, max, def, hints, fun, data);
00354     return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_NUM_TYPE);
00355 
00356   } else {
00357     if (type == FLUID_NUM_TYPE) {
00358       /* update the existing setting but don't change its value */
00359       fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00360       setting->update = fun;
00361       setting->data = data;
00362       setting->min = min;
00363       setting->max = max;
00364       setting->def = def;
00365       setting->hints = hints;
00366       return 1;
00367 
00368     } else {
00369       /* type mismatch */
00370       FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name);
00371       return 0;
00372     }
00373   }
00374 }
00375 
00378 int fluid_settings_register_int(fluid_settings_t* settings, char* name, int def,
00379                                int min, int max, int hints,
00380                                fluid_int_update_t fun, void* data)
00381 {
00382   int type;
00383   void* value;
00384   char* tokens[MAX_SETTINGS_TOKENS];
00385   char buf[MAX_SETTINGS_LABEL+1];
00386   int ntokens;
00387 
00388   ntokens = fluid_settings_tokenize(name, buf, tokens);
00389 
00390   if (!fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00391     /* insert a new setting */
00392     fluid_int_setting_t* setting;
00393     setting = new_fluid_int_setting(min, max, def, hints, fun, data);
00394     return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_INT_TYPE);
00395 
00396   } else {
00397     if (type == FLUID_INT_TYPE) {
00398       /* update the existing setting but don't change its value */
00399       fluid_int_setting_t* setting = (fluid_int_setting_t*) value;
00400       setting->update = fun;
00401       setting->data = data;
00402       setting->min = min;
00403       setting->max = max;
00404       setting->def = def;
00405       setting->hints = hints;
00406       return 1;
00407 
00408     } else {
00409       /* type mismatch */
00410       FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name);
00411       return 0;
00412     }
00413   }
00414 }
00415 
00416 int fluid_settings_get_type(fluid_settings_t* settings, char* name)
00417 {
00418   int type;
00419   void* value;
00420   char* tokens[MAX_SETTINGS_TOKENS];
00421   char buf[MAX_SETTINGS_LABEL+1];
00422   int ntokens;
00423 
00424   ntokens = fluid_settings_tokenize(name, buf, tokens);
00425 
00426   return (fluid_settings_get(settings, tokens, ntokens, &value, &type))? type : FLUID_NO_TYPE;
00427 }
00428 
00429 int fluid_settings_get_hints(fluid_settings_t* settings, char* name)
00430 {
00431   int type;
00432   void* value;
00433   char* tokens[MAX_SETTINGS_TOKENS];
00434   char buf[MAX_SETTINGS_LABEL+1];
00435   int ntokens;
00436 
00437   ntokens = fluid_settings_tokenize(name, buf, tokens);
00438 
00439   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00440     if (type == FLUID_NUM_TYPE) {
00441       fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00442       return setting->hints;
00443     } else if (type == FLUID_STR_TYPE) {
00444       fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00445       return setting->hints;
00446     } else {
00447       return 0;
00448     }
00449   } else {
00450     return 0;
00451   }
00452 }
00453 
00454 int fluid_settings_is_realtime(fluid_settings_t* settings, char* name)
00455 {
00456   int type;
00457   void* value;
00458   char* tokens[MAX_SETTINGS_TOKENS];
00459   char buf[MAX_SETTINGS_LABEL+1];
00460   int ntokens;
00461 
00462   ntokens = fluid_settings_tokenize(name, buf, tokens);
00463 
00464   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00465     if (type == FLUID_NUM_TYPE) {
00466       fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00467       return setting->update != NULL;
00468 
00469     } else if (type == FLUID_STR_TYPE) {
00470       fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00471       return setting->update != NULL;
00472     } else {
00473       return 0;
00474     }
00475   } else {
00476     return 0;
00477   }
00478 }
00479 
00480 int fluid_settings_setstr(fluid_settings_t* settings, char* name, char* str)
00481 {
00482   char* tokens[MAX_SETTINGS_TOKENS];
00483   char buf[MAX_SETTINGS_LABEL+1];
00484   int ntokens;
00485   int type;
00486   void* value;
00487   fluid_str_setting_t* setting;
00488 
00489   ntokens = fluid_settings_tokenize(name, buf, tokens);
00490 
00491   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00492 
00493     if (type != FLUID_STR_TYPE) {
00494       return 0;
00495     }
00496 
00497     setting = (fluid_str_setting_t*) value;
00498 
00499     if (setting->value) {
00500       FLUID_FREE(setting->value);
00501     }
00502     setting->value = str? FLUID_STRDUP(str) : NULL;
00503 
00504     if (setting->update) {
00505       (*setting->update)(setting->data, name, setting->value);
00506     }
00507 
00508     return 1;
00509 
00510   } else {
00511     /* insert a new setting */
00512     fluid_str_setting_t* setting;
00513     setting = new_fluid_str_setting(str, NULL, 0, NULL, NULL);
00514     return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_STR_TYPE);
00515   }
00516 }
00517 
00518 int fluid_settings_getstr(fluid_settings_t* settings, char* name, char** str)
00519 {
00520   int type;
00521   void* value;
00522   char* tokens[MAX_SETTINGS_TOKENS];
00523   char buf[MAX_SETTINGS_LABEL+1];
00524   int ntokens;
00525 
00526   ntokens = fluid_settings_tokenize(name, buf, tokens);
00527 
00528   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00529       && (type == FLUID_STR_TYPE)) {
00530     fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00531     *str = setting->value;
00532     return 1;
00533   }
00534   *str = NULL;
00535   return 0;
00536 }
00537 
00538 int fluid_settings_str_equal(fluid_settings_t* settings, char* name, char* s)
00539 {
00540   int type;
00541   void* value;
00542   char* tokens[MAX_SETTINGS_TOKENS];
00543   char buf[MAX_SETTINGS_LABEL+1];
00544   int ntokens;
00545 
00546   ntokens = fluid_settings_tokenize(name, buf, tokens);
00547 
00548   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00549       && (type == FLUID_STR_TYPE)) {
00550     fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00551     return FLUID_STRCMP(setting->value, s) == 0;
00552   }
00553   return 0;
00554 }
00555 
00556 char*
00557 fluid_settings_getstr_default(fluid_settings_t* settings, char* name)
00558 {
00559   int type;
00560   void* value;
00561   char* tokens[MAX_SETTINGS_TOKENS];
00562   char buf[MAX_SETTINGS_LABEL+1];
00563   int ntokens;
00564 
00565   ntokens = fluid_settings_tokenize(name, buf, tokens);
00566 
00567   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00568       && (type == FLUID_STR_TYPE)) {
00569     fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00570     return setting->def;
00571   } else {
00572     return NULL;
00573   }
00574 }
00575 
00576 int fluid_settings_add_option(fluid_settings_t* settings, char* name, char* s)
00577 {
00578   int type;
00579   void* value;
00580   char* tokens[MAX_SETTINGS_TOKENS];
00581   char buf[MAX_SETTINGS_LABEL+1];
00582   int ntokens;
00583 
00584   ntokens = fluid_settings_tokenize(name, buf, tokens);
00585 
00586   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00587       && (type == FLUID_STR_TYPE)) {
00588     fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00589     char* copy = FLUID_STRDUP(s);
00590     setting->options = fluid_list_append(setting->options, copy);
00591     return 1;
00592   } else {
00593     return 0;
00594   }
00595 }
00596 
00597 int fluid_settings_remove_option(fluid_settings_t* settings, char* name, char* s)
00598 {
00599   int type;
00600   void* value;
00601   char* tokens[MAX_SETTINGS_TOKENS];
00602   char buf[MAX_SETTINGS_LABEL+1];
00603   int ntokens;
00604 
00605   ntokens = fluid_settings_tokenize(name, buf, tokens);
00606 
00607   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00608       && (type == FLUID_STR_TYPE)) {
00609 
00610     fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00611     fluid_list_t* list = setting->options;
00612 
00613     while (list) {
00614       char* option = (char*) fluid_list_get(list);
00615       if (FLUID_STRCMP(s, option) == 0) {
00616         FLUID_FREE (option);
00617         setting->options = fluid_list_remove_link(setting->options, list);
00618         return 1;
00619       }
00620       list = fluid_list_next(list);
00621     }
00622 
00623     return 0;
00624   } else {
00625     return 0;
00626   }
00627 }
00628 
00629 int fluid_settings_setnum(fluid_settings_t* settings, char* name, double val)
00630 {
00631   int type;
00632   void* value;
00633   fluid_num_setting_t* setting;
00634   char* tokens[MAX_SETTINGS_TOKENS];
00635   char buf[MAX_SETTINGS_LABEL+1];
00636   int ntokens;
00637 
00638   ntokens = fluid_settings_tokenize(name, buf, tokens);
00639 
00640   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00641 
00642     if (type != FLUID_NUM_TYPE) {
00643       return 0;
00644     }
00645 
00646     setting = (fluid_num_setting_t*) value;
00647 
00648     if (val < setting->min) {
00649       val = setting->min;
00650     } else if (val > setting->max) {
00651       val = setting->max;
00652     }
00653 
00654     setting->value = val;
00655 
00656     if (setting->update) {
00657       (*setting->update)(setting->data, name, val);
00658     }
00659 
00660     return 1;
00661 
00662   } else {
00663     /* insert a new setting */
00664     fluid_num_setting_t* setting;
00665     setting = new_fluid_num_setting(-1e10, 1e10, 0.0f, 0, NULL, NULL);
00666     setting->value = val;
00667     return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_NUM_TYPE);
00668   }
00669 }
00670 
00671 int fluid_settings_getnum(fluid_settings_t* settings, char* name, double* val)
00672 {
00673   int type;
00674   void* value;
00675   char* tokens[MAX_SETTINGS_TOKENS];
00676   char buf[MAX_SETTINGS_LABEL+1];
00677   int ntokens;
00678 
00679   ntokens = fluid_settings_tokenize(name, buf, tokens);
00680 
00681   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00682       && (type == FLUID_NUM_TYPE)) {
00683     fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00684     *val = setting->value;
00685     return 1;
00686   }
00687   return 0;
00688 }
00689 
00690 
00691 void fluid_settings_getnum_range(fluid_settings_t* settings, char* name, double* min, double* max)
00692 {
00693   int type;
00694   void* value;
00695   char* tokens[MAX_SETTINGS_TOKENS];
00696   char buf[MAX_SETTINGS_LABEL+1];
00697   int ntokens;
00698 
00699   ntokens = fluid_settings_tokenize(name, buf, tokens);
00700 
00701   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00702       && (type == FLUID_NUM_TYPE)) {
00703     fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00704     *min = setting->min;
00705     *max = setting->max;
00706   }
00707 }
00708 
00709 double
00710 fluid_settings_getnum_default(fluid_settings_t* settings, char* name)
00711 {
00712   int type;
00713   void* value;
00714   char* tokens[MAX_SETTINGS_TOKENS];
00715   char buf[MAX_SETTINGS_LABEL+1];
00716   int ntokens;
00717 
00718   ntokens = fluid_settings_tokenize(name, buf, tokens);
00719 
00720   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00721       && (type == FLUID_NUM_TYPE)) {
00722     fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00723     return setting->def;
00724   } else {
00725     return 0.0f;
00726   }
00727 }
00728 
00729 
00730 int fluid_settings_setint(fluid_settings_t* settings, char* name, int val)
00731 {
00732   int type;
00733   void* value;
00734   fluid_int_setting_t* setting;
00735   char* tokens[MAX_SETTINGS_TOKENS];
00736   char buf[MAX_SETTINGS_LABEL+1];
00737   int ntokens;
00738 
00739   ntokens = fluid_settings_tokenize(name, buf, tokens);
00740 
00741   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00742 
00743     if (type != FLUID_INT_TYPE) {
00744       return 0;
00745     }
00746 
00747     setting = (fluid_int_setting_t*) value;
00748 
00749     if (val < setting->min) {
00750       val = setting->min;
00751     } else if (val > setting->max) {
00752       val = setting->max;
00753     }
00754 
00755     setting->value = val;
00756 
00757     if (setting->update) {
00758       (*setting->update)(setting->data, name, val);
00759     }
00760 
00761     return 1;
00762 
00763   } else {
00764     /* insert a new setting */
00765     fluid_int_setting_t* setting;
00766     setting = new_fluid_int_setting(INT_MIN, INT_MAX, 0, 0, NULL, NULL);
00767     setting->value = val;
00768     return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_INT_TYPE);
00769   }
00770 }
00771 
00772 int fluid_settings_getint(fluid_settings_t* settings, char* name, int* val)
00773 {
00774   int type;
00775   void* value;
00776   char* tokens[MAX_SETTINGS_TOKENS];
00777   char buf[MAX_SETTINGS_LABEL+1];
00778   int ntokens;
00779 
00780   ntokens = fluid_settings_tokenize(name, buf, tokens);
00781 
00782   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00783       && (type == FLUID_INT_TYPE)) {
00784     fluid_int_setting_t* setting = (fluid_int_setting_t*) value;
00785     *val = setting->value;
00786     return 1;
00787   }
00788   return 0;
00789 }
00790 
00791 
00792 void fluid_settings_getint_range(fluid_settings_t* settings, char* name, int* min, int* max)
00793 {
00794   int type;
00795   void* value;
00796   char* tokens[MAX_SETTINGS_TOKENS];
00797   char buf[MAX_SETTINGS_LABEL+1];
00798   int ntokens;
00799 
00800   ntokens = fluid_settings_tokenize(name, buf, tokens);
00801 
00802   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00803       && (type == FLUID_INT_TYPE)) {
00804     fluid_int_setting_t* setting = (fluid_int_setting_t*) value;
00805     *min = setting->min;
00806     *max = setting->max;
00807   }
00808 }
00809 
00810 int
00811 fluid_settings_getint_default(fluid_settings_t* settings, char* name)
00812 {
00813   int type;
00814   void* value;
00815   char* tokens[MAX_SETTINGS_TOKENS];
00816   char buf[MAX_SETTINGS_LABEL+1];
00817   int ntokens;
00818 
00819   ntokens = fluid_settings_tokenize(name, buf, tokens);
00820 
00821   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00822       && (type == FLUID_INT_TYPE)) {
00823     fluid_int_setting_t* setting = (fluid_int_setting_t*) value;
00824     return setting->def;
00825   } else {
00826     return 0.0f;
00827   }
00828 }
00829 
00830 
00831 
00832 
00833 void fluid_settings_foreach_option(fluid_settings_t* settings, char* name, void* data,
00834                                   fluid_settings_foreach_option_t func)
00835 {
00836   int type;
00837   void* value;
00838   char* tokens[MAX_SETTINGS_TOKENS];
00839   char buf[MAX_SETTINGS_LABEL+1];
00840   int ntokens;
00841 
00842   if (!func) {
00843     return;
00844   }
00845 
00846   ntokens = fluid_settings_tokenize(name, buf, tokens);
00847 
00848   if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00849       && (type == FLUID_STR_TYPE)) {
00850 
00851     fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00852     fluid_list_t* list = setting->options;
00853 
00854     while (list) {
00855       char* option = (char*) fluid_list_get(list);
00856       (*func)(data, name, option);
00857       list = fluid_list_next(list);
00858     }
00859   }
00860 }
00861 
00862 
00863 static fluid_settings_foreach_t fluid_settings_foreach_func;
00864 static void* fluid_settings_foreach_data;
00865 
00866 int fluid_settings_foreach_iter(char* key, void* value, int type, void* data)
00867 {
00868   char path[1024];
00869 
00870   if (data == 0) {
00871     snprintf(path, 1024, "%s", key);
00872   } else {
00873     snprintf(path, 1024, "%s.%s", (char*) data, key);
00874   }
00875   path[1023] = 0;
00876 
00877   switch (type) {
00878   case FLUID_NUM_TYPE:
00879   case FLUID_INT_TYPE:
00880   case FLUID_STR_TYPE:
00881     (*fluid_settings_foreach_func)(fluid_settings_foreach_data, path, type);
00882     break;
00883   case FLUID_SET_TYPE:
00884     fluid_hashtable_foreach((fluid_hashtable_t*) value, fluid_settings_foreach_iter, &path[0]);
00885     break;
00886   }
00887 
00888   return 0;
00889 }
00890 
00891 void fluid_settings_foreach(fluid_settings_t* settings, void* data, fluid_settings_foreach_t func)
00892 {
00893   fluid_settings_foreach_func = func;
00894   fluid_settings_foreach_data = data;
00895   fluid_hashtable_foreach(settings, fluid_settings_foreach_iter, 0);
00896 }

Generated on Sat Nov 17 13:40:23 2007 for libfluidsynth by  doxygen 1.5.3