/** * Rewinds the SMF. What that means is, after calling this routine, smf_get_next_event * will return first event in the song. */ void smf_rewind(smf_t *smf) { int i; smf_track_t *track = NULL; smf_event_t *event; assert(smf); smf->last_seek_position = 0.0; for (i = 1; i <= smf->number_of_tracks; i++) { track = smf_get_track_by_number(smf, i); assert(track != NULL); if (track->number_of_events > 0) { track->next_event_number = 1; event = smf_peek_next_event_from_track(track); assert(event); track->time_of_next_event = event->time_pulses; } else { track->next_event_number = -1; track->time_of_next_event = 0; #if 0 g_warning("Warning: empty track."); #endif } } }
static int cmd_track(char *arg) { int num; if (arg == NULL) { if (selected_track == NULL) g_message("No track currently selected."); else g_message("Currently selected is track number %d, containing %d events.", selected_track->track_number, selected_track->number_of_events); } else { if (smf->number_of_tracks == 0) { g_message("There are no tracks."); return (-1); } num = parse_track_number(arg); if (num < 0) return (-1); selected_track = smf_get_track_by_number(smf, num); if (selected_track == NULL) { g_critical("smf_get_track_by_number() failed, track not selected."); return (-3); } selected_event = NULL; g_message("Track number %d selected; it contains %d events.", selected_track->track_number, selected_track->number_of_events); } return (0); }
/** * Detaches track from the smf. */ void smf_track_remove_from_smf(smf_track_t *track) { int i, j; smf_track_t *tmp; smf_event_t *ev; assert(track->smf != NULL); track->smf->number_of_tracks--; assert(track->smf->tracks_array); g_ptr_array_remove(track->smf->tracks_array, track); /* Renumber the rest of the tracks, so they are consecutively numbered. */ for (i = track->track_number; i <= track->smf->number_of_tracks; i++) { tmp = smf_get_track_by_number(track->smf, i); tmp->track_number = i; /* * Events have track numbers too. I guess this wasn't a wise * decision. ;-/ */ for (j = 1; j <= tmp->number_of_events; j++) { ev = smf_track_get_event_by_number(tmp, j); ev->track_number = i; } } track->track_number = -1; track->smf = NULL; }
/** * Searches for track that contains next event, in time order. In other words, * returns the track that contains event that should be played next. * \return Track with next event or NULL, if there are no events left. */ smf_track_t * smf_find_track_with_next_event(smf_t *smf) { int i; size_t min_time = 0; smf_track_t *track = NULL, *min_time_track = NULL; /* Find track with event that should be played next. */ for (i = 1; i <= smf->number_of_tracks; i++) { track = smf_get_track_by_number(smf, i); assert(track); /* No more events in this track? */ if (track->next_event_number == 0) continue; if (track->time_of_next_event < min_time || min_time_track == NULL) { min_time = track->time_of_next_event; min_time_track = track; } } return (min_time_track); }
static int ui_load_state(ui_t *ui, char *filename) { int i; smf_t *smf; smf_event_t *event; smf_track_t *track; jack_nframes_t frame; if (!filename) { ui->filename = ui_get_filename(ui, ".", "Load file: "); } if (ui->filename) { smf = smf_load(ui->filename); if (!smf) { free(ui->filename); ui->filename = NULL; return 0; } ui_send_clear(ui, ui->pattern); for (i = 0; i < 8; i++) { track = smf_get_track_by_number(smf, i + 1); if (!track) { continue; } while ((event = smf_track_get_next_event(track))) { if (smf_event_is_metadata(event) || event->midi_buffer[0] == NOTEOFF) { continue; } frame = ui_seconds_to_nframes(ui, event->time_seconds); ui_send_add(ui, event->midi_buffer[1], event->midi_buffer[2], frame ? frame / (88200 / ui->steps) + 1 : 0, MAX_LEN, i); } } smf_delete(smf); } return 1; }
CAMLprim value ocaml_smf_get_track_by_number(value smf, value trackno) { CAMLparam2(smf, trackno); CAMLlocal1(ret); Track_t *t; t = malloc(sizeof(Track_t)); t->t = smf_get_track_by_number(Smf_val(smf), Int_val(trackno)); if(t->t == NULL) { free(t); /* Error */ t = NULL; smf_err(0); } ret = caml_alloc_custom(&track_ops, sizeof(Track_t*), 1, 0); Track_t_val(ret) = t; CAMLreturn(ret); }
static int cmd_trackrm(char *arg) { int num = parse_track_number(arg); if (num < 0) return (-1); if (selected_track != NULL && num == selected_track->track_number) { selected_track = NULL; selected_event = NULL; } smf_track_delete(smf_get_track_by_number(smf, num)); g_message("Track %d removed.", num); return (0); }
/** * \return Length of SMF, in pulses. */ int smf_get_length_pulses(const smf_t *smf) { int pulses = 0, i; for (i = 1; i <= smf->number_of_tracks; i++) { smf_track_t *track; smf_event_t *event; track = smf_get_track_by_number(smf, i); assert(track); event = smf_track_get_last_event(track); /* Empty track? */ if (event == NULL) continue; if (event->time_pulses > pulses) pulses = event->time_pulses; } return (pulses); }
/** * \return Length of SMF, in seconds. */ double smf_get_length_seconds(const smf_t *smf) { int i; double seconds = 0.0; for (i = 1; i <= smf->number_of_tracks; i++) { smf_track_t *track; smf_event_t *event; track = smf_get_track_by_number(smf, i); assert(track); event = smf_track_get_last_event(track); /* Empty track? */ if (event == NULL) continue; if (event->time_seconds > seconds) seconds = event->time_seconds; } return (seconds); }