Esempio n. 1
0
static short
_fluid_seq_queue_init(fluid_sequencer_t* seq, int maxEvents)
{
	seq->heap = _fluid_evt_heap_init(maxEvents);
	if (seq->heap == NULL) {
		fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
		return -1;
	}

	seq->preQueue = NULL;
	seq->preQueueLast = NULL;

	FLUID_MEMSET(seq->queue0, 0, 2*256*sizeof(fluid_evt_entry *));
	FLUID_MEMSET(seq->queue1, 0, 2*255*sizeof(fluid_evt_entry *));

	seq->queueLater = NULL;
	seq->queue0StartTime = fluid_sequencer_get_tick(seq);
	seq->prevCellNb = -1;

	fluid_mutex_init(seq->mutex);

	/* start timer */
	if (seq->useSystemTimer) {
		seq->timer = new_fluid_timer((int)(1000/seq->scale), _fluid_seq_queue_process,
					     (void *)seq, TRUE, FALSE, TRUE);
	}
	return (0);
}
int
main (int argc, char *argv[])
{
    int n;
    fluid_settings_t *settings;
    settings = new_fluid_settings ();
    if (argc < 2) {
        usage (argv[0]);
    } else {
        /* create the synth, driver and sequencer instances */
        synth = new_fluid_synth (settings);
        audiodriver = new_fluid_audio_driver (settings, synth);
        sequencer = new_fluid_sequencer ();
        /* register the synth with the sequencer */
        synth_destination = fluid_sequencer_register_fluidsynth (sequencer,
                synth);
        /* register the client name and callback */
        client_destination = fluid_sequencer_register_client (sequencer,
                "fluidsynth_metronome", sequencer_callback, NULL);
        /* load a SoundFont */
        n = fluid_synth_sfload (synth, argv[1], 1);
        if (n != -1) {
            if (argc > 2) {
                n = atoi (argv[2]);
                if (n > 0) pattern_size = n;
            }
            if (argc > 3) {
                n = atoi (argv[3]);
                if (n > 0) note_duration = 60000 / n;
            }
            /* get the current time in ticks */
            time_marker = fluid_sequencer_get_tick (sequencer);
            /* schedule patterns */
            schedule_pattern ();
            schedule_timer_event ();
            schedule_pattern ();
            /* wait for user input */
            printf ("press <Enter> to stop\n");
            n = getchar ();
        }
        /* clean and exit */
        delete_fluid_sequencer (sequencer);
        delete_fluid_audio_driver (audiodriver);
        delete_fluid_synth (synth);
    }
    delete_fluid_settings (settings);
    return 0;
}
Esempio n. 3
0
/**
 * Schedule an event for sending at a later time.
 * @param seq Sequencer object
 * @param evt Event to send
 * @param time Time value in ticks (in milliseconds with the default time scale of 1000).
 * @param absolute TRUE if \a time is absolute sequencer time (time since sequencer
 *   creation), FALSE if relative to current time.
 * @return #FLUID_OK on success, #FLUID_FAILED otherwise
 */
int
fluid_sequencer_send_at (fluid_sequencer_t* seq, fluid_event_t* evt,
                         unsigned int time, int absolute)
{
	unsigned int now = fluid_sequencer_get_tick(seq);

	/* set absolute */
	if (!absolute)
		time = now + time;

	/* time stamp event */
	fluid_event_set_time(evt, time);

	/* queue for processing later */
	return _fluid_seq_queue_pre_insert(seq, evt);
}
Esempio n. 4
0
/* Event not actually copied, but since its used immediately it virtually is. */
void
fluid_sequencer_send_now(fluid_sequencer_t* seq, fluid_event_t* evt)
{
	short destID = fluid_event_get_dest(evt);

	/* find callback */
	fluid_list_t *tmp = seq->clients;
	while (tmp) {
  		fluid_sequencer_client_t *dest = (fluid_sequencer_client_t*)tmp->data;

  		if (dest->id == destID) {
			if (dest->callback)
				(dest->callback)(fluid_sequencer_get_tick(seq),
						 evt, seq, dest->data);
			return;
  		}
   		tmp = tmp->next;
	}
}
Esempio n. 5
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);
}
Esempio n. 6
0
static void
_fluid_seq_queue_send_queued_events(fluid_sequencer_t* seq)
{
	unsigned int nowTicks = fluid_sequencer_get_tick(seq);
	short cellNb;

	cellNb = seq->prevCellNb + 1;
	while (cellNb <= (int)(nowTicks - seq->queue0StartTime)) {
		if (cellNb == 256) {
			cellNb = 0;
			_fluid_seq_queue_slide(seq);
		} /* slide */


		/* process queue0[cellNb] */
		_fluid_seq_queue_send_cell_events(seq, cellNb);

		/* next cell */
		cellNb++;
	}

	seq->prevCellNb = cellNb - 1;
}
Esempio n. 7
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;
}
Esempio n. 8
0
	unsigned midi_ticks() const {
		return fluid_sequencer_get_tick(source_.seq.get());
	}