Swapped tick and type fields in format.
[epichord.git] / src / saveload.cpp
blob41db10ebcb2bca37f9a5a5aadf75ee09c88bd640
1 /*
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
23 #include <iostream>
24 #include <fstream>
25 #include <vector>
26 #include <list>
28 #include <arpa/inet.h>
29 #include <string.h>
31 #include <fltk/file_chooser.h>
32 #include <fltk/filename.h>
34 #include "ui.h"
36 #include "backend.h"
38 #include "saveload.h"
40 #include "util.h"
42 #include "uihelper.h"
44 #include "backend.h"
46 extern UI* ui;
48 extern std::vector<track*> tracks;
51 extern struct conf config;
53 using namespace std;
55 std::string last_filename;
56 char last_dir[1024] = "";
59 void nextline(ifstream& f){
60 char dummy[512];
61 f.getline(dummy,512);
62 printf("%s\n",dummy);
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;
71 while(s){
72 if(s->layers){
73 for(int j=0; j<s->layers->total; j++){
74 pattern* p = s->layers->array[j];
75 patlist.push_back(p);
78 else{
79 patlist.push_back(s->p);
81 s=s->next;
85 patlist.sort();
86 patlist.unique();
88 return patlist;
91 int findpatternindex(pattern* p, std::list<pattern*>& patlist){
92 std::list<pattern*>::iterator i = patlist.begin();
93 int q = 0;
94 while(i != patlist.end()){
95 if(*i==p){
96 return q;
98 q++;
99 i++;
101 return -1;
104 pattern* findpatternbyindex(int index, std::list<pattern*>& patlist){
105 std::list<pattern*>::iterator i = patlist.begin();
106 int q = 0;
107 while(i != patlist.end()){
108 if(q==index){
109 return *i;
111 q++;
112 i++;
114 return NULL;
118 int clear(){
120 pause_backend();
121 reset_backend(0);
123 last_filename = "";
125 set_beats_per_measure(4);
126 set_measures_per_phrase(4);
127 update_config_gui();
129 track* t;
130 int total = tracks.size();
132 for(int i=0; i<total; i++){
133 t = tracks[tracks.size()-1];
134 tracks.pop_back();
135 delete t;
138 set_bpm(120);
140 ui->title_text->text("");
141 ui->author_text->text("");
143 fltk::TextBuffer* tb = ui->info_text->buffer();
144 tb->text("");
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);
156 last_dir[n] = '\0';
159 const char* get_last_dir(){
160 return last_dir;
163 int save(){
164 if(last_filename != ""){
165 return save(last_filename.c_str());
167 else{
168 return save(fltk::file_chooser("save file",NULL,last_dir));
174 int save(const char* filename){
176 if(filename == NULL){
177 return -1;
180 //create file
181 fstream file;
182 file.open(filename, fstream::out);
184 if(!file.is_open()){
185 printf("error, cant open file for saving\n");
186 return -1;
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;
198 //write song info
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;
213 file << endl;
216 //collect all visible patterns
217 std::list<pattern*> patlist = collectpatterns();
219 //for each pattern
220 std::list<pattern*>::iterator p = patlist.begin();
221 mevent* e;
222 int P = 0;
223 while(p != patlist.end()){
224 file << "pattern " << endl;
225 file << (*p)->h << " " << (*p)->s << " " << (*p)->v << endl;
226 e = (*p)->events->next;
227 mevent* eoff;
228 int n = 0;
229 int m = n;
230 while(e){
231 file << e->tick << " ";
232 file << e->type << " ";
233 file << e->value1 << " ";
234 file << e->value2 << endl;
235 //file << e->dur << endl;
236 n++;
237 e = e->next;
239 P++;
240 file << -1 << endl << endl;
241 p++;
244 seqpat* s;
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;
259 int m = 0;
260 while(s){
261 file << endl << endl << "seqpat " << endl;
262 file << s->tick << " " << s->dur << endl;
263 file << s->scrollx << " " << s->scrolly << endl;
265 if(s->layers){
266 file << s->layers->total << " ";
267 for(int j=0; j<s->layers->total; j++){
269 int index = findpatternindex(s->layers->array[j],patlist);
270 if(index < 0){
271 printf("save: pattern not found, cannot save\n");
272 file.close();
273 return -1;
275 file << index << " ";
278 file << s->layers->index;
280 else{
281 file << 1 << " ";
282 int index = findpatternindex(s->p,patlist);
283 if(index < 0){
284 printf("save: pattern not found, cannot save\n");
285 file.close();
286 return -1;
288 file << index;
291 file << endl;
292 m++;
293 s = s->next;
295 file << "kcart";
300 file.close();
302 return 0;
308 int load(const char* filename){
311 if(filename == NULL){
312 return -1;
315 ifstream file;
316 string str;
317 file.open(filename, fstream::in);
319 if(!file.is_open()){
320 printf("error, cant open file for saving\n");
321 return -1;
324 show_song_edit();
326 clear();
327 last_filename = filename;
328 set_last_dir(filename);
330 //pattern* pend = patterns;
331 std::list<pattern*> patlist;
334 //sanity check
335 file >> str;
336 if(str != "J2ULJwCgwHA"){
337 printf("load: this is definitely not a valid file (missing magic)\n");
338 file.close();
339 return -1;
341 file >> str;
342 if(str != "epichord"){
343 printf("load: this is definitely not a valid file (missing magic)\n");
344 file.close();
345 return -1;
347 file >> str;
348 if(str != "fileversion"){
349 printf("load: this is definitely not a valid file\n");
350 file.close();
351 return -1;
353 int M;
354 file >> M;
355 if(M!=FILE_VERSION){
356 printf("load: file has wrong version %d (need %d).\n",M,FILE_VERSION);
358 file >> str;
359 if(str != "ticksperbeat"){
360 printf("load: file is broken. (missing ticks per beat)\n");
361 file.close();
362 return -1;
364 int file_tpb;
365 file >> file_tpb;
366 if(file_tpb < 1){
367 printf("load: file is broken. (bad ticks per beat %d)\n",file_tpb);
368 file.close();
369 return -1;
373 file >> str;
374 while(!file.eof()){
376 int n;
378 if(str == "title"){
379 file >> n;
380 file.get();
381 char buf[256];
382 file.read(buf,n);
383 buf[n] = '\0';
384 ui->title_text->text(buf);
386 else if(str == "author"){
387 file >> n;
388 file.get();
389 char buf[256];
390 file.read(buf,n);
391 buf[n] = '\0';
392 ui->author_text->text(buf);
394 else if(str == "info"){
395 file >> n;
396 file.get();
397 fltk::TextBuffer* tb = ui->info_text->buffer();
398 char buf[1024];
399 file.read(buf,n);
400 buf[n] = '\0';
401 tb->text(buf);
403 else if(str == "bpm"){
404 int bpm;
405 file >> bpm;
406 set_bpm(bpm);
407 ui->bpm_wheel->value(bpm);
408 ui->bpm_output->value(bpm);
410 else if(str == "beatspermeasure"){
411 int N;
412 file >> N;
413 set_beats_per_measure(N);
415 else if(str == "measuresperphrase"){
416 int N;
417 file >> N;
418 set_measures_per_phrase(N);
420 else if(str == "loopstart"){
421 int ls;
422 file >> ls;
423 set_loop_start(ls);
425 else if(str == "loopend"){
426 int le;
427 file >> le;
428 set_loop_end(le);
430 else if(str == "pattern"){
431 pattern* p = new pattern();
432 file >> p->h;
433 file >> p->s;
434 file >> p->v;
435 p->regen_colors();
436 mevent* eend = p->events;
437 int off_index;
438 int type;
439 mevent* e;
440 while(1){
441 e = new mevent();
443 file >> e->tick;
444 if(e->tick == -1){delete e; break;}
445 file >> e->type;
447 file >> e->value1;
448 file >> e->value2;
449 //file >> e->dur;
450 e->prev = eend;
451 eend->next = e;
452 eend = e;
454 p->fixdur();
455 patlist.push_back(p);
457 else if(str == "track"){
458 int track_number;
459 string key;
460 track* t = new track();
461 t->head->track = tracks.size();
462 seqpat* send = t->head;
463 file >> key;
465 while(key != "kcart"){
466 if(key == "port"){ file >> t->port; }
467 else if(key == "chan"){ file >> t->chan; }
468 else if(key == "prog"){ file >> t->prog; }
469 else if(key == "bank"){ file >> t->bank; }
470 else if(key == "mute"){ file >> t->mute; }
471 else if(key == "solo"){ file >> t->solo; }
472 else if(key == "vol"){ file >> t->vol; }
473 else if(key == "pan"){ file >> t->pan; }
474 else if(key == "name"){
475 file >> n;
476 file.get();
477 char* buf = (char*)malloc(n+1);
478 file.read(buf,n);
479 buf[n] = '\0';
480 t->name = buf;
482 else if(key == "alive"){ file >> t->alive; }
483 else if(key == "seqpat"){
484 int pattern_number;
485 seqpat* s = new seqpat();
486 s->track = tracks.size();
487 file >> s->tick;
488 file >> s->dur;
489 int total_layers;
490 int index;
491 pattern* p;
493 file >> s->scrollx >> s->scrolly;
494 file >> total_layers;
496 if(total_layers == 1){
497 file >> index;
498 p = findpatternbyindex(index, patlist);
499 s->p = p;
500 s->layers = NULL;
502 else if(total_layers > 1){
503 file >> index;
504 p = findpatternbyindex(index, patlist);
505 layerstack* layers = new layerstack(p);
507 for(int j=1; j<total_layers; j++){
508 file >> index;
509 p = findpatternbyindex(index,patlist);
510 layers->push_new(p);
513 file >> layers->index;
514 s->p = layers->array[layers->index];
515 s->layers = layers;
516 layers->ref_c = 1;
518 else{
519 printf("load: bad number of layers\n");
520 file.close();
521 return -1;
524 s->prev = send;
525 send->next = s;
526 send = s;
528 file >> key;
530 tracks.push_back(t);
531 ui->track_info->add_track();
533 else{
534 file.ignore(std::numeric_limits<streamsize>::max(),'\n');
537 file >> str;
540 set_rec_track(0);
541 ui->track_info->set_rec(0);
542 ui->track_info->update();
544 ui->arranger->reset_handle();
545 ui->arranger->redraw();
547 reset_backend(0);
549 file.close();
551 return 0;
557 int tick2delta(unsigned tick, vector<unsigned char>& vbuf){
558 unsigned char buf[4];
559 uint32_t n;
560 if(tick < 128){
561 vbuf.push_back(tick);
562 return 1;
564 else if(tick < 16383){
565 n = htonl(tick);
566 memcpy(buf,&n,4);
567 vbuf.push_back(0x80|((buf[0]<<1)|(buf[1]&0x80)>>7));
568 vbuf.push_back(buf[1]&0x7f);
569 return 2;
571 else if(tick < 2097151){
572 n = htonl(tick);
573 memcpy(buf,&n,4);
574 vbuf.push_back(0x80|((buf[0]<<2)|(buf[1]&0xC0)>>6));
575 vbuf.push_back(0x80|((buf[1]<<1)|(buf[2]&0x80)>>7));
576 vbuf.push_back(buf[2]&0x7f);
577 return 3;
579 else{
580 n = htonl(tick);
581 memcpy(buf,&n,4);
582 vbuf.push_back(0x80|((buf[0]<<3)|(buf[1]&0xE0)>>5));
583 vbuf.push_back(0x80|((buf[1]<<2)|(buf[2]&0xC0)>>6));
584 vbuf.push_back(0x80|((buf[2]<<1)|(buf[3]&0x80)>>7));
585 vbuf.push_back(buf[3]&0x7f);
586 return 4;
590 int savesmf(const char* filename){
592 if(filename == NULL){
593 return -1;
596 fstream file;
597 file.open(filename, fstream::out);
599 if(!file.is_open()){
600 printf("error, cant open file for saving\n");
601 return -1;
604 unsigned char buf[64];
606 //chunk id
607 buf[0] = 'M';
608 buf[1] = 'T';
609 buf[2] = 'h';
610 buf[3] = 'd';
612 //chunk size
613 buf[4] = 0x00;
614 buf[5] = 0x00;
615 buf[6] = 0x00;
616 buf[7] = 0x06;
618 //type 1 midi file
619 buf[8] = 0x00;
620 buf[9] = 0x01;
622 //number of tracks
623 uint16_t L = tracks.size();
624 L = htons(L);
625 memcpy(buf+10,&L,2);
627 //128 ticks per beat, 128 | 0x0000
628 buf[12] = 0x00;
629 buf[13] = 0x80;
631 file.write((const char*)buf,14);
633 vector<unsigned char> vbuf;
634 int last_tick = 0;
635 uint32_t N = 0;
636 int MAX = tracks.size();
638 for(int i=0; i<MAX; i++){
640 //chunk id
641 N = 0;
642 last_tick = 0;
643 vbuf.clear();
644 vbuf.push_back('M');
645 vbuf.push_back('T');
646 vbuf.push_back('r');
647 vbuf.push_back('k');
649 //chunk size (yet unknown)
651 vbuf.push_back(0x00);
652 vbuf.push_back(0x00);
653 vbuf.push_back(0x00);
654 vbuf.push_back(0x00);
656 track* t = tracks[i];
657 seqpat* s;
658 pattern* p;
659 mevent* e;
661 //change program for this track
663 //write events
664 s = t->head->next;
666 while(s){
667 e = s->p->events->next;
669 while(e){
671 if(e->tick > s->dur){
672 break;
674 switch(e->type){
675 case 0x80://note off
676 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
677 last_tick = e->tick+s->tick;
678 vbuf.push_back(0x80 | t->chan);
679 vbuf.push_back(e->value1);
680 vbuf.push_back(e->value2);
681 N += 3;
682 break;
683 case 0x90://note on
684 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
685 last_tick = e->tick+s->tick;
686 vbuf.push_back(0x90 | t->chan);
687 vbuf.push_back(e->value1);
688 vbuf.push_back(e->value2);
689 N += 3;
690 break;
691 case 0xA0://after touch
692 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
693 last_tick = e->tick+s->tick;
694 vbuf.push_back(0xA0 | t->chan);
695 vbuf.push_back(e->value1);
696 vbuf.push_back(e->value2);
697 N += 3;
698 break;
699 case 0xB0://control change
700 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
701 last_tick = e->tick+s->tick;
702 vbuf.push_back(0xB0 | t->chan);
703 vbuf.push_back(e->value1);
704 vbuf.push_back(e->value2);
705 N += 3;
706 break;
707 case 0xC0://program change
708 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
709 last_tick = e->tick+s->tick;
710 vbuf.push_back(0xC0 | t->chan);
711 vbuf.push_back(e->value1);
712 N += 2;
713 break;
714 case 0xD0://channel pressure
715 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
716 last_tick = e->tick+s->tick;
717 vbuf.push_back(0xD0 | t->chan);
718 vbuf.push_back(e->value1);
719 N += 2;
720 break;
721 case 0xE0://pitch wheel
722 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
723 last_tick = e->tick+s->tick;
724 vbuf.push_back(0xE0 | t->chan);
725 vbuf.push_back(e->value1);
726 vbuf.push_back(e->value2);
727 N += 3;
728 break;
730 e = e->next;
733 s = s->next;
736 //end of track meta event
737 vbuf.push_back(0x00);
738 vbuf.push_back(0xff);
739 vbuf.push_back(0x2f);
740 vbuf.push_back(0x00);
741 N += 4;
743 N = htonl(N);
744 memcpy(buf,&N,4);
745 vbuf[4] = buf[0];
746 vbuf[5] = buf[1];
747 vbuf[6] = buf[2];
748 vbuf[7] = buf[3];
750 for(int i=0; i<vbuf.size(); i++){
751 buf[0] = vbuf[i];
752 file.write((const char*)buf,1);
756 file.close();
762 int getdelta(std::fstream& f){
763 unsigned char a,b,c,d;
765 f.read((char*)&a,1);
766 if(a<0x80){return a;}
768 f.read((char*)&b,1);
769 if(b<0x80){return ((a&0x7f)<<7) | b;}
771 f.read((char*)&c,1);
772 if(c<0x80){return ((a&0x7f)<<14) | ((b&0x7f)<<7) | c;}
774 f.read((char*)&d,1);
775 return ((a&0x7f)<<21) | ((b&0x7f)<<14) | ((c&0x7f)<<7) | d;
783 char fifths[15][8] = {
784 "Cb",
785 "Gb",
786 "Db",
787 "Ab",
788 "Eb",
789 "Bb",
790 "F",
791 "C",
792 "G",
793 "D",
794 "A",
795 "E",
796 "B",
797 "F#",
798 "C#"
802 int loadsmf(const char* filename){
803 if(filename == NULL){
804 return -1;
807 fstream file;
808 file.open(filename, fstream::in);
810 if(!file.is_open()){
811 printf("error, cant open file for saving\n");
812 return -1;
815 last_filename = filename;
816 set_last_dir(filename);
818 clear();
820 unsigned char buf[64];
821 char* abuf;
822 char sbuf[256];
823 char* tbuf;
824 uint32_t size;
825 uint32_t micros;
826 int N = 0;
827 int tempo_flag = 0;
829 std::list<pattern*> patlist;
830 std::vector<int> chanlist;
831 std::vector<int> proglist;
832 std::vector<int> banklist;
834 std::vector<track*> extratracks;
836 std::vector<char*> tracknames;
838 int maxblockdur = 0;
840 for(int i=0; i<16; i++){
841 extratracks.push_back(NULL);
844 while(!file.eof()){
846 file.read((char*)buf,4);
847 if(memcmp(buf,"MThd",4)){
848 printf("missing header, probably not a midi file\n");
849 file.close();
850 return -1;
852 //printf("MThd\n");
853 scope_print("Standard Midi File\n");
855 file.read((char*)buf,4);
856 if(buf[3] != 6){
857 printf("header has wrong size, probably a broken midi file\n");
858 scope_print("error: bad header size");
859 file.close();
860 return -1;
862 //printf("header size\n");
864 file.read((char*)buf,2);
865 if(buf[0] != 0){
866 printf("bad smf type code, probably a broken midi file\n");
867 scope_print("error: bad smf type");
868 file.close();
869 return -1;
873 int smftype;
874 switch(buf[1]){
875 case 0: smftype=0; break;
876 case 1: smftype=1; break;
877 case 2: smftype=2; break;
878 default:
879 printf("bad smf type code, probably a broken midi file\n");
880 scope_print("error: bad smf type");
881 file.close();
882 return -1;
885 snprintf(sbuf,256," type: %d\n",smftype);
886 scope_print(sbuf);
888 file.read((char*)buf,2);
889 size = ntohs(*(unsigned short*)buf);
890 if(size==0){
891 printf("track count of zero, probably a broken midi file\n");
892 scope_print("error: zero tracks");
893 file.close();
894 return -1;
896 int ntracks = size;
898 snprintf(sbuf,256," tracks: %d\n",ntracks);
899 scope_print(sbuf);
902 int tpb = TICKS_PER_BEAT;
903 file.read((char*)buf,2);
904 size = ntohs(*(unsigned short*)buf);
905 if(size >> 15 == 0){
906 tpb = size&0x7fff;
907 snprintf(sbuf,256," time division: %d ticks per beat\n",tpb);
908 scope_print(sbuf);
910 else{
911 int fps = size&0x7fff;
912 snprintf(sbuf,256," time division: %d frames per second (wrong)\n",fps);
913 scope_print(sbuf);
914 scope_print("error: smpte time division not support\n");
915 file.close();
916 return -1;
920 int trackindex = 0;
921 /*** read tracks ***/
922 file.read((char*)buf,4);
923 while(!file.eof()){
925 if(memcmp(buf,"MTrk",4)){
926 printf("bad track header, probably a broken midi file\n");
927 file.close();
928 return -1;
931 pattern* p = new pattern();
932 mevent* e;
934 trackindex++;
935 snprintf(sbuf,256," track %d\n",trackindex);
936 scope_print(sbuf);
938 file.read((char*)buf,4);
939 size = ntohl(*(unsigned long*)buf);
940 if(size==0){
941 printf("empty track\n");
942 file.close();
943 return -1;
946 int time = 0;
947 int tick = 0;
948 int endtrack=0;
950 chanlist.push_back(-1);
951 banklist.push_back(-1);
952 proglist.push_back(-1);
954 tracknames.push_back(NULL);
956 /***read events***/
957 while(!endtrack){
959 int delta = getdelta(file);
960 if(delta < 0){
961 printf("bad delta time, broken midi file\n");
962 file.close();
963 return -1;
965 time += delta;
966 tick = time*TICKS_PER_BEAT/tpb;
968 if(tick > maxblockdur){
969 maxblockdur = tick;
972 int last_byte0;
973 file.read((char*)buf,1);
974 int byte0 = buf[0];
975 int byte1 = -1;
977 if(byte0 < 0x80){//implicit byte0
978 byte1 = byte0;
979 byte0 = last_byte0;
981 last_byte0 = byte0;
983 if(byte0 < 0xf0){//channel event
985 int type = byte0&0xf0;
986 int chan = byte0&0x0f;
988 if(chanlist[N]==-1){
989 chanlist[N]=chan;
992 if(byte1<0){//didnt read byte1 yet
993 file.read((char*)buf,1);
994 byte1 = buf[0];
999 int val1 = byte1;
1000 int val2;
1002 if(!(type == 0xC0 || type == 0xD0)){
1003 file.read((char*)buf,1);
1004 val2 = buf[0];
1007 e = new mevent(type,tick,val1);
1010 switch(type){
1011 case 0x90://note on
1012 if(val2==0){//fake note off
1013 e->type = 0x80;
1015 e->value2 = val2;
1016 break;
1017 case 0x80://note off
1018 case 0xA0://aftertouch
1019 case 0xB0://controller change
1020 case 0xE0://pitchbend
1021 if(type==0xB0 && val1==0x00 && banklist[N]==-1){
1022 banklist[N]=val2;
1024 e->value2 = val2;
1025 break;
1027 case 0xC0://program change
1028 if(proglist[N]==-1){
1029 proglist[N]=val1;
1031 break;
1032 case 0xD0://channel pressure
1033 break;
1034 default:
1035 printf("unrecognized channel event %d\n",type);
1036 file.close();
1037 return -1;
1040 if(chan!=chanlist[N]){//put event in the a misfit track
1041 //printf("mistfit N=%d chan=%d type=%d\n",chanlist[N],chan,type);
1042 if(extratracks[chan] == NULL){
1043 track* t = new track();
1044 t->chan = chan;
1045 t->prog = -1;
1046 t->port = 0;
1047 t->bank = -1;
1049 extratracks[chan] = t;
1050 seqpat* s = new seqpat();
1051 t->head->next = s;
1052 s->prev = t->head;
1053 s->p = new pattern();
1054 //more track setup
1056 extratracks[chan]->head->next->p->insert(e,tick);
1058 else{//put it in a normal track
1059 p->append(e);
1063 else{/*** not a channel event ***/
1067 if(byte0 == 255){//meta events
1069 file.read((char*)buf,1);
1070 int meta = buf[0];
1073 size = getdelta(file);
1074 if(size < 0){
1075 printf("bad delta time\n");
1076 file.close();
1077 return -1;
1081 abuf = new char[size+1];
1083 switch(meta){
1084 case 0://sequence number
1086 snprintf(sbuf,256," %d sequence: ? ?\n",time);
1087 scope_print(sbuf);
1088 if(size != 2){
1089 printf("bad sequence number data length: %d\n",size);
1090 file.close();
1091 return -1;
1093 file.read((char*)buf,2);
1094 break;
1095 case 1://text event
1096 file.read(abuf,size);
1097 abuf[size]='\0';
1098 asprintf(&tbuf," %d text: \"%s\"\n",time,abuf);
1099 scope_print(tbuf);
1100 free(tbuf);
1102 ui->info_text->buffer()->append(abuf);
1103 ui->info_text->buffer()->append("\n");
1105 break;
1106 case 2://copyright notice
1107 file.read((char*)abuf,size);
1108 abuf[size]='\0';
1109 asprintf(&tbuf," %d copyright: \"%s\"\n",time,abuf);
1110 scope_print(tbuf);
1111 free(tbuf);
1112 break;
1113 case 3://track name
1114 file.read((char*)abuf,size);
1115 abuf[size]='\0';
1116 asprintf(&tbuf," %d track name: \"%s\"\n",time,abuf);
1117 scope_print(tbuf);
1118 free(tbuf);
1120 tracknames[N] = (char*)malloc(sizeof(char)*(size+1));
1121 strncpy(tracknames[N],abuf,size+1);
1123 break;
1124 case 4://instrument name
1125 file.read((char*)abuf,size);
1126 abuf[size]='\0';
1127 asprintf(&tbuf," %d instrument name: \"%s\"\n",time,abuf);
1128 scope_print(tbuf);
1129 free(tbuf);
1130 break;
1131 case 5://lyrics
1132 file.read((char*)abuf,size);
1133 abuf[size]='\0';
1134 asprintf(&tbuf," %d lyrics: \"%s\"\n",time,abuf);
1135 scope_print(tbuf);
1136 free(tbuf);
1137 break;
1138 case 6://marker
1139 file.read((char*)abuf,size);
1140 abuf[size]='\0';
1141 asprintf(&tbuf," %d marker: \"%s\"\n",time,abuf);
1142 scope_print(tbuf);
1143 free(tbuf);
1144 break;
1145 case 7://cue point
1146 file.read((char*)abuf,size);
1147 abuf[size]='\0';
1148 asprintf(&tbuf," %d cue point: \"%s\"\n",time,abuf);
1149 scope_print(tbuf);
1150 free(tbuf);
1151 break;
1152 case 32://channel prefix
1153 if(size!=1){
1154 printf("bad channel prefix data size: %d\n",size);
1155 file.close();
1156 return -1;
1158 file.read((char*)buf,1);
1159 asprintf(&tbuf," %d channel prefix: %d\n",time,buf[0]);
1160 scope_print(tbuf);
1161 free(tbuf);
1162 break;
1163 case 47://end of track
1164 if(size!=0){
1165 printf("end of track has non zero data size: %d\n",size);
1166 file.close();
1167 return -1;
1169 endtrack=1;
1170 break;
1171 case 81://set tempo
1172 if(size!=3){
1173 printf("set tempo has non-3 data size: %d\n",size);
1174 file.close();
1175 return -1;
1177 file.read((char*)buf,3);
1179 buf[3] = buf[2];
1180 buf[2] = buf[1];
1181 buf[1] = buf[0];
1182 buf[0] = 0;
1184 micros = *(unsigned*)buf;
1185 micros = ntohl(micros);
1187 asprintf(&tbuf," %d set tempo: %d us/quarter\n",time,micros);
1188 scope_print(tbuf);
1189 free(tbuf);
1191 if(time==0){
1192 tempo_flag = 1;
1193 set_beats_per_minute(60000000/micros);
1196 break;
1197 case 84://smpte offset
1198 if(size!=5){
1199 printf("smpte offset has non-5 data size: %d\n",size);
1200 file.close();
1201 return -1;
1203 file.read((char*)buf,5);
1204 asprintf(&tbuf," %d smpte offset: ?\n",time);
1205 scope_print(tbuf);
1206 free(tbuf);
1207 break;
1208 case 88://time signature
1209 if(size!=4){
1210 printf("time signature has non-4 data size: %d\n",size);
1211 file.close();
1212 return -1;
1214 file.read((char*)buf,4);
1215 asprintf(&tbuf," %d time signature: %d/%d\n",time,buf[0],1<<buf[1]);
1216 scope_print(tbuf);
1217 free(tbuf);
1218 break;
1219 case 89://key signature
1220 if(size!=2){
1221 printf("key signature has non-2 data size: %d\n",size);
1222 file.close();
1223 return -1;
1225 file.read((char*)buf,2);
1226 asprintf(&tbuf," %d key signature: %s %s\n",time,fifths[(signed char)buf[0]+7],buf[1]?"minor":"major");
1227 scope_print(tbuf);
1228 free(tbuf);
1229 break;
1230 case 127://sequencer specific
1231 file.read((char*)abuf,size);
1232 abuf[size]='\0';
1233 asprintf(&tbuf," %d sequencer specific: \"%s\"\n",time,abuf);
1234 scope_print(tbuf);
1235 free(tbuf);
1236 break;
1237 default://unknown meta event
1238 file.read((char*)abuf,size);
1239 abuf[size]='\0';
1240 asprintf(&tbuf," %d meta %d: \"%s\"\n",time,meta,abuf);
1241 scope_print(tbuf);
1242 free(tbuf);
1244 free(abuf);
1246 else if(byte0 == 240){//sysex event
1247 size = getdelta(file);
1248 if(size < 0){
1249 printf("bad delta time\n");
1250 return -1;
1252 abuf = new char[size+1];
1253 file.read((char*)abuf,size);
1254 abuf[size]='\0';
1256 asprintf(&tbuf," %d sysex: \"%s\"\n",time,abuf);
1257 scope_print(tbuf);
1258 free(tbuf);
1260 file.read((char*)buf,1);
1261 if(buf[0]!=0xf7){
1262 file.putback(buf[0]);
1264 else{
1265 scope_print(" end of sysex\n");
1270 free(abuf);
1272 else if(byte0 == 247){//divided sysex event
1273 size = getdelta(file);
1274 if(size < 0){
1275 printf("bad delta time\n");
1276 return -1;
1278 abuf = new char[size+1];
1279 file.read((char*)abuf,size);
1280 abuf[size]='\0';
1282 asprintf(&tbuf," %d sysex fragment: \"%s\"\n",time,abuf);
1283 scope_print(tbuf);
1284 free(tbuf);
1286 file.read((char*)buf,1);
1287 if(buf[0]!=0xf7){
1288 file.putback(buf[0]);
1290 else{
1291 scope_print(" end of sysex\n");
1293 free(abuf);
1295 else{
1296 printf("bad event type %d, broken midi file\n",byte0);
1297 file.close();
1298 return -1;
1305 if(proglist[N]==-1){
1306 proglist[N]=0;
1308 if(banklist[N]==-1){
1309 banklist[N]=0;
1311 if(chanlist[N]==-1){
1312 chanlist[N]=0;
1314 N++;
1317 p->fixdur();
1319 patlist.push_back(p);
1321 file.read((char*)buf,4);//read first byte of next track or EOF
1326 scope_print("End Of File\n\n");
1327 file.close();
1329 //TODO set up track settings using data remembered from the reading
1330 std::list<pattern*>::iterator p = patlist.begin();
1331 int i=0;
1332 while(p!=patlist.end()){
1333 track* t = new track();
1334 seqpat* s = new seqpat(i,0,128*64,*p);
1335 int Q = TICKS_PER_BEAT;
1336 s->dur = maxblockdur / Q * Q + Q;
1337 t->head->next = s;
1338 s->prev = t->head;
1339 t->skip = s;
1341 s->p->h = 360*i / 16;
1342 s->p->v = 0.8;
1343 while(s->p->h > 360){s->p->h -= 360;}
1344 s->p->regen_colors();
1346 t->chan = chanlist[i];
1347 t->prog = proglist[i];
1348 t->bank = banklist[i];
1349 t->port = 0;
1351 if(tracknames[i]){
1352 t->name = tracknames[i];
1354 else{
1355 t->name = (char*)malloc(8);
1356 t->name[0] = '\0';
1359 add_track(t);
1360 p++;
1361 i++;
1364 if(tempo_flag == 0){
1365 set_beats_per_minute(120);
1368 set_rec_track(0);
1369 ui->track_info->set_rec(0);
1370 ui->track_info->update();
1372 ui->arranger->reset_handle();
1373 ui->arranger->redraw();
1375 update_config_gui();
1377 reset_backend(0);
1379 return 0;