Exemplo n.º 1
0
Arquivo: smf.c Projeto: 63n/ardour
/**
 * Detaches event from its track.
 */
void
smf_event_remove_from_track(smf_event_t *event)
{
	size_t i;
	int was_last;
	smf_event_t *tmp;
	smf_track_t *track;

	assert(event->track != NULL);
	assert(event->track->smf != NULL);

	track = event->track;
	was_last = smf_event_is_last(event);

	/* Adjust ->delta_time_pulses of the next event. */
	if (event->event_number < track->number_of_events) {
		tmp = smf_track_get_event_by_number(track, event->event_number + 1);
		assert(tmp);
		tmp->delta_time_pulses += event->delta_time_pulses;
	}

	track->number_of_events--;
	g_ptr_array_remove(track->events_array, event);

	if (track->number_of_events == 0)
		track->next_event_number = 0;

	/* Renumber the rest of the events, so they are consecutively numbered. */
	for (i = event->event_number; i <= track->number_of_events; i++) {
		tmp = smf_track_get_event_by_number(track, i);
		tmp->event_number = i;
	}

	if (smf_event_is_tempo_change_or_time_signature(event)) {
		/* XXX: This will cause problems, when there is more than one Tempo Change event at a given time. */
		if (was_last)
			remove_last_tempo_with_pulses(event->track->smf, event->time_pulses);
		else
			smf_create_tempo_map_and_compute_seconds(track->smf);
	}

	event->track = NULL;
	event->event_number = 0;
	event->delta_time_pulses = -1;
	event->time_pulses = 0;
	event->time_seconds = -1.0;
}
Exemplo n.º 2
0
Arquivo: smf.c Projeto: Darko8/libsmf
/**
 * Adds the event to the track and computes ->delta_pulses.  Note that it is faster
 * to append events to the end of the track than to insert them in the middle.
 * Usually you want to use smf_track_add_event_seconds or smf_track_add_event_pulses
 * instead of this one.  Event needs to have ->time_pulses and ->time_seconds already set.
 * If you try to add event after an EOT, EOT event will be automatically deleted.
 */
void
smf_track_add_event(smf_track_t *track, smf_event_t *event)
{
	int i, last_pulses = 0;

	assert(track->smf != NULL);
	assert(event->track == NULL);
	assert(event->delta_time_pulses == -1);
	assert(event->time_pulses >= 0);
	assert(event->time_seconds >= 0.0);

	remove_eot_if_before_pulses(track, event->time_pulses);

	event->track = track;
	event->track_number = track->track_number;

	if (track->number_of_events == 0) {
		assert(track->next_event_number == -1);
		track->next_event_number = 1;
	}

	if (track->number_of_events > 0)
		last_pulses = smf_track_get_last_event(track)->time_pulses;

	track->number_of_events++;

	/* Are we just appending element at the end of the track? */
	if (last_pulses <= event->time_pulses) {
		event->delta_time_pulses = event->time_pulses - last_pulses;
		assert(event->delta_time_pulses >= 0);
		g_ptr_array_add(track->events_array, event);
		event->event_number = track->number_of_events;

	/* We need to insert in the middle of the track.  XXX: This is slow. */
	} else {
		/* Append, then sort according to ->time_pulses. */
		g_ptr_array_add(track->events_array, event);
		g_ptr_array_sort(track->events_array, events_array_compare_function);

		/* Renumber entries and fix their ->delta_pulses. */
		for (i = 1; i <= track->number_of_events; i++) {
			smf_event_t *tmp = smf_track_get_event_by_number(track, i);
			tmp->event_number = i;

			if (tmp->delta_time_pulses != -1)
				continue;

			if (i == 1) {
				tmp->delta_time_pulses = tmp->time_pulses;
			} else {
				tmp->delta_time_pulses = tmp->time_pulses -
					smf_track_get_event_by_number(track, i - 1)->time_pulses;
				assert(tmp->delta_time_pulses >= 0);
			}
		}

		/* Adjust ->delta_time_pulses of the next event. */
		if (event->event_number < track->number_of_events) {
			smf_event_t *next_event = smf_track_get_event_by_number(track, event->event_number + 1);
			assert(next_event);
			assert(next_event->time_pulses >= event->time_pulses);
			next_event->delta_time_pulses -= event->delta_time_pulses;
			assert(next_event->delta_time_pulses >= 0);
		}
	}

	if (smf_event_is_tempo_change_or_time_signature(event)) {
		if (smf_event_is_last(event))
			maybe_add_to_tempo_map(event);
		else
			smf_create_tempo_map_and_compute_seconds(event->track->smf);
	}
}