예제 #1
0
파일: midi.c 프로젝트: denemo/denemo
//Add the passed midi to a recording in Denemo.project->movement
static void
record_midi (gchar * buf, gdouble time)
{
  buf[0] |= 0xF; //here force the channel to 15
  smf_event_t *event = smf_event_new_from_pointer (buf, 3);
  if (event && smf_event_is_valid (event))
    {
      if (Denemo.project->movement->recorded_midi_track && ((smf_track_t *) Denemo.project->movement->recorded_midi_track)->smf)
        {

          smf_track_add_event_seconds (Denemo.project->movement->recorded_midi_track, event, time);
          if(Denemo.project->movement->recording && noteon_key(event))
            {
                DenemoRecordedNote *note = g_malloc0(sizeof(DenemoRecordedNote));
                note->timing = event->time_seconds * Denemo.project->movement->recording->samplerate;
                notenum2enharmonic (noteon_key(event), &(note->mid_c_offset), &(note->enshift), &(note->octave));
                note->event = event;
                Denemo.project->movement->recording->notes = g_list_append (Denemo.project->movement->recording->notes, note);
            }
        }
      else
        {
          smf_event_delete (event);
          gdk_beep ();
        }
    }
}
예제 #2
0
/**
 * Locates, basing on track->next_event_offset, the next event data in track->buffer,
 * interprets it, allocates smf_event_t and fills it properly.  Returns smf_event_t
 * or NULL, if there was an error.  Allocating event means adding it to the track;
 * see smf_event_new().
 */
static smf_event_t *
parse_next_event(smf_track_t *track)
{
	uint32_t etime = 0;
	uint32_t len;
	size_t buffer_length;
	unsigned char *c, *start;

	smf_event_t *event = smf_event_new();
	if (event == NULL)
		goto error;

	c = start = (unsigned char *)track->file_buffer + track->next_event_offset;

	assert(track->file_buffer != NULL);
	assert(track->file_buffer_length > 0);
	assert(track->next_event_offset > 0);

	buffer_length = track->file_buffer_length - track->next_event_offset;
	/* if there was no meta-EOT event, buffer_length can be zero. This is
	   an error in the SMF file, but it shouldn't be treated as fatal.
	*/
	if (buffer_length == 0) {
		g_warning ("SMF warning: expected EOT at end of track, but none found");
		goto error;
	}
	/* First, extract time offset from previous event. */
	if (smf_extract_vlq(c, buffer_length, &etime, &len)) {
		goto error;
	}

	c += len;
	buffer_length -= len;

	if (buffer_length <= 0)
		goto error;

	/* Now, extract the actual event. */
	if (extract_midi_event(c, buffer_length, event, &len, track->last_status)) {
		goto error;
	}

	c += len;
	buffer_length -= len;
	track->last_status = event->midi_buffer[0];
	track->next_event_offset += c - start;

	smf_track_add_event_delta_pulses(track, event, etime);

	return (event);

error:
	if (event != NULL)
		smf_event_delete(event);

	return (NULL);
}
예제 #3
0
static int
cmd_eventrm(char *number)
{
	int num = parse_event_number(number);

	if (num < 0)
		return (-1);

	if (selected_event != NULL && num == selected_event->event_number)
		selected_event = NULL;

	smf_event_delete(smf_track_get_event_by_number(selected_track, num));

	g_message("Event #%d removed.", num);

	return (0);
}
예제 #4
0
파일: smf.c 프로젝트: Darko8/libsmf
/**
 * Detaches track from its smf and frees it.
 */
void
smf_track_delete(smf_track_t *track)
{
	assert(track);
	assert(track->events_array);

	/* Remove all the events, from last to first. */
	while (track->events_array->len > 0)
		smf_event_delete(g_ptr_array_index(track->events_array, track->events_array->len - 1));

	if (track->smf)
		smf_track_remove_from_smf(track);

	assert(track->events_array->len == 0);
	assert(track->number_of_events == 0);
	g_ptr_array_free(track->events_array, TRUE);

	memset(track, 0, sizeof(smf_track_t));
	free(track);
}
예제 #5
0
파일: smf.c 프로젝트: Darko8/libsmf
/**
 * Allocates an smf_event_t structure and fills it with "len" bytes copied
 * from "midi_data".
 * \param midi_data Pointer to MIDI data.  It sill be copied to the newly allocated event->midi_buffer.
 * \param len Length of the buffer.  It must be proper MIDI event length, e.g. 3 for Note On event.
 * \return Event containing MIDI data or NULL.
 */
