/** * Register a sequencer client. * @param seq Sequencer object * @param name Name of sequencer client * @param callback Sequencer client callback or NULL for a source client. * @param data User data to pass to the \a callback * @return Unique sequencer ID or #FLUID_FAILED on error * * Clients can be sources or destinations of events. Sources don't need to * register a callback. */ short fluid_sequencer_register_client (fluid_sequencer_t* seq, const char *name, fluid_event_callback_t callback, void* data) { fluid_sequencer_client_t * client; char * nameCopy; client = FLUID_NEW(fluid_sequencer_client_t); if (client == NULL) { fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); return FLUID_FAILED; } nameCopy = FLUID_STRDUP(name); if (nameCopy == NULL) { fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); FLUID_FREE(client); return FLUID_FAILED; } seq->clientsID++; client->name = nameCopy; client->id = seq->clientsID; client->callback = callback; client->data = data; seq->clients = fluid_list_append(seq->clients, (void *)client); return (client->id); }
/** * Add a MIDI file to a player queue. * @param player MIDI player instance * @param midifile File name of the MIDI file to add * @return #FLUID_OK */ int fluid_player_add(fluid_player_t* player, const char* midifile) { char *s = FLUID_STRDUP(midifile); player->playlist = fluid_list_append(player->playlist, s); return FLUID_OK; }
/** * Add an option to a string setting (like an enumeration value). * @param settings a settings object * @param name a setting's name * @param s option string to add * @return 1 if the setting exists and option was added, 0 otherwise * * Causes the setting's #FLUID_HINT_OPTIONLIST hint to be set. */ int fluid_settings_add_option(fluid_settings_t* settings, const char *name, const char *s) { fluid_setting_node_t *node; int retval = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_return_val_if_fail (s != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node) && (node->type == FLUID_STR_TYPE)) { fluid_str_setting_t* setting = (fluid_str_setting_t*) node; char* copy = FLUID_STRDUP(s); setting->options = fluid_list_append(setting->options, copy); setting->hints |= FLUID_HINT_OPTIONLIST; retval = 1; } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * Add a MIDI file to a player queue. * @param player MIDI player instance * @param midifile File name of the MIDI file to add * @return #FLUID_OK or #FLUID_FAILED */ int fluid_player_add(fluid_player_t *player, const char *midifile) { fluid_playlist_item *pi = FLUID_MALLOC(sizeof(fluid_playlist_item)); char* f = FLUID_STRDUP(midifile); if (!pi || !f) { FLUID_FREE(pi); FLUID_FREE(f); FLUID_LOG(FLUID_PANIC, "Out of memory"); return FLUID_FAILED; } pi->filename = f; pi->buffer = NULL; pi->buffer_len = 0; player->playlist = fluid_list_append(player->playlist, pi); return FLUID_OK; }
/** * Add a MIDI file to a player queue, from a buffer in memory. * @param player MIDI player instance * @param buffer Pointer to memory containing the bytes of a complete MIDI * file. The data is copied, so the caller may free or modify it immediately * without affecting the playlist. * @param len Length of the buffer, in bytes. * @return #FLUID_OK or #FLUID_FAILED */ int fluid_player_add_mem(fluid_player_t* player, const void *buffer, size_t len) { /* Take a copy of the buffer, so the caller can free immediately. */ fluid_playlist_item *pi = FLUID_MALLOC(sizeof(fluid_playlist_item)); void *buf_copy = FLUID_MALLOC(len); if (!pi || !buf_copy) { FLUID_FREE(pi); FLUID_FREE(buf_copy); FLUID_LOG(FLUID_PANIC, "Out of memory"); return FLUID_FAILED; } FLUID_MEMCPY(buf_copy, buffer, len); pi->filename = NULL; pi->buffer = buf_copy; pi->buffer_len = len; player->playlist = fluid_list_append(player->playlist, pi); return FLUID_OK; }
static int fluid_settings_foreach_iter (void* key, void* value, void* data) { fluid_settings_foreach_bag_t *bag = data; char *keystr = key; fluid_setting_node_t *node = value; int pathlen; char *s; pathlen = strlen (bag->path); if (pathlen > 0) { bag->path[pathlen] = '.'; bag->path[pathlen + 1] = 0; } strcat (bag->path, keystr); switch (node->type) { case FLUID_NUM_TYPE: case FLUID_INT_TYPE: case FLUID_STR_TYPE: s = FLUID_STRDUP (bag->path); if (s) bag->names = fluid_list_append (bag->names, s); break; case FLUID_SET_TYPE: fluid_hashtable_foreach(((fluid_set_setting_t *)value)->hashtable, fluid_settings_foreach_iter, bag); break; } bag->path[pathlen] = 0; return 0; }
/** * Iterate the available options for a named string setting, calling the provided * callback function for each existing option. * * @param settings a settings object * @param name a setting's name * @param data any user provided pointer * @param func callback function to be called on each iteration * * NOTE: Starting with FluidSynth 1.1.0 the \a func callback is called for each * option in alphabetical order. Sort order was undefined in previous versions. */ void fluid_settings_foreach_option (fluid_settings_t* settings, const char *name, void* data, fluid_settings_foreach_option_t func) { fluid_setting_node_t *node; fluid_str_setting_t *setting; fluid_list_t *p, *newlist = NULL; fluid_return_if_fail (settings != NULL); fluid_return_if_fail (name != NULL); fluid_return_if_fail (func != NULL); fluid_rec_mutex_lock (settings->mutex); /* ++ lock */ if (!fluid_settings_get (settings, name, &node) || node->type != FLUID_STR_TYPE) { fluid_rec_mutex_unlock (settings->mutex); /* -- unlock */ return; } setting = (fluid_str_setting_t*)node; /* Duplicate option list */ for (p = setting->options; p; p = p->next) newlist = fluid_list_append (newlist, fluid_list_get (p)); /* Sort by name */ newlist = fluid_list_sort (newlist, fluid_list_str_compare_func); for (p = newlist; p; p = p->next) (*func)(data, (char *)name, (char *)fluid_list_get (p)); fluid_rec_mutex_unlock (settings->mutex); /* -- unlock */ delete_fluid_list (newlist); }
/** * Concatenate options for a string setting together with a separator between. * @param settings Settings object * @param name Settings name * @param separator String to use between options (NULL to use ", ") * @return Newly allocated string or NULL on error (out of memory, not a valid * setting \a name or not a string setting). Free the string when finished with it. * @since 1.1.0 */ char * fluid_settings_option_concat (fluid_settings_t *settings, const char *name, const char *separator) { fluid_setting_node_t *node; fluid_str_setting_t *setting; fluid_list_t *p, *newlist = NULL; int count, len; char *str, *option; fluid_return_val_if_fail (settings != NULL, NULL); fluid_return_val_if_fail (name != NULL, NULL); if (!separator) separator = ", "; fluid_rec_mutex_lock (settings->mutex); /* ++ lock */ if (!fluid_settings_get (settings, name, &node) || node->type != FLUID_STR_TYPE) { fluid_rec_mutex_unlock (settings->mutex); /* -- unlock */ return (NULL); } setting = (fluid_str_setting_t*)node; /* Duplicate option list, count options and get total string length */ for (p = setting->options, count = 0, len = 0; p; p = p->next, count++) { option = fluid_list_get (p); if (option) { newlist = fluid_list_append (newlist, option); len += strlen (option); } } if (count > 1) len += (count - 1) * strlen (separator); len++; /* For terminator */ /* Sort by name */ newlist = fluid_list_sort (newlist, fluid_list_str_compare_func); str = FLUID_MALLOC (len); str[0] = 0; if (str) { for (p = newlist; p; p = p->next) { option = fluid_list_get (p); strcat (str, option); if (p->next) strcat (str, separator); } } fluid_rec_mutex_unlock (settings->mutex); /* -- unlock */ delete_fluid_list (newlist); if (!str) FLUID_LOG (FLUID_ERR, "Out of memory"); return (str); }