various enhancements; see the change log

pull/18/head
Len Shustek 6 years ago
parent ee76ad2d1f
commit b167f406f7
  1. 157
      SAMPLE_MoneyMoney_scroll.txt
  2. 317
      miditones_scroll.c
  3. BIN
      miditones_scroll.exe
  4. 178
      miditones_scroll_example.txt

@ -1,157 +0,0 @@
MIDITONES_SCROLL V1.5, (C) 2011,2016 Len Shustek
Processing MoneyMoney.bin, 30291 bytes.
Found Pt self-describing file header with flags E0 00, # tone gens = 16
duration time gen0 gen1 gen2 gen3 gen4 gen5 bytestream code
2000 0.000 0000: 50 74 06 E0 00 10 07 D0
15 2.000 HHatC v65 0008: 90 AA 41 00 0F
484 2.015 000D: 80 01 E4
15 2.499 HHatC v65 0010: 90 AA 41 00 0F
484 2.514 0015: 80 01 E4
15 2.998 HHatC v65 0018: 90 AA 41 00 0F
484 3.013 001D: 80 01 E4
15 3.497 HHatC v65 0020: 90 AA 41 00 0F
484 3.512 0025: 80 01 E4
BPiano BPiano BPiano BPiano Xyloph
62 3.996 4E v104 4A v108 5C v104 5E v108 6E v88 0028: C0 01 90 40 68 C1 01 91 45 6C C2 01 92 48 68 C3 01 93 4C 6C C4 0D 94 58 58 00 3E
62 4.058 6E v88 0043: 83 82 81 80 00 3E
125 4.120 0049: 84 00 7D
62 4.245 4E v96 4A v100 5C v84 5E v78 6E v72 004C: 90 40 60 91 45 64 92 48 54 93 4C 4E 94 58 48 00 3E
62 4.307 6E v72 005D: 83 82 81 80 00 3E
125 4.369 0063: 84 00 7D
62 4.494 4E v84 4A v88 5C v78 5E v92 6E v84 0066: 90 40 54 91 45 58 92 48 4E 93 4C 5C 94 58 54 00 3E
62 4.556 6E v84 0077: 83 82 81 80 00 3E
125 4.618 007D: 84 00 7D
62 4.743 4E v100 4A v100 5C v82 5E v88 6E v88 0080: 90 40 64 91 45 64 92 48 52 93 4C 58 94 58 58 00 3E
62 4.805 6E v88 0091: 83 82 81 80 00 3E
125 4.867 0097: 84 00 7D
62 4.992 4E v96 4A v100 5C v88 5E v104 6E v88 009A: 90 40 60 91 45 64 92 48 58 93 4C 68 94 58 58 00 3E
62 5.054 6E v88 00AB: 83 82 81 80 00 3E
125 5.116 00B1: 84 00 7D
125 5.241 4E v88 4A v92 5C v78 5E v104 6E v88 00B4: 90 40 58 91 45 5C 92 48 4E 93 4C 68 94 58 58 00 7D
98 5.366 4E v88 4A v92 5C v78 5E v104 00C5: 84 00 62
26 5.464 00C8: 83 82 81 80 00 1A
125 5.490 4E v108 5E v66 00CE: 90 40 6C 94 4C 42 00 7D
125 5.615 4A v108 5A v62 00D6: 80 90 45 6C 84 94 51 3E 00 7D
125 5.740 5C v96 6C v62 00E0: 80 90 48 60 84 94 54 3E 00 7D
125 5.865 5E v104 6E v80 00EA: 80 90 4C 68 84 94 58 50 00 7D
62 5.990 4F v104 4A v86 5C v84 5D# v65 6D# v68 00F4: 80 90 41 68 91 45 56 92 48 54 93 4B 41 84 94 57 44 00 3E
62 6.052 6D# v68 0107: 83 82 81 80 00 3E
125 6.114 010D: 84 00 7D
62 6.239 4F v59 4A v88 5C v80 5D# v82 6D# v88 0110: 90 41 3B 91 45 58 92 48 50 93 4B 52 94 57 58 00 3E
62 6.301 6D# v88 0121: 83 82 81 80 00 3E
125 6.363 0127: 84 00 7D
62 6.488 4F v96 4A v100 5C v84 5D# v82 6D# v88 012A: 90 41 60 91 45 64 92 48 54 93 4B 52 94 57 58 00 3E
62 6.550 6D# v88 013B: 83 82 81 80 00 3E
125 6.612 0141: 84 00 7D
62 6.737 4F v92 4A v100 5C v80 5D# v82 6D# v76 0144: 90 41 5C 91 45 64 92 48 50 93 4B 52 94 57 4C 00 3E
62 6.799 6D# v76 0155: 83 82 81 80 00 3E
125 6.861 015B: 84 00 7D
62 6.986 4F v100 4A v108 5C v84 5D# v80 6D# v64 015E: 90 41 64 91 45 6C 92 48 54 93 4B 50 94 57 40 00 3E
62 7.048 6D# v64 016F: 83 82 81 80 00 3E
125 7.110 0175: 84 00 7D
125 7.235 4F v78 4A v100 5C v78 5D# v74 6D# v80 0178: 90 41 4E 91 45 64 92 48 4E 93 4B 4A 94 57 50 00 7D
98 7.360 4F v78 4A v100 5C v78 5D# v74 0189: 84 00 62
26 7.458 018C: 83 82 81 80 00 1A
125 7.484 4F v104 5F v64 0192: 90 41 68 94 4D 40 00 7D
125 7.609 4A v82 5A v64 019A: 80 90 45 52 84 94 51 40 00 7D
125 7.734 5C v74 6C v62 01A4: 80 90 48 4A 84 94 54 3E 00 7D
125 7.859 5D# v92 6D# v76 01AE: 80 90 4B 5C 84 94 57 4C 00 7D
125 7.984 3D v86 4F v92 4A v92 5D v88 6D v88 01B8: 80 90 32 56 91 41 5C 92 45 5C 93 4A 58 84 94 56 58 00 7D
333 8.109 3D v86 4F v92 4A v92 5D v88 01CB: 84 01 4D
20 8.442 3D v86 4F v92 5D v88 01CE: 82 00 14
20 8.462 3D v86 4F v92 01D1: 83 00 14
114 8.482 3D v86 4F v92 5C v104 6C v84 01D4: 92 48 68 94 54 54 00 72
10 8.596 3D v86 5C v104 6C v84 01DC: 81 00 0A
88 8.606 3D v86 5C v104 01DF: 84 00 58
36 8.694 3D v86 01E2: 82 00 24
62 8.730 3D v86 4A v72 5A v62 01E5: 91 45 48 94 51 3E 00 3E
62 8.792 3D v86 5A v62 01ED: 81 00 3E
93 8.854 3D v86 01F0: 84 00 5D
31 8.947 01F3: 80 00 1F
78 8.978 3E v74 4D v82 4G# v104 5C v104 6C v84 01F6: 90 34 4A 91 3E 52 92 44 68 93 48 68 94 54 54 00 4E
15 9.056 3E v74 4D v82 6C v84 0207: 82 83 00 0F
31 9.071 3E v74 6C v84 020B: 81 00 1F
83 9.102 3E v74 020E: 84 00 53
41 9.185 0211: 80 00 29
125 9.226 3E v58 4D v86 4G# v112 5C v112 6C v84 0214: 90 34 3A 91 3E 56 92 44 70 93 48 70 94 54 54 00 7D
250 9.351 3E v58 4D v86 4G# v112 5C v112 0225: 84 00 FA
83 9.601 3E v58 0228: 83 82 81 00 53
41 9.684 022D: 80 00 29
125 9.725 4C v112 4E v96 4A v100 5A v80 0230: 90 3C 70 91 40 60 92 45 64 94 51 50 00 7D
229 9.850 4C v112 4E v96 4A v100 023E: 84 00 E5
26 10.079 4C v112 4E v96 0241: 82 00 1A
31 10.105 4C v112 0244: 81 00 1F
338 10.136 0247: 80 01 52
62 10.474 2A v96 024A: 90 2D 60 00 3E
62 10.536 2A v96 3E v100 024F: 91 34 64 00 3E
31 10.598 2A v96 3E v100 3A v82 0254: 92 39 52 00 1F
10 10.629 3E v100 3A v82 0259: 80 00 0A
20 10.639 3A v82 025C: 81 00 14
15 10.659 3C v88 3A v82 025F: 90 30 58 00 0F
46 10.674 3C v88 0264: 82 00 2E
20 10.720 3C v88 3E v86 0267: 91 34 56 00 14
41 10.740 3E v86 026C: 80 00 29
15 10.781 3A v76 3E v86 026F: 90 39 4C 00 0F
31 10.796 3A v76 0274: 81 00 1F
15 10.827 0277: 80 00 0F
62 10.842 4C v100 027A: 90 3C 64 00 3E
62 10.904 4C v100 4E v88 027F: 91 40 58 00 3E
10 10.966 4C v100 4E v88 4A v112 6A v92 0284: 92 45 70 94 5D 5C 00 0A
20 10.976 4E v88 4A v112 6A v92 028C: 80 00 14
31 10.996 4A v112 6A v92 028F: 81 00 1F
62 11.027 6A v92 0292: 82 00 3E
875 11.089 0295: 84 03 6B
FiBass Callip
15 11.964 1A v56 3A v74 5A v55 BassD v61 0298: C0 21 90 21 38 91 39 4A 95 A3 3D C2 52 92 51 37 00 0F
109 11.979 1A v56 3A v74 5A v55 02AA: 85 00 6D
125 12.088 1A v56 3B v72 5B v53 02AD: 81 91 3B 48 82 92 53 35 00 7D
93 12.213 2A v58 4C v66 6C v52 02B7: 80 90 2D 3A 81 91 3C 42 82 92 54 34 00 5D
31 12.306 4C v66 6C v52 02C5: 80 00 1F
125 12.337 4E v96 6E v51 02C8: 81 91 40 60 82 92 58 33 00 7D
15 12.462 1A v56 3A v84 5A v50 BassD v61 02D2: 90 21 38 81 91 39 54 95 A3 3D 82 92 51 32 00 0F
109 12.477 1A v56 3A v84 5A v50 02E2: 85 00 6D
125 12.586 1A v56 3B v88 5B v48 02E5: 81 91 3B 58 82 92 53 30 00 7D
83 12.711 2A v54 4C v82 6C v47 02EF: 80 90 2D 36 81 91 3C 52 82 92 54 2F 00 53
41 12.794 4C v82 6C v47 02FD: 80 00 29
125 12.835 4E v112 6E v46 0300: 81 91 40 70 82 92 58 2E 00 7D
15 12.960 1A v60 3A v108 5A v44 BassD v62 030A: 90 21 3C 81 91 39 6C 95 A3 3E 82 92 51 2C 00 0F
109 12.975 1A v60 3A v108 5A v44 031A: 85 00 6D
125 13.084 1A v60 3B v104 5B v43 031D: 81 91 3B 68 82 92 53 2B 00 7D
119 13.209 2A v54 4C v100 6C v42 0327: 80 90 2D 36 81 91 3C 64 82 92 54 2A 00 77
5 13.328 4C v100 6C v42 0335: 80 00 05
125 13.333 4E v108 6E v40 0338: 81 91 40 6C 82 92 58 28 00 7D
15 13.458 1A v62 3A v100 5A v39 BassD v63 0342: 90 21 3E 81 91 39 64 95 A3 3F 82 92 51 27 00 0F
109 13.473 1A v62 3A v100 5A v39 0352: 85 00 6D
125 13.582 1A v62 3B v112 5B v38 0355: 81 91 3B 70 82 92 53 26 00 7D
125 13.707 2A v58 4C v104 6C v37 035F: 80 90 2D 3A 81 91 3C 68 82 92 54 25 00 7D
10 13.832 2A v58 4E v117 6E v35 036D: 81 91 40 75 82 92 58 23 00 0A
114 13.842 4E v117 6E v35 0377: 80 00 72
15 13.956 1A v60 3A v100 5A v34 BassD v63 037A: 90 21 3C 81 91 39 64 95 A3 3F 82 92 51 22 00 0F
109 13.971 1A v60 3A v100 5A v34 038A: 85 00 6D
125 14.080 1A v60 3B v100 5B v33 038D: 81 91 3B 64 82 92 53 21 00 7D
72 14.205 2A v54 4C v86 6C v31 0397: 80 90 2D 36 81 91 3C 56 82 92 54 1F 00 48
52 14.277 4C v86 6C v31 03A5: 80 00 34
125 14.329 4E v92 6E v30 03A8: 81 91 40 5C 82 92 58 1E 00 7D
15 14.454 1A v60 3A v84 5A v29 BassD v64 03B2: 90 21 3C 81 91 39 54 95 A3 40 82 92 51 1D 00 0F
109 14.469 1A v60 3A v84 5A v29 03C2: 85 00 6D
125 14.578 1A v60 3B v74 5B v27 03C5: 81 91 3B 4A 82 92 53 1B 00 7D
57 14.703 2A v50 4C v70 6C v26 03CF: 80 90 2D 32 81 91 3C 46 82 92 54 1A 00 39
67 14.760 4C v70 6C v26 03DD: 80 00 43
125 14.827 4E v86 6E v25 03E0: 81 91 40 56 82 92 58 19 00 7D
15 14.952 1A v62 3A v74 5A v24 BassD v65 03EA: 90 21 3E 81 91 39 4A 95 A3 41 82 92 51 18 00 0F
109 14.967 1A v62 3A v74 5A v24 03FA: 85 00 6D
125 15.076 1A v62 3B v74 5B v22 03FD: 81 91 3B 4A 82 92 53 16 00 7D
88 15.201 2A v54 4C v60 6C v21 0407: 80 90 2D 36 81 91 3C 3C 82 92 54 15 00 58
36 15.289 4C v60 6C v21 0415: 80 00 24
125 15.325 4E v72 6E v20 0418: 81 91 40 48 82 92 58 14 00 7D
15 15.450 1A v58 3A v56 5A v18 BassD v65 0422: 90 21 3A 81 91 39 38 95 A3 41 82 92 51 12 00 0F
109 15.465 1A v58 3A v56 5A v18 0432: 85 00 6D
125 15.574 1A v58 3B v64 5B v17 0435: 81 91 3B 40 82 92 53 11 00 7D
<...>
<...> 7652: F0
At most 16 tone generators were used.
2349 notes were not displayed because we were told to show only 6 generators.
Done.

