/** * Creates new SMF and fills it with data loaded from the given buffer. * \return SMF or NULL, if loading failed. */ smf_t * smf_load_from_memory(const void *buffer, const size_t buffer_length) { int i; int ret; smf_t *smf = smf_new(); smf->file_buffer = (void *)buffer; smf->file_buffer_length = buffer_length; smf->next_chunk_offset = 0; if (parse_mthd_chunk(smf)) return (NULL); for (i = 1; i <= smf->expected_number_of_tracks; i++) { smf_track_t *track = smf_track_new(); if (track == NULL) return (NULL); smf_add_track(smf, track); ret = parse_mtrk_chunk(track); track->file_buffer = NULL; track->file_buffer_length = 0; track->next_event_offset = -1; if (ret) { g_warning("SMF warning: Error parsing track, continuing with data loaded so far."); break; } } if (smf->expected_number_of_tracks != smf->number_of_tracks) { g_warning("SMF warning: MThd header declared %d tracks, but only %d found; continuing anyway.", smf->expected_number_of_tracks, smf->number_of_tracks); smf->expected_number_of_tracks = smf->number_of_tracks; } smf->file_buffer = NULL; smf->file_buffer_length = 0; smf->next_chunk_offset = 0; return (smf); }
static int cmd_trackadd(char *notused) { selected_track = smf_track_new(); if (selected_track == NULL) { g_critical("smf_track_new() failed, track not created."); return (-1); } smf_add_track(smf, selected_track); selected_event = NULL; g_message("Created new track; track number %d selected.", selected_track->track_number); return (0); }
CAMLprim value ocaml_smf_add_track(value smf, value track) { CAMLparam2(smf, track); smf_add_track(Smf_val(smf), Track_val(track)); CAMLreturn(Val_unit); }
static void safely_add_track (smf_t * smf, smf_track_t * track) { track->smf = NULL; smf_add_track (smf, track); }
G_MODULE_EXPORT void on_doIt_clicked( GtkButton *button, gpointer data ) { printf("button clicked\n"); smf_t* smf = smf_new(); smf_track_t* track = smf_track_new(); smf_add_track(smf, track); smf_event_t* event; gboolean prevFrame[NUMBER_OF_KEYS] = { FALSE }; // Start video from beginning currentFrame = startFrame; //upper 9 notes have lyrics //2920 start while (currentFrame <= stopFrame) { int i = 0; if ( currentFrame == stopFrame ) { for (i = 0; i < NUMBER_OF_KEYS; i++ ) { noteOn[i] = FALSE; } } else { redrawFrame(); } // Why NUMBER_OF_KEYS - 10? Well, the lyrics in my example are printed across // the upper 10 notes and were being detected as notes themselves, causing odd // trilling when they scrolled past. This was a quick hack to make that stop. for ( i = 0; i < NUMBER_OF_KEYS - 10; i++ ) { char note = 0xd + i; char eventBytes[3] = { 0 }; eventBytes[1] = note; // which note to play eventBytes[2] = 0x7f; // full velocity (may toy with later) if (prevFrame[i] && (!noteOn[i])) { // Time to generate a note-off eventBytes[0] = 0x80; printf("note-off: %x, at frame %f\n", i + 0xd, currentFrame); } if ((!prevFrame[i]) && noteOn[i]) { // Time to generate a note-on eventBytes[0] = 0x90; printf("note-on: %x, at frame %f\n", i + 0xd, currentFrame); } prevFrame[i] = noteOn[i]; if ( eventBytes[0] ) { event = smf_event_new_from_pointer(eventBytes, 3); smf_track_add_event_seconds(track, event, currentFrame / 30.0); } } currentFrame++; gtk_main_iteration_do( FALSE ); } smf_save(smf, "output.mid"); }
int main (int argc, char * argv []) { int ch, i; char * file_name, * autoconnect_port_name = NULL; g_thread_init(NULL); #ifdef WITH_LASH lash_args_t * lash_args = lash_extract_args(&argc, &argv); #endif g_log_set_default_handler(log_handler, NULL); while ((ch = getopt(argc, argv, "a:V")) != -1) { switch (ch) { case 'a': autoconnect_port_name = strdup(optarg); break; case 'V': show_version(); break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc == 0) usage(); file_name = argv[0]; smf = smf_new(); if (smf == NULL) exit(-1); for (i = 0; i < 16; ++i) { tracks[i] = smf_track_new(); if (tracks[i] == NULL) exit(-1); smf_add_track(smf, tracks[i]); } #ifdef WITH_LASH init_lash(lash_args); #endif init_jack(); if (autoconnect_port_name) { if (connect_to_output_port(autoconnect_port_name)) { g_critical("Couldn't connect to '%s', exiting.", autoconnect_port_name); exit(EX_UNAVAILABLE); } } g_timeout_add(100, writer_timeout, (gpointer)argv[0]); signal(SIGINT, ctrl_c_handler); g_message ( "Recording will start at the first received note; " "press ^C to write the file and exit." ); g_main_loop_run(g_main_loop_new(NULL, TRUE)); /* Not reached. */ return 0; }
static int ui_save_state(ui_t *ui, char *filename) { int i; smf_t *smf; smf_track_t *track; jack_nframes_t frame; double seconds; list_t *pattern, *lp; note_t *note; /* TODO: check if file exists */ if (!filename) { filename = ui_get_filename(ui, ".", "Save to: "); } ui->filename = filename; smf = smf_new(); if (!smf) { return 0; } for (i = 0; i < 8; i++) { track = smf_track_new(); if (!track) { smf_delete(smf); return 0; } smf_add_track(smf, track); pattern = ui->patterns[i]; if (!pattern) { continue; } for (lp = pattern; lp; lp = list_next(lp)) { note = (note_t *)list_data(lp); frame = 88200 / ui->steps * note->step; seconds = ui_nframes_to_seconds(ui, frame); note_event_save(note, track, 0x90, seconds); /* TODO: decide if and how noteoffs should be saved */ /* frame = 88200 / ui->steps */ /* * ((note->step + note->len) % ui->steps); */ /* seconds = ui_nframes_to_seconds(ui, frame); */ /* note_event_save(note, track, NOTEOFF, seconds); */ } if (smf_track_add_eot_seconds(track, 2)) { return 0; } } if (smf_save(smf, ui->filename)) { return 0; } return 1; }