Fixed bug that crashed on saving after importing.
[epichord.git] / src / saveload.cpp
blob62971c2bbdbf48499f946fa7461c5ddcd1e94698
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->type << " ";
232 file << e->tick << " ";
233 file << e->value1 << " ";
234 file << e->value2 << " ";
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 file >> type;
442 if(type == -1){break;}
443 e = new mevent();
444 e->type = type;
445 file >> e->tick;
446 file >> e->value1;
447 file >> e->value2;
448 file >> e->dur;
449 e->prev = eend;
450 eend->next = e;
451 eend = e;
453 patlist.push_back(p);
455 else if(str == "track"){
456 int track_number;
457 string key;
458 track* t = new track();
459 t->head->track = tracks.size();
460 seqpat* send = t->head;
461 file >> key;
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"){
473 file >> n;
474 file.get();
475 char* buf = (char*)malloc(n+1);
476 file.read(buf,n);
477 buf[n] = '\0';
478 t->name = buf;
480 else if(key == "alive"){ file >> t->alive; }
481 else if(key == "seqpat"){
482 int pattern_number;
483 seqpat* s = new seqpat();
484 s->track = tracks.size();
485 file >> s->tick;
486 file >> s->dur;
487 int total_layers;
488 int index;
489 pattern* p;
491 file >> s->scrollx >> s->scrolly;
492 file >> total_layers;
494 if(total_layers == 1){
495 file >> index;
496 p = findpatternbyindex(index, patlist);
497 s->p = p;
498 s->layers = NULL;
500 else if(total_layers > 1){
501 file >> index;
502 p = findpatternbyindex(index, patlist);
503 layerstack* layers = new layerstack(p);
505 for(int j=1; j<total_layers; j++){
506 file >> index;
507 p = findpatternbyindex(index,patlist);
508 layers->push_new(p);
511 file >> layers->index;
512 s->p = layers->array[layers->index];
513 s->layers = layers;
514 layers->ref_c = 1;
516 else{
517 printf("load: bad number of layers\n");
518 file.close();
519 return -1;
522 s->prev = send;
523 send->next = s;
524 send = s;
526 file >> key;
528 tracks.push_back(t);
529 ui->track_info->add_track();
531 else{
532 file.ignore(std::numeric_limits<streamsize>::max(),'\n');
535 file >> str;
538 ui->track_info->update();
540 ui->arranger->reset_handle();
541 ui->arranger->redraw();
543 reset_backend(0);
545 file.close();
547 return 0;
553 int tick2delta(unsigned tick, vector<unsigned char>& vbuf){
554 unsigned char buf[4];
555 uint32_t n;
556 if(tick < 128){
557 vbuf.push_back(tick);
558 return 1;
560 else if(tick < 16383){
561 n = htonl(tick);
562 memcpy(buf,&n,4);
563 vbuf.push_back(0x80|((buf[0]<<1)|(buf[1]&0x80)>>7));
564 vbuf.push_back(buf[1]&0x7f);
565 return 2;
567 else if(tick < 2097151){
568 n = htonl(tick);
569 memcpy(buf,&n,4);
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);
573 return 3;
575 else{
576 n = htonl(tick);
577 memcpy(buf,&n,4);
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);
582 return 4;
586 int savesmf(const char* filename){
588 if(filename == NULL){
589 return -1;
592 fstream file;
593 file.open(filename, fstream::out);
595 if(!file.is_open()){
596 printf("error, cant open file for saving\n");
597 return -1;
600 unsigned char buf[64];
602 //chunk id
603 buf[0] = 'M';
604 buf[1] = 'T';
605 buf[2] = 'h';
606 buf[3] = 'd';
608 //chunk size
609 buf[4] = 0x00;
610 buf[5] = 0x00;
611 buf[6] = 0x00;
612 buf[7] = 0x06;
614 //type 1 midi file
615 buf[8] = 0x00;
616 buf[9] = 0x01;
618 //number of tracks
619 uint16_t L = tracks.size();
620 L = htons(L);
621 memcpy(buf+10,&L,2);
623 //128 ticks per beat, 128 | 0x0000
624 buf[12] = 0x00;
625 buf[13] = 0x80;
627 file.write((const char*)buf,14);
629 vector<unsigned char> vbuf;
630 int last_tick = 0;
631 uint32_t N = 0;
632 int MAX = tracks.size();
634 for(int i=0; i<MAX; i++){
636 //chunk id
637 N = 0;
638 last_tick = 0;
639 vbuf.clear();
640 vbuf.push_back('M');
641 vbuf.push_back('T');
642 vbuf.push_back('r');
643 vbuf.push_back('k');
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];
653 seqpat* s;
654 pattern* p;
655 mevent* e;
657 //change program for this track
659 //write events
660 s = t->head->next;
662 while(s){
663 e = s->p->events->next;
665 while(e){
667 if(e->tick > s->dur){
668 break;
670 switch(e->type){
671 case 0x80://note off
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);
677 N += 3;
678 break;
679 case 0x90://note on
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);
685 N += 3;
686 break;
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);
693 N += 3;
694 break;
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);
701 N += 3;
702 break;
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);
708 N += 2;
709 break;
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);
715 N += 2;
716 break;
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);
723 N += 3;
724 break;
726 e = e->next;
729 s = s->next;
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);
737 N += 4;
739 N = htonl(N);
740 memcpy(buf,&N,4);
741 vbuf[4] = buf[0];
742 vbuf[5] = buf[1];
743 vbuf[6] = buf[2];
744 vbuf[7] = buf[3];
746 for(int i=0; i<vbuf.size(); i++){
747 buf[0] = vbuf[i];
748 file.write((const char*)buf,1);
752 file.close();
758 int getdelta(std::fstream& f){
759 unsigned char a,b,c,d;
761 f.read((char*)&a,1);
762 if(a<0x80){return a;}
764 f.read((char*)&b,1);
765 if(b<0x80){return ((a&0x7f)<<7) | b;}
767 f.read((char*)&c,1);
768 if(c<0x80){return ((a&0x7f)<<14) | ((b&0x7f)<<7) | c;}
770 f.read((char*)&d,1);
771 return ((a&0x7f)<<21) | ((b&0x7f)<<14) | ((c&0x7f)<<7) | d;
779 char fifths[15][8] = {
780 "Cb",
781 "Gb",
782 "Db",
783 "Ab",
784 "Eb",
785 "Bb",
786 "F",
787 "C",
788 "G",
789 "D",
790 "A",
791 "E",
792 "B",
793 "F#",
794 "C#"
798 int loadsmf(const char* filename){
799 if(filename == NULL){
800 return -1;
803 fstream file;
804 file.open(filename, fstream::in);
806 if(!file.is_open()){
807 printf("error, cant open file for saving\n");
808 return -1;
811 last_filename = filename;
812 set_last_dir(filename);
814 clear();
816 unsigned char buf[64];
817 char* abuf;
818 char sbuf[256];
819 char* tbuf;
820 uint32_t size;
821 uint32_t micros;
822 int N = 0;
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;
834 int maxblockdur = 0;
836 for(int i=0; i<16; i++){
837 extratracks.push_back(NULL);
840 while(!file.eof()){
842 file.read((char*)buf,4);
843 if(memcmp(buf,"MThd",4)){
844 printf("missing header, probably not a midi file\n");
845 file.close();
846 return -1;
848 //printf("MThd\n");
849 scope_print("Standard Midi File\n");
851 file.read((char*)buf,4);
852 if(buf[3] != 6){
853 printf("header has wrong size, probably a broken midi file\n");
854 scope_print("error: bad header size");
855 file.close();
856 return -1;
858 //printf("header size\n");
860 file.read((char*)buf,2);
861 if(buf[0] != 0){
862 printf("bad smf type code, probably a broken midi file\n");
863 scope_print("error: bad smf type");
864 file.close();
865 return -1;
869 int smftype;
870 switch(buf[1]){
871 case 0: smftype=0; break;
872 case 1: smftype=1; break;
873 case 2: smftype=2; break;
874 default:
875 printf("bad smf type code, probably a broken midi file\n");
876 scope_print("error: bad smf type");
877 file.close();
878 return -1;
881 snprintf(sbuf,256," type: %d\n",smftype);
882 scope_print(sbuf);
884 file.read((char*)buf,2);
885 size = ntohs(*(unsigned short*)buf);
886 if(size==0){
887 printf("track count of zero, probably a broken midi file\n");
888 scope_print("error: zero tracks");
889 file.close();
890 return -1;
892 int ntracks = size;
894 snprintf(sbuf,256," tracks: %d\n",ntracks);
895 scope_print(sbuf);
898 int tpb = TICKS_PER_BEAT;
899 file.read((char*)buf,2);
900 size = ntohs(*(unsigned short*)buf);
901 if(size >> 15 == 0){
902 tpb = size&0x7fff;
903 snprintf(sbuf,256," time division: %d ticks per beat\n",tpb);
904 scope_print(sbuf);
906 else{
907 int fps = size&0x7fff;
908 snprintf(sbuf,256," time division: %d frames per second (wrong)\n",fps);
909 scope_print(sbuf);
910 scope_print("error: smpte time division not support\n");
911 file.close();
912 return -1;
916 int trackindex = 0;
917 /*** read tracks ***/
918 file.read((char*)buf,4);
919 while(!file.eof()){
921 if(memcmp(buf,"MTrk",4)){
922 printf("bad track header, probably a broken midi file\n");
923 file.close();
924 return -1;
927 pattern* p = new pattern();
928 mevent* e;
930 trackindex++;
931 snprintf(sbuf,256," track %d\n",trackindex);
932 scope_print(sbuf);
934 file.read((char*)buf,4);
935 size = ntohl(*(unsigned long*)buf);
936 if(size==0){
937 printf("empty track\n");
938 file.close();
939 return -1;
942 int time = 0;
943 int tick = 0;
944 int endtrack=0;
946 chanlist.push_back(-1);
947 banklist.push_back(-1);
948 proglist.push_back(-1);
950 tracknames.push_back(NULL);
952 /***read events***/
953 while(!endtrack){
955 int delta = getdelta(file);
956 if(delta < 0){
957 printf("bad delta time, broken midi file\n");
958 file.close();
959 return -1;
961 time += delta;
962 tick = time*TICKS_PER_BEAT/tpb;
964 if(tick > maxblockdur){
965 maxblockdur = tick;
968 int last_byte0;
969 file.read((char*)buf,1);
970 int byte0 = buf[0];
971 int byte1 = -1;
973 if(byte0 < 0x80){//implicit byte0
974 byte1 = byte0;
975 byte0 = last_byte0;
977 last_byte0 = byte0;
979 if(byte0 < 0xf0){//channel event
981 int type = byte0&0xf0;
982 int chan = byte0&0x0f;
984 if(chanlist[N]==-1){
985 chanlist[N]=chan;
988 if(byte1<0){//didnt read byte1 yet
989 file.read((char*)buf,1);
990 byte1 = buf[0];
995 int val1 = byte1;
996 int val2;
998 if(!(type == 0xC0 || type == 0xD0)){
999 file.read((char*)buf,1);
1000 val2 = buf[0];
1003 e = new mevent(type,tick,val1);
1006 switch(type){
1007 case 0x90://note on
1008 if(val2==0){//fake note off
1009 e->type = 0x80;
1011 e->value2 = val2;
1012 break;
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){
1018 banklist[N]=val2;
1020 e->value2 = val2;
1021 break;
1023 case 0xC0://program change
1024 if(proglist[N]==-1){
1025 proglist[N]=val1;
1027 break;
1028 case 0xD0://channel pressure
1029 break;
1030 default:
1031 printf("unrecognized channel event %d\n",type);
1032 file.close();
1033 return -1;
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();
1040 t->chan = chan;
1041 t->prog = -1;
1042 t->port = 0;
1043 t->bank = -1;
1045 extratracks[chan] = t;
1046 seqpat* s = new seqpat();
1047 t->head->next = s;
1048 s->prev = t->head;
1049 s->p = new pattern();
1050 //more track setup
1052 extratracks[chan]->head->next->p->insert(e,tick);
1054 else{//put it in a normal track
1055 p->append(e);
1059 else{/*** not a channel event ***/
1063 if(byte0 == 255){//meta events
1065 file.read((char*)buf,1);
1066 int meta = buf[0];
1069 size = getdelta(file);
1070 if(size < 0){
1071 printf("bad delta time\n");
1072 file.close();
1073 return -1;
1077 abuf = new char[size+1];
1079 switch(meta){
1080 case 0://sequence number
1082 snprintf(sbuf,256," %d sequence: ? ?\n",time);
1083 scope_print(sbuf);
1084 if(size != 2){
1085 printf("bad sequence number data length: %d\n",size);
1086 file.close();
1087 return -1;
1089 file.read((char*)buf,2);
1090 break;
1091 case 1://text event
1092 file.read(abuf,size);
1093 abuf[size]='\0';
1094 asprintf(&tbuf," %d text: \"%s\"\n",time,abuf);
1095 scope_print(tbuf);
1096 free(tbuf);
1098 ui->info_text->buffer()->append(abuf);
1099 ui->info_text->buffer()->append("\n");
1101 break;
1102 case 2://copyright notice
1103 file.read((char*)abuf,size);
1104 abuf[size]='\0';
1105 asprintf(&tbuf," %d copyright: \"%s\"\n",time,abuf);
1106 scope_print(tbuf);
1107 free(tbuf);
1108 break;
1109 case 3://track name
1110 file.read((char*)abuf,size);
1111 abuf[size]='\0';
1112 asprintf(&tbuf," %d track name: \"%s\"\n",time,abuf);
1113 scope_print(tbuf);
1114 free(tbuf);
1116 tracknames[N] = (char*)malloc(sizeof(char)*(size+1));
1117 strncpy(tracknames[N],abuf,size+1);
1119 break;
1120 case 4://instrument name
1121 file.read((char*)abuf,size);
1122 abuf[size]='\0';
1123 asprintf(&tbuf," %d instrument name: \"%s\"\n",time,abuf);
1124 scope_print(tbuf);
1125 free(tbuf);
1126 break;
1127 case 5://lyrics
1128 file.read((char*)abuf,size);
1129 abuf[size]='\0';
1130 asprintf(&tbuf," %d lyrics: \"%s\"\n",time,abuf);
1131 scope_print(tbuf);
1132 free(tbuf);
1133 break;
1134 case 6://marker
1135 file.read((char*)abuf,size);
1136 abuf[size]='\0';
1137 asprintf(&tbuf," %d marker: \"%s\"\n",time,abuf);
1138 scope_print(tbuf);
1139 free(tbuf);
1140 break;
1141 case 7://cue point
1142 file.read((char*)abuf,size);
1143 abuf[size]='\0';
1144 asprintf(&tbuf," %d cue point: \"%s\"\n",time,abuf);
1145 scope_print(tbuf);
1146 free(tbuf);
1147 break;
1148 case 32://channel prefix
1149 if(size!=1){
1150 printf("bad channel prefix data size: %d\n",size);
1151 file.close();
1152 return -1;
1154 file.read((char*)buf,1);
1155 asprintf(&tbuf," %d channel prefix: %d\n",time,buf[0]);
1156 scope_print(tbuf);
1157 free(tbuf);
1158 break;
1159 case 47://end of track
1160 if(size!=0){
1161 printf("end of track has non zero data size: %d\n",size);
1162 file.close();
1163 return -1;
1165 endtrack=1;
1166 break;
1167 case 81://set tempo
1168 if(size!=3){
1169 printf("set tempo has non-3 data size: %d\n",size);
1170 file.close();
1171 return -1;
1173 file.read((char*)buf,3);
1175 buf[3] = buf[2];
1176 buf[2] = buf[1];
1177 buf[1] = buf[0];
1178 buf[0] = 0;
1180 micros = *(unsigned*)buf;
1181 micros = ntohl(micros);
1183 asprintf(&tbuf," %d set tempo: %d us/quarter\n",time,micros);
1184 scope_print(tbuf);
1185 free(tbuf);
1187 if(time==0){
1188 set_beats_per_minute(60000000/micros);
1191 break;
1192 case 84://smpte offset
1193 if(size!=5){
1194 printf("smpte offset has non-5 data size: %d\n",size);
1195 file.close();
1196 return -1;
1198 file.read((char*)buf,5);
1199 asprintf(&tbuf," %d smpte offset: ?\n",time);
1200 scope_print(tbuf);
1201 free(tbuf);
1202 break;
1203 case 88://time signature
1204 if(size!=4){
1205 printf("time signature has non-4 data size: %d\n",size);
1206 file.close();
1207 return -1;
1209 file.read((char*)buf,4);
1210 asprintf(&tbuf," %d time signature: %d/%d\n",time,buf[0],1<<buf[1]);
1211 scope_print(tbuf);
1212 free(tbuf);
1213 break;
1214 case 89://key signature
1215 if(size!=2){
1216 printf("key signature has non-2 data size: %d\n",size);
1217 file.close();
1218 return -1;
1220 file.read((char*)buf,2);
1221 asprintf(&tbuf," %d key signature: %s %s\n",time,fifths[(signed char)buf[0]+7],buf[1]?"minor":"major");
1222 scope_print(tbuf);
1223 free(tbuf);
1224 break;
1225 case 127://sequencer specific
1226 file.read((char*)abuf,size);
1227 abuf[size]='\0';
1228 asprintf(&tbuf," %d sequencer specific: \"%s\"\n",time,abuf);
1229 scope_print(tbuf);
1230 free(tbuf);
1231 break;
1232 default://unknown meta event
1233 file.read((char*)abuf,size);
1234 abuf[size]='\0';
1235 asprintf(&tbuf," %d meta %d: \"%s\"\n",time,meta,abuf);
1236 scope_print(tbuf);
1237 free(tbuf);
1239 free(abuf);
1241 else if(byte0 == 240){//sysex event
1242 size = getdelta(file);
1243 if(size < 0){
1244 printf("bad delta time\n");
1245 return -1;
1247 abuf = new char[size+1];
1248 file.read((char*)abuf,size);
1249 abuf[size]='\0';
1251 asprintf(&tbuf," %d sysex: \"%s\"\n",time,abuf);
1252 scope_print(tbuf);
1253 free(tbuf);
1255 file.read((char*)buf,1);
1256 if(buf[0]!=0xf7){
1257 file.putback(buf[0]);
1259 else{
1260 scope_print(" end of sysex\n");
1265 free(abuf);
1267 else if(byte0 == 247){//divided sysex event
1268 size = getdelta(file);
1269 if(size < 0){
1270 printf("bad delta time\n");
1271 return -1;
1273 abuf = new char[size+1];
1274 file.read((char*)abuf,size);
1275 abuf[size]='\0';
1277 asprintf(&tbuf," %d sysex fragment: \"%s\"\n",time,abuf);
1278 scope_print(tbuf);
1279 free(tbuf);
1281 file.read((char*)buf,1);
1282 if(buf[0]!=0xf7){
1283 file.putback(buf[0]);
1285 else{
1286 scope_print(" end of sysex\n");
1288 free(abuf);
1290 else{
1291 printf("bad event type %d, broken midi file\n",byte0);
1292 file.close();
1293 return -1;
1300 if(proglist[N]==-1){
1301 proglist[N]=0;
1303 if(banklist[N]==-1){
1304 banklist[N]=0;
1306 if(chanlist[N]==-1){
1307 chanlist[N]=0;
1309 N++;
1312 p->fixdur();
1314 patlist.push_back(p);
1316 file.read((char*)buf,4);//read first byte of next track or EOF
1321 scope_print("End Of File\n\n");
1322 file.close();
1324 //TODO set up track settings using data remembered from the reading
1325 std::list<pattern*>::iterator p = patlist.begin();
1326 int i=0;
1327 while(p!=patlist.end()){
1328 track* t = new track();
1329 seqpat* s = new seqpat(i,0,128*64,*p);
1330 int Q = TICKS_PER_BEAT;
1331 s->dur = maxblockdur / Q * Q + Q;
1332 t->head->next = s;
1333 s->prev = t->head;
1334 t->skip = s;
1336 s->p->h = 360*i / 16;
1337 s->p->v = 0.8;
1338 while(s->p->h > 360){s->p->h -= 360;}
1339 s->p->regen_colors();
1341 t->chan = chanlist[i];
1342 t->prog = proglist[i];
1343 t->bank = banklist[i];
1344 t->port = 0;
1346 if(tracknames[i]){
1347 t->name = tracknames[i];
1349 else{
1350 t->name = (char*)malloc(8);
1351 t->name[0] = '\0';
1354 add_track(t);
1355 p++;
1356 i++;
1359 ui->track_info->update();
1361 ui->arranger->reset_handle();
1362 ui->arranger->redraw();
1364 update_config_gui();
1366 reset_backend(0);
1368 return 0;