Added option to disable track init events.
[epichord.git] / src / seq.h
blobac62df122b780853d9677549ce40ecb53f236fc0
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>
36 struct mevent {
38 public:
39 int tick;
41 int type;
42 int value1;
43 int value2;
44 int dur; //for note on events
46 //struct mevent* off; //for note on events
47 //int off_index; //used when reloading
49 struct mevent* prev;
50 struct mevent* next;
52 int selected;
53 int modified;
55 mevent(){
56 type = -1;
57 //off = NULL;
58 prev = NULL;
59 next = NULL;
60 dur = 32;
61 selected = 0;
62 modified = 0;
65 mevent(int ztype, int ztick, int zv1){
66 //off=NULL;
67 prev=NULL;
68 next=NULL;
69 dur = 32;
70 type=ztype;
71 tick=ztick;
72 value1=zv1;
73 value2=0x7f;
74 selected = 0;
75 modified = 0;
78 mevent(mevent* e){
79 type = e->type;
80 tick = e->tick;
81 value1 = e->value1;
82 value2 = e->value2;
83 dur = e->dur;
84 //off = e->off;
85 prev = e->prev;
86 next = e->next;
87 selected = e->selected;
88 modified = e->modified;
93 struct pattern {
94 public:
95 struct mevent* events;
96 struct pattern* next;
97 int ref_c;
99 unsigned char r1,g1,b1;//main color
100 unsigned char r2,g2,b2;//bottom color
101 unsigned char r3,g3,b3;//top color
102 unsigned char rx,gx,bx;//xray color
104 float h, s, v; //color
106 void regen_colors();
108 pattern();
109 pattern(pattern* p);
110 ~pattern();
111 void append(mevent* ze);
112 void insert(mevent* ze, int tick);
113 void fixdur();
118 struct layerstack {
119 pattern** array;
121 int index;
122 int total;
123 int memsize;
125 int ref_c;
127 pattern* push_new();
128 void push(pattern* p);
129 pattern* pop();
130 void remove(int n);
131 void insert(pattern* p, int n);
132 pattern* next();
133 pattern* prev();
134 void reallocate();
136 layerstack(){};
137 layerstack(pattern* p);
138 ~layerstack();
142 struct seqpat {
143 int track;
144 int tick;
145 int dur;
146 struct pattern* p;
147 struct mevent* skip;
148 struct seqpat* prev;
149 struct seqpat* next;
151 layerstack* layers;
153 // unsigned char color[3][3];
154 int selected;
155 int modified;
156 int record_flag;//0=on record, erase/save. 1=dont
158 int scrollx, scrolly;
160 void restate();
161 void apply_erase();
162 void apply_layer();
163 void next_layer();
164 void prev_layer();
165 int layer_index();
166 int layer_total();
167 void record_check(int mode);
168 void autocomplete();
171 seqpat(){
172 p = NULL;
173 skip = NULL;
174 prev = NULL;
175 next = NULL;
176 dur=0;
177 selected=0;
178 modified=0;
179 record_flag=1;
180 layers = NULL;
181 scrollx = 0;
182 scrolly = 300;
185 seqpat(int ztrack, int ztick, int zdur, pattern* zp){
186 p = zp;
187 p->ref_c++;
188 track = ztrack;
189 dur = zdur;
190 tick = ztick;
191 skip = NULL;
192 prev = NULL;
193 next = NULL;
194 selected = 0;
195 modified = 0;
196 record_flag = 1;
197 layers = NULL;
198 scrollx = 0;
199 scrolly = 300;
202 seqpat(seqpat* zs){
203 p = zs->p;
204 p->ref_c++;
205 track = zs->track;
206 dur = zs->dur;
207 tick = zs->tick;
208 if(p){p->ref_c++;}
210 skip = p->events;
211 prev = zs->prev;
212 next = zs->next;
214 scrollx = zs->scrollx;
215 scrolly = zs->scrolly;
217 selected = zs->selected;
218 modified = zs->modified;
220 record_flag = 1;
221 layers = NULL;
224 seqpat(seqpat* zs, pattern* zp){
225 p = zp;
226 p->ref_c++;
227 track = zs->track;
228 dur = zs->dur;
229 tick = zs->tick;
230 if(p){p->ref_c++;}
232 skip = p->events;
233 prev = zs->prev;
234 next = zs->next;
236 scrollx = zs->scrollx;
237 scrolly = zs->scrolly;
239 selected = zs->selected;
240 modified = zs->modified;
242 record_flag=1;
243 layers = NULL;
246 ~seqpat(){
247 if(p){
248 p->ref_c--;
249 if(p->ref_c == 0){
250 delete p;
253 if(layers){
254 layers->ref_c--;
255 if(layers->ref_c == 0){
256 delete layers;
268 struct track {
269 int port;
270 int chan;
271 int prog;
272 int bank;
273 int mute;
274 int solo;
275 int vol;
276 int pan;
277 char* name;
278 int alive;
279 seqpat* head;
280 seqpat* skip;
282 int modified;
284 void restate();
286 track(){
287 port = 0;
288 chan = 0;
289 prog = 0;
290 bank = 0;
291 mute = 0;
292 solo = 0;
293 vol = 127;
294 pan = 64;
295 name = (char*)malloc(8);
296 name[0] = '\0';
297 alive = 1;
298 head = new seqpat(0,0,0,new pattern());
299 head->tick = 0;
300 skip = head;
301 modified = 0;
304 ~track(){
305 free(name);
306 seqpat* s = head;
307 seqpat* next;
308 while(s){
309 next = s->next;
310 delete s;
311 s = next;
320 template <class T>
321 void tswap(T* old, T* nu){
322 nu->next = old->next;
323 nu->prev = old->prev;
325 if(old->prev){
326 old->prev->next = nu; //'atomic'
328 if(old->next){
329 old->next->prev = nu; //prev ptrs are only read by gui thread
333 template <class T>
334 void tremove(T* old){
335 if(old->prev){
336 old->prev->next = old->next; //'atomic'
338 if(old->next){
339 old->next->prev = old->prev; //prev ptrs are only read by gui thread
343 template <class T>
344 void tinsert(T* targ, T* nu){
345 nu->prev = targ;
346 nu->next = targ->next;
348 targ->next = nu; //'atomic'
349 if(nu->next){
350 nu->next->prev = nu; //prev ptrs are only read by gui thread
354 template <class T>
355 T* tfind(T* begin, int tick){
356 T* ptr = begin;
357 while(ptr->next){
358 if(ptr->next->tick > tick){
359 break;
361 ptr = ptr->next;
363 return ptr;
366 mevent* find_off(mevent* e);
369 class Command {
371 public:
373 virtual void undo() {}
374 virtual void redo() {}
378 void set_undo(Command* c);
379 void push_undo(int n);
380 void do_undo();
381 void do_redo();
383 int clear_undos(int number);
387 class CreateSeqpat : public Command {
388 protected:
389 seqpat* s;
391 public:
393 CreateSeqpat(){}
394 CreateSeqpat(int track, int tick, seqpat* zs, int copy);
396 ~CreateSeqpat(){
397 if(s->p->ref_c-- == 0){
398 delete s->p;
400 delete s;
403 void redo();
404 void undo();
407 class CreateSeqpatBlank : public CreateSeqpat {
409 public:
411 CreateSeqpatBlank(int track, int tick, int len);
416 class DeleteSeqpat : public Command {
417 seqpat* s;
419 public:
421 DeleteSeqpat(seqpat* zs){
422 s = zs;
425 void redo();
426 void undo();
429 class ResizeSeqpat : public Command {
430 seqpat* s1;
431 seqpat* s2;
433 public:
435 ResizeSeqpat(seqpat* zs, int dur){
436 s1 = zs;
437 s2 = new seqpat(zs);
438 s2->dur = dur;
440 ~ResizeSeqpat(){
441 delete s2;
444 void redo();
445 void undo();
448 class MoveSeqpat : public Command {
449 seqpat* s;
450 seqpat *targ1, *targ2;
451 int track1, track2;
452 int tick1, tick2;
454 public:
456 MoveSeqpat(seqpat* zs, int track, int tick);
457 ~MoveSeqpat(){}
459 void redo();
460 void undo();
464 class SplitSeqpat : public Command {
465 seqpat* s;
466 seqpat* s1;
467 seqpat* s2;
469 public:
471 SplitSeqpat(seqpat* zs, int tick);
473 ~SplitSeqpat(){
474 //delete s1 and s2
477 void redo();
478 void undo();
483 class JoinSeqpat : public Command {
484 seqpat* s1;
485 seqpat* s2;
486 seqpat* s;
488 public:
490 JoinSeqpat(seqpat* zs1, seqpat* zs2);
492 ~JoinSeqpat(){
493 //delete s
496 void redo();
497 void undo();
500 class ClearSeqpat : public Command {
502 seqpat* s;
503 pattern* p1;
504 pattern* p2;
506 public:
508 ClearSeqpat(seqpat* zs){
509 s = zs;
510 p1 = s->p;
511 p2 = new pattern();
512 p2->ref_c = 1;
515 ~ClearSeqpat(){
516 //delete p2
519 void redo();
520 void undo();
523 class LayerSeqpat : public Command {
525 seqpat* s;
526 pattern* p;
528 public:
530 LayerSeqpat(seqpat* zs){
531 s = zs;
532 p = new pattern();
533 p->ref_c = 1;
536 ~LayerSeqpat(){
537 //delete p2
540 void redo();
541 void undo();
547 class CreateNote : public Command {
548 pattern* p;
549 mevent* e1;
550 mevent* e2;
552 public:
554 CreateNote(pattern* zp, int note, int vel, int tick, int dur){
555 p = zp;
556 e1 = new mevent(MIDI_NOTE_ON, tick, note);
557 e1->dur = dur;
558 e1->value2 = vel;
559 e2 = new mevent(MIDI_NOTE_OFF, tick+dur, note);
560 e2->value2 = 0;
561 //e->off = new mevent(MIDI_NOTE_OFF, tick+dur, note);
563 ~CreateNote(){
564 //delete e->off;
565 delete e1;
566 delete e2;
569 void redo();
570 void undo();
573 class CreateNoteOn : public Command {
574 pattern* p;
575 mevent* e1;
577 public:
579 CreateNoteOn(pattern* zp, int note, int vel, int tick, int dur){
580 p = zp;
581 e1 = new mevent(MIDI_NOTE_ON, tick, note);
582 e1->value2 = vel;
583 e1->dur = dur;
585 ~CreateNoteOn(){
586 delete e1;
589 void redo();
590 void undo();
593 class CreateNoteOff : public Command {
594 pattern* p;
595 mevent* e1;
596 mevent* e2;
598 int dur1;
599 int dur2;
601 public:
603 CreateNoteOff(pattern* zp, int note, int vel, int tick);
604 ~CreateNoteOff(){
605 delete e2;
608 void redo();
609 void undo();
612 class DeleteNote : public Command {
613 pattern* p;
614 mevent* e1;
615 mevent* e2;
617 public:
619 DeleteNote(pattern* zp, mevent* ze){
620 p = zp;
621 e1 = ze;
622 e2 = find_off(e1);
625 void redo();
626 void undo();
629 class MoveNote : public Command {
630 pattern* p;
631 mevent* e1;
632 mevent* e2;
633 int t1;
634 int t2;
635 int note1;
636 int note2;
638 void arrive(int t);
640 public:
642 MoveNote(pattern* zp, mevent* ze, int zt, int znote){
643 p = zp;
644 e1 = ze;
645 e2 = find_off(e1);
646 note1 = ze->value1;
647 note2 = znote;
648 t1 = ze->tick;
649 t2 = zt;
652 void redo();
653 void undo();
657 class ResizeNote : public Command {
658 pattern* p;
659 mevent* l1;
660 int d1;
661 int d2;
662 //mevent* l2;
663 mevent* r1;
664 mevent* r2;
666 public:
668 ResizeNote(pattern* zp, mevent* ze, int dur);
669 ~ResizeNote(){
670 if(r2){
671 delete r2;
675 void redo();
676 void undo();
682 class CreateEvent : public Command {
683 pattern* p;
684 mevent* e;
686 public:
688 CreateEvent(pattern* zp, int type, int tick, int value1, int value2){
689 p = zp;
690 e = new mevent(type,tick,value1);
691 e->value2 = value2;
692 e->prev = tfind<mevent>(zp->events,tick);
693 e->next = e->prev->next;
695 ~CreateEvent(){
696 delete e;
699 void redo();
700 void undo();
703 class DeleteEvent : public Command {
704 mevent* e;
706 public:
708 DeleteEvent(mevent* ze){
709 e = ze;
712 void redo();
713 void undo();
716 class ChangeEvent : public Command {
717 mevent* e1;
718 mevent* e2;
720 public:
722 ChangeEvent(mevent* ze, int zv1, int zv2){
723 e1 = ze;
724 e2 = new mevent(ze);
725 e2->value1 = zv1;
726 e2->value2 = zv2;
729 void redo();
730 void undo();
735 int play_seq(int cur_tick);
736 int set_seq_pos(int new_tick);
738 void set_rec_track(int t);
739 int get_rec_track();
741 int set_default_hsv_value(float v);
743 void set_undo(Command* c);
744 void undo_push(int n);
745 void do_undo();
746 void do_redo();
747 void undo_reset();
750 void reset_record_flags();
753 //encodes data in e as a midi event placed in buf
754 int midi_encode(mevent* e, int chan, unsigned char* buf, size_t* n);
756 //decodes midi data and creates a new mevent
757 int midi_decode(char* buf, mevent* e);
759 #endif