smf_event_t *
smf_event_new_from_pointer(void *midi_data, int len)
{
	smf_event_t *event;

	event = smf_event_new();
	if (event == NULL)
		return (NULL);

	event->midi_buffer_length = len;
	event->midi_buffer = malloc(event->midi_buffer_length);
	if (event->midi_buffer == NULL) {
		g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno));
		smf_event_delete(event);

		return (NULL); 
	}

	memcpy(event->midi_buffer, midi_data, len);

	return (event);
}
예제 #6
0
파일: smf_stubs.c 프로젝트: aplusbi/smf
CAMLprim value ocaml_smf_event_delete(value event)
{
    CAMLparam1(event);
    smf_event_delete(get_event(event));
    CAMLreturn(Val_unit);
}
예제 #7
0
static int
cmd_eventadd(char *str)
{
	int midi_buffer_length;
	double seconds;
	unsigned char *midi_buffer;
	char *time, *endtime;

	if (selected_track == NULL) {
		g_critical("Please select a track first, using 'track <number>' command.");
		return (-1);
	}

	if (str == NULL) {
		eventadd_usage();
		return (-2);
	}

	/* Extract the time.  Don't use strsep(3), it doesn't work on SunOS. */
	time = str;
	str = strchr(str, ' ');
	if (str != NULL) {
		*str = '\0';
		str++;
	}

	seconds = strtod(time, &endtime);
	if (endtime - time != strlen(time)) {
		g_critical("Time is supposed to be a number, without trailing characters.");
		return (-3);
	}

	/* Called with one parameter? */
	if (str == NULL) {
		eventadd_usage();
		return (-4);
	}

	if (decode_hex(str, &midi_buffer, &midi_buffer_length)) {
		eventadd_usage();
		return (-5);
	}

	selected_event = smf_event_new();
	if (selected_event == NULL) {
		g_critical("smf_event_new() failed, event not created.");
		return (-6);
	}

	selected_event->midi_buffer = midi_buffer;
	selected_event->midi_buffer_length = midi_buffer_length;

	if (smf_event_is_valid(selected_event) == 0) {
		g_critical("Event is invalid from the MIDI specification point of view, not created.");
		smf_event_delete(selected_event);
		selected_event = NULL;
		return (-7);
	}

	smf_track_add_event_seconds(selected_track, selected_event, seconds);

	g_message("Event created.");

	return (0);
}
예제 #8
0
파일: smf.c 프로젝트: Darko8/libsmf
/**
 * Allocates an smf_event_t structure and fills it with at most three bytes of data.
 * For example, if you need to create Note On event, do something like this:
 *
 * smf_event_new_from_bytes(0x90, 0x3C, 0x7f);
 *
 * To create event for MIDI message that is shorter than three bytes, do something
 * like this:
 *
 * smf_event_new_from_bytes(0xC0, 0x42, -1);
 * 
 * \param first_byte First byte of MIDI message.  Must be valid status byte.
 * \param second_byte Second byte of MIDI message or -1, if message is one byte long.
 * \param third_byte Third byte of MIDI message or -1, if message is two bytes long.
 * \return Event containing MIDI data or NULL.
 */
smf_event_t *
smf_event_new_from_bytes(int first_byte, int second_byte, int third_byte)
{
	int len;

	smf_event_t *event;

	event = smf_event_new();
	if (event == NULL)
		return (NULL);

	if (first_byte < 0) {
		g_critical("First byte of MIDI message cannot be < 0");
		smf_event_delete(event);

		return (NULL);
	}

	if (first_byte > 255) {
		g_critical("smf_event_new_from_bytes: first byte is %d, which is larger than 255.", first_byte);
		return (NULL);
	}

	if (!is_status_byte(first_byte)) {
		g_critical("smf_event_new_from_bytes: first byte is not a valid status byte.");
		return (NULL);
	}


	if (second_byte < 0)
		len = 1;
	else if (third_byte < 0)
		len = 2;
	else
		len = 3;

	if (len > 1) {
		if (second_byte > 255) {
			g_critical("smf_event_new_from_bytes: second byte is %d, which is larger than 255.", second_byte);
			return (NULL);
		}

		if (is_status_byte(second_byte)) {
			g_critical("smf_event_new_from_bytes: second byte cannot be a status byte.");
			return (NULL);
		}
	}

	if (len > 2) {
		if (third_byte > 255) {
			g_critical("smf_event_new_from_bytes: third byte is %d, which is larger than 255.", third_byte);
			return (NULL);
		}

		if (is_status_byte(third_byte)) {
			g_critical("smf_event_new_from_bytes: third byte cannot be a status byte.");
			return (NULL);
		}
	}

	event->midi_buffer_length = len;
	event->midi_buffer = malloc(event->midi_buffer_length);
	if (event->midi_buffer == NULL) {
		g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno));
		smf_event_delete(event);

		return (NULL); 
	}

	event->midi_buffer[0] = first_byte;
	if (len > 1)
		event->midi_buffer[1] = second_byte;
	if (len > 2)
		event->midi_buffer[2] = third_byte;

	return (event);
}