Beispiel #1
0
/* Create event_entry and append to the preQueue.
 * May be called from the main thread (usually) but also recursively
 * from the queue thread, when a callback itself does an insert... */
static void
_fluid_seq_queue_pre_remove(fluid_sequencer_t* seq, short src, short dest, int type)
{
	fluid_evt_entry * evtentry = _fluid_seq_heap_get_free(seq->heap);
	if (evtentry == NULL) {
		/* should not happen */
		fluid_log(FLUID_PANIC, "sequencer: no more free events\n");
		return;
	}

	evtentry->next = NULL;
	evtentry->entryType = FLUID_EVT_ENTRY_REMOVE;
	{
		fluid_event_t* evt = &(evtentry->evt);
		fluid_event_set_source(evt, src);
		fluid_event_set_source(evt, src);
		fluid_event_set_dest(evt, dest);
		evt->type = type;
	}

	fluid_mutex_lock(seq->mutex);

	/* append to preQueue */
	if (seq->preQueueLast) {
		seq->preQueueLast->next = evtentry;
	} else {
		seq->preQueue = evtentry;
	}
	seq->preQueueLast = evtentry;

	fluid_mutex_unlock(seq->mutex);
	return;
}
/* schedule a timer event (shall trigger the callback) */
void
schedule_timer_event ()
{
    fluid_event_t *ev = new_fluid_event ();
    fluid_event_set_source (ev, -1);
    fluid_event_set_dest (ev, client_destination);
    fluid_event_timer (ev, NULL);
    fluid_sequencer_send_at (sequencer, ev, time_marker, 1);
    delete_fluid_event (ev);
}
/* schedule a note on message */
void
schedule_noteon (int chan, short key, unsigned int ticks)
{
    fluid_event_t *ev = new_fluid_event ();
    fluid_event_set_source (ev, -1);
    fluid_event_set_dest (ev, synth_destination);
    fluid_event_noteon (ev, chan, key, 127);
    fluid_sequencer_send_at (sequencer, ev, ticks, 1);
    delete_fluid_event (ev);
}
Beispiel #4
0
static void sendpitchbend(Data *data, int chan, int pitch, int time)
{
  int fluid_res;

  fluid_event_clear(data->event);
  fluid_event_set_source(data->event, -1);
  fluid_event_set_dest(data->event, data->synth_seq_ID);
  fluid_event_pitch_bend(data->event, chan, pitch);
  fluid_res = fluid_sequencer_send_at(data->sequencer, data->event, get_fluidsynth_time(data,time), 1);
  
  if(fluid_res==FLUID_FAILED)
    printf("Unable to send pitchbend\n");
}
Beispiel #5
0
static void sendcontrolchange(Data *data, int chan, int cc, int val, int time)
{
  int fluid_res;

  fluid_event_clear(data->event);
  fluid_event_set_source(data->event, -1);
  fluid_event_set_dest(data->event, data->synth_seq_ID);
  fluid_event_control_change(data->event, chan, cc, val);
  fluid_res = fluid_sequencer_send_at(data->sequencer, data->event, get_fluidsynth_time(data,time), 1);
  
  if(fluid_res==FLUID_FAILED)
    printf("Unable to send controlchange\n");
}
Beispiel #6
0
static void sendnoteoff(Data *data, int chan, short key, int velocity, unsigned int time) 
{
  int fluid_res;

  if(velocity>127) // not supported by fluidsynth
    velocity=127;

  fluid_event_clear(data->event);
  fluid_event_set_source(data->event, -1);
  fluid_event_set_dest(data->event, data->synth_seq_ID);
  fluid_event_noteoff(data->event, chan, key);
  fluid_res = fluid_sequencer_send_at(data->sequencer, data->event, get_fluidsynth_time(data,time), 1);
  
  if(fluid_res==FLUID_FAILED)
    printf("Unable to send noteOFF %d (vel: %d) at time %d. Time now: %d\n",key,velocity,time,(int)data->time);
}
Beispiel #7
0
/**
 * Transforms an incoming midi event (from a midi driver or midi router) to a 
 * sequencer event and adds it to the sequencer queue for sending as soon as possible.
 * @param data The sequencer, must be a valid #fluid_sequencer_t
 * @param event MIDI event
 * @return #FLUID_OK or #FLUID_FAILED
 * @since 1.1.0
 */
int
fluid_sequencer_add_midi_event_to_buffer(void* data, fluid_midi_event_t* event)
{
	fluid_event_t evt;
	fluid_sequencer_t* seq = (fluid_sequencer_t*) data;
	int chan = fluid_midi_event_get_channel(event);

	fluid_event_clear(&evt);
	fluid_event_set_time(&evt, fluid_sequencer_get_tick(seq));
	fluid_event_set_dest(&evt, get_fluidsynth_dest(seq));

	switch (fluid_midi_event_get_type(event)) {
	case NOTE_OFF:
		fluid_event_noteoff(&evt, chan, fluid_midi_event_get_key(event));	
		break;  
	case NOTE_ON:
		fluid_event_noteon(&evt, fluid_midi_event_get_channel(event),
		                   fluid_midi_event_get_key(event), fluid_midi_event_get_velocity(event));	
		break;  
	case CONTROL_CHANGE:
		fluid_event_control_change(&evt, chan, fluid_midi_event_get_control(event),
		                           fluid_midi_event_get_value(event));
		break;
	case PROGRAM_CHANGE:
		fluid_event_program_change(&evt, chan, fluid_midi_event_get_program(event));
		break;
	case PITCH_BEND:
		fluid_event_pitch_bend(&evt, chan, fluid_midi_event_get_pitch(event));
		break;
	case CHANNEL_PRESSURE:
		fluid_event_channel_pressure(&evt, chan, fluid_midi_event_get_program(event));
		break;
	case MIDI_SYSTEM_RESET:
		fluid_event_system_reset(&evt);
		break;
	default:  /* Not yet implemented */
		return FLUID_FAILED; 
	}

	/* Schedule for sending at next call to fluid_sequencer_process */
	return fluid_sequencer_send_at(seq, &evt, 0, 0);
}
Beispiel #8
0
/**
 * Unregister a previously registered client.
 * @param seq Sequencer object
 * @param id Client ID as returned by fluid_sequencer_register_client().
 */
void
fluid_sequencer_unregister_client (fluid_sequencer_t* seq, short id)
{
	fluid_list_t *tmp;
	fluid_event_t* evt;

	if (seq->clients == NULL) return;

	evt = new_fluid_event();
	if (evt != NULL) {
		fluid_event_unregistering(evt);
		fluid_event_set_dest(evt, id);
	}

	tmp = seq->clients;
	while (tmp) {
  		fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data;

  		if (client->id == id) {
			/* What should we really do if evt is null due to out-of-memory? */
			if (client->callback != NULL && evt != NULL)
				(client->callback)(fluid_sequencer_get_tick(seq),
						 evt, seq, client->data);
   			if (client->name)
				FLUID_FREE(client->name);
			seq->clients = fluid_list_remove_link(seq->clients, tmp);
			delete1_fluid_list(tmp);
			FLUID_FREE(client);
			delete_fluid_event(evt);
			return;
  		}
   		tmp = tmp->next;
	}
	delete_fluid_event(evt);
	return;
}