@ -2,11 +2,11 @@
* *
* MIDITONES_SCROLL * MIDITONES_SCROLL
* *
* Decode a PLAYTUNE bytestream of notes as a time-ordered scroll, sort of like a * Decode a PLAYTUNE bytestream of notes as a time-ordered scroll, sort of like
* piano roll with non-uniform time. This is a command-line program with no GUI. * a piano roll with non-uniform time. Instrument and volume information, if
* present, is displayed.
* *
* * This is a command-line program with no GUI. There are two primary uses:
* There are two primary uses:
* *
* (1) To debug errors that cause some MIDI scripts to sound strange. * (1) To debug errors that cause some MIDI scripts to sound strange.
* *
@ -18,48 +18,42 @@
* In both cases it reads a xxx.bin file that was created from a MIDI file by * In both cases it reads a xxx.bin file that was created from a MIDI file by
* MIDITONES using the -b option. * MIDITONES using the -b option.
* *
* * Starting with the midi file "song.mid", do this:
* For use case (1), just invoke the program with the base filename. The output is
* to the console, which can be directed to a file using the usual >file redirection.
* For example, starting with the original midi file "song.mid", say this:
*
* miditones -b song * miditones -b song
* miditones_scroll song >song.txt * miditones_scroll song
*
* and then the file "song.txt" will contain the piano roll. * and then the file "song.txt" will contain the piano roll.
* *
* * If instead you do this:
* For use case (2), use the -c option to create a <basefile>.c file.
* For example, starting with the original midi file "song.mid", say this:
*
* miditones -b song * miditones -b song
* miditones_scroll -c song * miditones_scroll -c song
* then the file "song.c" will contain the annotated PLAYTUNE bytestream C code.
* *
* and then the file "song.c" will contain the PLAYTUNE bytestream C code. * Other command-line options besides -c:
*
* *
* Other command-line options: * -tn Up to n tone generators should be displayed. The default
*
* -tn says that up to n tone generators should be displayed. The default
* is 6 and the maximum is 16. * is 6 and the maximum is 16.
* *
* -v says that we expect the binary file to contain encoded note volume * -v Expect the binary file to contain encoded note volume
* information as generated from Miditones with the -v option. That * information as generated from Miditones with the -v option,
* volume information is displayed next to each note. * even if there is no file header that says so.
* * The volume is displayed next to each note.
* -vi says that we expect volume information to be in the file, but we
* should ignore it when creating the display.
* *
* -ii says we should not display instrument information we find * -vi Expect volume information to be in the file, but ignore
* it when creating the display.
* *
* -x Show notes in hex instead of as octave-noteletter-sharp
* *
* For source code to this and related programs, see * For source code to this and related programs, see
* www.github.com/LenShustek/miditones * www.github.com/LenShustek/miditones
* www.github.com/LenShustek/arduino-playtune * www.github.com/LenShustek/arduino-playtune
* www.github.com/LenShustek/Playtune_poll
* www.github.com/LenShustek/Playtune_poll
* www.github.com/LenShustek/Playtune_synth
* www.github.com/LenShustek/ATtiny-playtune
* *
*---------------------------------------------------------------------------------------- *----------------------------------------------------------------------------------------
* The MIT License (MIT) * The MIT License (MIT)
* Copyright (c) 2011,2013,2015,2016, Len Shustek * Copyright (c) 2011,2013,2015,2016,2019, Len Shustek
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -78,8 +72,7 @@
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************************/ ******************************************************************************************/
// formatted with: indent miditones_scroll.c -br -brf -brs -ce -npsl -nut -i3 -l100 -lc100 // formatted with: Astyle -style=lisp -indent=spaces=3 -mode=c
/* /*
* Change log * Change log
* *
@ -108,9 +101,17 @@
* - Count the number of unnecessary "stop note" commands in the bytestream * - Count the number of unnecessary "stop note" commands in the bytestream
* 3 January 2019, Chris van Marle, V1.7 * 3 January 2019, Chris van Marle, V1.7
* - Handle repeat command (0xe0) * - Handle repeat command (0xe0)
* 13 January 2019, L. Shustek, V1.8
* - Warn about consecutive delays without intervening notes
* - Mark the location of warnings with a '!' before the hex address
* - Move the "duration" column (now "delay") to before the
* bytestream, to better indicate what order events happen in.
* - Write the output to <basefilename>.txt, if not -c
* - Decode the header flags
* - Reformat to condense the code
*/ */
#define VERSION "1.6" #define VERSION "1.8"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -119,7 +120,6 @@
#include <time.h> #include <time.h>
#include <inttypes.h> #include <inttypes.h>
/*********** Global variables ******************/ /*********** Global variables ******************/
#define MAX_TONEGENS 16 /* max tone generators we could display */ #define MAX_TONEGENS 16 /* max tone generators we could display */
@ -132,13 +132,15 @@ int gen_instrument[MAX_TONEGENS]; // the instrument we're playing
bool gen_instrument_changed[MAX_TONEGENS]; bool gen_instrument_changed[MAX_TONEGENS];
bool gen_did_stopnote[MAX_TONEGENS]; // did we just do a stopnote? bool gen_did_stopnote[MAX_TONEGENS]; // did we just do a stopnote?
FILE *infile, *outfile; FILE *infile, *outfile, *infofile;
unsigned char *buffer, *bufptr; unsigned char *buffer, *bufptr;
unsigned long buflen; unsigned long buflen;
unsigned int num_tonegens = 6; // default number of generators unsigned int num_tonegens = 6; // default number of generators
unsigned int max_tonegen_found = 0; unsigned int max_tonegen_found = 0;
unsigned int notes_skipped = 0; unsigned int notes_skipped = 0;
unsigned int stopnotes_before_startnote = 0; unsigned int stopnotes_before_startnote = 0;
unsigned int consecutive_delays = 0;
bool warning = false;
unsigned long timenow = 0; unsigned long timenow = 0;
unsigned char cmd, gen; unsigned char cmd, gen;
@ -147,7 +149,7 @@ unsigned delay;
bool codeoutput = false; bool codeoutput = false;
bool expect_volume = false; bool expect_volume = false;
bool ignore_volume = false; bool ignore_volume = false;
bool ignore_instruments = false; bool showhex = false;
struct file_hdr_t { /* what the optional file header looks like */ struct file_hdr_t { /* what the optional file header looks like */
char id1; // 'P' char id1; // 'P'
@ -195,8 +197,7 @@ static char *notename[256] = { /* maximum 5 characters */
"P096 ", "P097 ", "P098 ", "P099 ", "P100 ", "P101 ", "P102 ", "P103 ", "P096 ", "P097 ", "P098 ", "P099 ", "P100 ", "P101 ", "P102 ", "P103 ",
"P104 ", "P105 ", "P106 ", "P107 ", "P108 ", "P109 ", "P110 ", "P111 ", "P104 ", "P105 ", "P106 ", "P107 ", "P108 ", "P109 ", "P110 ", "P111 ",
"P112 ", "P113 ", "P114 ", "P115 ", "P116 ", "P117 ", "P118 ", "P119 ", "P112 ", "P113 ", "P114 ", "P115 ", "P116 ", "P117 ", "P118 ", "P119 ",
"P120 ", "P121 ", "P122 ", "P123 ", "P124 ", "P125 ", "P126 ", "P127" "P120 ", "P121 ", "P122 ", "P123 ", "P124 ", "P125 ", "P126 ", "P127" };
};
static char *instrumentname[128] = { /* maximum 6 characters */ static char *instrumentname[128] = { /* maximum 6 characters */
"APiano", "BPiano", "EPiano", "HPiano", "E1Pian", "E2Pian", "Harpsi", "Clavic", "APiano", "BPiano", "EPiano", "HPiano", "E1Pian", "E2Pian", "Harpsi", "Clavic",
@ -214,8 +215,7 @@ static char *instrumentname[128] = { /* maximum 6 characters */
"FX1 ", "FX2 ", "FX3 ", "FX4 ", "FX5 ", "FX6 ", "FX7 ", "FX8 ", "FX1 ", "FX2 ", "FX3 ", "FX4 ", "FX5 ", "FX6 ", "FX7 ", "FX8 ",
"Sitar ", "Banjo ", "Shamis", "Koto ", "Kalimb", "Bagpip", "Fiddle", "Shanai", "Sitar ", "Banjo ", "Shamis", "Koto ", "Kalimb", "Bagpip", "Fiddle", "Shanai",
"TnkBel", "Agogo ", "StDrum", "WdBlok", "TaiDrm", "MelTom", "SynDrm", "RevCym", "TnkBel", "Agogo ", "StDrum", "WdBlok", "TaiDrm", "MelTom", "SynDrm", "RevCym",
"GuitFr", "Breath", "Seashr", "BirdTw", "Phone ", "Copter", "Claps ", "Guns " "GuitFr", "Breath", "Seashr", "BirdTw", "Phone ", "Copter", "Claps ", "Guns " };
};
/************** command-line processing *******************/ /************** command-line processing *******************/
@ -228,13 +228,12 @@ void SayUsage (char *programName) {
" -tn displays up to n tone generators", " -tn displays up to n tone generators",
" -v expects and displays volume information", " -v expects and displays volume information",
" -vi expects and ignores volume information", " -vi expects and ignores volume information",
" -c option creates an annotated C source file as <basefile>.c", " -c creates an annotated C source file as <basefile>.c",
"" " -x show notes in hex instead of octave/note",
}; "" };
int i = 0; int i = 0;
while (usage[i][0] != '\0') while (usage[i][0] != '\0')
fprintf (stderr, "%s\n", usage[i++]); fprintf (stderr, "%s\n", usage[i++]); }
}
int HandleOptions (int argc, char *argv[]) { int HandleOptions (int argc, char *argv[]) {
/* returns the index of the first argument that is not an option; i.e. /* returns the index of the first argument that is not an option; i.e.
@ -253,11 +252,13 @@ int HandleOptions (int argc, char *argv[]) {
case 'C': case 'C':
codeoutput = true; codeoutput = true;
break; break;
case 'X':
showhex = true;
break;
case 'T': case 'T':
if (sscanf (&argv[i][2], "%d", &num_tonegens) != 1 || num_tonegens < 1 if (sscanf (&argv[i][2], "%d", &num_tonegens) != 1 || num_tonegens < 1
|| num_tonegens > MAX_TONEGENS) || num_tonegens > MAX_TONEGENS)
goto opterror; goto opterror;
printf ("Displaying %d tone generators.\n", num_tonegens);
break; break;
case 'V': case 'V':
expect_volume = true; expect_volume = true;
@ -274,23 +275,18 @@ int HandleOptions (int argc, char *argv[]) {
default: default:
fprintf (stderr, "unknown option: %s\n", argv[i]); fprintf (stderr, "unknown option: %s\n", argv[i]);
SayUsage (argv[0]); SayUsage (argv[0]);
exit (4); exit (4); } }
} else {
} else {
firstnonoption = i; firstnonoption = i;
break; break; } }
} return firstnonoption; }
}
return firstnonoption;
}
/*************** portable string length *****************/ /*************** portable string length *****************/
int strlength (const char *str) { int strlength (const char *str) {
int i; int i;
for (i = 0; str[i] != '\0'; ++i); for (i = 0; str[i] != '\0'; ++i);
return i; return i; }
}
/*************** safe string copy *****************/ /*************** safe string copy *****************/
@ -298,19 +294,15 @@ unsigned int strlcpy (char *dst, const char *src, unsigned int siz) {
char *d = dst; char *d = dst;
const char *s = src; const char *s = src;
unsigned int n = siz; unsigned int n = siz;
/* Copy as many bytes as will fit */ if (n != 0) { /* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) { while (--n != 0) {
if ((*d++ = *s++) == '\0') if ((*d++ = *s++) == '\0')
break; break; } }
}
}
/* Not enough room in dst, add NUL and traverse rest of src */ /* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) { if (n == 0) {
if (siz != 0) if (siz != 0)
*d = '\0'; /* NUL-terminate dst */ *d = '\0'; /* NUL-terminate dst */
while (*s++); while (*s++); }
}
return (s - src - 1); /* count does not include NUL */ return (s - src - 1); /* count does not include NUL */
} }
@ -322,140 +314,118 @@ unsigned int strlcat (char *dst, const char *src, unsigned int siz) {
unsigned int n = siz; unsigned int n = siz;
unsigned int dlen; unsigned int dlen;
/* Find the end of dst and adjust bytes left but don't go past end */ /* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0') while (n-- != 0 && *d != '\0') d++;
d++;
dlen = d - dst; dlen = d - dst;
n = siz - dlen; n = siz - dlen;
if (n == 0) if (n == 0) return (dlen + strlength (s));
return (dlen + strlength (s));
while (*s != '\0') { while (*s != '\0') {
if (n != 1) { if (n != 1) {
*d++ = *s; *d++ = *s;
n--; n--; }
} s++; }
s++;
}
*d = '\0'; *d = '\0';
return (dlen + (s - src)); /* count does not include NUL */ return (dlen + (s - src)); /* count does not include NUL */
} }
/*************** Found a file format error ************************/
/*************** Found a fatal input file format error ************************/
void file_error (char *msg, unsigned char *bufptr) { void file_error (char *msg, unsigned char *bufptr) {
unsigned char *ptr; unsigned char *ptr;
fprintf (stderr, "\n---> file format error at position %04X (%d): %s\n", fprintf (outfile, "\n---> file format error at position %04X (%d), time %d.%03d: %s\n",
(unsigned int) (bufptr - buffer), (unsigned int) (bufptr - buffer), msg); (unsigned int) (bufptr - buffer), (unsigned int) (bufptr - buffer), timenow / 1000, timenow % 1000, msg);
/* print some bytes surrounding the error */ /* print some bytes surrounding the error */
ptr = bufptr - 16; ptr = bufptr - 16;
if (ptr < buffer) if (ptr < buffer) ptr = buffer;
ptr = buffer;
for (; ptr <= bufptr + 16 && ptr < buffer + buflen; ++ptr) for (; ptr <= bufptr + 16 && ptr < buffer + buflen; ++ptr)
fprintf (stderr, ptr == bufptr ? " [%02X] " : "%02X ", *ptr); fprintf (outfile, ptr == bufptr ? " [%02X] " : "%02X ", *ptr);
fprintf (stderr, "\n"); fprintf (outfile, "\n"); }
exit (8);
}
/************** Output a line for the current status as we start a delay **************/ /************** Output a line for the current status as we start a delay **************/
// show the current time, status of all the tone generators, and the bytestream data that got us here // show the current time, status of all the tone generators, and the bytestream data that got us here
void print_status (void) { void print_status (void) {
int gen; unsigned gen;
bool any_instr_changed = false; bool any_instr_changed = false;
for (gen = 0; gen < num_tonegens; ++gen) for (gen = 0; gen < num_tonegens; ++gen)
any_instr_changed |= gen_instrument_changed[gen]; any_instr_changed |= gen_instrument_changed[gen];
if (any_instr_changed) { if (any_instr_changed) {
if (codeoutput) if (codeoutput)
fprintf (outfile, "//"); fprintf (outfile, "//");
fprintf (outfile, "%21s", ""); fprintf (outfile, "%15s", "");
for (gen = 0; gen < num_tonegens; ++gen) { for (gen = 0; gen < num_tonegens; ++gen) {
if (gen_instrument_changed[gen]) { if (gen_instrument_changed[gen]) {
gen_instrument_changed[gen] = false; gen_instrument_changed[gen] = false;
fprintf (outfile, "%6s", instrumentname[gen_instrument[gen]]); fprintf (outfile, "%6s", instrumentname[gen_instrument[gen]]); }
} else else
fprintf (outfile, "%6s", ""); fprintf (outfile, "%6s", "");
if (expect_volume && !ignore_volume) if (expect_volume && !ignore_volume)
fprintf (outfile, "%5s", ""); fprintf (outfile, "%5s", ""); }
} fprintf (outfile, "\n"); }
fprintf (outfile, "\n");
}
if (codeoutput) if (codeoutput)
fprintf (outfile, "/*"); // start comment fprintf (outfile, "/*"); // start comment
// print the current timestamp // print the current timestamp
fprintf (outfile, "%5d %7d.%03d ", delay, timenow / 1000, timenow % 1000); fprintf (outfile, "%7d.%03d ", timenow / 1000, timenow % 1000);
// print the current status of all tone generators // print the current status of all tone generators
for (gen = 0; gen < num_tonegens; ++gen) { for (gen = 0; gen < num_tonegens; ++gen) {
fprintf (outfile, "%6s", gen_note[gen] == SILENT ? " " : notename[gen_note[gen]]); if (showhex && gen_note[gen] != SILENT)
fprintf(outfile, " 0x%02X ", gen_note[gen]);
else fprintf (outfile, "%6s", gen_note[gen] == SILENT ? " " : notename[gen_note[gen]]);
if (expect_volume && !ignore_volume) if (expect_volume && !ignore_volume)
if (gen_note[gen] == SILENT) if (gen_note[gen] == SILENT)
fprintf (outfile, " "); fprintf (outfile, " ");
else else
fprintf (outfile, " v%-3d", gen_volume[gen]); fprintf (outfile, " v%-3d", gen_volume[gen]); }
}
// display the hex commands that created these changes // display the hex commands that created these changes
fprintf (outfile, " %04X: ", (unsigned int) (lastbufptr - buffer)); // offset fprintf (outfile, "%3u.%03u %c%04X: ", delay/1000, delay%1000, warning ? '!' : ' ', (unsigned int) (lastbufptr - buffer));
warning = false;
if (codeoutput) if (codeoutput)
fprintf (outfile, "*/ "); // end comment fprintf (outfile, "*/ "); // end comment
for (; lastbufptr <= bufptr; ++lastbufptr) for (; lastbufptr <= bufptr; ++lastbufptr)
fprintf (outfile, codeoutput ? "0x%02X," : "%02X ", *lastbufptr); fprintf (outfile, codeoutput ? "0x%02X," : "%02X ", *lastbufptr);
fprintf (outfile, "\n"); fprintf (outfile, "\n");
lastbufptr = bufptr + 1; lastbufptr = bufptr + 1; }
}
int countbits (unsigned int bitmap) { int countbits (unsigned int bitmap) {
int count; int count;
for (count = 0; bitmap; bitmap >>= 1) for (count = 0; bitmap; bitmap >>= 1)
count += bitmap & 1; count += bitmap & 1;
return count; return count; }
}
/********************* main loop ****************************/ /********************* main loop ****************************/
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
int argno, i; int argno;
char *filebasename; char *filebasename;
#define MAXPATH 80 #define MAXPATH 80
char filename[MAXPATH]; char filename[MAXPATH];
unsigned int tonegens_used; // bitmap of tone generators used
unsigned int num_tonegens_used; // count of tone generators used
printf ("MIDITONES_SCROLL V%s, (C) 2011,2016 Len Shustek\n", VERSION); printf ("MIDITONES_SCROLL V%s, (C) 2011,2019 Len Shustek\n", VERSION);
if (argc == 1) { /* no arguments */ if (argc == 1) { /* no arguments */
SayUsage (argv[0]); SayUsage (argv[0]);
return 1; return 1; }
}
/* process options */ argno = HandleOptions (argc, argv); /* process options */
argno = HandleOptions (argc, argv);
filebasename = argv[argno]; filebasename = argv[argno];
/* Open the input file */ strlcpy (filename, filebasename, MAXPATH); // Open the input file
strlcpy (filename, filebasename, MAXPATH);
strlcat (filename, ".bin", MAXPATH); strlcat (filename, ".bin", MAXPATH);
infile = fopen (filename, "rb"); infile = fopen (filename, "rb");
if (!infile) { if (!infile) {
fprintf (stderr, "Unable to open input file %s", filename); fprintf (stderr, "Unable to open input file %s", filename);
return 1; return 8; }
} printf("Opening %s\n", filename);
/* Create the output file */
if (codeoutput) { strlcpy (filename, filebasename, MAXPATH); // open the output file
strlcpy (filename, filebasename, MAXPATH); strlcat (filename, codeoutput ? ".c" : ".txt", MAXPATH);
strlcat (filename, ".c", MAXPATH);
outfile = fopen (filename, "w"); outfile = fopen (filename, "w");
if (!infile) { if (!outfile) {
fprintf (stderr, "Unable to open output file %s", filename); fprintf (stderr, "Unable to open output file %s", filename);
return 1; return 8; }
} printf("Creating %s\n", filename);
} else infofile = codeoutput ? stdout : outfile;
outfile = stdout;
/* Read the whole input file into memory */ /* Read the whole input file into memory */
@ -465,62 +435,77 @@ int main (int argc, char *argv[]) {
buffer = (unsigned char *) malloc (buflen + 1); buffer = (unsigned char *) malloc (buflen + 1);
if (!buffer) { if (!buffer) {
fprintf (stderr, "Unable to allocate %ld bytes for the file", buflen); fprintf (stderr, "Unable to allocate %ld bytes for the file", buflen);
return 1; return 8; }
}
fread (buffer, buflen, 1, infile); fread (buffer, buflen, 1, infile);
fclose (infile); fclose (infile);
printf ("Processing %s.bin, %ld bytes.\n", filebasename, buflen);
if (codeoutput) { /* write the prologue */
time_t rawtime; time_t rawtime;
time (&rawtime); time (&rawtime);
printf ("Reading %s.bin with %ld bytes\n", filebasename, buflen);
if (!codeoutput) {
fprintf(outfile, "MIDITONES_SCROLL V%s on %s", VERSION, asctime(localtime(&rawtime)));
fprintf(outfile, "command line: ");
for (int i = 0; i < argc; i++) fprintf(outfile, "%s ", argv[i]);
fprintf(outfile, "\n");
fprintf(outfile, "reading %s.bin with %ld bytes\n", filebasename, buflen);
if (num_tonegens < MAX_TONEGENS) fprintf(outfile, "displaying only %d tone generators.\n", num_tonegens);
}
else {
fprintf (outfile, "// Playtune bytestream for file \"%s.bin\"", filebasename); fprintf (outfile, "// Playtune bytestream for file \"%s.bin\"", filebasename);
fprintf (outfile, " created by MIDITONES_SCROLL V%s on %s\n", VERSION, fprintf (outfile, " created by MIDITONES_SCROLL V%s on %s\n", VERSION,
asctime (localtime (&rawtime))); asctime (localtime (&rawtime)));
fprintf (outfile, "const byte PROGMEM score [] = {\n"); fprintf (outfile, "const byte PROGMEM score [] = {\n"); }
} bufptr = lastbufptr = buffer;
/* Check for the optional self-describing file header */ /* Check for the optional self-describing file header */
bufptr = buffer;
{
struct file_hdr_t *hdrptr = (struct file_hdr_t *) buffer; struct file_hdr_t *hdrptr = (struct file_hdr_t *) buffer;
if (buflen > sizeof (struct file_hdr_t) && hdrptr->id1 == 'P' && hdrptr->id2 == 't') { if (buflen > sizeof (struct file_hdr_t) && hdrptr->id1 == 'P' && hdrptr->id2 == 't') {
printf ("Found Pt self-describing file header with flags %02X %02X, # tone gens = %d\n", fprintf(infofile, "\nfound Pt self-describing file header with flags %02X %02X\n", hdrptr->f1, hdrptr->f2);
hdrptr->f1, hdrptr->f2, hdrptr->num_tgens); fprintf(infofile, " number of tone generators used: %d\n", hdrptr->num_tgens);
if (hdrptr->f1 & HDR_F1_VOLUME_PRESENT) fprintf(infofile, " volume levels are present\n");
if (hdrptr->f1 & HDR_F1_INSTRUMENTS_PRESENT) fprintf(infofile, " instrument changes are present\n");
if (hdrptr->f1 & HDR_F1_PERCUSSION_PRESENT) fprintf(infofile, " percussion is encoded as notes 128 to 255\n");
expect_volume = hdrptr->f1 & HDR_F1_VOLUME_PRESENT; expect_volume = hdrptr->f1 & HDR_F1_VOLUME_PRESENT;
bufptr += hdrptr->hdr_length; bufptr += hdrptr->hdr_length;
lastbufptr = bufptr;
if (codeoutput) { if (codeoutput) {
fprintf (outfile, "'P','t', 6, 0x%02X, 0x%02X, %2d, // (Playtune file header)\n", fprintf (outfile, "'P','t', 6, 0x%02X, 0x%02X, %2d, // (Playtune file header)\n",
hdrptr->f1, hdrptr->f2, hdrptr->num_tgens); hdrptr->f1, hdrptr->f2, hdrptr->num_tgens); } }
}
}
}
/* Do the titles */ /* Do the titles */
fprintf (outfile, "\n"); fprintf (outfile, "\n");
if (codeoutput) if (codeoutput) fprintf (outfile, "//");
fprintf (outfile, "//"); fprintf (outfile, " time ");
fprintf (outfile, "duration time "); for (unsigned i = 0; i < num_tonegens; ++i)
for (i = 0; i < num_tonegens; ++i)
fprintf (outfile, expect_volume && !ignore_volume ? " gen%-5d" : " gen%-2d", i); fprintf (outfile, expect_volume && !ignore_volume ? " gen%-5d" : " gen%-2d", i);
fprintf (outfile, " bytestream code\n\n"); fprintf (outfile, "delay addr bytestream code\n\n");
for (gen = 0; gen < num_tonegens; ++gen) for (gen = 0; gen < num_tonegens; ++gen)
gen_note[gen] = SILENT; gen_note[gen] = SILENT;
tonegens_used = 0;
lastbufptr = buffer;
/* Process the commmands sequentially */ unsigned tonegens_used = 0;
bool gotcommand = true;
/* Process the commmands in order */
for (; bufptr < buffer + buflen; ++bufptr) { for (; bufptr < buffer + buflen; ++bufptr) {
cmd = *bufptr; cmd = *bufptr;
if (cmd < 0x80) { /* delay */ if (cmd < 0x80) { /* delay */
if (!gotcommand) {
++consecutive_delays;
warning = true; }
gotcommand = false;
delay = ((unsigned int)cmd << 8) + *++bufptr; delay = ((unsigned int)cmd << 8) + *++bufptr;
print_status(); // tone generator status now print_status(); // tone generator status now
timenow += delay; // advance time timenow += delay; // advance time
for (gen = 0; gen < MAX_TONEGENS; ++gen) for (gen = 0; gen < MAX_TONEGENS; ++gen)
gen_did_stopnote[gen] = false; gen_did_stopnote[gen] = false; }
} else if (cmd != 0xf0 && cmd != 0xe0) { /* a command */ else if (cmd != 0xf0 && cmd != 0xe0) { /* a command */
gotcommand = true;
gen = cmd & 0x0f; gen = cmd & 0x0f;
if (gen > max_tonegen_found) if (gen > max_tonegen_found)
max_tonegen_found = gen; max_tonegen_found = gen;
@ -528,27 +513,25 @@ int main (int argc, char *argv[]) {
if (cmd == 0x90) { /* note on */ if (cmd == 0x90) { /* note on */
gen_note[gen] = *++bufptr; // note number gen_note[gen] = *++bufptr; // note number
tonegens_used |= 1 << gen; // record that we used this generator at least once tonegens_used |= 1 << gen; // record that we used this generator at least once
if (gen_did_stopnote[gen]) { if (gen_did_stopnote[gen]) { // unnecesary stop note
++stopnotes_before_startnote; ++stopnotes_before_startnote;
// printf("unnecessary stopnote on gen %d\n", gen); warning = true; }
}
if (expect_volume) if (expect_volume)
gen_volume[gen] = *++bufptr; // volume gen_volume[gen] = *++bufptr; // volume
if (gen >= num_tonegens) if (gen >= num_tonegens) ++notes_skipped; // won't be displaying this note
++notes_skipped; // won't be displaying this note }
} else if (cmd == 0x80) { /* note off */ else if (cmd == 0x80) { /* note off */
if (gen_note[gen] == SILENT) if (gen_note[gen] == SILENT)
file_error("tone generator not on", bufptr); file_error("tone generator not on", bufptr);
gen_note[gen] = SILENT; gen_note[gen] = SILENT;
gen_did_stopnote[gen] = true; gen_did_stopnote[gen] = true; }
} else if (cmd == 0xc0) { /* change instrument */ else if (cmd == 0xc0) { /* change instrument */
gen_instrument[gen] = *++bufptr & 0x7f; gen_instrument[gen] = *++bufptr & 0x7f;
gen_instrument_changed[gen] = true; gen_instrument_changed[gen] = true; }
} else else {
file_error("unknown command", bufptr); file_error("unknown command", bufptr);
} fprintf(stderr, "*** unknown command in input bytestream; see output file\n");
} exit(8); } } }
/* Do the final cleanup */ /* Do the final cleanup */
@ -559,15 +542,17 @@ int main (int argc, char *argv[]) {
print_status (); // print final status print_status (); // print final status
if (codeoutput) { if (codeoutput) {
fprintf (outfile, " 0x%02x};\n", *(bufptr+1) & 0xf0); fprintf (outfile, " 0x%02x};\n", *(bufptr+1) & 0xf0);
num_tonegens_used = countbits (tonegens_used); unsigned num_tonegens_used = countbits (tonegens_used);
fprintf (outfile, "// This score contains %ld bytes, and %d tone generator%s used.\n", fprintf (outfile, "// This score contains %ld bytes, and %d tone generator%s used.\n",
buflen, num_tonegens_used, num_tonegens_used == 1 ? " is" : "s are"); buflen, num_tonegens_used, num_tonegens_used == 1 ? " is" : "s are"); }
} else else
fprintf (outfile, "\n"); fprintf (outfile, "\n");
printf ("At most %u tone generators were used.\n", max_tonegen_found + 1);
fprintf (infofile, "At most %u tone generators were used.\n", max_tonegen_found + 1);
if (notes_skipped) if (notes_skipped)
printf ("%u notes were not displayed because we were told to show only %u generators.\n", fprintf (infofile, "%u notes were not displayed because we were told to show only %u generators.\n",
notes_skipped, num_tonegens); notes_skipped, num_tonegens);
printf("%u stopnote commands were unnecessary.\n", stopnotes_before_startnote); fprintf (infofile, "%u stopnote commands were unnecessary.\n", stopnotes_before_startnote);
printf ("Done.\n"); fprintf (infofile, "%u consecutive delays could have been merged.\n", consecutive_delays);
} if (stopnotes_before_startnote + consecutive_delays > 0) fprintf (infofile, "(Those locations are marked with \"!\")\n");
printf ("Done.\n"); }

Binary file not shown.

@ -0,0 +1,178 @@
MIDITONES_SCROLL V1.8 on Tue Jan 15 08:25:22 2019
command line: ..\..\miditones_scroll\debug\miditones_scroll -t6 money
reading money.bin with 29733 bytes
displaying only 6 tone generators.
found Pt self-describing file header with flags E0 00
number of tone generators used: 16
volume levels are present
instrument changes are present
percussion is encoded as notes 128 to 255
time gen0 gen1 gen2 gen3 gen4 gen5 delay addr bytestream code
0.000 2.000 0006: 07 D0
2.000 HHatC v65 0.015 0008: 90 AA 41 00 0F
2.015 0.485 000D: 80 01 E5
2.500 HHatC v65 0.015 0010: 90 AA 41 00 0F
2.515 0.485 0015: 80 01 E5
3.000 HHatC v65 0.015 0018: 90 AA 41 00 0F
3.015 0.485 001D: 80 01 E5
3.500 HHatC v65 0.015 0020: 90 AA 41 00 0F
3.515 0.485 0025: 80 01 E5
BPiano BPiano BPiano BPiano Xyloph
4.000 4E v104 4A v108 5C v104 5E v108 6E v88 0.062 0028: C0 01 90 40 68 C1 01 91 45 6C C2 01 92 48 68 C3 01 93 4C 6C C4 0D 94 58 58 00 3E
4.062 6E v88 0.063 0043: 80 81 82 83 00 3F
4.125 0.125 0049: 84 00 7D
4.250 4E v96 4A v100 5C v84 5E v78 6E v72 0.062 004C: 90 40 60 91 45 64 92 48 54 93 4C 4E 94 58 48 00 3E
4.312 6E v72 0.063 005D: 80 81 82 83 00 3F
4.375 0.125 0063: 84 00 7D
4.500 4E v84 4A v88 5C v78 5E v92 6E v84 0.062 0066: 90 40 54 91 45 58 92 48 4E 93 4C 5C 94 58 54 00 3E
4.562 6E v84 0.063 0077: 80 81 82 83 00 3F
4.625 0.125 007D: 84 00 7D
4.750 4E v100 4A v100 5C v82 5E v88 6E v88 0.062 0080: 90 40 64 91 45 64 92 48 52 93 4C 58 94 58 58 00 3E
4.812 6E v88 0.063 0091: 80 81 82 83 00 3F
4.875 0.125 0097: 84 00 7D
5.000 4E v96 4A v100 5C v88 5E v104 6E v88 0.062 009A: 90 40 60 91 45 64 92 48 58 93 4C 68 94 58 58 00 3E
5.062 6E v88 0.063 00AB: 80 81 82 83 00 3F
5.125 0.125 00B1: 84 00 7D
5.250 4E v88 4A v92 5C v78 5E v104 6E v88 0.125 00B4: 90 40 58 91 45 5C 92 48 4E 93 4C 68 94 58 58 00 7D
5.375 4E v88 4A v92 5C v78 5E v104 0.098 00C5: 84 00 62
5.473 0.026 00C8: 80 81 82 83 00 1A
5.499 4E v108 5E v66 0.125 00CE: 90 40 6C 94 4C 42 00 7D
5.624 4A v108 5A v62 0.125 00D6: 90 45 6C 94 51 3E 00 7D
5.749 5C v96 6C v62 0.125 00DE: 90 48 60 94 54 3E 00 7D
5.874 5E v104 6E v80 0.125 00E6: 90 4C 68 94 58 50 00 7D
5.999 4F v104 4A v86 5C v84 5D# v65 6D# v68 0.063 00EE: 90 41 68 91 45 56 92 48 54 93 4B 41 94 57 44 00 3F
6.062 6D# v68 0.062 00FF: 80 81 82 83 00 3E
6.124 0.125 0105: 84 00 7D
6.249 4F v59 4A v88 5C v80 5D# v82 6D# v88 0.063 0108: 90 41 3B 91 45 58 92 48 50 93 4B 52 94 57 58 00 3F
6.312 6D# v88 0.062 0119: 80 81 82 83 00 3E
6.374 0.125 011F: 84 00 7D
6.499 4F v96 4A v100 5C v84 5D# v82 6D# v88 0.063 0122: 90 41 60 91 45 64 92 48 54 93 4B 52 94 57 58 00 3F
6.562 6D# v88 0.062 0133: 80 81 82 83 00 3E
6.624 0.125 0139: 84 00 7D
6.749 4F v92 4A v100 5C v80 5D# v82 6D# v76 0.063 013C: 90 41 5C 91 45 64 92 48 50 93 4B 52 94 57 4C 00 3F
6.812 6D# v76 0.062 014D: 80 81 82 83 00 3E
6.874 0.125 0153: 84 00 7D
6.999 4F v100 4A v108 5C v84 5D# v80 6D# v64 0.063 0156: 90 41 64 91 45 6C 92 48 54 93 4B 50 94 57 40 00 3F
7.062 6D# v64 0.062 0167: 80 81 82 83 00 3E
7.124 0.125 016D: 84 00 7D
7.249 4F v78 4A v100 5C v78 5D# v74 6D# v80 0.125 0170: 90 41 4E 91 45 64 92 48 4E 93 4B 4A 94 57 50 00 7D
7.374 4F v78 4A v100 5C v78 5D# v74 0.099 0181: 84 00 63
7.473 0.026 0184: 80 81 82 83 00 1A
7.499 4F v104 5F v64 0.125 018A: 90 41 68 94 4D 40 00 7D
7.624 4A v82 5A v64 0.125 0192: 90 45 52 94 51 40 00 7D
7.749 5C v74 6C v62 0.125 019A: 90 48 4A 94 54 3E 00 7D
7.874 5D# v92 6D# v76 0.125 01A2: 90 4B 5C 94 57 4C 00 7D
7.999 3D v86 4F v92 4A v92 5D v88 6D v88 0.125 01AA: 90 32 56 91 41 5C 92 45 5C 93 4A 58 94 56 58 00 7D
8.124 3D v86 4F v92 4A v92 5D v88 0.334 01BB: 84 01 4E
8.458 3D v86 4F v92 5D v88 0.021 01BE: 82 00 15
8.479 3D v86 4F v92 0.020 01C1: 83 00 14
8.499 3D v86 4F v92 5C v104 6C v84 0.115 01C4: 92 48 68 94 54 54 00 73
8.614 3D v86 5C v104 6C v84 0.010 01CC: 81 00 0A
8.624 3D v86 5C v104 0.089 01CF: 84 00 59
8.713 3D v86 0.036 01D2: 82 00 24
8.749 3D v86 4A v72 5A v62 0.063 01D5: 91 45 48 94 51 3E 00 3F
8.812 3D v86 5A v62 0.062 01DD: 81 00 3E
8.874 3D v86 0.094 01E0: 84 00 5E
8.968 0.031 01E3: 80 00 1F
8.999 3E v74 4D v82 4G# v104 5C v104 6C v84 0.079 01E6: 90 34 4A 91 3E 52 92 44 68 93 48 68 94 54 54 00 4F
9.078 3E v74 4D v82 6C v84 0.015 01F7: 82 83 00 0F
9.093 3E v74 6C v84 0.031 01FB: 81 00 1F
9.124 3E v74 0.084 01FE: 84 00 54
9.208 0.041 0201: 80 00 29
9.249 3E v58 4D v86 4G# v112 5C v112 6C v84 0.125 0204: 90 34 3A 91 3E 56 92 44 70 93 48 70 94 54 54 00 7D
9.374 3E v58 4D v86 4G# v112 5C v112 0.250 0215: 84 00 FA
9.624 3E v58 0.084 0218: 81 82 83 00 54
9.708 0.041 021D: 80 00 29
9.749 4C v112 4E v96 4A v100 5A v80 0.125 0220: 90 3C 70 91 40 60 92 45 64 94 51 50 00 7D
9.874 4C v112 4E v96 4A v100 0.230 022E: 84 00 E6
10.104 4C v112 4E v96 0.026 0231: 82 00 1A
10.130 4C v112 0.031 0234: 81 00 1F
10.161 0.338 0237: 80 01 52
10.499 2A v96 0.063 023A: 90 2D 60 00 3F
10.562 2A v96 3E v100 0.062 023F: 91 34 64 00 3E
10.624 2A v96 3E v100 3A v82 0.032 0244: 92 39 52 00 20
10.656 3E v100 3A v82 0.010 0249: 80 00 0A
10.666 3A v82 0.021 024C: 81 00 15
10.687 3C v88 3A v82 0.016 024F: 90 30 58 00 10
10.703 3C v88 0.046 0254: 82 00 2E
10.749 3C v88 3E v86 0.021 0257: 91 34 56 00 15
10.770 3E v86 0.042 025C: 80 00 2A
10.812 3A v76 3E v86 0.016 025F: 90 39 4C 00 10
10.828 3A v76 0.031 0264: 81 00 1F
10.859 0.015 0267: 80 00 0F
10.874 4C v100 0.063 026A: 90 3C 64 00 3F
10.937 4C v100 4E v88 0.062 026F: 91 40 58 00 3E
10.999 4C v100 4E v88 4A v112 6A v92 0.011 0274: 92 45 70 94 5D 5C 00 0B
11.010 4E v88 4A v112 6A v92 0.021 027C: 80 00 15
11.031 4A v112 6A v92 0.031 027F: 81 00 1F
11.062 6A v92 0.062 0282: 82 00 3E
11.124 0.875 0285: 84 03 6B
FiBass Callip
11.999 1A v56 3A v74 5A v55 BassD v61 0.016 0288: C0 21 90 21 38 91 39 4A 95 A3 3D C2 52 92 51 37 00 10
12.015 1A v56 3A v74 5A v55 0.109 029A: 85 00 6D
12.124 1A v56 3B v72 5B v53 0.125 029D: 91 3B 48 92 53 35 00 7D
12.249 2A v58 4C v66 6C v52 0.094 02A5: 90 2D 3A 91 3C 42 92 54 34 00 5E
12.343 4C v66 6C v52 0.031 02B0: 80 00 1F
12.374 4E v96 6E v51 0.125 02B3: 91 40 60 92 58 33 00 7D
12.499 1A v56 3A v84 5A v50 BassD v61 0.016 02BB: 90 21 38 91 39 54 95 A3 3D 92 51 32 00 10
12.515 1A v56 3A v84 5A v50 0.109 02C9: 85 00 6D
12.624 1A v56 3B v88 5B v48 0.125 02CC: 91 3B 58 92 53 30 00 7D
12.749 2A v54 4C v82 6C v47 0.084 02D4: 90 2D 36 91 3C 52 92 54 2F 00 54
12.833 4C v82 6C v47 0.041 02DF: 80 00 29
12.874 4E v112 6E v46 0.125 02E2: 91 40 70 92 58 2E 00 7D
12.999 1A v60 3A v108 5A v44 BassD v62 0.016 02EA: 90 21 3C 91 39 6C 95 A3 3E 92 51 2C 00 10
13.015 1A v60 3A v108 5A v44 0.109 02F8: 85 00 6D
13.124 1A v60 3B v104 5B v43 0.125 02FB: 91 3B 68 92 53 2B 00 7D
13.249 2A v54 4C v100 6C v42 0.120 0303: 90 2D 36 91 3C 64 92 54 2A 00 78
13.369 4C v100 6C v42 0.005 030E: 80 00 05
13.374 4E v108 6E v40 0.125 0311: 91 40 6C 92 58 28 00 7D
13.499 1A v62 3A v100 5A v39 BassD v63 0.016 0319: 90 21 3E 91 39 64 95 A3 3F 92 51 27 00 10
13.515 1A v62 3A v100 5A v39 0.109 0327: 85 00 6D
13.624 1A v62 3B v112 5B v38 0.125 032A: 91 3B 70 92 53 26 00 7D
13.749 2A v58 4C v104 6C v37 0.125 0332: 90 2D 3A 91 3C 68 92 54 25 00 7D
13.874 2A v58 4E v117 6E v35 0.011 033D: 91 40 75 92 58 23 00 0B
13.885 4E v117 6E v35 0.114 0345: 80 00 72
13.999 1A v60 3A v100 5A v34 BassD v63 0.016 0348: 90 21 3C 91 39 64 95 A3 3F 92 51 22 00 10
14.015 1A v60 3A v100 5A v34 0.109 0356: 85 00 6D
14.124 1A v60 3B v100 5B v33 0.125 0359: 91 3B 64 92 53 21 00 7D
14.249 2A v54 4C v86 6C v31 0.073 0361: 90 2D 36 91 3C 56 92 54 1F 00 49
14.322 4C v86 6C v31 0.052 036C: 80 00 34
14.374 4E v92 6E v30 0.125 036F: 91 40 5C 92 58 1E 00 7D
14.499 1A v60 3A v84 5A v29 BassD v64 0.016 0377: 90 21 3C 91 39 54 95 A3 40 92 51 1D 00 10
14.515 1A v60 3A v84 5A v29 0.109 0385: 85 00 6D
14.624 1A v60 3B v74 5B v27 0.125 0388: 91 3B 4A 92 53 1B 00 7D
14.749 2A v50 4C v70 6C v26 0.058 0390: 90 2D 32 91 3C 46 92 54 1A 00 3A
14.807 4C v70 6C v26 0.067 039B: 80 00 43
14.874 4E v86 6E v25 0.125 039E: 91 40 56 92 58 19 00 7D
14.999 1A v62 3A v74 5A v24 BassD v65 0.016 03A6: 90 21 3E 91 39 4A 95 A3 41 92 51 18 00 10
15.015 1A v62 3A v74 5A v24 0.109 03B4: 85 00 6D
15.124 1A v62 3B v74 5B v22 0.125 03B7: 91 3B 4A 92 53 16 00 7D
15.249 2A v54 4C v60 6C v21 0.089 03BF: 90 2D 36 91 3C 3C 92 54 15 00 59
15.338 4C v60 6C v21 0.036 03CA: 80 00 24
15.374 4E v72 6E v20 0.125 03CD: 91 40 48 92 58 14 00 7D
15.499 1A v58 3A v56 5A v18 BassD v65 0.016 03D5: 90 21 3A 91 39 38 95 A3 41 92 51 12 00 10
15.515 1A v58 3A v56 5A v18 0.109 03E3: 85 00 6D
15.624 1A v58 3B v64 5B v17 0.125 03E6: 91 3B 40 92 53 11 00 7D
BPiano BPiano
15.749 2A v60 4C v66 6C v16 3A v60 4C v78 4E v72 0.058 03EE: 90 2D 3C 93 39 3C C4 01 94 3C 4E C5 01 95 40 48 C6 57 96 40 49 91 3C 42 92 54 10 00 3A
15.807 2A v60 4C v66 6C v16 3A v60 4E v72 0.005 040B: 84 00 05
15.812 2A v60 4C v66 6C v16 3A v60 4E v72 0.010 040E: 86 00 0A
15.822 2A v60 4C v66 6C v16 0.011 0411: 83 85 00 0B
15.833 4C v66 6C v16 0.041 0415: 80 00 29
<...snip...>
188.300 1A# v92 4A# v102 2A# v100 3A# v127 5C# v100 5F v117 0.021 740D: 87 88 8F 00 15
188.321 1A# v92 4A# v102 2A# v100 3A# v127 5C# v100 5F v117 0.031 7412: 8D 00 1F
188.352 1A# v92 2A# v100 3A# v127 5C# v100 5F v117 0.036 7415: 81 00 24
188.388 2A# v100 5C# v100 5F v117 0.011 7418: 80 83 89 00 0B
188.399 2A# v100 5F v117 0.005 741D: 84 00 05
188.404 2A# v100 0.026 7420: 85 00 1A
188.430 0.000 7423: 82 F0
At most 16 tone generators were used.
2306 notes were not displayed because we were told to show only 6 generators.
0 stopnote commands were unnecessary.
1 consecutive delays could have been merged.
(Those locations are marked with "!")
Loading…
Cancel
Save