summaryrefslogtreecommitdiff
path: root/libs/fluidsynth/src/fluid_rvoice_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/fluidsynth/src/fluid_rvoice_event.c')
-rw-r--r--libs/fluidsynth/src/fluid_rvoice_event.c364
1 files changed, 135 insertions, 229 deletions
diff --git a/libs/fluidsynth/src/fluid_rvoice_event.c b/libs/fluidsynth/src/fluid_rvoice_event.c
index 65edb9dacb..4a513778bd 100644
--- a/libs/fluidsynth/src/fluid_rvoice_event.c
+++ b/libs/fluidsynth/src/fluid_rvoice_event.c
@@ -3,16 +3,16 @@
* Copyright (C) 2003 Peter Hanappe and others.
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License
- * as published by the Free Software Foundation; either version 2 of
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
@@ -25,242 +25,144 @@
#include "fluid_lfo.h"
#include "fluid_adsr_env.h"
-#define EVENTFUNC_0(proc, type) \
- if (event->method == proc) { \
- proc((type) event->object); \
- return; }
-
-#define EVENTFUNC_R1(proc, type) \
- if (event->method == proc) { \
- if(event->intparam != 0) { FLUID_LOG(FLUID_DBG, "IR-mismatch"); } \
- proc((type) event->object, event->realparams[0]); \
- return; }
-
-#define EVENTFUNC_PTR(proc, type, type2) \
- if (event->method == proc) { \
- proc((type) event->object, (type2) event->ptr); \
- return; }
-
-#define EVENTFUNC_I1(proc, type) \
- if (event->method == proc) { \
- if(event->realparams[0] != 0.0f) { FLUID_LOG(FLUID_DBG, "IR-mismatch"); } \
- proc((type) event->object, event->intparam); \
- return; }
-
-#define EVENTFUNC_IR(proc, type) \
- if (event->method == proc) { \
- proc((type) event->object, event->intparam, event->realparams[0]); \
- return; }
-
-#define EVENTFUNC_ALL(proc, type) \
- if (event->method == proc) { \
- proc((type) event->object, event->intparam, event->realparams[0], \
- event->realparams[1], event->realparams[2], event->realparams[3], \
- event->realparams[4]); \
- return; }
-
-#define EVENTFUNC_R4(proc, type) \
- if (event->method == proc) { \
- proc((type) event->object, event->intparam, event->realparams[0], \
- event->realparams[1], event->realparams[2], event->realparams[3]); \
- return; }
+static int fluid_rvoice_eventhandler_push_LOCAL(fluid_rvoice_eventhandler_t *handler, const fluid_rvoice_event_t *src_event);
-void
-fluid_rvoice_event_dispatch(fluid_rvoice_event_t* event)
+static FLUID_INLINE 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);
+ event->method(event->object, event->param);
}
/**
* In order to be able to push more than one event atomically,
- * use push for all events, then use flush to commit them to the
+ * use push for all events, then use flush to commit them to the
* queue. If threadsafe is false, all events are processed immediately. */
int
-fluid_rvoice_eventhandler_push(fluid_rvoice_eventhandler_t* handler,
- void* method, void* object, int intparam,
- fluid_real_t realparam)
+fluid_rvoice_eventhandler_push_int_real(fluid_rvoice_eventhandler_t *handler,
+ fluid_rvoice_function_t method, void *object, int intparam,
+ fluid_real_t realparam)
{
- fluid_rvoice_event_t* event;
- fluid_rvoice_event_t local_event;
- event = handler->is_threadsafe ?
- fluid_ringbuffer_get_inptr(handler->queue, handler->queue_stored) : &local_event;
-
- if (event == NULL) {
- FLUID_LOG(FLUID_WARN, "Ringbuffer full, try increasing polyphony!");
- return FLUID_FAILED; // Buffer full...
- }
-
- event->method = method;
- event->object = object;
- event->intparam = intparam;
- event->realparams[0] = realparam;
- if (handler->is_threadsafe)
- handler->queue_stored++;
- else
- fluid_rvoice_event_dispatch(event);
- return FLUID_OK;
-}
+ fluid_rvoice_event_t local_event;
+ local_event.method = method;
+ local_event.object = object;
+ local_event.param[0].i = intparam;
+ local_event.param[1].real = realparam;
-int
-fluid_rvoice_eventhandler_push_ptr(fluid_rvoice_eventhandler_t* handler,
- void* method, void* object, void* ptr)
+ return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event);
+}
+
+int
+fluid_rvoice_eventhandler_push(fluid_rvoice_eventhandler_t *handler, fluid_rvoice_function_t method, void *object, fluid_rvoice_param_t param[MAX_EVENT_PARAMS])
{
- fluid_rvoice_event_t* event;
- fluid_rvoice_event_t local_event;
- event = handler->is_threadsafe ?
- fluid_ringbuffer_get_inptr(handler->queue, handler->queue_stored) : &local_event;
-
- if (event == NULL) {
- FLUID_LOG(FLUID_WARN, "Ringbuffer full, try increasing polyphony!");
- return FLUID_FAILED; // Buffer full...
- }
-
- event->method = method;
- event->object = object;
- event->ptr = ptr;
- if (handler->is_threadsafe)
- handler->queue_stored++;
- else
- fluid_rvoice_event_dispatch(event);
- return FLUID_OK;
+ fluid_rvoice_event_t local_event;
+
+ local_event.method = method;
+ local_event.object = object;
+ FLUID_MEMCPY(&local_event.param, param, sizeof(*param) * MAX_EVENT_PARAMS);
+
+ return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event);
}
+int
+fluid_rvoice_eventhandler_push_ptr(fluid_rvoice_eventhandler_t *handler,
+ fluid_rvoice_function_t method, void *object, void *ptr)
+{
+ fluid_rvoice_event_t local_event;
+
+ local_event.method = method;
+ local_event.object = object;
+ local_event.param[0].ptr = ptr;
-int
-fluid_rvoice_eventhandler_push5(fluid_rvoice_eventhandler_t* handler,
- void* method, void* object, int intparam,
- fluid_real_t r1, fluid_real_t r2,
- fluid_real_t r3, fluid_real_t r4, fluid_real_t r5)
+ return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event);
+}
+
+static int fluid_rvoice_eventhandler_push_LOCAL(fluid_rvoice_eventhandler_t *handler, const fluid_rvoice_event_t *src_event)
{
- fluid_rvoice_event_t* event;
- fluid_rvoice_event_t local_event;
- event = handler->is_threadsafe ?
- fluid_ringbuffer_get_inptr(handler->queue, handler->queue_stored) : &local_event;
-
- if (event == NULL) {
- FLUID_LOG(FLUID_WARN, "Ringbuffer full, try increasing polyphony!");
- return FLUID_FAILED; // Buffer full...
- }
-
- event->method = method;
- event->object = object;
- event->intparam = intparam;
- event->realparams[0] = r1;
- event->realparams[1] = r2;
- event->realparams[2] = r3;
- event->realparams[3] = r4;
- event->realparams[4] = r5;
- if (handler->is_threadsafe)
- handler->queue_stored++;
- else
- fluid_rvoice_event_dispatch(event);
- return FLUID_OK;
+ fluid_rvoice_event_t *event;
+ int old_queue_stored = fluid_atomic_int_add(&handler->queue_stored, 1);
+
+ event = fluid_ringbuffer_get_inptr(handler->queue, old_queue_stored);
+
+ if(event == NULL)
+ {
+ fluid_atomic_int_add(&handler->queue_stored, -1);
+ FLUID_LOG(FLUID_WARN, "Ringbuffer full, try increasing polyphony!");
+ return FLUID_FAILED; // Buffer full...
+ }
+
+ FLUID_MEMCPY(event, src_event, sizeof(*event));
+
+ return FLUID_OK;
}
-static void
-finished_voice_callback(void* userdata, fluid_rvoice_t* rvoice)
+void
+fluid_rvoice_eventhandler_finished_voice_callback(fluid_rvoice_eventhandler_t *eventhandler, fluid_rvoice_t *rvoice)
{
- fluid_rvoice_eventhandler_t* eventhandler = userdata;
- fluid_rvoice_t** vptr = fluid_ringbuffer_get_inptr(eventhandler->finished_voices, 0);
- if (vptr == NULL)
- return; // Buffer full
- *vptr = rvoice;
- fluid_ringbuffer_next_inptr(eventhandler->finished_voices, 1);
+ fluid_rvoice_t **vptr = fluid_ringbuffer_get_inptr(eventhandler->finished_voices, 0);
+
+ if(vptr == NULL)
+ {
+ return; // Buffer full
+ }
+
+ *vptr = rvoice;
+ fluid_ringbuffer_next_inptr(eventhandler->finished_voices, 1);
}
-fluid_rvoice_eventhandler_t*
-new_fluid_rvoice_eventhandler(int is_threadsafe, int queuesize,
- int finished_voices_size, int bufs, int fx_bufs, fluid_real_t sample_rate)
+fluid_rvoice_eventhandler_t *
+new_fluid_rvoice_eventhandler(int queuesize,
+ int finished_voices_size, int bufs, int fx_bufs, int fx_units, fluid_real_t sample_rate, int extra_threads, int prio)
{
- fluid_rvoice_eventhandler_t* eventhandler = FLUID_NEW(fluid_rvoice_eventhandler_t);
- if (eventhandler == NULL) {
- FLUID_LOG(FLUID_ERR, "Out of memory");
- return NULL;
- }
- eventhandler->mixer = NULL;
- eventhandler->queue = NULL;
- eventhandler->finished_voices = NULL;
- eventhandler->is_threadsafe = is_threadsafe;
- eventhandler->queue_stored = 0;
-
- eventhandler->finished_voices = new_fluid_ringbuffer(finished_voices_size,
- sizeof(fluid_rvoice_t*));
- if (eventhandler->finished_voices == NULL)
- goto error_recovery;
-
- eventhandler->queue = new_fluid_ringbuffer(queuesize, sizeof(fluid_rvoice_event_t));
- if (eventhandler->queue == NULL)
- goto error_recovery;
-
- eventhandler->mixer = new_fluid_rvoice_mixer(bufs, fx_bufs, sample_rate);
- if (eventhandler->mixer == NULL)
- goto error_recovery;
- fluid_rvoice_mixer_set_finished_voices_callback(eventhandler->mixer,
- finished_voice_callback, eventhandler);
- return eventhandler;
-
+ fluid_rvoice_eventhandler_t *eventhandler = FLUID_NEW(fluid_rvoice_eventhandler_t);
+
+ if(eventhandler == NULL)
+ {
+ FLUID_LOG(FLUID_ERR, "Out of memory");
+ return NULL;
+ }
+
+ eventhandler->mixer = NULL;
+ eventhandler->queue = NULL;
+ eventhandler->finished_voices = NULL;
+
+ fluid_atomic_int_set(&eventhandler->queue_stored, 0);
+
+ eventhandler->finished_voices = new_fluid_ringbuffer(finished_voices_size,
+ sizeof(fluid_rvoice_t *));
+
+ if(eventhandler->finished_voices == NULL)
+ {
+ goto error_recovery;
+ }
+
+ eventhandler->queue = new_fluid_ringbuffer(queuesize, sizeof(fluid_rvoice_event_t));
+
+ if(eventhandler->queue == NULL)
+ {
+ goto error_recovery;
+ }
+
+ eventhandler->mixer = new_fluid_rvoice_mixer(bufs, fx_bufs, fx_units, sample_rate, eventhandler, extra_threads, prio);
+
+ if(eventhandler->mixer == NULL)
+ {
+ goto error_recovery;
+ }
+
+ return eventhandler;
+
error_recovery:
- delete_fluid_rvoice_eventhandler(eventhandler);
- return NULL;
+ delete_fluid_rvoice_eventhandler(eventhandler);
+ return NULL;
}
-int
-fluid_rvoice_eventhandler_dispatch_count(fluid_rvoice_eventhandler_t* handler)
+int
+fluid_rvoice_eventhandler_dispatch_count(fluid_rvoice_eventhandler_t *handler)
{
- return fluid_ringbuffer_get_count(handler->queue);
+ return fluid_ringbuffer_get_count(handler->queue);
}
@@ -268,26 +170,30 @@ fluid_rvoice_eventhandler_dispatch_count(fluid_rvoice_eventhandler_t* handler)
* Call fluid_rvoice_event_dispatch for all events in queue
* @return number of events dispatched
*/
-int
-fluid_rvoice_eventhandler_dispatch_all(fluid_rvoice_eventhandler_t* handler)
+int
+fluid_rvoice_eventhandler_dispatch_all(fluid_rvoice_eventhandler_t *handler)
{
- fluid_rvoice_event_t* event;
- int result = 0;
- while (NULL != (event = fluid_ringbuffer_get_outptr(handler->queue))) {
- fluid_rvoice_event_dispatch(event);
- result++;
- fluid_ringbuffer_next_outptr(handler->queue);
- }
- return result;
+ fluid_rvoice_event_t *event;
+ int result = 0;
+
+ while(NULL != (event = fluid_ringbuffer_get_outptr(handler->queue)))
+ {
+ fluid_rvoice_event_dispatch(event);
+ result++;
+ fluid_ringbuffer_next_outptr(handler->queue);
+ }
+
+ return result;
}
-void
-delete_fluid_rvoice_eventhandler(fluid_rvoice_eventhandler_t* handler)
+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);
+ fluid_return_if_fail(handler != NULL);
+
+ delete_fluid_rvoice_mixer(handler->mixer);
+ delete_fluid_ringbuffer(handler->queue);
+ delete_fluid_ringbuffer(handler->finished_voices);
+ FLUID_FREE(handler);
}