/** * 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); }
//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 (); } } }
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); }
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); }
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); }