void fluid_rvoice_event_dispatch(fluid_rvoice_event_t* event) { EVENTFUNC_PTR(fluid_rvoice_mixer_add_voice, fluid_rvoice_mixer_t*, fluid_rvoice_t*); EVENTFUNC_I1(fluid_rvoice_noteoff, fluid_rvoice_t*); EVENTFUNC_0(fluid_rvoice_voiceoff, fluid_rvoice_t*); EVENTFUNC_0(fluid_rvoice_reset, fluid_rvoice_t*); EVENTFUNC_ALL(fluid_adsr_env_set_data, fluid_adsr_env_t*); EVENTFUNC_I1(fluid_lfo_set_delay, fluid_lfo_t*); EVENTFUNC_R1(fluid_lfo_set_incr, fluid_lfo_t*); EVENTFUNC_R1(fluid_iir_filter_set_fres, fluid_iir_filter_t*); EVENTFUNC_R1(fluid_iir_filter_set_q_dB, fluid_iir_filter_t*); EVENTFUNC_IR(fluid_rvoice_buffers_set_mapping, fluid_rvoice_buffers_t*); EVENTFUNC_IR(fluid_rvoice_buffers_set_amp, fluid_rvoice_buffers_t*); EVENTFUNC_R1(fluid_rvoice_set_modenv_to_pitch, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_output_rate, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_root_pitch_hz, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_synth_gain, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_pitch, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_attenuation, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_min_attenuation_cB, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_viblfo_to_pitch, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_modlfo_to_pitch, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_modlfo_to_vol, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_modlfo_to_fc, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_modenv_to_fc, fluid_rvoice_t*); EVENTFUNC_R1(fluid_rvoice_set_modenv_to_pitch, fluid_rvoice_t*); EVENTFUNC_I1(fluid_rvoice_set_interp_method, fluid_rvoice_t*); EVENTFUNC_I1(fluid_rvoice_set_start, fluid_rvoice_t*); EVENTFUNC_I1(fluid_rvoice_set_end, fluid_rvoice_t*); EVENTFUNC_I1(fluid_rvoice_set_loopstart, fluid_rvoice_t*); EVENTFUNC_I1(fluid_rvoice_set_loopend, fluid_rvoice_t*); EVENTFUNC_I1(fluid_rvoice_set_samplemode, fluid_rvoice_t*); EVENTFUNC_PTR(fluid_rvoice_set_sample, fluid_rvoice_t*, fluid_sample_t*); EVENTFUNC_R1(fluid_rvoice_mixer_set_samplerate, fluid_rvoice_mixer_t*); EVENTFUNC_I1(fluid_rvoice_mixer_set_polyphony, fluid_rvoice_mixer_t*); EVENTFUNC_I1(fluid_rvoice_mixer_set_reverb_enabled, fluid_rvoice_mixer_t*); EVENTFUNC_I1(fluid_rvoice_mixer_set_chorus_enabled, fluid_rvoice_mixer_t*); EVENTFUNC_I1(fluid_rvoice_mixer_set_mix_fx, fluid_rvoice_mixer_t*); EVENTFUNC_0(fluid_rvoice_mixer_reset_fx, fluid_rvoice_mixer_t*); EVENTFUNC_0(fluid_rvoice_mixer_reset_reverb, fluid_rvoice_mixer_t*); EVENTFUNC_0(fluid_rvoice_mixer_reset_chorus, fluid_rvoice_mixer_t*); EVENTFUNC_IR(fluid_rvoice_mixer_set_threads, fluid_rvoice_mixer_t*); EVENTFUNC_ALL(fluid_rvoice_mixer_set_chorus_params, fluid_rvoice_mixer_t*); EVENTFUNC_R4(fluid_rvoice_mixer_set_reverb_params, fluid_rvoice_mixer_t*); FLUID_LOG(FLUID_ERR, "fluid_rvoice_event_dispatch: Unknown method %p to dispatch!", event->method); }
void * fluid_sndio_midi_run(void *addr) { int n, i; fluid_midi_event_t* evt; fluid_sndio_midi_driver_t *dev = (fluid_sndio_midi_driver_t *)addr; #define MIDI_BUFLEN (3125 / 10) unsigned char buffer[MIDI_BUFLEN]; /* make sure the other threads can cancel this thread any time */ if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) { FLUID_LOG(FLUID_ERR, "Failed to set the cancel state of the midi thread"); pthread_exit(NULL); } if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { FLUID_LOG(FLUID_ERR, "Failed to set the cancel state of the midi thread"); pthread_exit(NULL); } /* go into a loop until someone tells us to stop */ dev->status = FLUID_MIDI_LISTENING; while (dev->status == FLUID_MIDI_LISTENING) { /* read new data */ n = mio_read(dev->hdl, buffer, MIDI_BUFLEN); if (n == 0 && mio_eof(dev->hdl)) { FLUID_LOG(FLUID_ERR, "Failed to read the midi input"); dev->status = FLUID_MIDI_DONE; } /* let the parser convert the data into events */ for (i = 0; i < n; i++) { evt = fluid_midi_parser_parse(dev->parser, buffer[i]); if (evt != NULL) { /* send the event to the next link in the chain */ (*dev->driver.handler)(dev->driver.data, evt); } } } pthread_exit(NULL); }
void fluid_portaudio_driver_settings (fluid_settings_t *settings) { const PaDeviceInfo *deviceInfo; int numDevices; PaError err; int i; fluid_settings_register_str (settings, "audio.portaudio.device", PORTAUDIO_DEFAULT_DEVICE, 0, NULL, NULL); fluid_settings_add_option (settings, "audio.portaudio.device", PORTAUDIO_DEFAULT_DEVICE); err = Pa_Initialize(); if (err != paNoError) { FLUID_LOG (FLUID_ERR, "Error initializing PortAudio driver: %s", Pa_GetErrorText (err)); return; } numDevices = Pa_GetDeviceCount(); if (numDevices < 0) { FLUID_LOG (FLUID_ERR, "PortAudio returned unexpected device count %d", numDevices); return; } for (i = 0; i < numDevices; i++) { deviceInfo = Pa_GetDeviceInfo (i); if ( deviceInfo->maxOutputChannels >= 2 ) fluid_settings_add_option (settings, "audio.portaudio.device", deviceInfo->name); } /* done with PortAudio for now, may get reopened later */ err = Pa_Terminate(); if (err != paNoError) printf ("PortAudio termination error: %s\n", Pa_GetErrorText (err) ); }
/* * new_fluid_midi_parser */ fluid_midi_parser_t* new_fluid_midi_parser() { fluid_midi_parser_t* parser; parser = FLUID_NEW(fluid_midi_parser_t); if (parser == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } parser->status = 0; /* As long as the status is 0, the parser won't do anything -> no need to initialize all the fields. */ return parser; }
void fluid_profiling_print(void) { int i; printf("fluid_profiling_print\n"); FLUID_LOG(FLUID_INFO, "Estimated times: min/avg/max (micro seconds)"); for (i = 0; i < FLUID_PROF_LAST; i++) { if (fluid_profile_data[i].count > 0) { FLUID_LOG(FLUID_INFO, "%s: %.3f/%.3f/%.3f", fluid_profile_data[i].description, fluid_profile_data[i].min, fluid_profile_data[i].total / fluid_profile_data[i].count, fluid_profile_data[i].max); } else { FLUID_LOG(FLUID_DBG, "%s: no profiling available", fluid_profile_data[i].description); } } }
int fluid_samplecache_load(SFData *sf, unsigned int sample_start, unsigned int sample_end, int sample_type, int try_mlock, short **sample_data, char **sample_data24) { fluid_samplecache_entry_t *entry; int ret; fluid_mutex_lock(samplecache_mutex); entry = get_samplecache_entry(sf, sample_start, sample_end, sample_type); if (entry == NULL) { entry = new_samplecache_entry(sf, sample_start, sample_end, sample_type); if (entry == NULL) { ret = -1; goto unlock_exit; } samplecache_list = fluid_list_prepend(samplecache_list, entry); } if (try_mlock && !entry->mlocked) { /* Lock the memory to disable paging. It's okay if this fails. It * probably means that the user doesn't have the required permission. */ if (fluid_mlock(entry->sample_data, entry->sample_count * sizeof(short)) == 0) { if (entry->sample_data24 != NULL) { entry->mlocked = (fluid_mlock(entry->sample_data24, entry->sample_count) == 0); } else { entry->mlocked = TRUE; } if (!entry->mlocked) { fluid_munlock(entry->sample_data, entry->sample_count * sizeof(short)); FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible."); } } } entry->num_references++; *sample_data = entry->sample_data; *sample_data24 = entry->sample_data24; ret = entry->sample_count; unlock_exit: fluid_mutex_unlock(samplecache_mutex); return ret; }
/* * fluid_midi_file_read */ int fluid_midi_file_read(fluid_midi_file* mf, void* buf, int len) { int num = FLUID_FREAD(buf, 1, len, mf->fp); mf->trackpos += num; #if DEBUG if (num != len) { FLUID_LOG(FLUID_DBG, "Coulnd't read the requested number of bytes"); } #endif return (num != len)? FLUID_FAILED : FLUID_OK; }
/** * Set the tempo of a MIDI player. * @param player MIDI player instance * @param tempo Tempo to set playback speed to (in microseconds per quarter note, as per MIDI file spec) * @return Always returns #FLUID_OK */ int fluid_player_set_midi_tempo(fluid_player_t* player, int tempo) { player->miditempo = tempo; player->deltatime = (double) tempo / player->division / 1000.0; /* in milliseconds */ player->start_msec = player->cur_msec; player->start_ticks = player->cur_ticks; FLUID_LOG(FLUID_DBG,"tempo=%d, tick time=%f msec, cur time=%d msec, cur tick=%d", tempo, player->deltatime, player->cur_msec, player->cur_ticks); return FLUID_OK; }
/** * Create a new thread. * @param func Function to execute in new thread context * @param data User defined data to pass to func * @param prio_level Priority level. If greater than 0 then high priority scheduling will * be used, with the given priority level (used by pthreads only). 0 uses normal scheduling. * @param detach If TRUE, 'join' does not work and the thread destroys itself when finished. * @return New thread pointer or NULL on error */ fluid_thread_t * new_fluid_thread (fluid_thread_func_t func, void *data, int prio_level, int detach) { GThread *thread; fluid_thread_info_t *info; GError *err = NULL; g_return_val_if_fail (func != NULL, NULL); /* Make sure g_thread_init has been called. * FIXME - Probably not a good idea in a shared library, * but what can we do *and* remain backwards compatible? */ if (!g_thread_supported ()) g_thread_init (NULL); if (prio_level > 0) { info = FLUID_NEW (fluid_thread_info_t); if (!info) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } info->func = func; info->data = data; info->prio_level = prio_level; thread = g_thread_create (fluid_thread_high_prio, info, detach == FALSE, &err); } else thread = g_thread_create ((GThreadFunc)func, data, detach == FALSE, &err); if (!thread) { FLUID_LOG(FLUID_ERR, "Failed to create the thread: %s", fluid_gerror_message (err)); g_clear_error (&err); } return thread; }
/* * new_fluid_sndmgr_audio_driver2 * * This implementation used the audio_func float format, with * conversion from float to 16bits in the driver. */ fluid_audio_driver_t* new_fluid_sndmgr_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, void* data) { fluid_sndmgr_audio_driver_t* dev = NULL; int period_size, periods, buffer_size; /* compute buffer size */ fluid_settings_getint(settings, "audio.period-size", &period_size); fluid_settings_getint(settings, "audio.periods", &periods); buffer_size = period_size*periods; /* allocated dev */ dev = FLUID_NEW(fluid_sndmgr_audio_driver_t); if (dev == NULL) { FLUID_LOG(FLUID_PANIC, "Out of memory"); return NULL; } FLUID_MEMSET(dev, 0, sizeof(fluid_sndmgr_audio_driver_t)); /* allocate the conversion buffers */ dev->convbuffers[0] = FLUID_ARRAY(float, buffer_size); dev->convbuffers[1] = FLUID_ARRAY(float, buffer_size); if ((dev->convbuffers[0] == NULL) || (dev->convbuffers[1] == NULL)) { FLUID_LOG(FLUID_PANIC, "Out of memory"); goto error_recovery; } dev->callback_is_audio_func = true; dev->data = data; dev->callback = func; if (start_fluid_sndmgr_audio_driver(settings, dev, buffer_size) != 0) { goto error_recovery; } return (fluid_audio_driver_t*)dev; error_recovery: delete_fluid_sndmgr_audio_driver((fluid_audio_driver_t*)dev); return NULL; }
fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) { fluid_file_audio_driver_t* dev; int msec; dev = FLUID_NEW(fluid_file_audio_driver_t); if (dev == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } FLUID_MEMSET(dev, 0, sizeof(fluid_file_audio_driver_t)); fluid_settings_getint(settings, "audio.period-size", &dev->period_size); fluid_settings_getnum(settings, "synth.sample-rate", &dev->sample_rate); dev->data = synth; dev->callback = (fluid_audio_func_t) fluid_synth_process; dev->samples = 0; dev->renderer = new_fluid_file_renderer(synth); if (dev->renderer == NULL) goto error_recovery; msec = (int) (0.5 + dev->period_size / dev->sample_rate * 1000.0); dev->timer = new_fluid_timer(msec, fluid_file_audio_run_s16, (void*) dev, TRUE, FALSE, TRUE); if (dev->timer == NULL) { FLUID_LOG(FLUID_PANIC, "Couldn't create the audio thread."); goto error_recovery; } return (fluid_audio_driver_t*) dev; error_recovery: delete_fluid_file_audio_driver((fluid_audio_driver_t*) dev); return NULL; }
/* * fluid_hashtable_insert_internal: * @hashtable: our #fluid_hashtable_t * @key: the key to insert * @value: the value to insert * @keep_new_key: if %TRUE and this key already exists in the table * then call the destroy notify function on the old key. If %FALSE * then call the destroy notify function on the new key. * * Implements the common logic for the fluid_hashtable_insert() and * fluid_hashtable_replace() functions. * * Do a lookup of @key. If it is found, replace it with the new * @value (and perhaps the new @key). If it is not found, create a * new node. */ static void fluid_hashtable_insert_internal (fluid_hashtable_t *hashtable, void *key, void *value, int keep_new_key) { fluid_hashnode_t **node_ptr, *node; unsigned int key_hash; fluid_return_if_fail (hashtable != NULL); fluid_return_if_fail (hashtable->ref_count > 0); node_ptr = fluid_hashtable_lookup_node (hashtable, key, &key_hash); if ((node = *node_ptr)) { if (keep_new_key) { if (hashtable->key_destroy_func) hashtable->key_destroy_func (node->key); node->key = key; } else { if (hashtable->key_destroy_func) hashtable->key_destroy_func (key); } if (hashtable->value_destroy_func) hashtable->value_destroy_func (node->value); node->value = value; } else { node = FLUID_NEW (fluid_hashnode_t); if (!node) { FLUID_LOG (FLUID_ERR, "Out of memory"); return; } node->key = key; node->value = value; node->key_hash = key_hash; node->next = NULL; *node_ptr = node; hashtable->nnodes++; fluid_hashtable_maybe_resize (hashtable); } }
/* * fluid_midishare_open_appl */ static int fluid_midishare_open_appl (fluid_midishare_midi_driver_t* dev) { /* register to MidiShare */ #if defined(MACINTOSH) && defined(MACOS9) dev->refnum = MidiOpen(MSHDriverName); if (dev->refnum < 0) { FLUID_LOG(FLUID_ERR, "Can not open MidiShare Driver client"); return 0; } dev->upp_alarm_ptr = NewRcvAlarmPtr(fluid_midishare_midi_driver_receive); dev->upp_task_ptr = NewTaskPtr(fluid_midishare_keyoff_task); MidiSetRcvAlarm(dev->refnum, dev->upp_alarm_ptr); #else dev->refnum = MidiOpen(MSHDriverName); if (dev->refnum < 0) { FLUID_LOG(FLUID_ERR, "Can not open MidiShare Driver client"); return 0; } MidiSetRcvAlarm(dev->refnum, fluid_midishare_midi_driver_receive); MidiConnect(0,dev->refnum,true); #endif return 1; }
/* Duplicate a tuning */ fluid_tuning_t * fluid_tuning_duplicate (fluid_tuning_t *tuning) { fluid_tuning_t *new_tuning; int i; new_tuning = FLUID_NEW (fluid_tuning_t); if (!new_tuning) { FLUID_LOG (FLUID_PANIC, "Out of memory"); return NULL; } if (tuning->name) { new_tuning->name = FLUID_STRDUP (tuning->name); if (!new_tuning->name) { FLUID_FREE (new_tuning); FLUID_LOG (FLUID_PANIC, "Out of memory"); return NULL; } } else new_tuning->name = NULL; new_tuning->bank = tuning->bank; new_tuning->prog = tuning->prog; for (i = 0; i < 128; i++) new_tuning->pitch[i] = tuning->pitch[i]; new_tuning->refcount = 1; /* Start with a refcount of 1 */ return new_tuning; }
/* * fluid_midi_file_skip */ int fluid_midi_file_skip (fluid_midi_file *mf, int skip) { int new_pos = mf->buf_pos + skip; /* Mimic the behaviour of fseek: Error to seek past the start of file, but * OK to seek past end (this just puts it into the EOF state). */ if (new_pos < 0) { FLUID_LOG(FLUID_ERR, "Failed to seek position in file"); return FLUID_FAILED; } /* Clear the EOF flag, even if moved past the end of the file (this is * consistent with the behaviour of fseek). */ mf->eof = FALSE; mf->buf_pos = new_pos; return FLUID_OK; }
/* * fluid_player_callback */ int fluid_player_callback(void *data, unsigned int msec) { int i; int loadnextfile; int status = FLUID_PLAYER_DONE; fluid_player_t *player; fluid_synth_t *synth; player = (fluid_player_t *) data; synth = player->synth; loadnextfile = player->currentfile == NULL ? 1 : 0; do { if (loadnextfile) { loadnextfile = 0; fluid_player_playlist_load(player, msec); if (player->currentfile == NULL) { return 0; } } player->cur_msec = msec; player->cur_ticks = (player->start_ticks + (int) ((double) (player->cur_msec - player->start_msec) / player->deltatime)); for (i = 0; i < player->ntracks; i++) { if (!fluid_track_eot(player->track[i])) { status = FLUID_PLAYER_PLAYING; if (fluid_track_send_events(player->track[i], synth, player, player->cur_ticks) != FLUID_OK) { /* */ } } } if (status == FLUID_PLAYER_DONE) { FLUID_LOG(FLUID_DBG, "%s: %d: Duration=%.3f sec", __FILE__, __LINE__, (msec - player->begin_msec) / 1000.0); loadnextfile = 1; } } while (loadnextfile); player->status = status; return 1; }
int fluid_samplecache_unload(const short *sample_data) { fluid_list_t *entry_list; fluid_samplecache_entry_t *entry; int ret; fluid_mutex_lock(samplecache_mutex); entry_list = samplecache_list; while (entry_list) { entry = (fluid_samplecache_entry_t *)fluid_list_get(entry_list); if (sample_data == entry->sample_data) { entry->num_references--; if (entry->num_references == 0) { if (entry->mlocked) { fluid_munlock(entry->sample_data, entry->sample_count * sizeof(short)); if (entry->sample_data24 != NULL) { fluid_munlock(entry->sample_data24, entry->sample_count); } } samplecache_list = fluid_list_remove(samplecache_list, entry); delete_samplecache_entry(entry); } ret = FLUID_OK; goto unlock_exit; } entry_list = fluid_list_next(entry_list); } FLUID_LOG(FLUID_ERR, "Trying to free sample data not found in cache."); ret = FLUID_FAILED; unlock_exit: fluid_mutex_unlock(samplecache_mutex); return ret; }
/** * Create a MIDI event structure. * @return New MIDI event structure or NULL when out of memory. */ fluid_midi_event_t* new_fluid_midi_event() { fluid_midi_event_t* evt; evt = FLUID_NEW(fluid_midi_event_t); if (evt == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } evt->dtime = 0; evt->type = 0; evt->channel = 0; evt->param1 = 0; evt->param2 = 0; evt->next = NULL; evt->paramptr = NULL; return evt; }
/** * 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; }
/** returns 1 if the value has been register correctly, zero otherwise. */ int fluid_settings_register_int(fluid_settings_t* settings, char* name, int def, int min, int max, int hints, fluid_int_update_t fun, void* data) { fluid_setting_node_t *node; int retval; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); /* For now, all integer settings are bounded below and above */ hints |= FLUID_HINT_BOUNDED_BELOW | FLUID_HINT_BOUNDED_ABOVE; fluid_rec_mutex_lock (settings->mutex); if (!fluid_settings_get(settings, name, &node)) { /* insert a new setting */ fluid_int_setting_t* setting; setting = new_fluid_int_setting(min, max, def, hints, fun, data); retval = fluid_settings_set(settings, name, setting); if (retval != 1) delete_fluid_int_setting (setting); } else { if (node->type == FLUID_INT_TYPE) { /* update the existing setting but don't change its value */ fluid_int_setting_t* setting = (fluid_int_setting_t*) node; setting->update = fun; setting->data = data; setting->min = min; setting->max = max; setting->def = def; setting->hints = hints; retval = 1; } else { /* type mismatch */ FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name); retval = 0; } } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/* * fluid_track_set_name */ int fluid_track_set_name(fluid_track_t* track, char* name) { int len; if (track->name != NULL) { FLUID_FREE(track->name); } if (name == NULL) { track->name = NULL; return FLUID_OK; } len = FLUID_STRLEN(name); track->name = FLUID_MALLOC(len + 1); if (track->name == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return FLUID_FAILED; } FLUID_STRCPY(track->name, name); 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; }
/* * new_fluid_channel */ fluid_channel_t* new_fluid_channel(fluid_synth_t* synth, int num) { fluid_channel_t* chan; chan = FLUID_NEW(fluid_channel_t); if (chan == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } chan->synth = synth; chan->channum = num; chan->preset = NULL; fluid_channel_init(chan); fluid_channel_init_ctrl(chan); return chan; }
BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { FLUID_LOG(FLUID_DBG, "DllMain"); switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: fluid_refCount++; if (1 == fluid_refCount) { fluid_set_hinstance((void*) hModule); fluid_win32_create_window(); } break; case DLL_PROCESS_DETACH: fluid_refCount--; if (fluid_refCount == 0) { fluid_win32_destroy_window(); } break; } return TRUE; }
/* * fluid_sndio_audio_run */ void* fluid_sndio_audio_run(void* d) { fluid_sndio_audio_driver_t* dev = (fluid_sndio_audio_driver_t*) d; fluid_synth_t* synth = dev->synth; void* buffer = dev->buffer; int len = dev->buffer_size; /* it's as simple as that: */ while (dev->cont) { dev->read (synth, len, buffer, 0, 2, buffer, 1, 2); sio_write (dev->hdl, buffer, dev->buffer_byte_size); } FLUID_LOG(FLUID_DBG, "Audio thread finished"); pthread_exit(NULL); return 0; /* not reached */ }
/* Purpose: * Checks, if the floating point unit has produced an exception, print a message * if so and clear the exception. */ unsigned int fluid_check_fpe_i386(char* explanation) { unsigned int s; _FPU_GET_SW(s); _FPU_CLR_SW(); s &= _FPU_STATUS_IE | _FPU_STATUS_DE | _FPU_STATUS_ZE | _FPU_STATUS_OE | _FPU_STATUS_UE; if (s) { FLUID_LOG(FLUID_WARN, "FPE exception (before or in %s): %s%s%s%s%s", explanation, (s & _FPU_STATUS_IE) ? "Invalid operation " : "", (s & _FPU_STATUS_DE) ? "Denormal number " : "", (s & _FPU_STATUS_ZE) ? "Zero divide " : "", (s & _FPU_STATUS_OE) ? "Overflow " : "", (s & _FPU_STATUS_UE) ? "Underflow " : ""); } return s; }
/** * Create a new midi router. The default rules will pass all events unmodified. * @param settings Settings used to configure MIDI router * @param handler MIDI event callback. * @param event_handler_data Caller defined data pointer which gets passed to 'handler' * @return New MIDI router instance or NULL on error * * The MIDI handler callback should process the possibly filtered/modified MIDI * events from the MIDI router and forward them on to a synthesizer for example. * The function fluid_synth_handle_midi_event() can be used for \a handle and * a #fluid_synth_t passed as the \a event_handler_data parameter for this purpose. */ fluid_midi_router_t * new_fluid_midi_router(fluid_settings_t *settings, handle_midi_event_func_t handler, void *event_handler_data) { fluid_midi_router_t *router = NULL; int i; router = FLUID_NEW (fluid_midi_router_t); if (router == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } FLUID_MEMSET (router, 0, sizeof (fluid_midi_router_t)); /* Retrieve the number of MIDI channels for range limiting */ fluid_settings_getint(settings, "synth.midi-channels", &router->nr_midi_channels); fluid_mutex_init (router->rules_mutex); router->synth = (fluid_synth_t *)event_handler_data; router->event_handler = handler; router->event_handler_data = event_handler_data; /* Create default routing rules which pass all events unmodified */ for (i = 0; i < FLUID_MIDI_ROUTER_RULE_COUNT; i++) { router->rules[i] = new_fluid_midi_router_rule (); if (!router->rules[i]) goto error_recovery; } return router; error_recovery: delete_fluid_midi_router (router); return NULL; }
static fluid_str_setting_t* new_fluid_str_setting(const char* value, char* def, int hints, fluid_str_update_t fun, void* data) { fluid_str_setting_t* str; str = FLUID_NEW(fluid_str_setting_t); if (!str) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } str->node.type = FLUID_STR_TYPE; str->value = value? FLUID_STRDUP(value) : NULL; str->def = def? FLUID_STRDUP(def) : NULL; str->hints = hints; str->options = NULL; str->update = fun; str->data = data; return str; }
/* * fluid_hashtable_resize: * @hashtable: our #fluid_hashtable_t * * Resizes the hash table to the optimal size based on the number of * nodes currently held. If you call this function then a resize will * occur, even if one does not need to occur. Use * fluid_hashtable_maybe_resize() instead. */ static void fluid_hashtable_resize (fluid_hashtable_t *hashtable) { fluid_hashnode_t **new_nodes; fluid_hashnode_t *node; fluid_hashnode_t *next; unsigned int hash_val; int new_size; int i; new_size = spaced_primes_closest (hashtable->nnodes); new_size = (new_size < HASH_TABLE_MIN_SIZE) ? HASH_TABLE_MIN_SIZE : ((new_size > HASH_TABLE_MAX_SIZE) ? HASH_TABLE_MAX_SIZE : new_size); new_nodes = FLUID_ARRAY (fluid_hashnode_t *, new_size); if (!new_nodes) { FLUID_LOG (FLUID_ERR, "Out of memory"); return; } FLUID_MEMSET (new_nodes, 0, new_size * sizeof (fluid_hashnode_t *)); for (i = 0; i < hashtable->size; i++) for (node = hashtable->nodes[i]; node; node = next) { next = node->next; hash_val = node->key_hash % new_size; node->next = new_nodes[hash_val]; new_nodes[hash_val] = node; } FLUID_FREE (hashtable->nodes); hashtable->nodes = new_nodes; hashtable->size = new_size; }
/** * Create a new thread. * @param func Function to execute in new thread context * @param data User defined data to pass to func * @param prio_level Priority level. If greater than 0 then high priority scheduling will * be used, with the given priority level (used by pthreads only). 0 uses normal scheduling. * @param detach If TRUE, 'join' does not work and the thread destroys itself when finished. * @return New thread pointer or NULL on error */ fluid_thread_t * new_fluid_thread (const char *name, fluid_thread_func_t func, void *data, int prio_level, int detach) { GThread *thread; fluid_thread_info_t *info; GError *err = NULL; g_return_val_if_fail (func != NULL, NULL); #if OLD_GLIB_THREAD_API /* Make sure g_thread_init has been called. * FIXME - Probably not a good idea in a shared library, * but what can we do *and* remain backwards compatible? */ if (!g_thread_supported ()) g_thread_init (NULL); #endif if (prio_level > 0) { info = FLUID_NEW (fluid_thread_info_t); if (!info) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } info->func = func; info->data = data; info->prio_level = prio_level; #if NEW_GLIB_THREAD_API thread = g_thread_try_new (name, fluid_thread_high_prio, info, &err); #else thread = g_thread_create (fluid_thread_high_prio, info, detach == FALSE, &err); #endif } #if NEW_GLIB_THREAD_API else thread = g_thread_try_new (name, (GThreadFunc)func, data, &err); #else else thread = g_thread_create ((GThreadFunc)func, data, detach == FALSE, &err);