Mouse wheel now scrolls horizontally in piano roll.
[epichord.git] / src / seq.h
blob65e9d641c6de3984648986e6466ca01d9cbf8bc8
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 #ifndef seq_h
24 #define seq_h
26 #define MIDI_NOTE_OFF 0x80
27 #define MIDI_NOTE_ON 0x90
28 #define MIDI_AFTERTOUCH 0xA0
29 #define MIDI_CONTROLLER_CHANGE 0xB0
30 #define MIDI_PROGRAM_CHANGE 0xC0
31 #define MIDI_CHANNEL_PRESSURE 0xD0
32 #define MIDI_PITCH_WHEEL 0xE0
34 #include <stdlib.h>
35 #include <stdio.h>
37 class OnBitArray {
38 unsigned char bytes[16];
39 int spos;
40 int jpos;
42 public:
44 int get(int note);
45 void set(int note, int value);
47 void search_init();
48 int search_next();
50 void clear();
52 OnBitArray();
55 struct mevent {
57 public:
58 int tick;
60 int type;
61 int value1;
62 int value2;
63 int dur; //for note on events
65 //struct mevent* off; //for note on events
66 //int off_index; //used when reloading
68 struct mevent* prev;
69 struct mevent* next;
71 int selected;
72 int modified;
74 mevent(){
75 type = -1;
76 //off = NULL;
77 prev = NULL;
78 next = NULL;
79 dur = 32;
80 selected = 0;
81 modified = 0;
84 mevent(int ztype, int ztick, int zv1){
85 //off=NULL;
86 prev=NULL;
87 next=NULL;
88 dur = 32;
89 type=ztype;
90 tick=ztick;
91 value1=zv1;
92 value2=0x7f;
93 selected = 0;
94 modified = 0;
97 mevent(mevent* e){
98 type = e->type;
99 tick = e->tick;
100 value1 = e->value1;
101 value2 = e->value2;
102 dur = e->dur;
103 //off = e->off;
104 prev = e->prev;
105 next = e->next;
106 selected = e->selected;
107 modified = e->modified;
112 struct pattern {
113 public:
114 struct mevent* events;
115 struct pattern* next;
116 int ref_c;
118 unsigned char r1,g1,b1;//main color
119 unsigned char r2,g2,b2;//bottom color
120 unsigned char r3,g3,b3;//top color
121 unsigned char rx,gx,bx;//xray color
123 float h, s, v; //color
125 void regen_colors();
127 pattern();
128 pattern(pattern* p);
129 ~pattern();
130 void append(mevent* ze);
131 void insert(mevent* ze, int tick);
132 void fixdur();
137 struct layerstack {
138 pattern** array;
140 int index;
141 int total;
142 int memsize;
144 int ref_c;
146 pattern* push_new();
147 void push(pattern* p);
148 pattern* pop();
149 void remove(int n);
150 void insert(pattern* p, int n);
151 pattern* next();
152 pattern* prev();
153 void reallocate();
155 layerstack(){};
156 layerstack(pattern* p);
157 ~layerstack();
161 struct seqpat {
162 int track;
163 int tick;
164 int dur;
165 struct pattern* p;
166 struct mevent* skip;
167 struct seqpat* prev;
168 struct seqpat* next;
170 layerstack* layers;
172 // unsigned char color[3][3];
173 int selected;
174 int modified;
175 int record_flag;//0=on record, erase/save. 1=dont
177 int scrollx, scrolly;
179 void restate();
180 void apply_erase();
181 void apply_layer();
182 void next_layer();
183 void prev_layer();
184 int layer_index();
185 int layer_total();
186 void record_check(int mode);
187 void autocomplete();
190 seqpat(){
191 p = NULL;
192 skip = NULL;
193 prev = NULL;
194 next = NULL;
195 dur=0;
196 selected=0;
197 modified=0;
198 record_flag=1;
199 layers = NULL;
200 scrollx = 0;
201 scrolly = 300;
204 seqpat(int ztrack, int ztick, int zdur, pattern* zp){
205 p = zp;
206 p->ref_c++;
207 track = ztrack;
208 dur = zdur;
209 tick = ztick;
210 skip = NULL;
211 prev = NULL;
212 next = NULL;
213 selected = 0;
214 modified = 0;
215 record_flag = 1;
216 layers = NULL;
217 scrollx = 0;
218 scrolly = 300;
221 seqpat(seqpat* zs){
222 p = zs->p;
223 p->ref_c++;
224 track = zs->track;
225 dur = zs->dur;
226 tick = zs->tick;
227 if(p){p->ref_c++;}
229 skip = p->events;
230 prev = zs->prev;
231 next = zs->next;
233 scrollx = zs->scrollx;
234 scrolly = zs->scrolly;
236 selected = zs->selected;
237 modified = zs->modified;
239 record_flag = 1;
240 layers = NULL;
243 seqpat(seqpat* zs, pattern* zp){
244 p = zp;
245 p->ref_c++;
246 track = zs->track;
247 dur = zs->dur;
248 tick = zs->tick;
249 if(p){p->ref_c++;}
251 skip = p->events;
252 prev = zs->prev;
253 next = zs->next;
255 scrollx = zs->scrollx;
256 scrolly = zs->scrolly;
258 selected = zs->selected;
259 modified = zs->modified;
261 record_flag=1;
262 layers = NULL;
265 ~seqpat(){
266 if(p){
267 p->ref_c--;
268 if(p->ref_c == 0){
269 delete p;
272 if(layers){
273 layers->ref_c--;
274 if(layers->ref_c == 0){
275 delete layers;
287 struct track {
288 int port;
289 int chan;
290 int prog;
291 int bank;
292 int mute;
293 int solo;
294 int vol;
295 int pan;
296 char* name;
297 int alive;
298 seqpat* head;
299 seqpat* skip;
301 OnBitArray onbits;
303 int contr[128];
304 int pressure;
305 int pitchwheel;
307 int modified;
309 void restate();
311 track(){
312 port = 0;
313 chan = 0;
314 prog = 0;
315 bank = 0;
316 mute = 0;
317 solo = 0;
318 vol = 127;
319 pan = 64;
320 name = (char*)malloc(8);
321 name[0] = '\0';
322 alive = 1;
323 head = new seqpat(0,0,0,new pattern());
324 head->tick = 0;
325 skip = head;
326 modified = 0;
328 pressure = 64;
329 pitchwheel = 0;
330 contr[7] = 64;
331 contr[10] = 64;
332 contr[32] = 0;
335 ~track(){
336 free(name);
337 seqpat* s = head;
338 seqpat* next;
339 while(s){
340 next = s->next;
341 delete s;
342 s = next;
351 template <class T>
352 void tswap(T* old, T* nu){
353 nu->next = old->next;
354 nu->prev = old->prev;
356 if(old->prev){
357 old->prev->next = nu; //'atomic'
359 if(old->next){
360 old->next->prev = nu; //prev ptrs are only read by gui thread
364 template <class T>
365 void tremove(T* old){
366 if(old->prev){
367 old->prev->next = old->next; //'atomic'
369 if(old->next){
370 old->next->prev = old->prev; //prev ptrs are only read by gui thread
374 template <class T>
375 void tinsert(T* targ, T* nu){
376 nu->prev = targ;
377 nu->next = targ->next;
379 targ->next = nu; //'atomic'
380 if(nu->next){
381 nu->next->prev = nu; //prev ptrs are only read by gui thread
385 template <class T>
386 T* tfind(T* begin, int tick){
387 T* ptr = begin;
388 while(ptr->next){
389 if(ptr->next->tick > tick){
390 break;
392 ptr = ptr->next;
394 return ptr;
397 mevent* find_off(mevent* e);
400 class Command {
402 public:
404 virtual void undo() {}
405 virtual void redo() {}
409 void set_undo(Command* c);
410 void push_undo(int n);
411 void do_undo();
412 void do_redo();
414 int clear_undos(int number);
418 class CreateSeqpat : public Command {
419 protected:
420 seqpat* s;
422 public:
424 CreateSeqpat(){}
425 CreateSeqpat(int track, int tick, seqpat* zs, int copy);
427 ~CreateSeqpat(){
428 if(s->p->ref_c-- == 0){
429 delete s->p;
431 delete s;
434 void redo();
435 void undo();
438 class CreateSeqpatBlank : public CreateSeqpat {
440 public:
442 CreateSeqpatBlank(int track, int tick, int len);
447 class DeleteSeqpat : public Command {
448 seqpat* s;
450 public:
452 DeleteSeqpat(seqpat* zs){
453 s = zs;
456 void redo();
457 void undo();
460 class ResizeSeqpat : public Command {
461 seqpat* s1;
462 seqpat* s2;
464 public:
466 ResizeSeqpat(seqpat* zs, int dur){
467 s1 = zs;
468 s2 = new seqpat(zs);
469 s2->dur = dur;
471 ~ResizeSeqpat(){
472 delete s2;
475 void redo();
476 void undo();
479 class MoveSeqpat : public Command {
480 seqpat* s;
481 seqpat *targ1, *targ2;
482 int track1, track2;
483 int tick1, tick2;
485 public:
487 MoveSeqpat(seqpat* zs, int track, int tick);
488 ~MoveSeqpat(){}
490 void redo();
491 void undo();
495 class SplitSeqpat : public Command {
496 seqpat* s;
497 seqpat* s1;
498 seqpat* s2;
500 public:
502 SplitSeqpat(seqpat* zs, int tick);
504 ~SplitSeqpat(){
505 //delete s1 and s2
508 void redo();
509 void undo();
514 class JoinSeqpat : public Command {
515 seqpat* s1;
516 seqpat* s2;
517 seqpat* s;
519 public:
521 JoinSeqpat(seqpat* zs1, seqpat* zs2);
523 ~JoinSeqpat(){
524 //delete s
527 void redo();
528 void undo();
531 class ClearSeqpat : public Command {
533 seqpat* s;
534 pattern* p1;
535 pattern* p2;
537 public:
539 ClearSeqpat(seqpat* zs){
540 s = zs;
541 p1 = s->p;
542 p2 = new pattern();
543 p2->ref_c = 1;
546 ~ClearSeqpat(){
547 //delete p2
550 void redo();
551 void undo();
554 class LayerSeqpat : public Command {
556 seqpat* s;
557 pattern* p;
559 public:
561 LayerSeqpat(seqpat* zs){
562 s = zs;
563 p = new pattern();
564 p->ref_c = 1;
567 ~LayerSeqpat(){
568 //delete p2
571 void redo();
572 void undo();
578 class CreateNote : public Command {
579 pattern* p;
580 mevent* e1;
581 mevent* e2;
583 public:
585 CreateNote(pattern* zp, int note, int vel, int tick, int dur){
586 p = zp;
587 e1 = new mevent(MIDI_NOTE_ON, tick, note);
588 e1->dur = dur;
589 e1->value2 = vel;
590 e2 = new mevent(MIDI_NOTE_OFF, tick+dur, note);
591 e2->value2 = 0;
592 //e->off = new mevent(MIDI_NOTE_OFF, tick+dur, note);
594 ~CreateNote(){
595 //delete e->off;
596 delete e1;
597 delete e2;
600 void redo();
601 void undo();
604 class CreateNoteOn : public Command {
605 pattern* p;
606 mevent* e1;
608 public:
610 CreateNoteOn(pattern* zp, int note, int vel, int tick, int dur){
611 p = zp;
612 e1 = new mevent(MIDI_NOTE_ON, tick, note);
613 e1->value2 = vel;
614 e1->dur = dur;
616 ~CreateNoteOn(){
617 delete e1;
620 void redo();
621 void undo();
624 class CreateNoteOff : public Command {
625 pattern* p;
626 mevent* e1;
627 mevent* e2;
629 int dur1;
630 int dur2;
632 public:
634 CreateNoteOff(pattern* zp, int note, int vel, int tick);
635 ~CreateNoteOff(){
636 delete e2;
639 void redo();
640 void undo();
643 class DeleteNote : public Command {
644 pattern* p;
645 mevent* e1;
646 mevent* e2;
648 public:
650 DeleteNote(pattern* zp, mevent* ze){
651 p = zp;
652 e1 = ze;
653 e2 = find_off(e1);
656 void redo();
657 void undo();
660 class MoveNote : public Command {
661 pattern* p;
662 mevent* e1;
663 mevent* e2;
664 int t1;
665 int t2;
666 int note1;
667 int note2;
669 void arrive(int t);
671 public:
673 MoveNote(pattern* zp, mevent* ze, int zt, int znote){
674 p = zp;
675 e1 = ze;
676 e2 = find_off(e1);
677 note1 = ze->value1;
678 note2 = znote;
679 t1 = ze->tick;
680 t2 = zt;
683 void redo();
684 void undo();
688 class ResizeNote : public Command {
689 pattern* p;
690 mevent* l1;
691 int d1;
692 int d2;
693 //mevent* l2;
694 mevent* r1;
695 mevent* r2;
697 public:
699 ResizeNote(pattern* zp, mevent* ze, int dur);
700 ~ResizeNote(){
701 if(r2){
702 delete r2;
706 void redo();
707 void undo();
713 class CreateEvent : public Command {
714 pattern* p;
715 mevent* e;
717 public:
719 CreateEvent(pattern* zp, int type, int tick, int value1, int value2){
720 p = zp;
721 e = new mevent(type,tick,value1);
722 e->value2 = value2;
723 e->prev = tfind<mevent>(zp->events,tick);
724 e->next = e->prev->next;
726 ~CreateEvent(){
727 delete e;
730 void redo();
731 void undo();
734 class DeleteEvent : public Command {
735 mevent* e;
737 public:
739 DeleteEvent(mevent* ze){
740 e = ze;
743 void redo();
744 void undo();
747 class ChangeEvent : public Command {
748 mevent* e1;
749 mevent* e2;
751 public:
753 ChangeEvent(mevent* ze, int zv1, int zv2){
754 e1 = ze;
755 e2 = new mevent(ze);
756 e2->value1 = zv1;
757 e2->value2 = zv2;
760 void redo();
761 void undo();
766 int play_seq(int cur_tick);
767 int set_seq_pos(int new_tick);
769 void set_rec_track(int t);
770 int get_rec_track();
772 void tracks_auto_off();
774 int set_default_hsv_value(float v);
776 void set_undo(Command* c);
777 void undo_push(int n);
778 void do_undo();
779 void do_redo();
780 void undo_reset();
783 void reset_record_flags();
786 //encodes data in e as a midi event placed in buf
787 int midi_encode(mevent* e, int chan, unsigned char* buf, size_t* n);
789 //decodes midi data and creates a new mevent
790 int midi_decode(char* buf, mevent* e);
792 #endif