Преглед изворни кода

Add velocity option to miditones program

dds
PaulStoffregen пре 10 година
родитељ
комит
ea2d6f5b11
2 измењених фајлова са 39 додато и 12 уклоњено
  1. +5
    -0
      examples/Synthesis/PlaySynthMusic/miditones/Makefile
  2. +34
    -12
      examples/Synthesis/PlaySynthMusic/miditones/miditonesV1.6.c

+ 5
- 0
examples/Synthesis/PlaySynthMusic/miditones/Makefile Прегледај датотеку

miditones: miditonesV1.6.c
gcc -O2 -Wall -o miditones miditonesV1.6.c

clean:
rm -f miditones

+ 34
- 12
examples/Synthesis/PlaySynthMusic/miditones/miditonesV1.6.c Прегледај датотеку

* by using C99 standard intN_t and uintN_t types for MIDI structures, * by using C99 standard intN_t and uintN_t types for MIDI structures,
* and formatting specifications like "PRId32" instead of "ld". * and formatting specifications like "PRId32" instead of "ld".
*/ */
// Sept 2014 - Add option for velocity output
#define VERSION "1.6" #define VERSION "1.6"
* -kn Change the musical key of the output by n chromatic notes. * -kn Change the musical key of the output by n chromatic notes.
* -k-12 goes one octave down, -k12 goes one octave up, etc. * -k-12 goes one octave down, -k12 goes one octave up, etc.
* *
* -v Add velocity information to output
*
* *
* ***** The score bytestream ***** * ***** The score bytestream *****
* *
#define DEFAULT_TONEGENS 6 /* default number of tone generators */ #define DEFAULT_TONEGENS 6 /* default number of tone generators */
#define MAX_TRACKS 24 /* max number of MIDI tracks we will process */ #define MAX_TRACKS 24 /* max number of MIDI tracks we will process */
bool loggen, logparse, parseonly, strategy1, strategy2, binaryoutput;
bool loggen, logparse, parseonly, strategy1, strategy2, binaryoutput, velocityoutput;
FILE *infile, *outfile, *logfile; FILE *infile, *outfile, *logfile;
uint8_t *buffer, *hdrptr; uint8_t *buffer, *hdrptr;
unsigned long buflen; unsigned long buflen;
int note; /* what note is playing? */ int note; /* what note is playing? */
} }
tonegen [MAX_TONEGENS] = { tonegen [MAX_TONEGENS] = {
0};
{0}};
struct track_status { /* current processing point of a MIDI track */ struct track_status { /* current processing point of a MIDI track */
uint8_t *trkptr; /* ptr to the next note change */ uint8_t *trkptr; /* ptr to the next note change */
unsigned int preferred_tonegen; /* for strategy2: try to use this generator */ unsigned int preferred_tonegen; /* for strategy2: try to use this generator */
unsigned char cmd; /* CMD_xxxx next to do */ unsigned char cmd; /* CMD_xxxx next to do */
unsigned char note; /* for which note */ unsigned char note; /* for which note */
unsigned char velocity;
unsigned char last_event; /* the last event, for MIDI's "running status" */ unsigned char last_event; /* the last event, for MIDI's "running status" */
bool tonegens[MAX_TONEGENS];/* which tone generators our notes are playing on */ bool tonegens[MAX_TONEGENS];/* which tone generators our notes are playing on */
} }
track[MAX_TRACKS] = { track[MAX_TRACKS] = {
0};
{0}};
/* output bytestream commands, which are also stored in track_status.cmd */ /* output bytestream commands, which are also stored in track_status.cmd */
case 'B': case 'B':
binaryoutput = true; binaryoutput = true;
break; break;
case 'V':
velocityoutput = true;
break;
case 'S': case 'S':
if (argv[i][2] == '1') strategy1 = true; if (argv[i][2] == '1') strategy1 = true;
else if (argv[i][2] == '2') strategy2 = true; else if (argv[i][2] == '2') strategy2 = true;
/* match a constant character sequence */ /* match a constant character sequence */
int charcmp (char *buf, char *match) {
int charcmp (const char *buf, const char *match) {
int len, i; int len, i;
len = strlen (match); len = strlen (match);
for (i=0; i<len; ++i) for (i=0; i<len; ++i)
chk_bufdata(hdrptr, sizeof(struct midi_header)); chk_bufdata(hdrptr, sizeof(struct midi_header));
hdr = (struct midi_header *) hdrptr; hdr = (struct midi_header *) hdrptr;
if (!charcmp(hdr->MThd,"MThd")) midi_error("Missing 'MThd'", hdrptr);
if (!charcmp((char *)(hdr->MThd),"MThd")) midi_error("Missing 'MThd'", hdrptr);
num_tracks = rev_short(hdr->number_of_tracks); num_tracks = rev_short(hdr->number_of_tracks);
chk_bufdata(hdrptr, sizeof(struct track_header)); chk_bufdata(hdrptr, sizeof(struct track_header));
hdr = (struct track_header *) hdrptr; hdr = (struct track_header *) hdrptr;
if (!charcmp(hdr->MTrk,"MTrk")) midi_error("Missing 'MTrk'", hdrptr);
if (!charcmp((char *)(hdr->MTrk),"MTrk")) midi_error("Missing 'MTrk'", hdrptr);
tracklen = rev_long(hdr->track_size); tracklen = rev_long(hdr->track_size);
if (logparse) fprintf (logfile, "\nTrack %d length %ld\n", tracknum, tracklen); if (logparse) fprintf (logfile, "\nTrack %d length %ld\n", tracknum, tracklen);
unsigned long int delta_time; unsigned long int delta_time;
int event, chan; int event, chan;
int i; int i;
int note, velocity, parm;
int note, velocity; // , parm;
int meta_cmd, meta_length; int meta_cmd, meta_length;
unsigned long int sysex_length; unsigned long int sysex_length;
struct track_status *t; struct track_status *t;
t->note = *t->trkptr++; t->note = *t->trkptr++;
velocity = *t->trkptr++; velocity = *t->trkptr++;
if (velocity == 0) /* some scores use note-on with zero velocity for off! */ goto note_off; if (velocity == 0) /* some scores use note-on with zero velocity for off! */ goto note_off;
t->velocity = velocity;
if (logparse) fprintf (logfile, "note %02X on, chan %d, velocity %d\n", t->note, chan, velocity); if (logparse) fprintf (logfile, "note %02X on, chan %d, velocity %d\n", t->note, chan, velocity);
if ((1<<chan) & channel_mask) { // if we're processing this channel if ((1<<chan) & channel_mask) { // if we're processing this channel
t->cmd = CMD_PLAYNOTE; t->cmd = CMD_PLAYNOTE;
#define MAXPATH 120 #define MAXPATH 120
char filename[MAXPATH]; char filename[MAXPATH];
int i;
//int i;
int tracknum; int tracknum;
int earliest_tracknum; int earliest_tracknum;
unsigned long earliest_time; unsigned long earliest_time;
} }
if (!binaryoutput) { /* create header of C file that initializes score data */ if (!binaryoutput) { /* create header of C file that initializes score data */
time_t rawtime; time_t rawtime;
struct tm *ptime;
//struct tm *ptime;
time (&rawtime); time (&rawtime);
fprintf(outfile, "// Playtune bytestream for file \"%s.mid\" ", filebasename); fprintf(outfile, "// Playtune bytestream for file \"%s.mid\" ", filebasename);
fprintf(outfile, "created by MIDITONES V%s on %s", VERSION, asctime(localtime(&rawtime))); fprintf(outfile, "created by MIDITONES V%s on %s", VERSION, asctime(localtime(&rawtime)));
fprintf(outfile, "// Only the masked channels were processed: %04X\n", channel_mask); fprintf(outfile, "// Only the masked channels were processed: %04X\n", channel_mask);
if (keyshift != 0) if (keyshift != 0)
fprintf(outfile, "// Keyshift was %d chromatic notes\n", keyshift); fprintf(outfile, "// Keyshift was %d chromatic notes\n", keyshift);
fprintf(outfile, "byte PROGMEM score [] = {\n");
fprintf(outfile, "#ifdef __AVR__\n");
fprintf(outfile, "#include <avr/pgmspace.h>\n");
fprintf(outfile, "#else\n");
fprintf(outfile, "#define PROGMEM\n");
fprintf(outfile, "#endif\n");
fprintf(outfile, "const unsigned char PROGMEM score [] = {\n");
} }
} }
putc (CMD_PLAYNOTE | tgnum, outfile); putc (CMD_PLAYNOTE | tgnum, outfile);
putc (shifted_note, outfile); putc (shifted_note, outfile);
outfile_bytecount += 2; outfile_bytecount += 2;
if (velocityoutput) {
putc (shifted_note, outfile);
outfile_bytecount++;
}
} }
else { else {
fprintf (outfile, "0x%02X,%d, ", CMD_PLAYNOTE | tgnum, shifted_note);
outfile_items(2);
if (velocityoutput == 0) {
fprintf (outfile, "0x%02X,%d, ", CMD_PLAYNOTE | tgnum, shifted_note);
outfile_items(2);
} else {
fprintf (outfile, "0x%02X,%d,%d ", CMD_PLAYNOTE | tgnum, shifted_note, trk->velocity);
outfile_items(3);
}
} }
} }
else { else {

Loading…
Откажи
Сачувај