/** * Free a sequencer object. * @param seq Sequencer to delete */ void delete_fluid_sequencer (fluid_sequencer_t* seq) { if (seq == NULL) { return; } /* cleanup clients */ while (seq->clients) { fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)seq->clients->data; fluid_sequencer_unregister_client(seq, client->id); } _fluid_seq_queue_end(seq); /* if (seq->clients) { fluid_list_t *tmp = seq->clients; while (tmp != NULL) { fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data; if (client->name) FLUID_FREE(client->name); tmp = tmp->next; } delete_fluid_list(seq->clients); seq->clients = NULL; }*/ #if FLUID_SEQ_WITH_TRACE if (seq->tracebuf != NULL) FLUID_FREE(seq->tracebuf); seq->tracebuf = NULL; #endif FLUID_FREE(seq); }
void _fluid_evt_heap_free(fluid_evt_heap_t* heap) { #ifdef HEAP_WITH_DYNALLOC fluid_evt_entry *tmp, *next; /* LOCK */ fluid_mutex_lock(heap->mutex); tmp = heap->freelist; while (tmp) { next = tmp->next; FLUID_FREE(tmp); tmp = next; } /* UNLOCK */ fluid_mutex_unlock(heap->mutex); fluid_mutex_destroy(heap->mutex); FLUID_FREE(heap); #else FLUID_FREE(heap); #endif }
/** * Open a MIDI file and return a new MIDI file handle. * @internal * @param filename Path of file to open. * @return New MIDI file handle or NULL on error. */ fluid_midi_file* new_fluid_midi_file(char* filename) { fluid_midi_file* mf; mf = FLUID_NEW(fluid_midi_file); if (mf == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } FLUID_MEMSET(mf, 0, sizeof(fluid_midi_file)); mf->c = -1; mf->running_status = -1; mf->fp = FLUID_FOPEN(filename, "rb"); if (mf->fp == NULL) { FLUID_LOG(FLUID_ERR, "Couldn't open the MIDI file"); FLUID_FREE(mf); return NULL; } if (fluid_midi_file_read_mthd(mf) != FLUID_OK) { FLUID_FREE(mf); return NULL; } return mf; }
void delete_fluid_dsound_audio_driver(fluid_audio_driver_t* d) { fluid_dsound_audio_driver_t* dev = (fluid_dsound_audio_driver_t*) d; fluid_return_if_fail(dev != NULL); /* tell the audio thread to stop its loop */ dev->cont = 0; /* wait till the audio thread exits */ if (dev->thread != 0) { if (WaitForSingleObject(dev->thread, 2000) != WAIT_OBJECT_0) { /* on error kill the thread mercilessly */ FLUID_LOG(FLUID_DBG, "Couldn't join the audio thread. killing it."); TerminateThread(dev->thread, 0); } } /* release all the allocated ressources */ FLUID_FREE(dev->format); if (dev->sec_buffer != NULL) { IDirectSoundBuffer_Stop(dev->sec_buffer); IDirectSoundBuffer_Release(dev->sec_buffer); } if (dev->prim_buffer != NULL) { IDirectSoundBuffer_Release(dev->prim_buffer); } if (dev->direct_sound != NULL) { IDirectSound_Release(dev->direct_sound); } FLUID_FREE(dev); }
/* * delete_fluid_portaudio_driver */ int delete_fluid_portaudio_driver(fluid_audio_driver_t *p) { fluid_portaudio_driver_t* dev; PaError err; dev = (fluid_portaudio_driver_t*)p; if (dev == NULL) return FLUID_OK; /* PortAudio section */ if (dev->stream) Pa_CloseStream (dev->stream); err = Pa_Terminate(); if (err != paNoError) printf ("PortAudio termination error: %s\n", Pa_GetErrorText (err) ); if (dev->buffers[0]) { FLUID_FREE(dev->buffers[0]); } if (dev->buffers[1]) { FLUID_FREE(dev->buffers[1]); } FLUID_FREE (dev); return FLUID_OK; }
/** * Delete a MIDI player instance. * @param player MIDI player instance * @return Always returns #FLUID_OK */ int delete_fluid_player(fluid_player_t *player) { fluid_list_t *q; fluid_playlist_item* pi; if (player == NULL) { return FLUID_OK; } fluid_player_stop(player); fluid_player_reset(player); while (player->playlist != NULL) { q = player->playlist->next; pi = (fluid_playlist_item*) player->playlist->data; FLUID_FREE(pi->filename); FLUID_FREE(pi->buffer); FLUID_FREE(pi); delete1_fluid_list(player->playlist); player->playlist = q; } FLUID_FREE(player); return FLUID_OK; }
static void delete_samplecache_entry(fluid_samplecache_entry_t *entry) { fluid_return_if_fail(entry != NULL); FLUID_FREE(entry->filename); FLUID_FREE(entry->sample_data); FLUID_FREE(entry->sample_data24); FLUID_FREE(entry); }
void delete_fluid_tuning(fluid_tuning_t* tuning) { if (tuning == NULL) { return; } if (tuning->name != NULL) { FLUID_FREE(tuning->name); } FLUID_FREE(tuning); }
/* * delete_fluid_track */ int delete_fluid_track(fluid_track_t* track) { if (track->name != NULL) { FLUID_FREE(track->name); } if (track->first != NULL) { delete_fluid_midi_event(track->first); } FLUID_FREE(track); return FLUID_OK; }
/** * fluid_hashtable_unref: * @hashtable: a valid #fluid_hashtable_t. * * Atomically decrements the reference count of @hashtable by one. * If the reference count drops to 0, all keys and values will be * destroyed, and all memory allocated by the hash table is released. * This function is MT-safe and may be called from any thread. * * Since: 2.10 **/ void fluid_hashtable_unref (fluid_hashtable_t *hashtable) { fluid_return_if_fail (hashtable != NULL); fluid_return_if_fail (hashtable->ref_count > 0); if (fluid_atomic_int_exchange_and_add (&hashtable->ref_count, -1) - 1 == 0) { fluid_hashtable_remove_all_nodes (hashtable, TRUE); FLUID_FREE (hashtable->nodes); FLUID_FREE (hashtable); } }
/* * delete_fluid_midishare_midi_driver */ int delete_fluid_midishare_midi_driver(fluid_midi_driver_t* p) { fluid_midishare_midi_driver_t* dev; dev = (fluid_midishare_midi_driver_t*) p; if (dev == NULL) { return FLUID_OK; } if (dev->filter) MidiFreeFilter(dev->filter); #if defined(MIDISHARE_DRIVER) fluid_midishare_close_driver(dev); #else fluid_midishare_close_appl(dev); #endif #if defined(MACINTOSH) && defined(MACOS9) DisposeRoutineDescriptor(dev->upp_alarm_ptr); DisposeRoutineDescriptor(dev->upp_wakeup_ptr); DisposeRoutineDescriptor(dev->upp_sleep_ptr); DisposeRoutineDescriptor(dev->upp_task_ptr); #endif dev->status = FLUID_MIDI_DONE; FLUID_FREE(dev); return FLUID_OK; }
/** * Remove an option previously assigned by fluid_settings_add_option(). * @param settings a settings object * @param name a setting's name * @param s option string to remove * @return 1 if the setting exists and option was removed, 0 otherwise */ int fluid_settings_remove_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; fluid_list_t* list = setting->options; while (list) { char* option = (char*) fluid_list_get(list); if (FLUID_STRCMP(s, option) == 0) { FLUID_FREE (option); setting->options = fluid_list_remove_link(setting->options, list); retval = 1; break; } list = fluid_list_next(list); } } fluid_rec_mutex_unlock (settings->mutex); return retval; }
int delete_fluid_dart_audio_driver(fluid_audio_driver_t* p) { fluid_dart_audio_driver_t* dev = (fluid_dart_audio_driver_t*) p; if (dev == NULL) { return FLUID_OK; } if (dev->usDeviceID != 0) { MCI_GENERIC_PARMS GenericParms; /* Send message to stop the audio device */ m_pfnmciSendCommand(dev->usDeviceID, MCI_STOP, MCI_WAIT, (PVOID)&GenericParms, 0); /* Deallocate device buffers */ m_pfnmciSendCommand(dev->usDeviceID, MCI_BUFFER, MCI_WAIT | MCI_DEALLOCATE_MEMORY, (PVOID)&dev->BufferParms, 0); /* Close device the mixer device */ m_pfnmciSendCommand(dev->usDeviceID, MCI_CLOSE, MCI_WAIT, (PVOID)&GenericParms, 0); } FLUID_FREE(dev); return FLUID_OK; }
fluid_timer_t* new_fluid_timer (int msec, fluid_timer_callback_t callback, void* data, int new_thread, int auto_destroy, int high_priority) { fluid_timer_t *timer; timer = FLUID_NEW (fluid_timer_t); if (timer == NULL) { FLUID_LOG (FLUID_ERR, "Out of memory"); return NULL; } timer->msec = msec; timer->callback = callback; timer->data = data; timer->cont = TRUE ; timer->thread = NULL; timer->auto_destroy = auto_destroy; if (new_thread) { timer->thread = new_fluid_thread ("timer", fluid_timer_run, timer, high_priority ? FLUID_SYS_TIMER_HIGH_PRIO_LEVEL : 0, FALSE); if (!timer->thread) { FLUID_FREE (timer); return NULL; } } else fluid_timer_run (timer); /* Run directly, instead of as a separate thread */ return timer; }
void fluid_timer_run (void *data) { fluid_timer_t *timer; int count = 0; int cont; long start; long delay; timer = (fluid_timer_t *)data; /* keep track of the start time for absolute positioning */ start = fluid_curtime (); while (timer->cont) { cont = (*timer->callback)(timer->data, fluid_curtime() - start); count++; if (!cont) break; /* to avoid incremental time errors, calculate the delay between two callbacks bringing in the "absolute" time (count * timer->msec) */ delay = (count * timer->msec) - (fluid_curtime() - start); if (delay > 0) fluid_usleep (delay * 1000); } FLUID_LOG (FLUID_DBG, "Timer thread finished"); if (timer->auto_destroy) FLUID_FREE (timer); return; }
/** * Iterate the existing settings defined in a settings object, calling the * provided callback function for each setting. * * @param settings a settings object * @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 * setting in alphabetical order. Sort order was undefined in previous versions. */ void fluid_settings_foreach (fluid_settings_t* settings, void* data, fluid_settings_foreach_t func) { fluid_settings_foreach_bag_t bag; fluid_setting_node_t *node; fluid_list_t *p; int r; fluid_return_if_fail (settings != NULL); fluid_return_if_fail (func != NULL); bag.path[0] = 0; bag.names = NULL; fluid_rec_mutex_lock (settings->mutex); /* Add all node names to the bag.names list */ fluid_hashtable_foreach (settings, fluid_settings_foreach_iter, &bag); /* Sort names */ bag.names = fluid_list_sort (bag.names, fluid_list_str_compare_func); /* Loop over names and call the callback */ for (p = bag.names; p; p = p->next) { r = fluid_settings_get (settings, (char *)(p->data), &node); if (r && node) (*func) (data, (char *)(p->data), node->type); FLUID_FREE (p->data); /* -- Free name */ } fluid_rec_mutex_unlock (settings->mutex); delete_fluid_list (bag.names); /* -- Free names list */ }
static fluid_set_setting_t* new_fluid_set_setting(void) { fluid_set_setting_t* setting; setting = FLUID_NEW(fluid_set_setting_t); if (!setting) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } setting->node.type = FLUID_SET_TYPE; setting->hashtable = new_fluid_hashtable_full(fluid_str_hash, fluid_str_equal, fluid_settings_key_destroy_func, fluid_settings_value_destroy_func); if (!setting->hashtable) { FLUID_FREE (setting); return NULL; } return setting; }
/* * delete_fluid_channel */ int delete_fluid_channel(fluid_channel_t* chan) { if (chan->preset) delete_fluid_preset (chan->preset); FLUID_FREE(chan); return FLUID_OK; }
/** * Set a setting name, value and type, replacing it if already exists * * @param settings a settings object * @param name Settings name * @param value Node instance to assign (used directly) * @return 1 if the value has been set, zero otherwise */ static int fluid_settings_set(fluid_settings_t* settings, const char *name, void* value) { fluid_hashtable_t* table = settings; fluid_setting_node_t *node; char* tokens[MAX_SETTINGS_TOKENS]; char buf[MAX_SETTINGS_LABEL+1]; int n, num; char *dupname; num = fluid_settings_tokenize (name, buf, tokens) - 1; for (n = 0; n < num; n++) { node = fluid_hashtable_lookup(table, tokens[n]); if (node) { if (node->type == FLUID_SET_TYPE) { table = ((fluid_set_setting_t *)node)->hashtable; } else { /* path ends prematurely */ FLUID_LOG(FLUID_WARN, "'%s' is not a node", name[n]); return 0; } } else { /* create a new node */ fluid_set_setting_t* setnode; dupname = FLUID_STRDUP (tokens[n]); setnode = new_fluid_set_setting (); if (!dupname || !setnode) { if (dupname) FLUID_FREE (dupname); else FLUID_LOG(FLUID_ERR, "Out of memory"); if (setnode) delete_fluid_set_setting (setnode); return 0; } fluid_hashtable_insert(table, dupname, setnode); table = setnode->hashtable; } } dupname = FLUID_STRDUP (tokens[num]); if (!dupname) { FLUID_LOG(FLUID_ERR, "Out of memory"); return 0; } fluid_hashtable_insert(table, dupname, value); return 1; }
void delete_fluid_sndio_midi_driver(fluid_midi_driver_t *addr) { int err; fluid_sndio_midi_driver_t *dev = (fluid_sndio_midi_driver_t *)addr; if (dev == NULL) { return; } dev->status = FLUID_MIDI_DONE; /* cancel the thread and wait for it before cleaning up */ if (dev->thread) { err = pthread_cancel(dev->thread); if (err) { FLUID_LOG(FLUID_ERR, "Failed to cancel the midi thread"); return; } if (pthread_join(dev->thread, NULL)) { FLUID_LOG(FLUID_ERR, "Failed to join the midi thread"); return; } } if (dev->hdl != NULL) { mio_close(dev->hdl); } if (dev->parser != NULL) { delete_fluid_midi_parser(dev->parser); } FLUID_FREE(dev); return; }
/** * Add a rule to a MIDI router. * @param router MIDI router * @param rule Rule to add (used directly and should not be accessed again following a * successful call to this function). * @param type The type of rule to add (#fluid_midi_router_rule_type) * @return #FLUID_OK on success, #FLUID_FAILED otherwise (invalid rule for example) * @since 1.1.0 */ int fluid_midi_router_add_rule (fluid_midi_router_t *router, fluid_midi_router_rule_t *rule, int type) { fluid_midi_router_rule_t *free_rules, *next_rule; fluid_return_val_if_fail (router != NULL, FLUID_FAILED); fluid_return_val_if_fail (rule != NULL, FLUID_FAILED); fluid_return_val_if_fail (type >= 0 && type < FLUID_MIDI_ROUTER_RULE_COUNT, FLUID_FAILED); fluid_mutex_lock (router->rules_mutex); /* ++ lock */ /* Take over free rules list, if any (to free outside of lock) */ free_rules = router->free_rules; router->free_rules = NULL; rule->next = router->rules[type]; router->rules[type] = rule; fluid_mutex_unlock (router->rules_mutex); /* -- unlock */ /* Free any deactivated rules which were waiting for events and are now done */ for (; free_rules; free_rules = next_rule) { next_rule = free_rules->next; FLUID_FREE (free_rules); } return FLUID_OK; }
/** * 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); }
static char* fluid_file_read_full(fluid_file fp, size_t* length) { size_t buflen; char* buffer; size_t n; /* Work out the length of the file in advance */ if (FLUID_FSEEK(fp, 0, SEEK_END) != 0) { FLUID_LOG(FLUID_ERR, "File load: Could not seek within file"); return NULL; } buflen = ftell(fp); if (FLUID_FSEEK(fp, 0, SEEK_SET) != 0) { FLUID_LOG(FLUID_ERR, "File load: Could not seek within file"); return NULL; } FLUID_LOG(FLUID_DBG, "File load: Allocating %d bytes", buflen); buffer = FLUID_MALLOC(buflen); if (buffer == NULL) { FLUID_LOG(FLUID_PANIC, "Out of memory"); return NULL; } n = FLUID_FREAD(buffer, 1, buflen, fp); if (n != buflen) { FLUID_LOG(FLUID_ERR, "Only read %d bytes; expected %d", n, buflen); FLUID_FREE(buffer); return NULL; }; *length = n; return buffer; }
/** * Return a new MIDI file handle for parsing an already-loaded MIDI file. * @internal * @param buffer Pointer to full contents of MIDI file (borrows the pointer). * The caller must not free buffer until after the fluid_midi_file is deleted. * @param length Size of the buffer in bytes. * @return New MIDI file handle or NULL on error. */ fluid_midi_file * new_fluid_midi_file(const char* buffer, size_t length) { fluid_midi_file *mf; mf = FLUID_NEW(fluid_midi_file); if (mf == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } FLUID_MEMSET(mf, 0, sizeof(fluid_midi_file)); mf->c = -1; mf->running_status = -1; mf->buffer = buffer; mf->buf_len = length; mf->buf_pos = 0; mf->eof = FALSE; if (fluid_midi_file_read_mthd(mf) != FLUID_OK) { FLUID_FREE(mf); return NULL; } return mf; }
/** * Delete MIDI event structure. * @param evt MIDI event structure * @return Always returns #FLUID_OK */ int delete_fluid_midi_event(fluid_midi_event_t *evt) { fluid_midi_event_t *temp; while (evt) { temp = evt->next; /* Dynamic SYSEX event? - free (param2 indicates if dynamic) */ if (evt->type == MIDI_SYSEX && evt->paramptr && evt->param2) FLUID_FREE (evt->paramptr); FLUID_FREE(evt); evt = temp; } return FLUID_OK; }
/* Only called by delete_fluid_synth(), so no need to queue a preset free event */ void delete_fluid_channel(fluid_channel_t* chan) { fluid_return_if_fail(chan != NULL); fluid_preset_delete_internal (chan->preset); FLUID_FREE(chan); }
void delete_fluid_rvoice_eventhandler(fluid_rvoice_eventhandler_t* handler) { if (handler == NULL) return; delete_fluid_rvoice_mixer(handler->mixer); delete_fluid_ringbuffer(handler->queue); delete_fluid_ringbuffer(handler->finished_voices); FLUID_FREE(handler); }
static void delete_fluid_set_setting(fluid_set_setting_t* setting) { if (setting) { delete_fluid_hashtable(setting->hashtable); FLUID_FREE(setting); } }
/** * 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; }
/** * Delete a MIDI file handle. * @internal * @param mf MIDI file handle to close and free. */ void delete_fluid_midi_file (fluid_midi_file *mf) { if (mf == NULL) { return; } FLUID_FREE(mf); return; }