2 Epichord - a midi sequencer
3 Copyright (C) 2008 Evan Rinehart
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to
18 The Free Software Foundation, Inc.
19 51 Franklin Street, Fifth Floor
20 Boston, MA 02110-1301, USA
28 #include <arpa/inet.h>
31 #include <fltk/file_chooser.h>
32 #include <fltk/filename.h>
48 extern std::vector
<track
*> tracks
;
51 extern struct conf config
;
55 std::string last_filename
;
56 char last_dir
[1024] = "";
59 void nextline(ifstream
& f
){
66 std::list
<pattern
*> collectpatterns(){
67 std::list
<pattern
*> patlist
;
69 for(int i
=0; i
<tracks
.size(); i
++){
70 seqpat
* s
= tracks
[i
]->head
->next
;
73 for(int j
=0; j
<s
->layers
->total
; j
++){
74 pattern
* p
= s
->layers
->array
[j
];
79 patlist
.push_back(s
->p
);
91 int findpatternindex(pattern
* p
, std::list
<pattern
*>& patlist
){
92 std::list
<pattern
*>::iterator i
= patlist
.begin();
94 while(i
!= patlist
.end()){
104 pattern
* findpatternbyindex(int index
, std::list
<pattern
*>& patlist
){
105 std::list
<pattern
*>::iterator i
= patlist
.begin();
107 while(i
!= patlist
.end()){
125 set_beats_per_measure(4);
126 set_measures_per_phrase(4);
130 int total
= tracks
.size();
132 for(int i
=0; i
<total
; i
++){
133 t
= tracks
[tracks
.size()-1];
140 ui
->title_text
->text("");
141 ui
->author_text
->text("");
143 fltk::TextBuffer
* tb
= ui
->info_text
->buffer();
146 ui
->track_info
->clear_tracks();
148 ui
->main_window
->redraw();
152 void set_last_dir(const char* name
){
153 const char* theend
= fltk::filename_name(name
);
154 int n
= (int)(theend
- name
) / sizeof(char);
155 memcpy(last_dir
,name
,n
);
159 const char* get_last_dir(){
164 if(last_filename
!= ""){
165 return save(last_filename
.c_str());
168 return save(fltk::file_chooser("save file",NULL
,last_dir
));
174 int save(const char* filename
){
176 if(filename
== NULL
){
182 file
.open(filename
, fstream::out
);
185 printf("error, cant open file for saving\n");
189 last_filename
= filename
;
190 set_last_dir(filename
);
192 //header to protect against accidentally opening wrong file
193 file
<< "J2ULJwCgwHA" << endl
;
194 file
<< "epichord" << endl
;
195 file
<< "fileversion " << FILE_VERSION
<< endl
;
196 file
<< "ticksperbeat " << TICKS_PER_BEAT
<< endl
<< endl
;
199 file
<< "title " << ui
->title_text
->size() << " "
200 << ui
->title_text
->text() << endl
;
201 file
<< "author " << ui
->author_text
->size() << " "
202 << ui
->author_text
->text() << endl
;
203 file
<< "info " << ui
->info_text
->size() << " "
204 << ui
->info_text
->text() << endl
;
206 file
<< "bpm " << ui
->bpm_wheel
->value() << endl
;
207 file
<< "beatspermeasure " << config
.beats_per_measure
<< endl
;
208 file
<< "measuresperphrase " << config
.measures_per_phrase
<< endl
;
210 file
<< "loopstart " << get_loop_start() << endl
;
211 file
<< "loopend " << get_loop_end() << endl
;
216 //collect all visible patterns
217 std::list
<pattern
*> patlist
= collectpatterns();
220 std::list
<pattern
*>::iterator p
= patlist
.begin();
223 while(p
!= patlist
.end()){
224 file
<< "pattern " << endl
;
225 file
<< (*p
)->h
<< " " << (*p
)->s
<< " " << (*p
)->v
<< endl
;
226 e
= (*p
)->events
->next
;
231 file
<< e
->type
<< " ";
232 file
<< e
->tick
<< " ";
233 file
<< e
->value1
<< " ";
234 file
<< e
->value2
<< " ";
235 file
<< e
->dur
<< endl
;
240 file
<< -1 << endl
<< endl
;
245 for(int i
=0; i
<tracks
.size(); i
++){
246 file
<< endl
<< endl
<< "track " << endl
;
247 file
<< "port " << tracks
[i
]->port
<< endl
;
248 file
<< "chan " << tracks
[i
]->chan
<< endl
;
249 file
<< "prog " << tracks
[i
]->prog
<< endl
;
250 file
<< "bank " << tracks
[i
]->bank
<< endl
;
251 file
<< "mute " << tracks
[i
]->mute
<< endl
;
252 file
<< "solo " << tracks
[i
]->solo
<< endl
;
253 file
<< "vol " << tracks
[i
]->vol
<< endl
;
254 file
<< "pan " << tracks
[i
]->pan
<< endl
;
255 file
<< "name " << strlen(tracks
[i
]->name
) << " "
256 << tracks
[i
]->name
<< endl
;
257 file
<< "alive " << tracks
[i
]->alive
<< endl
;
258 s
= tracks
[i
]->head
->next
;
261 file
<< endl
<< endl
<< "seqpat " << endl
;
262 file
<< s
->tick
<< " " << s
->dur
<< endl
;
263 file
<< s
->scrollx
<< " " << s
->scrolly
<< endl
;
266 file
<< s
->layers
->total
<< " ";
267 for(int j
=0; j
<s
->layers
->total
; j
++){
269 int index
= findpatternindex(s
->layers
->array
[j
],patlist
);
271 printf("save: pattern not found, cannot save\n");
275 file
<< index
<< " ";
278 file
<< s
->layers
->index
;
282 int index
= findpatternindex(s
->p
,patlist
);
284 printf("save: pattern not found, cannot save\n");
308 int load(const char* filename
){
311 if(filename
== NULL
){
317 file
.open(filename
, fstream::in
);
320 printf("error, cant open file for saving\n");
327 last_filename
= filename
;
328 set_last_dir(filename
);
330 //pattern* pend = patterns;
331 std::list
<pattern
*> patlist
;
336 if(str
!= "J2ULJwCgwHA"){
337 printf("load: this is definitely not a valid file (missing magic)\n");
342 if(str
!= "epichord"){
343 printf("load: this is definitely not a valid file (missing magic)\n");
348 if(str
!= "fileversion"){
349 printf("load: this is definitely not a valid file\n");
356 printf("load: file has wrong version %d (need %d).\n",M
,FILE_VERSION
);
359 if(str
!= "ticksperbeat"){
360 printf("load: file is broken. (missing ticks per beat)\n");
367 printf("load: file is broken. (bad ticks per beat %d)\n",file_tpb
);
384 ui
->title_text
->text(buf
);
386 else if(str
== "author"){
392 ui
->author_text
->text(buf
);
394 else if(str
== "info"){
397 fltk::TextBuffer
* tb
= ui
->info_text
->buffer();
403 else if(str
== "bpm"){
407 ui
->bpm_wheel
->value(bpm
);
408 ui
->bpm_output
->value(bpm
);
410 else if(str
== "beatspermeasure"){
413 set_beats_per_measure(N
);
415 else if(str
== "measuresperphrase"){
418 set_measures_per_phrase(N
);
420 else if(str
== "loopstart"){
425 else if(str
== "loopend"){
430 else if(str
== "pattern"){
431 pattern
* p
= new pattern();
436 mevent
* eend
= p
->events
;
442 if(type
== -1){break;}
453 patlist
.push_back(p
);
455 else if(str
== "track"){
458 track
* t
= new track();
459 t
->head
->track
= tracks
.size();
460 seqpat
* send
= t
->head
;
463 while(key
!= "kcart"){
464 if(key
== "port"){ file
>> t
->port
; }
465 else if(key
== "chan"){ file
>> t
->chan
; }
466 else if(key
== "prog"){ file
>> t
->prog
; }
467 else if(key
== "bank"){ file
>> t
->bank
; }
468 else if(key
== "mute"){ file
>> t
->mute
; }
469 else if(key
== "solo"){ file
>> t
->solo
; }
470 else if(key
== "vol"){ file
>> t
->vol
; }
471 else if(key
== "pan"){ file
>> t
->pan
; }
472 else if(key
== "name"){
475 char* buf
= (char*)malloc(n
+1);
480 else if(key
== "alive"){ file
>> t
->alive
; }
481 else if(key
== "seqpat"){
483 seqpat
* s
= new seqpat();
484 s
->track
= tracks
.size();
491 file
>> s
->scrollx
>> s
->scrolly
;
492 file
>> total_layers
;
494 if(total_layers
== 1){
496 p
= findpatternbyindex(index
, patlist
);
500 else if(total_layers
> 1){
502 p
= findpatternbyindex(index
, patlist
);
503 layerstack
* layers
= new layerstack(p
);
505 for(int j
=1; j
<total_layers
; j
++){
507 p
= findpatternbyindex(index
,patlist
);
511 file
>> layers
->index
;
512 s
->p
= layers
->array
[layers
->index
];
517 printf("load: bad number of layers\n");
529 ui
->track_info
->add_track();
532 file
.ignore(std::numeric_limits
<streamsize
>::max(),'\n');
538 ui
->track_info
->update();
540 ui
->arranger
->reset_handle();
541 ui
->arranger
->redraw();
553 int tick2delta(unsigned tick
, vector
<unsigned char>& vbuf
){
554 unsigned char buf
[4];
557 vbuf
.push_back(tick
);
560 else if(tick
< 16383){
563 vbuf
.push_back(0x80|((buf
[0]<<1)|(buf
[1]&0x80)>>7));
564 vbuf
.push_back(buf
[1]&0x7f);
567 else if(tick
< 2097151){
570 vbuf
.push_back(0x80|((buf
[0]<<2)|(buf
[1]&0xC0)>>6));
571 vbuf
.push_back(0x80|((buf
[1]<<1)|(buf
[2]&0x80)>>7));
572 vbuf
.push_back(buf
[2]&0x7f);
578 vbuf
.push_back(0x80|((buf
[0]<<3)|(buf
[1]&0xE0)>>5));
579 vbuf
.push_back(0x80|((buf
[1]<<2)|(buf
[2]&0xC0)>>6));
580 vbuf
.push_back(0x80|((buf
[2]<<1)|(buf
[3]&0x80)>>7));
581 vbuf
.push_back(buf
[3]&0x7f);
586 int savesmf(const char* filename
){
588 if(filename
== NULL
){
593 file
.open(filename
, fstream::out
);
596 printf("error, cant open file for saving\n");
600 unsigned char buf
[64];
619 uint16_t L
= tracks
.size();
623 //128 ticks per beat, 128 | 0x0000
627 file
.write((const char*)buf
,14);
629 vector
<unsigned char> vbuf
;
632 int MAX
= tracks
.size();
634 for(int i
=0; i
<MAX
; i
++){
645 //chunk size (yet unknown)
647 vbuf
.push_back(0x00);
648 vbuf
.push_back(0x00);
649 vbuf
.push_back(0x00);
650 vbuf
.push_back(0x00);
652 track
* t
= tracks
[i
];
657 //change program for this track
663 e
= s
->p
->events
->next
;
667 if(e
->tick
> s
->dur
){
672 N
+= tick2delta(e
->tick
+s
->tick
- last_tick
,vbuf
);
673 last_tick
= e
->tick
+s
->tick
;
674 vbuf
.push_back(0x80 | t
->chan
);
675 vbuf
.push_back(e
->value1
);
676 vbuf
.push_back(e
->value2
);
680 N
+= tick2delta(e
->tick
+s
->tick
- last_tick
,vbuf
);
681 last_tick
= e
->tick
+s
->tick
;
682 vbuf
.push_back(0x90 | t
->chan
);
683 vbuf
.push_back(e
->value1
);
684 vbuf
.push_back(e
->value2
);
687 case 0xA0://after touch
688 N
+= tick2delta(e
->tick
+s
->tick
- last_tick
,vbuf
);
689 last_tick
= e
->tick
+s
->tick
;
690 vbuf
.push_back(0xA0 | t
->chan
);
691 vbuf
.push_back(e
->value1
);
692 vbuf
.push_back(e
->value2
);
695 case 0xB0://control change
696 N
+= tick2delta(e
->tick
+s
->tick
- last_tick
,vbuf
);
697 last_tick
= e
->tick
+s
->tick
;
698 vbuf
.push_back(0xB0 | t
->chan
);
699 vbuf
.push_back(e
->value1
);
700 vbuf
.push_back(e
->value2
);
703 case 0xC0://program change
704 N
+= tick2delta(e
->tick
+s
->tick
- last_tick
,vbuf
);
705 last_tick
= e
->tick
+s
->tick
;
706 vbuf
.push_back(0xC0 | t
->chan
);
707 vbuf
.push_back(e
->value1
);
710 case 0xD0://channel pressure
711 N
+= tick2delta(e
->tick
+s
->tick
- last_tick
,vbuf
);
712 last_tick
= e
->tick
+s
->tick
;
713 vbuf
.push_back(0xD0 | t
->chan
);
714 vbuf
.push_back(e
->value1
);
717 case 0xE0://pitch wheel
718 N
+= tick2delta(e
->tick
+s
->tick
- last_tick
,vbuf
);
719 last_tick
= e
->tick
+s
->tick
;
720 vbuf
.push_back(0xE0 | t
->chan
);
721 vbuf
.push_back(e
->value1
);
722 vbuf
.push_back(e
->value2
);
732 //end of track meta event
733 vbuf
.push_back(0x00);
734 vbuf
.push_back(0xff);
735 vbuf
.push_back(0x2f);
736 vbuf
.push_back(0x00);
746 for(int i
=0; i
<vbuf
.size(); i
++){
748 file
.write((const char*)buf
,1);
758 int getdelta(std::fstream
& f
){
759 unsigned char a
,b
,c
,d
;
762 if(a
<0x80){return a
;}
765 if(b
<0x80){return ((a
&0x7f)<<7) | b
;}
768 if(c
<0x80){return ((a
&0x7f)<<14) | ((b
&0x7f)<<7) | c
;}
771 return ((a
&0x7f)<<21) | ((b
&0x7f)<<14) | ((c
&0x7f)<<7) | d
;
779 char fifths
[15][8] = {
798 int loadsmf(const char* filename
){
799 if(filename
== NULL
){
804 file
.open(filename
, fstream::in
);
807 printf("error, cant open file for saving\n");
811 last_filename
= filename
;
812 set_last_dir(filename
);
816 unsigned char buf
[64];
825 std::list
<pattern
*> patlist
;
826 std::vector
<int> chanlist
;
827 std::vector
<int> proglist
;
828 std::vector
<int> banklist
;
830 std::vector
<track
*> extratracks
;
832 std::vector
<char*> tracknames
;
836 for(int i
=0; i
<16; i
++){
837 extratracks
.push_back(NULL
);
842 file
.read((char*)buf
,4);
843 if(memcmp(buf
,"MThd",4)){
844 printf("missing header, probably not a midi file\n");
849 scope_print("Standard Midi File\n");
851 file
.read((char*)buf
,4);
853 printf("header has wrong size, probably a broken midi file\n");
854 scope_print("error: bad header size");
858 //printf("header size\n");
860 file
.read((char*)buf
,2);
862 printf("bad smf type code, probably a broken midi file\n");
863 scope_print("error: bad smf type");
871 case 0: smftype
=0; break;
872 case 1: smftype
=1; break;
873 case 2: smftype
=2; break;
875 printf("bad smf type code, probably a broken midi file\n");
876 scope_print("error: bad smf type");
881 snprintf(sbuf
,256," type: %d\n",smftype
);
884 file
.read((char*)buf
,2);
885 size
= ntohs(*(unsigned short*)buf
);
887 printf("track count of zero, probably a broken midi file\n");
888 scope_print("error: zero tracks");
894 snprintf(sbuf
,256," tracks: %d\n",ntracks
);
898 int tpb
= TICKS_PER_BEAT
;
899 file
.read((char*)buf
,2);
900 size
= ntohs(*(unsigned short*)buf
);
903 snprintf(sbuf
,256," time division: %d ticks per beat\n",tpb
);
907 int fps
= size
&0x7fff;
908 snprintf(sbuf
,256," time division: %d frames per second (wrong)\n",fps
);
910 scope_print("error: smpte time division not support\n");
917 /*** read tracks ***/
918 file
.read((char*)buf
,4);
921 if(memcmp(buf
,"MTrk",4)){
922 printf("bad track header, probably a broken midi file\n");
927 pattern
* p
= new pattern();
931 snprintf(sbuf
,256," track %d\n",trackindex
);
934 file
.read((char*)buf
,4);
935 size
= ntohl(*(unsigned long*)buf
);
937 printf("empty track\n");
946 chanlist
.push_back(-1);
947 banklist
.push_back(-1);
948 proglist
.push_back(-1);
950 tracknames
.push_back(NULL
);
955 int delta
= getdelta(file
);
957 printf("bad delta time, broken midi file\n");
962 tick
= time
*TICKS_PER_BEAT
/tpb
;
964 if(tick
> maxblockdur
){
969 file
.read((char*)buf
,1);
973 if(byte0
< 0x80){//implicit byte0
979 if(byte0
< 0xf0){//channel event
981 int type
= byte0
&0xf0;
982 int chan
= byte0
&0x0f;
988 if(byte1
<0){//didnt read byte1 yet
989 file
.read((char*)buf
,1);
998 if(!(type
== 0xC0 || type
== 0xD0)){
999 file
.read((char*)buf
,1);
1003 e
= new mevent(type
,tick
,val1
);
1008 if(val2
==0){//fake note off
1013 case 0x80://note off
1014 case 0xA0://aftertouch
1015 case 0xB0://controller change
1016 case 0xE0://pitchbend
1017 if(type
==0xB0 && val1
==0x00 && banklist
[N
]==-1){
1023 case 0xC0://program change
1024 if(proglist
[N
]==-1){
1028 case 0xD0://channel pressure
1031 printf("unrecognized channel event %d\n",type
);
1036 if(chan
!=chanlist
[N
]){//put event in the a misfit track
1037 //printf("mistfit N=%d chan=%d type=%d\n",chanlist[N],chan,type);
1038 if(extratracks
[chan
] == NULL
){
1039 track
* t
= new track();
1045 extratracks
[chan
] = t
;
1046 seqpat
* s
= new seqpat();
1049 s
->p
= new pattern();
1052 extratracks
[chan
]->head
->next
->p
->insert(e
,tick
);
1054 else{//put it in a normal track
1059 else{/*** not a channel event ***/
1063 if(byte0
== 255){//meta events
1065 file
.read((char*)buf
,1);
1069 size
= getdelta(file
);
1071 printf("bad delta time\n");
1077 abuf
= new char[size
+1];
1080 case 0://sequence number
1082 snprintf(sbuf
,256," %d sequence: ? ?\n",time
);
1085 printf("bad sequence number data length: %d\n",size
);
1089 file
.read((char*)buf
,2);
1092 file
.read(abuf
,size
);
1094 asprintf(&tbuf
," %d text: \"%s\"\n",time
,abuf
);
1098 ui
->info_text
->buffer()->append(abuf
);
1099 ui
->info_text
->buffer()->append("\n");
1102 case 2://copyright notice
1103 file
.read((char*)abuf
,size
);
1105 asprintf(&tbuf
," %d copyright: \"%s\"\n",time
,abuf
);
1110 file
.read((char*)abuf
,size
);
1112 asprintf(&tbuf
," %d track name: \"%s\"\n",time
,abuf
);
1116 tracknames
[N
] = (char*)malloc(sizeof(char)*(size
+1));
1117 strncpy(tracknames
[N
],abuf
,size
+1);
1120 case 4://instrument name
1121 file
.read((char*)abuf
,size
);
1123 asprintf(&tbuf
," %d instrument name: \"%s\"\n",time
,abuf
);
1128 file
.read((char*)abuf
,size
);
1130 asprintf(&tbuf
," %d lyrics: \"%s\"\n",time
,abuf
);
1135 file
.read((char*)abuf
,size
);
1137 asprintf(&tbuf
," %d marker: \"%s\"\n",time
,abuf
);
1142 file
.read((char*)abuf
,size
);
1144 asprintf(&tbuf
," %d cue point: \"%s\"\n",time
,abuf
);
1148 case 32://channel prefix
1150 printf("bad channel prefix data size: %d\n",size
);
1154 file
.read((char*)buf
,1);
1155 asprintf(&tbuf
," %d channel prefix: %d\n",time
,buf
[0]);
1159 case 47://end of track
1161 printf("end of track has non zero data size: %d\n",size
);
1169 printf("set tempo has non-3 data size: %d\n",size
);
1173 file
.read((char*)buf
,3);
1180 micros
= *(unsigned*)buf
;
1181 micros
= ntohl(micros
);
1183 asprintf(&tbuf
," %d set tempo: %d us/quarter\n",time
,micros
);
1189 set_beats_per_minute(60000000/micros
);
1193 case 84://smpte offset
1195 printf("smpte offset has non-5 data size: %d\n",size
);
1199 file
.read((char*)buf
,5);
1200 asprintf(&tbuf
," %d smpte offset: ?\n",time
);
1204 case 88://time signature
1206 printf("time signature has non-4 data size: %d\n",size
);
1210 file
.read((char*)buf
,4);
1211 asprintf(&tbuf
," %d time signature: %d/%d\n",time
,buf
[0],1<<buf
[1]);
1215 case 89://key signature
1217 printf("key signature has non-2 data size: %d\n",size
);
1221 file
.read((char*)buf
,2);
1222 asprintf(&tbuf
," %d key signature: %s %s\n",time
,fifths
[(signed char)buf
[0]+7],buf
[1]?"minor":"major");
1226 case 127://sequencer specific
1227 file
.read((char*)abuf
,size
);
1229 asprintf(&tbuf
," %d sequencer specific: \"%s\"\n",time
,abuf
);
1233 default://unknown meta event
1234 file
.read((char*)abuf
,size
);
1236 asprintf(&tbuf
," %d meta %d: \"%s\"\n",time
,meta
,abuf
);
1242 else if(byte0
== 240){//sysex event
1243 size
= getdelta(file
);
1245 printf("bad delta time\n");
1248 abuf
= new char[size
+1];
1249 file
.read((char*)abuf
,size
);
1252 asprintf(&tbuf
," %d sysex: \"%s\"\n",time
,abuf
);
1256 file
.read((char*)buf
,1);
1258 file
.putback(buf
[0]);
1261 scope_print(" end of sysex\n");
1268 else if(byte0
== 247){//divided sysex event
1269 size
= getdelta(file
);
1271 printf("bad delta time\n");
1274 abuf
= new char[size
+1];
1275 file
.read((char*)abuf
,size
);
1278 asprintf(&tbuf
," %d sysex fragment: \"%s\"\n",time
,abuf
);
1282 file
.read((char*)buf
,1);
1284 file
.putback(buf
[0]);
1287 scope_print(" end of sysex\n");
1292 printf("bad event type %d, broken midi file\n",byte0
);
1301 if(proglist
[N
]==-1){
1304 if(banklist
[N
]==-1){
1307 if(chanlist
[N
]==-1){
1315 patlist
.push_back(p
);
1317 file
.read((char*)buf
,4);//read first byte of next track or EOF
1322 scope_print("End Of File\n\n");
1325 //TODO set up track settings using data remembered from the reading
1326 std::list
<pattern
*>::iterator p
= patlist
.begin();
1328 while(p
!=patlist
.end()){
1329 track
* t
= new track();
1330 seqpat
* s
= new seqpat(i
,0,128*64,*p
);
1331 int Q
= TICKS_PER_BEAT
;
1332 s
->dur
= maxblockdur
/ Q
* Q
+ Q
;
1337 s
->p
->h
= 360*i
/ 16;
1339 while(s
->p
->h
> 360){s
->p
->h
-= 360;}
1340 s
->p
->regen_colors();
1342 t
->chan
= chanlist
[i
];
1343 t
->prog
= proglist
[i
];
1344 t
->bank
= banklist
[i
];
1348 t
->name
= tracknames
[i
];
1351 t
->name
= (char*)malloc(8);
1360 if(tempo_flag
== 0){
1361 set_beats_per_minute(120);
1364 ui
->track_info
->update();
1366 ui
->arranger
->reset_handle();
1367 ui
->arranger
->redraw();
1369 update_config_gui();