示例#1
0
/**
 * Parse events and put it on the track.
 */
static int
parse_mtrk_chunk(smf_track_t *track)
{
	smf_event_t *event;
	int ret = 0;

	if (parse_mtrk_header(track))
		return (-1);

	for (;;) {
		event = parse_next_event(track);

		/* Couldn't parse an event? */
		if (event == NULL || !smf_event_is_valid(event)) {
			ret = -1;
			break;
		}

		if (event_is_end_of_track(event))
			break;
	}

	track->file_buffer = NULL;
	track->file_buffer_length = 0;
	track->next_event_offset = -1;

	return (ret);
}
示例#2
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 ();
        }
    }
}
示例#3
0
static int
extract_escaped_event(const unsigned char *buf, const size_t buffer_length, smf_event_t *event, uint32_t *len, int last_status)
{
	(void) last_status;
	
	int status;
	int32_t message_length = 0;
	int32_t vlq_length = 0;
	const unsigned char *c = buf;

	status = *buf;

	if (!(is_escape_byte(status))) {
		g_critical("Corrupt escape status byte in extract_escaped_event().");
		return (-6);
	}

	c++;

	message_length = expected_escaped_length(status, c, buffer_length - 1, &vlq_length);

	if (message_length < 0)
		return (-3);

	c += vlq_length;

	if (vlq_length + (size_t)message_length >= buffer_length) {
		g_critical("End of buffer in extract_escaped_event().");
		return (-5);
	}

	event->midi_buffer_length = message_length;
	event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
	if (event->midi_buffer == NULL) {
		g_critical("Cannot allocate memory in extract_escaped_event(): %s", strerror(errno));
		return (-4);
	}

	memcpy(event->midi_buffer, c, message_length);

	if (smf_event_is_valid(event)) {
		g_critical("Escaped event is invalid.");
		return (-1);
	}

	if (smf_event_is_system_realtime(event) || smf_event_is_system_common(event)) {
		g_warning("Escaped event is not System Realtime nor System Common.");
	}

	*len = vlq_length + message_length;

	return (0);
}
示例#4
0
static int
cmd_text(char *str)
{
	double seconds, type;
	char *time, *typestr, *end;

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

	if (str == NULL) {
		g_critical("Usage: text <time-in-seconds> <event-type> <text-itself>");
		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, &end);
	if (end - time != strlen(time)) {
		g_critical("Time is supposed to be a number, without trailing characters.");
		return (-3);
	}

	/* Called with one parameter? */
	if (str == NULL) {
		g_critical("Usage: text <time-in-seconds> <event-type> <text-itself>");
		return (-4);
	}

	/* Extract the event type. */
	typestr = str;
	str = strchr(str, ' ');
	if (str != NULL) {
		*str = '\0';
		str++;
	}

	type = strtod(typestr, &end);
	if (end - typestr != strlen(typestr)) {
		g_critical("Type is supposed to be a number, without trailing characters.");
		return (-4);
	}

	if (type < 1 || type > 9) {
		g_critical("Valid values for type are 1 - 9, inclusive.");
		return (-5);
	}

	/* Called with one parameter? */
	if (str == NULL) {
		g_critical("Usage: text <time-in-seconds> <event-type> <text-itself>");
		return (-4);
	}

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

	assert(smf_event_is_valid(selected_event));

	smf_track_add_event_seconds(selected_track, selected_event, seconds);

	g_message("Event created.");

	return (0);
}
示例#5
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);
}