Mouse wheel now scrolls horizontally in piano roll.
[epichord.git] / src / seq.cpp
blob44d02dc87ae3b59aed7852660fcf814f4c9212b7
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 <stdlib.h>
24 #include <math.h>
25 #include <list>
26 #include <vector>
28 #include <fltk/TextDisplay.h>
29 #include "seq.h"
31 #include "util.h"
33 #include "backend.h"
35 std::vector<track*> tracks;
37 std::list<Command*> undo_stack;
38 std::list<Command*>::iterator undo_ptr;
39 std::list<int> undo_number;
40 std::list<int>::iterator undo_nptr;
43 struct total_event{
44 mevent* e;
45 int t;
46 seqpat* s;
48 total_event(){}
49 total_event(mevent* ze, int zt, seqpat* zs){
50 e=ze;
51 t=zt;
52 s=zs;
54 ~total_event(){}
55 total_event(const total_event& zte){
56 e=zte.e;
57 t=zte.t;
58 s=zte.s;
60 int operator<(const total_event& zte){
61 return e->tick+s->tick < zte.e->tick+zte.s->tick;
63 void operator=(const total_event& zte){
64 e=zte.e;
65 t=zte.t;
66 s=zte.s;
69 std::list<total_event> dispatch_queue;
71 int solo_flag = 0;
73 int rec_track = 0;
75 static float default_hsv_value = 0.8;
81 int play_seq(int cur_tick){
83 seqpat* s;
84 pattern* p;
85 mevent* e;
86 int base;
89 dispatch_queue.clear();
91 /* start at skip s, and skip e
92 if e is in the past, dispatch event and set new skip
93 if next e is past pattern dur, switch patseq
94 if next e is null, switch patseq
95 switch patseq sets skip s
96 do the above until e is in the future and not past end
97 then go to next track and start over
100 //printf("playing. cur_tick = %d\n",cur_tick);
101 s = tracks[0]->skip;
102 for(int i=0; i<tracks.size(); i++){
103 //if(tracks[i]->alive == 0){continue;}
104 s = tracks[i]->skip;
105 if(!s){continue;}
106 p = s->p;
107 e = s->skip;
109 if(!e){ goto switchblock; }//no more events in this seqpat
111 again:
113 if(e->tick+s->tick <= cur_tick && e->tick <= s->dur){//should have happened
115 if(e->tick != s->dur || e->type == MIDI_NOTE_OFF)
116 if(tracks[i]->mute == 0)
117 if((get_solo() && tracks[i]->solo != 0) || !get_solo()){
118 //dispatch_event(e, i, s->tick);
119 dispatch_queue.push_back(total_event(e,i,s));
122 e = e->next;
123 s->skip = e;
124 if(!e){//no more events in this seqpat
125 goto switchblock;
128 else if(e->tick > s->dur){//went past the end
129 goto switchblock;
131 else{//no more events on this track right now
132 continue;
134 goto again;//try to play next event
136 switchblock:
138 //TODO auto off all playing notes on track because end of block
140 s = s->next;
142 tracks[i]->skip = s;
143 if(!s){continue;}//no more seqpats
144 p = s->p;
145 if(!p){continue;}//this shouldnt happen anymore
146 e = s->skip;
147 if(!e){continue;}//...means this pattern has played already...
149 goto again;//play some or all of the next seqpat
153 //sort and dispatch
154 dispatch_queue.sort();
156 std::list<total_event>::iterator i = dispatch_queue.begin();
157 while(i != dispatch_queue.end()){
158 OnBitArray* oba = &(tracks[i->t]->onbits);
159 if(i->e->type == MIDI_NOTE_ON){
160 if(!oba->get(i->e->value1)){
161 tracks[i->t]->onbits.set(i->e->value1, 1);
163 else{
164 mevent eoff = i->e;
165 eoff.type = MIDI_NOTE_OFF;
166 eoff.value2 = 0;
167 //dispatch_event(&eoff, i->t, i->s->tick);
170 else if(i->e->type == MIDI_NOTE_OFF){
171 tracks[i->t]->onbits.set(i->e->value1, 0);
174 if(i->e->type == MIDI_CONTROLLER_CHANGE){
175 int V = i->e->value2;
176 int B = tracks[i->t]->bank;
177 tracks[i->t]->contr[i->e->value1] = V;
178 if(V == 0){
179 tracks[i->t]->bank = B%128 + V*128;
181 else if(V == 32){
182 tracks[i->t]->bank = B/128*128 + V;
185 if(i->e->type == MIDI_PROGRAM_CHANGE){
186 tracks[i->t]->prog = i->e->value1;
189 dispatch_event(i->e, i->t, i->s->tick);
191 i++;
196 int set_seq_pos(int new_tick){
197 //reset all skip
198 //reset cur_seqpat
199 seqpat* s;
200 pattern* p;
201 mevent* e;
203 for(int i=0; i<tracks.size(); i++){
205 s = tracks[i]->head;
206 tracks[i]->skip = s;
208 while(s){
209 s->skip = s->p->events;
210 s = s->next;
213 s = tracks[i]->head;
214 while(s){
215 if(s->tick+s->dur <= new_tick){
216 tracks[i]->skip = s;
218 else{
219 tracks[i]->skip = s;
220 break;
222 s = s->next;
225 if(!s){
226 tracks[i]->skip = NULL;
227 continue;
230 if(!s->p){continue;}
231 e = s->p->events;
233 while(1){
234 if(e == NULL){
235 s->skip = e;
236 break;
238 else if(e->tick >= new_tick - s->tick){
239 s->skip = e;
240 break;
242 e = e->next;
247 void set_rec_track(int t){
248 rec_track = t;
251 int get_rec_track(){
252 return rec_track;
255 int set_default_hsv_value(float v){
256 default_hsv_value = v;
265 CreateSeqpat::CreateSeqpat(int track, int tick, seqpat* zs, int copy){
266 s = new seqpat(zs);
267 s->selected = 0;
268 if(copy){
269 s->p = new pattern(zs->p);
270 s->skip = s->p->events;
272 s->track = track;
273 s->tick = tick;
275 s->prev = tfind<seqpat>(tracks[track]->head,tick);
276 s->next = s->prev->next;
279 void CreateSeqpat::redo(){
280 tinsert<seqpat>(s->prev, s);
283 void CreateSeqpat::undo(){
284 tremove<seqpat>(s);
287 CreateSeqpatBlank::CreateSeqpatBlank(int track, int tick, int len){
288 s = new seqpat(track, tick, len, new pattern());
289 unsigned char r,g,b;
291 pattern* p = s->p;
292 p->ref_c = 1;
293 p->h = ((track%16) / 16.0) * 360;
294 p->v = default_hsv_value;
295 p->regen_colors();
297 s->scrolly = 300;
298 s->scrollx = 0;
300 s->prev = tfind<seqpat>(tracks[track]->head,tick);
301 s->next = s->prev->next;
302 s->skip = s->p->events;
306 void DeleteSeqpat::redo(){
307 //check for restate
308 int pos = get_play_position();
309 if(pos >= s->tick && pos <= s->tick+s->dur){
310 tracks[s->track]->skip = s->next;
313 tremove<seqpat>(s);
316 void DeleteSeqpat::undo(){
317 tinsert<seqpat>(s->prev, s);
318 //check for restate
321 void ResizeSeqpat::redo(){
322 tremove<seqpat>(s1);
323 tinsert<seqpat>(s1->prev,s2);
325 //check for restate
328 void ResizeSeqpat::undo(){
329 tremove<seqpat>(s2);
330 tinsert<seqpat>(s1->prev,s1);
333 MoveSeqpat::MoveSeqpat(seqpat* zs, int track, int tick){
334 s = zs;
335 track1 = s->track;
336 track2 = track;
337 tick1 = s->tick;
338 tick2 = tick;
339 targ1 = s->prev;
340 targ2 = tfind<seqpat>(tracks[track2]->head,tick);
341 if(targ2 == zs){//dont put it after itself
342 targ2 = zs->prev;
346 void MoveSeqpat::redo(){
348 tremove<seqpat>(s);
351 int play_pos = get_play_position();
352 if(play_pos >= s->tick && play_pos <= s->tick+s->dur){//no entry into s by cb
353 tracks[track1]->skip = s->next;
356 track* t = tracks[track2];
358 //here possibly wait a few ms for the audio to leave s if it was in
360 //perform nitty gritty
361 s->track = track2;
363 s->tick = tick2;
365 s->skip = tfind<mevent>(s->p->events, play_pos - s->tick)->next;
366 tinsert<seqpat>(targ2,s);
369 void MoveSeqpat::undo(){
371 tremove<seqpat>(s);
373 int play_pos = get_play_position();
374 if(play_pos >= s->tick && play_pos <= s->tick+s->dur){
375 tracks[track2]->skip = s->next;
377 s->track = track1;
378 s->tick = tick1;
381 s->skip = tfind<mevent>(s->p->events, play_pos - s->tick)->next;
383 tinsert<seqpat>(targ1,s);
387 SplitSeqpat::SplitSeqpat(seqpat* zs, int tick){
388 s = zs;
390 int w1 = tick - s->tick;
391 int w2 = s->tick+s->dur - tick;
393 pattern* p1 = new pattern();
394 pattern* p2 = new pattern();
396 p1->h = s->p->h;
397 p1->s = s->p->s;
398 p1->v = s->p->v;
399 p1->regen_colors();
401 p2->h = s->p->h;
402 p2->s = s->p->s;
403 p2->v = randf(0.2,0.8);
404 p2->regen_colors();
407 //split the events into two groups
408 mevent* e = s->p->events->next;
409 while(e){
410 mevent* f = new mevent(e);
411 f->next = NULL;
412 if(e->tick < tick-s->tick){//group 1
413 p1->append(f);
415 else if(e->tick == tick-s->tick){//depends, maybe one, maybe other
416 if(e->type == MIDI_NOTE_OFF){
417 p1->append(f);
419 else{
420 p2->append(f);
421 f->tick -= w1;
424 else{//group 2
425 p2->append(f);
426 f->tick -= w1;
428 e = e->next;
431 s1 = new seqpat(zs,p1);
432 s1->dur = w1;
433 s1->scrollx = 0;
435 s2 = new seqpat(zs,p2);
436 s2->tick = s1->tick + w1;
437 s2->dur = w2;
438 s2->scrollx = 0;
443 void SplitSeqpat::redo(){
444 tremove<seqpat>(s);
445 tinsert<seqpat>(s->prev,s1);
446 tinsert<seqpat>(s1,s2);
449 void SplitSeqpat::undo(){
450 tremove<seqpat>(s2);
451 tremove<seqpat>(s1);
452 tinsert<seqpat>(s->prev,s);
457 JoinSeqpat::JoinSeqpat(seqpat* zs1, seqpat* zs2){
458 s1 = zs1;
459 s2 = zs2;
461 pattern* p = new pattern();
462 p->h = s1->p->h;
463 p->s = s1->p->s;
464 p->v = s1->p->v;
465 p->regen_colors();
467 mevent* e = s1->p->events->next;
468 while(e){
469 mevent* f = new mevent(e);
470 f->next = NULL;
471 p->append(f);
472 e=e->next;
475 e=s2->p->events->next;
476 while(e){
477 mevent* f = new mevent(e);
478 f->next = NULL;
479 f->tick += s1->dur;
480 p->append(f);
481 e=e->next;
484 s = new seqpat(s1,p);
485 s->scrollx = 0;
486 s->dur = s1->dur + s2->dur;
489 void JoinSeqpat::redo(){
490 tremove<seqpat>(s2);
491 tremove<seqpat>(s1);
492 tinsert<seqpat>(s->prev,s);
495 void JoinSeqpat::undo(){
496 tremove<seqpat>(s);
497 tinsert<seqpat>(s->prev,s1);
498 tinsert<seqpat>(s1,s2);
502 void ClearSeqpat::redo(){
503 s->p = p2;
506 void ClearSeqpat::undo(){
507 s->p = p1;
510 void LayerSeqpat::redo(){
511 if(s->layers == NULL){
512 s->layers = new layerstack(s->p);
514 s->layers->push(p);
515 s->p = p;
518 void LayerSeqpat::undo(){
519 s->p = s->layers->pop();
520 printf("ok...%d\n",s->layers->total);
521 if(s->layers->total == 1){
522 printf("deleting layers\n");
523 delete s->layers;
524 s->layers = NULL;
529 void CreateNote::redo(){
530 mevent* targ = tfind<mevent>(p->events, e1->tick);
531 tinsert<mevent>(targ, e1);
532 targ = tfind<mevent>(p->events, e2->tick);
533 tinsert<mevent>(targ, e2);
536 void CreateNote::undo(){
537 tremove<mevent>(e1);
538 tremove<mevent>(e2);
541 void CreateNoteOn::redo(){
542 mevent* targ = tfind<mevent>(p->events, e1->tick);
543 tinsert<mevent>(targ, e1);
544 //targ = tfind<mevent>(p->events, e2->tick);
545 //tinsert<mevent>(targ, e2);
548 void CreateNoteOn::undo(){
549 tremove<mevent>(e1);
550 //tremove<mevent>(e2);
554 CreateNoteOff::CreateNoteOff(pattern* zp, int note, int vel, int tick){
555 p = zp;
556 e1 = NULL;
557 mevent* ptr = tfind<mevent>(zp->events,tick);
558 while(ptr){
559 if(ptr->type == MIDI_NOTE_ON && ptr->value1 == note){
560 dur1 = ptr->dur;
561 dur2 = tick - ptr->tick;
562 e1 = ptr;
563 break;
565 if(ptr->type == MIDI_NOTE_OFF && ptr->value1 == note){
566 break;
568 ptr = ptr->prev;
570 e2 = new mevent(MIDI_NOTE_OFF, tick, note);
571 e2->value2 = vel;
574 void CreateNoteOff::redo(){
575 //mevent* targ = tfind<mevent>(p->events, e1->tick);
576 //tinsert<mevent>(targ, e1);
577 mevent* targ;
578 targ = tfind<mevent>(p->events, e2->tick);
579 tinsert<mevent>(targ, e2);
580 if(e1){
581 e1->dur = dur2;
585 void CreateNoteOff::undo(){
586 //tremove<mevent>(e1);
587 if(e1){
588 e1->dur = dur1;
590 tremove<mevent>(e2);
593 void DeleteNote::redo(){
594 tremove<mevent>(e1);
595 if(e2){
596 tremove<mevent>(e2);
600 void DeleteNote::undo(){
601 tinsert<mevent>(e1->prev,e1);
602 if(e2){
603 tinsert<mevent>(e2->prev,e2);
609 void MoveNote::arrive(int t){
610 mevent* targ = tfind<mevent>(p->events, t);
611 tinsert<mevent>(targ, e1);
612 if(e2){
613 targ = tfind<mevent>(p->events, t+e1->dur);
614 tinsert<mevent>(targ, e2);
618 void MoveNote::redo(){
619 tremove<mevent>(e1);
620 e1->tick = t2;
621 e1->value1 = note2;
622 if(e2){
623 tremove<mevent>(e2);
624 e2->tick = t2+e1->dur;
625 e2->value1 = note2;
627 arrive(t2);
630 void MoveNote::undo(){
631 tremove<mevent>(e1);
632 e1->tick = t1;
633 e1->value1 = note1;
634 if(e2){
635 tremove<mevent>(e2);
636 e2->tick = t1+e1->dur;
637 e2->value1 = note1;
639 arrive(t1);
645 ResizeNote::ResizeNote(pattern* zp, mevent* ze, int dur){
646 p = zp;
647 l1 = ze;
649 d1 = l1->dur;
650 d2 = dur;
652 r2 = NULL;
653 r1 = find_off(ze);
654 if(r1){
655 r2 = new mevent(r1);
656 r2->prev = tfind<mevent>(p->events, ze->tick + dur);
657 r2->next = r2->prev->next;
659 if(r2->prev == r1){//prev fix up
660 r2->prev = ze;
661 r2->next = r1->next;
664 if(r2->next == r1){//next fix up
665 r2->next = r1->next;
668 r2->tick = ze->tick + dur;
672 void ResizeNote::redo(){
673 //tremove<mevent>(l1);
674 if(r1){
675 tremove<mevent>(r1);
676 tinsert<mevent>(r2->prev, r2);
679 //tinsert<mevent>(l2->prev, l2);
680 //if(r2){
681 // tinsert<mevent>(r2->prev, r2);
682 // }
684 l1->dur = d2;
687 void ResizeNote::undo(){
688 if(r2){
689 tremove<mevent>(r2);
690 tinsert<mevent>(r1->prev, r1);
692 //tremove<mevent>(l2);
694 //tinsert<mevent>(l1->prev, l1);
695 //if(r1){
696 // tinsert<mevent>(r1->prev, r1);
699 l1->dur = d1;
705 void CreateEvent::redo(){
706 tinsert<mevent>(e->prev, e);
709 void CreateEvent::undo(){
710 tremove<mevent>(e);
713 void DeleteEvent::redo(){
714 tremove<mevent>(e);
717 void DeleteEvent::undo(){
718 tinsert<mevent>(e->prev, e);
721 void ChangeEvent::redo(){
722 tswap<mevent>(e1,e2);
725 void ChangeEvent::undo(){
726 tswap<mevent>(e2,e1);
733 mevent* find_off(mevent* e){
734 mevent* ptr = e;
735 while(ptr){
736 if(ptr->type == MIDI_NOTE_OFF && ptr->value1 == e->value1 &&
737 ptr->tick != e->tick){
738 return ptr;
740 ptr = ptr->next;
742 return NULL;
752 pattern::pattern(){
753 events = new mevent();//dummy
754 events->tick = 0;
755 next = NULL;
756 ref_c = 0;
757 h=0;
758 s=1;
759 v=0.8;
760 regen_colors();
764 pattern::~pattern(){
765 mevent* e = events;
766 mevent* next;
767 while(e){
768 next = e->next;
769 delete e;
770 e = next;
775 pattern::pattern(pattern* p){
776 mevent* ptr = p->events;
777 mevent* ptr2;
778 events = new mevent(ptr);
779 ptr2 = events;
780 ptr=ptr->next;
781 while(ptr){
782 ptr2->next = new mevent(ptr);
783 ptr2->next->prev = ptr2;
784 ptr=ptr->next;
785 ptr2=ptr2->next;
787 ptr2->next = NULL;
789 next = NULL;
790 ref_c = 0;
791 h = p->h;
792 s = p->s;
793 v = p->v;
794 regen_colors();
798 void pattern::regen_colors(){
800 while(h>360){h-=360;}
801 while(h<0){h+=360;}
802 if(s < 0){s = 0;}
803 if(s > 1){s = 1;}
804 if(v < 0.2){v = 0.2;}
805 if(v > 0.8){v = 0.8;}
807 hsv_to_rgb(h,s,v,&r1,&g1,&b1);
808 hsv_to_rgb(h,s,v/2,&r2,&g2,&b2);
809 hsv_to_rgb(h,s,v+0.2 > 1 ? 1 : v+0.2,&r3,&g3,&b3);
810 if(v > 0.5){
811 hsv_to_rgb(h,s,v-0.3,&rx,&gx,&bx);
813 else{
814 hsv_to_rgb(h,s,0.7,&rx,&gx,&bx);
819 void pattern::append(mevent* ze){
820 mevent* e = events;
821 while(e->next){
822 e = e->next;
824 e->next = ze;
825 ze->prev = e;
828 void pattern::insert(mevent* ze, int tick){
829 mevent* ptr = events;
830 while(ptr->next){
831 if(ptr->next->tick > tick){
832 ze->next = ptr->next;
833 ze->next->prev = ze;
834 ptr->next = ze;
835 ze->prev = ptr;
836 return;
838 ptr=ptr->next;
840 ptr->next = ze;
841 ze->prev = ptr;
845 void pattern::fixdur(){
846 mevent* e = events;
847 mevent* f;
848 while(e->next){
849 if(e->type == MIDI_NOTE_ON){
850 f = find_off(e);
851 if(f){e->dur = f->tick - e->tick;}
853 e = e->next;
857 //used when the sequence is changed in such a way
858 //that the sequencer state needs to be updated
859 void track::restate(){
860 int pos = get_play_position();
861 seqpat* s = head->next;
862 int snullflag = 1;
863 int pnullflag = 1;
864 int pointfound = 0;
865 while(s){
866 //printf("trying block: pos %d, tick %d, t2 %d\n",pos,s->tick,s->tick+s->dur);
867 if(pointfound){//we are past the point, reset up coming blocks
868 //printf("future block\n");
869 s->skip = s->p->events->next;
872 else if(s->tick+s->dur < pos){//we are past this block
873 //printf("past block\n");
874 s->skip = NULL;
877 else if(s->tick+s->dur > pos && s->tick <= pos){//we are inside this block, point found
878 //printf("inside block\n");
879 pointfound = 1;
880 snullflag = 0;
881 skip = s;
882 mevent* e = s->p->events->next;
883 while(e){
884 if(e->tick+s->tick >= pos){
885 s->skip = e;
886 pointfound = 1;
887 pnullflag = 0;
888 break;
890 e = e->next;
892 if(pnullflag){
893 s->skip = NULL;
897 else{//we are not in a block, point found
898 //printf("pointfound outside block\n");
899 skip = s;
900 snullflag = 0;
901 pointfound = 1;
904 s = s->next;
907 if(snullflag){skip = NULL;}
911 void seqpat::restate(){
912 mevent* e = p->events->next;
913 int pos = get_play_position();
914 while(e){
915 if(e->tick+tick >= pos){
916 skip = e;
917 return;
919 e = e->next;
921 skip = NULL;
925 //clear the pattern
926 void seqpat::apply_erase(){
928 Command* c;
930 c = new ClearSeqpat(this);
931 set_undo(c);
932 undo_push(1);
935 //create new pattern and make it current
936 void seqpat::apply_layer(){
937 Command* c = new LayerSeqpat(this);
938 set_undo(c);
939 undo_push(1);
942 void seqpat::next_layer(){
943 if(layers){
944 p = layers->next();
948 void seqpat::prev_layer(){
949 if(layers){
950 p = layers->prev();
954 int seqpat::layer_index(){
955 if(layers){
956 return layers->index;
958 else{
959 return 0;
963 int seqpat::layer_total(){
964 if(layers){
965 return layers->total;
967 else{
968 return 1;
972 void seqpat::record_check(int mode){
973 if(record_flag==0){
974 if(mode==1 || mode==2){
975 autocomplete();//end stuck notes
976 if(mode == 1){apply_erase();}
977 else if(mode == 2){apply_layer();}
978 tracks[track]->restate();
980 record_flag = 1;
984 //sends note off if it determines that
985 //we are in between two notes
986 void seqpat::autocomplete(){
987 mevent* ptr;
988 mevent* e = p->events->next;
989 mevent* eoff;
991 int pos = get_play_position()-tick;
993 int chan = tracks[track]->chan;
994 int port = tracks[track]->port;
995 printf("use of deprecated function seqpat::autocomplete\n");
996 while(e){
997 if(e->type == MIDI_NOTE_ON && e->tick < pos){
998 eoff = find_off(e);
999 if(eoff){
1000 if(eoff->tick > pos){
1001 midi_note_off(e->value1,chan,port);
1005 e = e->next;
1015 pattern* layerstack::push_new(){
1016 if(total==memsize){
1017 reallocate();
1019 total++;
1020 array[total-1] = new pattern();
1021 array[total-1]->h = array[0]->h;
1022 array[total-1]->s = array[0]->s;
1023 array[total-1]->v = array[0]->v;
1024 array[total-1]->regen_colors();
1025 index=total-1;
1026 return array[index];
1029 void layerstack::push(pattern* p){
1030 if(total==memsize){
1031 reallocate();
1034 total++;
1035 array[total-1] = p;
1036 index = total-1;
1037 p->ref_c++;
1040 void layerstack::reallocate(){
1041 pattern** ptmp = new pattern*[memsize*2];
1042 for(int i=0; i<memsize; i++){
1043 ptmp[i] = array[i];
1045 memsize *= 2;
1046 delete [] array;
1047 array = ptmp;
1050 pattern* layerstack::pop(){
1051 if(index == 0){
1052 return NULL;
1054 if(index == total-1){
1055 index--;
1057 array[total-1]=NULL;
1058 total--;
1059 return array[index];
1062 void layerstack::remove(int n){
1066 void layerstack::insert(pattern* p, int n){
1071 pattern* layerstack::next(){
1072 if(index==total-1){
1073 index=0;
1075 else{
1076 index++;
1078 return array[index];
1081 pattern* layerstack::prev(){
1082 if(index==0){
1083 index=total-1;
1085 else{
1086 index--;
1088 return array[index];
1091 layerstack::layerstack(pattern* p){
1092 index = 0;
1093 total = 1;
1094 array = new pattern*[16];
1095 memsize = 16;
1096 array[0] = p;
1097 // ptr = array[0];
1098 ref_c = 0;
1101 layerstack::~layerstack(){
1102 for(int i=0; i<total; i++){
1103 array[i]->ref_c--;
1104 if(array[i]->ref_c == 0){
1105 delete array[i];
1112 void reset_record_flags(){
1113 for(int i=0; i<tracks.size(); i++){
1114 seqpat* s = tracks[i]->head->next;
1115 while(s){
1116 if(s->record_flag == 1){
1117 s->record_flag = 0;
1119 s = s->next;
1127 void set_undo(Command* c){
1128 if(undo_ptr != undo_stack.end()){
1129 //printf("changing the past, need to erase the future\n");
1130 std::list<int>::iterator nptr = undo_number.end();
1131 nptr--;
1132 while(nptr != undo_nptr){
1133 int N = *nptr;
1134 //printf("deleting %d commands\n",N);
1135 for(int i=0; i<N; i++){
1136 //delete this command
1137 undo_stack.pop_back();
1139 nptr--;
1140 undo_number.pop_back();
1143 //printf("pushing command\n");
1144 undo_stack.push_back(c);
1145 undo_ptr = undo_stack.end();
1146 c->redo();
1149 void undo_push(int n){
1150 if(n==0){return;}
1151 //printf("pushing number of commands %d\n",n);
1152 undo_number.push_back(n);
1153 undo_nptr++;
1156 void do_undo(){
1157 if(undo_ptr==undo_stack.begin()){
1158 printf("no more to undo!\n");
1159 return;
1161 //printf("undoing\n");
1162 int N = *undo_nptr;
1163 undo_nptr--;
1164 for(int i=0; i<N; i++){
1165 undo_ptr--;
1166 (*undo_ptr)->undo();
1170 void do_redo(){
1171 if(undo_ptr==undo_stack.end()){
1172 printf("no more to redo!\n");
1173 return;
1175 //printf("redoing\n");
1176 undo_nptr++;
1177 int N = *undo_nptr;
1178 for(int i=0; i<N; i++){
1179 (*undo_ptr)->redo();
1180 undo_ptr++;
1184 void undo_reset(){
1185 //printf("undo reset\n");
1186 int N = undo_stack.size();
1187 for(int i=0; i<N; i++){
1188 std::list<Command*>::iterator c = undo_stack.end();
1189 c--;
1190 //delete (*c);
1191 undo_stack.pop_back();
1194 N = undo_number.size();
1195 for(int i=0; i<N; i++){
1196 undo_number.pop_back();
1199 undo_nptr = undo_number.begin();
1200 undo_ptr = undo_stack.begin();
1204 OnBitArray::OnBitArray(){
1205 for(int i=0; i<16; i++){
1206 bytes[i] = 0;
1208 spos = 0;
1209 jpos = 0;
1212 int OnBitArray::get(int note){
1213 //note/8 = note >> 3
1214 //note%8 = note & 0x7
1215 return bytes[note >> 3] & (1 << (note & 0x7));
1218 void OnBitArray::set(int note, int value){
1219 //note/8 = note >> 3
1220 //note%8 = note & 0x3
1222 if(value){
1223 bytes[note >> 3] |= (1 << (note & 0x7));
1225 else{
1226 bytes[note >> 3] &= ~(1 << (note & 0x7));
1230 void OnBitArray::search_init(){
1231 spos = 0;
1232 jpos = 0;
1235 int OnBitArray::search_next(){
1236 unsigned char byte;
1237 for(int i=spos; i<16; i++){
1238 byte = bytes[i];
1240 if(byte){
1241 for(int j=jpos; j<8; j++){
1242 if(byte & (1<<j)){
1243 if(j==7){
1244 spos = i+1;
1245 jpos = 0;
1247 else{
1248 spos = i;
1249 jpos = j+1;
1251 int note = i*8 + j;
1252 //bytes[i] &= ~(1<<j);
1253 return note;
1256 jpos = 0;
1259 return -1;
1262 void OnBitArray::clear(){
1263 for(int i=0; i<16; i++){
1264 bytes[i] = 0;