Fixed bug in which import and load cause stuck notes.
[epichord.git] / src / saveload.cpp
blob5ada17781d86fd7606177473caf9cfd38f7b0600
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 <limits>
30 #include <arpa/inet.h>
31 #include <string.h>
32 #include <stdlib.h>
34 #include <fltk/file_chooser.h>
35 #include <fltk/filename.h>
37 #include "ui.h"
39 #include "backend.h"
41 #include "saveload.h"
43 #include "util.h"
45 #include "uihelper.h"
47 #include "backend.h"
49 extern UI* ui;
51 extern std::vector<track*> tracks;
54 extern struct conf config;
56 using namespace std;
58 std::string last_filename;
59 char last_dir[1024] = "";
62 void nextline(ifstream& f){
63 char dummy[512];
64 f.getline(dummy,512);
65 printf("%s\n",dummy);
69 std::list<pattern*> collectpatterns(){
70 std::list<pattern*> patlist;
72 for(int i=0; i<tracks.size(); i++){
73 seqpat* s = tracks[i]->head->next;
74 while(s){
75 if(s->layers){
76 for(int j=0; j<s->layers->total; j++){
77 pattern* p = s->layers->array[j];
78 patlist.push_back(p);
81 else{
82 patlist.push_back(s->p);
84 s=s->next;
88 patlist.sort();
89 patlist.unique();
91 return patlist;
94 int findpatternindex(pattern* p, std::list<pattern*>& patlist){
95 std::list<pattern*>::iterator i = patlist.begin();
96 int q = 0;
97 while(i != patlist.end()){
98 if(*i==p){
99 return q;
101 q++;
102 i++;
104 return -1;
107 pattern* findpatternbyindex(int index, std::list<pattern*>& patlist){
108 std::list<pattern*>::iterator i = patlist.begin();
109 int q = 0;
110 while(i != patlist.end()){
111 if(q==index){
112 return *i;
114 q++;
115 i++;
117 return NULL;
121 int clear(){
123 pause_backend();
124 all_notes_off();
125 reset_backend(0);
127 last_filename = "";
129 set_beats_per_measure(4);
130 set_measures_per_phrase(4);
132 set_bpm(120);
133 set_beats_per_minute(120);
134 update_config_gui();
136 track* t;
137 int total = tracks.size();
139 for(int i=0; i<total; i++){
140 t = tracks[tracks.size()-1];
141 tracks.pop_back();
142 delete t;
145 ui->title_text->text("");
146 ui->author_text->text("");
148 fltk::TextBuffer* tb = ui->info_text->buffer();
149 tb->text("");
151 ui->track_info->clear_tracks();
154 undo_reset();
156 ui->main_window->redraw();
160 void set_last_dir(const char* name){
161 const char* theend = fltk::filename_name(name);
162 int n = (int)(theend - name) / sizeof(char);
163 memcpy(last_dir,name,n);
164 last_dir[n] = '\0';
167 const char* get_last_dir(){
168 return last_dir;
171 int save(){
172 if(last_filename != ""){
173 return save(last_filename.c_str());
175 else{
176 return save(fltk::file_chooser("save file",NULL,last_dir));
182 int save(const char* filename){
184 if(filename == NULL){
185 return -1;
188 //create file
189 fstream file;
190 file.open(filename, fstream::out);
192 if(!file.is_open()){
193 printf("save: can't open file for saving.\n");
194 return -1;
197 last_filename = filename;
198 set_last_dir(filename);
200 //header to protect against accidentally opening wrong file
201 file << "J2ULJwCgwHA" << endl;
202 file << "epichord" << endl;
203 file << "fileversion " << FILE_VERSION << endl;
204 file << "ticksperbeat " << TICKS_PER_BEAT << endl << endl;
206 //write song info
207 file << "title " << ui->title_text->size() << " "
208 << ui->title_text->text() << endl;
209 file << "author " << ui->author_text->size() << " "
210 << ui->author_text->text() << endl;
211 file << "info " << ui->info_text->size() << " "
212 << ui->info_text->text() << endl;
214 file << "bpm " << ui->bpm_wheel->value() << endl;
215 file << "beatspermeasure " << config.beats_per_measure << endl;
216 file << "measuresperphrase " << config.measures_per_phrase << endl;
218 file << "loopstart " << get_loop_start() << endl;
219 file << "loopend " << get_loop_end() << endl;
221 file << endl;
224 //collect all visible patterns
225 std::list<pattern*> patlist = collectpatterns();
227 //for each pattern
228 std::list<pattern*>::iterator p = patlist.begin();
229 mevent* e;
230 int P = 0;
231 while(p != patlist.end()){
232 file << "pattern " << endl;
233 file << (*p)->h << " " << (*p)->s << " " << (*p)->v << endl;
234 e = (*p)->events->next;
235 mevent* eoff;
236 int n = 0;
237 int m = n;
238 int last_tick = 0;
239 int delta;
240 while(e){
241 delta = e->tick - last_tick;
242 last_tick = e->tick;
243 file << delta << " ";
244 file << e->type << " ";
245 file << e->value1 << " ";
246 file << e->value2 << endl;
247 //file << e->dur << endl;
248 n++;
249 e = e->next;
251 P++;
252 file << -1 << endl << endl;
253 p++;
256 seqpat* s;
257 for(int i=0; i<tracks.size(); i++){
258 file << endl << endl << "track " << endl;
259 file << "port " << tracks[i]->port << endl;
260 file << "chan " << tracks[i]->chan << endl;
261 file << "prog " << tracks[i]->prog << endl;
262 file << "bank " << tracks[i]->bank << endl;
263 file << "mute " << tracks[i]->mute << endl;
264 file << "solo " << tracks[i]->solo << endl;
265 file << "vol " << tracks[i]->vol << endl;
266 file << "pan " << tracks[i]->pan << endl;
267 file << "name " << strlen(tracks[i]->name) << " "
268 << tracks[i]->name << endl;
269 file << "alive " << tracks[i]->alive << endl;
270 s = tracks[i]->head->next;
271 int m = 0;
272 while(s){
273 file << endl << endl << "seqpat " << endl;
274 file << s->tick << " " << s->dur << endl;
275 file << s->scrollx << " " << s->scrolly << endl;
277 if(s->layers){
278 file << s->layers->total << " ";
279 for(int j=0; j<s->layers->total; j++){
281 int index = findpatternindex(s->layers->array[j],patlist);
282 if(index < 0){
283 printf("save: pattern not found, cannot save\n");
284 file.close();
285 return -1;
287 file << index << " ";
290 file << s->layers->index;
292 else{
293 file << 1 << " ";
294 int index = findpatternindex(s->p,patlist);
295 if(index < 0){
296 printf("save: pattern not found, cannot save\n");
297 file.close();
298 return -1;
300 file << index;
303 file << endl;
304 m++;
305 s = s->next;
307 file << "kcart";
312 file.close();
314 return 0;
320 int load(const char* filename){
323 if(filename == NULL){
324 return -1;
327 ifstream file;
328 string str;
329 file.open(filename, fstream::in);
331 if(!file.is_open()){
332 printf("load: can't open file for loading.\n");
333 return -1;
336 show_song_edit();
338 clear();
339 last_filename = filename;
340 set_last_dir(filename);
342 //pattern* pend = patterns;
343 std::list<pattern*> patlist;
346 //sanity check
347 file >> str;
348 if(str != "J2ULJwCgwHA"){
349 printf("load: this is definitely not a valid file (missing magic)\n");
350 file.close();
351 return -1;
353 file >> str;
354 if(str != "epichord"){
355 printf("load: this is definitely not a valid file (missing magic)\n");
356 file.close();
357 return -1;
359 file >> str;
360 if(str != "fileversion"){
361 printf("load: this is definitely not a valid file\n");
362 file.close();
363 return -1;
365 int M;
366 file >> M;
367 if(M!=FILE_VERSION){
368 printf("load: file has wrong version %d (need %d).\n",M,FILE_VERSION);
370 file >> str;
371 if(str != "ticksperbeat"){
372 printf("load: file is broken. (missing ticks per beat)\n");
373 file.close();
374 return -1;
376 int file_tpb;
377 file >> file_tpb;
378 if(file_tpb < 1){
379 printf("load: file is broken. (bad ticks per beat %d)\n",file_tpb);
380 file.close();
381 return -1;
385 file >> str;
386 while(!file.eof()){
388 int n;
390 if(str == "title"){
391 file >> n;
392 file.get();
393 char buf[256];
394 file.read(buf,n);
395 buf[n] = '\0';
396 ui->title_text->text(buf);
398 else if(str == "author"){
399 file >> n;
400 file.get();
401 char buf[256];
402 file.read(buf,n);
403 buf[n] = '\0';
404 ui->author_text->text(buf);
406 else if(str == "info"){
407 file >> n;
408 file.get();
409 fltk::TextBuffer* tb = ui->info_text->buffer();
410 char buf[1024];
411 file.read(buf,n);
412 buf[n] = '\0';
413 tb->text(buf);
415 else if(str == "bpm"){
416 int bpm;
417 file >> bpm;
418 set_bpm(bpm);
419 ui->bpm_wheel->value(bpm);
420 ui->bpm_output->value(bpm);
422 else if(str == "beatspermeasure"){
423 int N;
424 file >> N;
425 set_beats_per_measure(N);
427 else if(str == "measuresperphrase"){
428 int N;
429 file >> N;
430 set_measures_per_phrase(N);
432 else if(str == "loopstart"){
433 int ls;
434 file >> ls;
435 set_loop_start(ls);
437 else if(str == "loopend"){
438 int le;
439 file >> le;
440 set_loop_end(le);
442 else if(str == "pattern"){
443 pattern* p = new pattern();
444 file >> p->h;
445 file >> p->s;
446 file >> p->v;
447 p->regen_colors();
448 mevent* eend = p->events;
449 int off_index;
450 int type;
451 mevent* e;
452 int tick = 0;
453 int delta;
454 while(1){
455 e = new mevent();
457 file >> delta;
458 if(delta == -1){delete e; break;}
459 tick += delta;
460 e->tick = tick;
462 file >> e->type;
463 file >> e->value1;
464 file >> e->value2;
465 //file >> e->dur;
466 e->prev = eend;
467 eend->next = e;
468 eend = e;
470 p->fixdur();
471 patlist.push_back(p);
473 else if(str == "track"){
474 int track_number;
475 string key;
476 track* t = new track();
477 t->head->track = tracks.size();
478 seqpat* send = t->head;
479 file >> key;
481 while(key != "kcart"){
482 if(key == "port"){ file >> t->port; }
483 else if(key == "chan"){ file >> t->chan; }
484 else if(key == "prog"){ file >> t->prog; }
485 else if(key == "bank"){ file >> t->bank; }
486 else if(key == "mute"){ file >> t->mute; }
487 else if(key == "solo"){ file >> t->solo; }
488 else if(key == "vol"){ file >> t->vol; }
489 else if(key == "pan"){ file >> t->pan; }
490 else if(key == "name"){
491 file >> n;
492 file.get();
493 char* buf = (char*)malloc(n+1);
494 file.read(buf,n);
495 buf[n] = '\0';
496 t->name = buf;
498 else if(key == "alive"){ file >> t->alive; }
499 else if(key == "seqpat"){
500 int pattern_number;
501 seqpat* s = new seqpat();
502 s->track = tracks.size();
503 file >> s->tick;
504 file >> s->dur;
505 int total_layers;
506 int index;
507 pattern* p;
509 file >> s->scrollx >> s->scrolly;
510 file >> total_layers;
512 if(total_layers == 1){
513 file >> index;
514 p = findpatternbyindex(index, patlist);
515 s->p = p;
516 s->layers = NULL;
518 else if(total_layers > 1){
519 file >> index;
520 p = findpatternbyindex(index, patlist);
521 layerstack* layers = new layerstack(p);
523 for(int j=1; j<total_layers; j++){
524 file >> index;
525 p = findpatternbyindex(index,patlist);
526 layers->push(p);
529 file >> layers->index;
530 s->p = layers->array[layers->index];
531 s->layers = layers;
532 layers->ref_c = 1;
534 else{
535 printf("load: bad number of layers\n");
536 file.close();
537 return -1;
540 s->prev = send;
541 send->next = s;
542 send = s;
544 file >> key;
546 tracks.push_back(t);
547 ui->track_info->add_track();
549 else{
550 file.ignore(std::numeric_limits<streamsize>::max(),'\n');
553 file >> str;
556 set_rec_track(0);
557 ui->track_info->set_rec(0);
558 ui->track_info->update();
560 ui->arranger->redraw();
562 reset_backend(0);
564 file.close();
566 return 0;
572 int tick2delta(unsigned tick, vector<unsigned char>& vbuf){
573 unsigned char buf[4];
574 uint32_t n;
575 if(tick < 128){
576 vbuf.push_back(tick);
577 return 1;
579 else if(tick < 16383){
580 n = htonl(tick);
581 memcpy(buf,&n,4);
582 vbuf.push_back(0x80|((buf[0]<<1)|(buf[1]&0x80)>>7));
583 vbuf.push_back(buf[1]&0x7f);
584 return 2;
586 else if(tick < 2097151){
587 n = htonl(tick);
588 memcpy(buf,&n,4);
589 vbuf.push_back(0x80|((buf[0]<<2)|(buf[1]&0xC0)>>6));
590 vbuf.push_back(0x80|((buf[1]<<1)|(buf[2]&0x80)>>7));
591 vbuf.push_back(buf[2]&0x7f);
592 return 3;
594 else{
595 n = htonl(tick);
596 memcpy(buf,&n,4);
597 vbuf.push_back(0x80|((buf[0]<<3)|(buf[1]&0xE0)>>5));
598 vbuf.push_back(0x80|((buf[1]<<2)|(buf[2]&0xC0)>>6));
599 vbuf.push_back(0x80|((buf[2]<<1)|(buf[3]&0x80)>>7));
600 vbuf.push_back(buf[3]&0x7f);
601 return 4;
605 int savesmf(const char* filename){
607 if(filename == NULL){
608 return -1;
611 fstream file;
612 file.open(filename, fstream::out);
614 if(!file.is_open()){
615 printf("savesmf: can't open file for exporting.\n");
616 return -1;
619 unsigned char buf[64];
621 //chunk id
622 buf[0] = 'M';
623 buf[1] = 'T';
624 buf[2] = 'h';
625 buf[3] = 'd';
627 //chunk size
628 buf[4] = 0x00;
629 buf[5] = 0x00;
630 buf[6] = 0x00;
631 buf[7] = 0x06;
633 //type 1 midi file
634 buf[8] = 0x00;
635 buf[9] = 0x01;
637 //number of tracks
638 uint16_t L = tracks.size();
639 L = htons(L);
640 memcpy(buf+10,&L,2);
642 //ticks per beat
643 buf[12] = TICKS_PER_BEAT >> 8;
644 buf[13] = TICKS_PER_BEAT & 0x00ff;
646 file.write((const char*)buf,14);
648 vector<unsigned char> vbuf;
649 int last_tick = 0;
650 uint32_t N = 0;
651 int MAX = tracks.size();
653 for(int i=0; i<MAX; i++){
655 //chunk id
656 N = 0;
657 last_tick = 0;
658 vbuf.clear();
659 vbuf.push_back('M');
660 vbuf.push_back('T');
661 vbuf.push_back('r');
662 vbuf.push_back('k');
664 //chunk size (yet unknown)
666 vbuf.push_back(0x00);
667 vbuf.push_back(0x00);
668 vbuf.push_back(0x00);
669 vbuf.push_back(0x00);
671 track* t = tracks[i];
672 seqpat* s;
673 pattern* p;
674 mevent* e;
676 //change program for this track
678 //write events
679 s = t->head->next;
681 while(s){
682 e = s->p->events->next;
684 while(e){
686 if(e->tick > s->dur){
687 break;
689 switch(e->type){
690 case 0x80://note off
691 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
692 last_tick = e->tick+s->tick;
693 vbuf.push_back(0x80 | t->chan);
694 vbuf.push_back(e->value1);
695 vbuf.push_back(e->value2);
696 N += 3;
697 break;
698 case 0x90://note on
699 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
700 last_tick = e->tick+s->tick;
701 vbuf.push_back(0x90 | t->chan);
702 vbuf.push_back(e->value1);
703 vbuf.push_back(e->value2);
704 N += 3;
705 break;
706 case 0xA0://after touch
707 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
708 last_tick = e->tick+s->tick;
709 vbuf.push_back(0xA0 | t->chan);
710 vbuf.push_back(e->value1);
711 vbuf.push_back(e->value2);
712 N += 3;
713 break;
714 case 0xB0://control change
715 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
716 last_tick = e->tick+s->tick;
717 vbuf.push_back(0xB0 | t->chan);
718 vbuf.push_back(e->value1);
719 vbuf.push_back(e->value2);
720 N += 3;
721 break;
722 case 0xC0://program change
723 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
724 last_tick = e->tick+s->tick;
725 vbuf.push_back(0xC0 | t->chan);
726 vbuf.push_back(e->value1);
727 N += 2;
728 break;
729 case 0xD0://channel pressure
730 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
731 last_tick = e->tick+s->tick;
732 vbuf.push_back(0xD0 | t->chan);
733 vbuf.push_back(e->value1);
734 N += 2;
735 break;
736 case 0xE0://pitch wheel
737 N += tick2delta(e->tick+s->tick - last_tick,vbuf);
738 last_tick = e->tick+s->tick;
739 vbuf.push_back(0xE0 | t->chan);
740 vbuf.push_back(e->value1);
741 vbuf.push_back(e->value2);
742 N += 3;
743 break;
745 e = e->next;
748 s = s->next;
751 //end of track meta event
752 vbuf.push_back(0x00);
753 vbuf.push_back(0xff);
754 vbuf.push_back(0x2f);
755 vbuf.push_back(0x00);
756 N += 4;
758 N = htonl(N);
759 memcpy(buf,&N,4);
760 vbuf[4] = buf[0];
761 vbuf[5] = buf[1];
762 vbuf[6] = buf[2];
763 vbuf[7] = buf[3];
765 for(int i=0; i<vbuf.size(); i++){
766 buf[0] = vbuf[i];
767 file.write((const char*)buf,1);
771 file.close();
777 int getdelta(std::fstream& f){
778 unsigned char a,b,c,d;
780 f.read((char*)&a,1);
781 if(a<0x80){return a;}
783 f.read((char*)&b,1);
784 if(b<0x80){return ((a&0x7f)<<7) | b;}
786 f.read((char*)&c,1);
787 if(c<0x80){return ((a&0x7f)<<14) | ((b&0x7f)<<7) | c;}
789 f.read((char*)&d,1);
790 return ((a&0x7f)<<21) | ((b&0x7f)<<14) | ((c&0x7f)<<7) | d;
798 char fifths[15][8] = {
799 "Cb",
800 "Gb",
801 "Db",
802 "Ab",
803 "Eb",
804 "Bb",
805 "F",
806 "C",
807 "G",
808 "D",
809 "A",
810 "E",
811 "B",
812 "F#",
813 "C#"
817 int loadsmf(const char* filename){
818 if(filename == NULL){
819 return -1;
822 fstream file;
823 file.open(filename, fstream::in);
825 if(!file.is_open()){
826 printf("loadsmf: can't open file for importing.\n");
827 return -1;
830 last_filename = filename;
831 set_last_dir(filename);
833 clear();
835 unsigned char buf[64];
836 char* abuf;
837 char sbuf[256];
838 char* tbuf;
839 uint32_t size;
840 uint32_t micros;
841 int N = 0;
842 int tempo_flag = 0;
844 std::list<pattern*> patlist;
845 std::vector<int> chanlist;
846 std::vector<int> proglist;
847 std::vector<int> banklist;
849 std::vector<track*> extratracks;
851 std::vector<char*> tracknames;
853 int maxblockdur = 0;
855 for(int i=0; i<16; i++){
856 extratracks.push_back(NULL);
859 while(!file.eof()){
861 file.read((char*)buf,4);
862 if(memcmp(buf,"MThd",4)){
863 printf("missing header, probably not a midi file\n");
864 file.close();
865 return -1;
867 //printf("MThd\n");
868 scope_print("Standard Midi File\n");
870 file.read((char*)buf,4);
871 if(buf[3] != 6){
872 printf("header has wrong size, probably a broken midi file\n");
873 scope_print("error: bad header size");
874 file.close();
875 return -1;
877 //printf("header size\n");
879 file.read((char*)buf,2);
880 if(buf[0] != 0){
881 printf("bad smf type code, probably a broken midi file\n");
882 scope_print("error: bad smf type");
883 file.close();
884 return -1;
888 int smftype;
889 switch(buf[1]){
890 case 0: smftype=0; break;
891 case 1: smftype=1; break;
892 case 2: smftype=2; break;
893 default:
894 printf("bad smf type code, probably a broken midi file\n");
895 scope_print("error: bad smf type");
896 file.close();
897 return -1;
900 snprintf(sbuf,256," type: %d\n",smftype);
901 scope_print(sbuf);
903 file.read((char*)buf,2);
904 size = ntohs(*(unsigned short*)buf);
905 if(size==0){
906 printf("track count of zero, probably a broken midi file\n");
907 scope_print("error: zero tracks");
908 file.close();
909 return -1;
911 int ntracks = size;
913 snprintf(sbuf,256," tracks: %d\n",ntracks);
914 scope_print(sbuf);
917 int tpb = TICKS_PER_BEAT;
918 file.read((char*)buf,2);
919 size = ntohs(*(unsigned short*)buf);
920 if(size >> 15 == 0){
921 tpb = size&0x7fff;
922 snprintf(sbuf,256," time division: %d ticks per beat\n",tpb);
923 scope_print(sbuf);
925 else{
926 int fps = size&0x7fff;
927 snprintf(sbuf,256," time division: %d frames per second (wrong)\n",fps);
928 scope_print(sbuf);
929 scope_print("error: smpte time division not support\n");
930 file.close();
931 return -1;
935 int trackindex = 0;
936 /*** read tracks ***/
937 file.read((char*)buf,4);
938 while(!file.eof()){
940 if(memcmp(buf,"MTrk",4)){
941 printf("bad track header, probably a broken midi file\n");
942 file.close();
943 return -1;
946 pattern* p = new pattern();
947 mevent* e;
949 trackindex++;
950 snprintf(sbuf,256," track %d\n",trackindex);
951 scope_print(sbuf);
953 file.read((char*)buf,4);
954 size = ntohl(*(unsigned long*)buf);
955 if(size==0){
956 printf("empty track\n");
957 file.close();
958 return -1;
961 int time = 0;
962 int tick = 0;
963 int endtrack=0;
965 chanlist.push_back(-1);
966 banklist.push_back(-1);
967 proglist.push_back(-1);
969 tracknames.push_back(NULL);
971 /***read events***/
972 while(!endtrack){
974 int delta = getdelta(file);
975 if(delta < 0){
976 printf("bad delta time, broken midi file\n");
977 file.close();
978 return -1;
980 time += delta;
981 tick = time*TICKS_PER_BEAT/tpb;
983 if(tick > maxblockdur){
984 maxblockdur = tick;
987 int last_byte0;
988 file.read((char*)buf,1);
989 int byte0 = buf[0];
990 int byte1 = -1;
992 if(byte0 < 0x80){//implicit byte0
993 byte1 = byte0;
994 byte0 = last_byte0;
996 last_byte0 = byte0;
998 if(byte0 < 0xf0){//channel event
1000 int type = byte0&0xf0;
1001 int chan = byte0&0x0f;
1003 if(chanlist[N]==-1){
1004 chanlist[N]=chan;
1007 if(byte1<0){//didnt read byte1 yet
1008 file.read((char*)buf,1);
1009 byte1 = buf[0];
1014 int val1 = byte1;
1015 int val2;
1017 if(!(type == 0xC0 || type == 0xD0)){
1018 file.read((char*)buf,1);
1019 val2 = buf[0];
1022 e = new mevent(type,tick,val1);
1025 switch(type){
1026 case 0x90://note on
1027 if(val2==0){//fake note off
1028 e->type = 0x80;
1030 e->value2 = val2;
1031 break;
1032 case 0x80://note off
1033 case 0xA0://aftertouch
1034 case 0xB0://controller change
1035 case 0xE0://pitchbend
1036 if(type==0xB0 && val1==0x00 && banklist[N]==-1){
1037 banklist[N]=val2;
1039 e->value2 = val2;
1040 break;
1042 case 0xC0://program change
1043 if(proglist[N]==-1){
1044 proglist[N]=val1;
1046 break;
1047 case 0xD0://channel pressure
1048 break;
1049 default:
1050 printf("unrecognized channel event %d\n",type);
1051 file.close();
1052 return -1;
1055 if(chan!=chanlist[N]){//put event in the a misfit track
1056 //printf("mistfit N=%d chan=%d type=%d\n",chanlist[N],chan,type);
1057 if(extratracks[chan] == NULL){
1058 track* t = new track();
1059 t->chan = chan;
1060 t->prog = -1;
1061 t->port = 0;
1062 t->bank = -1;
1064 extratracks[chan] = t;
1065 seqpat* s = new seqpat();
1066 t->head->next = s;
1067 s->prev = t->head;
1068 s->p = new pattern();
1069 //more track setup
1071 extratracks[chan]->head->next->p->insert(e,tick);
1073 else{//put it in a normal track
1074 p->append(e);
1078 else{/*** not a channel event ***/
1082 if(byte0 == 255){//meta events
1084 file.read((char*)buf,1);
1085 int meta = buf[0];
1088 size = getdelta(file);
1089 if(size < 0){
1090 printf("bad delta time\n");
1091 file.close();
1092 return -1;
1096 abuf = new char[size+1];
1098 switch(meta){
1099 case 0://sequence number
1101 snprintf(sbuf,256," %d sequence: ? ?\n",time);
1102 scope_print(sbuf);
1103 if(size != 2){
1104 printf("bad sequence number data length: %d\n",size);
1105 file.close();
1106 return -1;
1108 file.read((char*)buf,2);
1109 break;
1110 case 1://text event
1111 file.read(abuf,size);
1112 abuf[size]='\0';
1113 asprintf(&tbuf," %d text: \"%s\"\n",time,abuf);
1114 scope_print(tbuf);
1115 free(tbuf);
1117 ui->info_text->buffer()->append(abuf);
1118 ui->info_text->buffer()->append("\n");
1120 break;
1121 case 2://copyright notice
1122 file.read((char*)abuf,size);
1123 abuf[size]='\0';
1124 asprintf(&tbuf," %d copyright: \"%s\"\n",time,abuf);
1125 scope_print(tbuf);
1126 free(tbuf);
1127 break;
1128 case 3://track name
1129 file.read((char*)abuf,size);
1130 abuf[size]='\0';
1131 asprintf(&tbuf," %d track name: \"%s\"\n",time,abuf);
1132 scope_print(tbuf);
1133 free(tbuf);
1135 tracknames[N] = (char*)malloc(sizeof(char)*(size+1));
1136 strncpy(tracknames[N],abuf,size+1);
1138 break;
1139 case 4://instrument name
1140 file.read((char*)abuf,size);
1141 abuf[size]='\0';
1142 asprintf(&tbuf," %d instrument name: \"%s\"\n",time,abuf);
1143 scope_print(tbuf);
1144 free(tbuf);
1145 break;
1146 case 5://lyrics
1147 file.read((char*)abuf,size);
1148 abuf[size]='\0';
1149 asprintf(&tbuf," %d lyrics: \"%s\"\n",time,abuf);
1150 scope_print(tbuf);
1151 free(tbuf);
1152 break;
1153 case 6://marker
1154 file.read((char*)abuf,size);
1155 abuf[size]='\0';
1156 asprintf(&tbuf," %d marker: \"%s\"\n",time,abuf);
1157 scope_print(tbuf);
1158 free(tbuf);
1159 break;
1160 case 7://cue point
1161 file.read((char*)abuf,size);
1162 abuf[size]='\0';
1163 asprintf(&tbuf," %d cue point: \"%s\"\n",time,abuf);
1164 scope_print(tbuf);
1165 free(tbuf);
1166 break;
1167 case 32://channel prefix
1168 if(size!=1){
1169 printf("bad channel prefix data size: %d\n",size);
1170 file.close();
1171 return -1;
1173 file.read((char*)buf,1);
1174 asprintf(&tbuf," %d channel prefix: %d\n",time,buf[0]);
1175 scope_print(tbuf);
1176 free(tbuf);
1177 break;
1178 case 47://end of track
1179 if(size!=0){
1180 printf("end of track has non zero data size: %d\n",size);
1181 file.close();
1182 return -1;
1184 endtrack=1;
1185 break;
1186 case 81://set tempo
1187 if(size!=3){
1188 printf("set tempo has non-3 data size: %d\n",size);
1189 file.close();
1190 return -1;
1192 file.read((char*)buf,3);
1194 buf[3] = buf[2];
1195 buf[2] = buf[1];
1196 buf[1] = buf[0];
1197 buf[0] = 0;
1199 micros = *(unsigned*)buf;
1200 micros = ntohl(micros);
1202 asprintf(&tbuf," %d set tempo: %d us/quarter\n",time,micros);
1203 scope_print(tbuf);
1204 free(tbuf);
1206 if(time==0){
1207 tempo_flag = 1;
1208 set_beats_per_minute(60000000/micros);
1211 break;
1212 case 84://smpte offset
1213 if(size!=5){
1214 printf("smpte offset has non-5 data size: %d\n",size);
1215 file.close();
1216 return -1;
1218 file.read((char*)buf,5);
1219 asprintf(&tbuf," %d smpte offset: ?\n",time);
1220 scope_print(tbuf);
1221 free(tbuf);
1222 break;
1223 case 88://time signature
1224 if(size!=4){
1225 printf("time signature has non-4 data size: %d\n",size);
1226 file.close();
1227 return -1;
1229 file.read((char*)buf,4);
1230 asprintf(&tbuf," %d time signature: %d/%d\n",time,buf[0],1<<buf[1]);
1231 scope_print(tbuf);
1232 free(tbuf);
1233 break;
1234 case 89://key signature
1235 if(size!=2){
1236 printf("key signature has non-2 data size: %d\n",size);
1237 file.close();
1238 return -1;
1240 file.read((char*)buf,2);
1241 asprintf(&tbuf," %d key signature: %s %s\n",time,fifths[(signed char)buf[0]+7],buf[1]?"minor":"major");
1242 scope_print(tbuf);
1243 free(tbuf);
1244 break;
1245 case 127://sequencer specific
1246 file.read((char*)abuf,size);
1247 abuf[size]='\0';
1248 asprintf(&tbuf," %d sequencer specific: \"%s\"\n",time,abuf);
1249 scope_print(tbuf);
1250 free(tbuf);
1251 break;
1252 default://unknown meta event
1253 file.read((char*)abuf,size);
1254 abuf[size]='\0';
1255 asprintf(&tbuf," %d meta %d: \"%s\"\n",time,meta,abuf);
1256 scope_print(tbuf);
1257 free(tbuf);
1259 free(abuf);
1261 else if(byte0 == 240){//sysex event
1262 size = getdelta(file);
1263 if(size < 0){
1264 printf("bad delta time\n");
1265 return -1;
1267 abuf = new char[size+1];
1268 file.read((char*)abuf,size);
1269 abuf[size]='\0';
1271 asprintf(&tbuf," %d sysex: \"%s\"\n",time,abuf);
1272 scope_print(tbuf);
1273 free(tbuf);
1275 file.read((char*)buf,1);
1276 if(buf[0]!=0xf7){
1277 file.putback(buf[0]);
1279 else{
1280 scope_print(" end of sysex\n");
1285 free(abuf);
1287 else if(byte0 == 247){//divided sysex event
1288 size = getdelta(file);
1289 if(size < 0){
1290 printf("bad delta time\n");
1291 return -1;
1293 abuf = new char[size+1];
1294 file.read((char*)abuf,size);
1295 abuf[size]='\0';
1297 asprintf(&tbuf," %d sysex fragment: \"%s\"\n",time,abuf);
1298 scope_print(tbuf);
1299 free(tbuf);
1301 file.read((char*)buf,1);
1302 if(buf[0]!=0xf7){
1303 file.putback(buf[0]);
1305 else{
1306 scope_print(" end of sysex\n");
1308 free(abuf);
1310 else{
1311 printf("bad event type %d, broken midi file\n",byte0);
1312 file.close();
1313 return -1;
1320 if(proglist[N]==-1){
1321 proglist[N]=0;
1323 if(banklist[N]==-1){
1324 banklist[N]=0;
1326 if(chanlist[N]==-1){
1327 chanlist[N]=0;
1329 N++;
1332 p->fixdur();
1334 patlist.push_back(p);
1336 file.read((char*)buf,4);//read first byte of next track or EOF
1341 scope_print("End Of File\n\n");
1342 file.close();
1344 //TODO set up track settings using data remembered from the reading
1345 std::list<pattern*>::iterator p = patlist.begin();
1346 int i=0;
1347 while(p!=patlist.end()){
1348 track* t = new track();
1349 seqpat* s = new seqpat(i,0,128*64,*p);
1350 int Q = TICKS_PER_BEAT;
1351 s->dur = maxblockdur / Q * Q + Q;
1352 t->head->next = s;
1353 s->prev = t->head;
1354 t->skip = s;
1356 s->p->h = 360*i / 16;
1357 s->p->v = 0.8;
1358 while(s->p->h > 360){s->p->h -= 360;}
1359 s->p->regen_colors();
1361 t->chan = chanlist[i];
1362 t->prog = proglist[i];
1363 t->bank = banklist[i];
1364 t->port = 0;
1366 if(tracknames[i]){
1367 t->name = tracknames[i];
1369 else{
1370 t->name = (char*)malloc(8);
1371 t->name[0] = '\0';
1374 add_track(t);
1375 p++;
1376 i++;
1379 if(tempo_flag == 0){
1380 set_beats_per_minute(120);
1383 set_rec_track(0);
1384 ui->track_info->set_rec(0);
1385 ui->track_info->update();
1387 ui->arranger->redraw();
1389 update_config_gui();
1391 reset_backend(0);
1393 return 0;