Fixed copying of layers.
[epichord.git] / src / seq.h
blob7df606e5ba5208f636e9c3b3ede3259271768dbc
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 #define MAX_TRACK_NAME 256
36 #include <stdio.h>
37 struct mevent {
39 public:
40 int tick;
42 int type;
43 int value1;
44 int value2;
45 int dur; //for note on events
47 //struct mevent* off; //for note on events
48 //int off_index; //used when reloading
50 struct mevent* prev;
51 struct mevent* next;
53 int selected;
54 int modified;
56 mevent(){
57 type = -1;
58 //off = NULL;
59 prev = NULL;
60 next = NULL;
61 dur = 32;
62 selected = 0;
63 modified = 0;
66 mevent(int ztype, int ztick, int zv1){
67 //off=NULL;
68 prev=NULL;
69 next=NULL;
70 dur = 32;
71 type=ztype;
72 tick=ztick;
73 value1=zv1;
74 value2=0x7f;
75 selected = 0;
76 modified = 0;
79 mevent(mevent* e){
80 type = e->type;
81 tick = e->tick;
82 value1 = e->value1;
83 value2 = e->value2;
84 dur = e->dur;
85 //off = e->off;
86 prev = e->prev;
87 next = e->next;
88 selected = e->selected;
89 modified = e->modified;
94 struct pattern {
95 public:
96 struct mevent* events;
97 struct pattern* next;
98 int ref_c;
100 unsigned char r1,g1,b1;//main color
101 unsigned char r2,g2,b2;//bottom color
102 unsigned char r3,g3,b3;//top color
103 unsigned char rx,gx,bx;//xray color
105 float h, s, v; //color
107 void regen_colors();
109 pattern();
110 pattern(pattern* p);
111 ~pattern();
116 struct layerstack {
117 pattern** array;
118 pattern* ptr;
120 int index;
121 int total;
122 int memsize;
124 int ref_c;
126 pattern* push_new();
127 void push_new(pattern* p);
128 pattern* next();
129 pattern* prev();
130 void reallocate();
132 layerstack(){};
133 layerstack(pattern* p);
134 ~layerstack();
138 struct seqpat {
139 int track;
140 int tick;
141 int dur;
142 struct pattern* p;
143 struct mevent* skip;
144 struct seqpat* prev;
145 struct seqpat* next;
147 layerstack* layers;
149 // unsigned char color[3][3];
150 int selected;
151 int modified;
152 int record_flag;//0=on record, erase/save. 1=dont
153 int rhandle;
154 int lhandle;
156 int scrollx, scrolly;
158 void restate();
159 void apply_erase();
160 void apply_layer();
161 void next_layer();
162 void prev_layer();
163 int layer_index();
164 int layer_total();
165 void record_check(int mode);
166 void autocomplete();
168 seqpat(){
169 p = NULL;
170 skip = NULL;
171 prev = NULL;
172 next = NULL;
173 dur=0;
174 selected=0;
175 modified=0;
176 rhandle=0;
177 lhandle=0;
178 record_flag=1;
179 layers = NULL;
182 seqpat(int ztrack, int ztick, int zdur, pattern* zp){
183 p = zp;
184 p->ref_c++;
185 track = ztrack;
186 dur = zdur;
187 tick = ztick;
188 skip = NULL;
189 prev = NULL;
190 next = NULL;
191 selected = 0;
192 modified = 0;
193 rhandle = 0;
194 lhandle = 0;
195 record_flag = 1;
196 layers = NULL;
199 seqpat(seqpat* zs){
200 p = zs->p;
201 p->ref_c++;
202 track = zs->track;
203 dur = zs->dur;
204 tick = zs->tick;
205 if(p){p->ref_c++;}
207 skip = p->events;
208 prev = zs->prev;
209 next = zs->next;
211 scrollx = zs->scrollx;
212 scrolly = zs->scrolly;
214 selected = zs->selected;
215 modified = zs->modified;
217 rhandle = 0;
218 lhandle = 0;
219 record_flag = 1;
220 layers = NULL;
223 seqpat(seqpat* zs, pattern* zp){
224 p = zp;
225 p->ref_c++;
226 track = zs->track;
227 dur = zs->dur;
228 tick = zs->tick;
229 if(p){p->ref_c++;}
231 skip = p->events;
232 prev = zs->prev;
233 next = zs->next;
235 scrollx = zs->scrollx;
236 scrolly = zs->scrolly;
238 selected = zs->selected;
239 modified = zs->modified;
241 rhandle=0;
242 lhandle=0;
243 record_flag=1;
244 layers = NULL;
247 ~seqpat(){
248 if(p){
249 p->ref_c--;
250 if(p->ref_c == 0){
251 delete p;
254 if(layers){
255 layers->ref_c--;
256 if(layers->ref_c == 0){
257 delete layers;
269 struct track {
270 int port;
271 int chan;
272 int prog;
273 int bank;
274 int mute;
275 int solo;
276 int vol;
277 int pan;
278 char name[MAX_TRACK_NAME];
279 int alive;
280 seqpat* head;
281 seqpat* skip;
283 int modified;
285 void restate();
287 track(){
288 port = 0;
289 chan = 0;
290 prog = 0;
291 bank = 0;
292 mute = 0;
293 solo = 0;
294 vol = 127;
295 pan = 64;
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 seqpat* s = head;
306 seqpat* next;
307 while(s){
308 next = s->next;
309 delete s;
310 s = next;
319 template <class T>
320 void tswap(T* old, T* nu){
321 nu->next = old->next;
322 nu->prev = old->prev;
324 if(old->prev){
325 old->prev->next = nu; //'atomic'
327 if(old->next){
328 old->next->prev = nu; //prev ptrs are only read by gui thread
332 template <class T>
333 void tremove(T* old){
334 if(old->prev){
335 old->prev->next = old->next; //'atomic'
337 if(old->next){
338 old->next->prev = old->prev; //prev ptrs are only read by gui thread
342 template <class T>
343 void tinsert(T* targ, T* nu){
344 nu->prev = targ;
345 nu->next = targ->next;
347 targ->next = nu; //'atomic'
348 if(nu->next){
349 nu->next->prev = nu; //prev ptrs are only read by gui thread
353 template <class T>
354 T* tfind(T* begin, int tick){
355 T* ptr = begin;
356 while(ptr->next){
357 if(ptr->next->tick > tick){
358 break;
360 ptr = ptr->next;
362 return ptr;
365 mevent* find_off(mevent* e);
368 class Command {
370 public:
372 virtual void undo() {}
373 virtual void redo() {}
377 void set_undo(Command* c);
378 void push_undo(int n);
379 void do_undo();
380 void do_redo();
382 int clear_undos(int number);
386 class CreateSeqpat : public Command {
387 protected:
388 seqpat* s;
390 public:
392 CreateSeqpat(){}
393 CreateSeqpat(int track, int tick, seqpat* zs, int copy);
395 ~CreateSeqpat(){
396 if(s->p->ref_c-- == 0){
397 delete s->p;
399 delete s;
402 void redo();
403 void undo();
406 class CreateSeqpatBlank : public CreateSeqpat {
408 public:
410 CreateSeqpatBlank(int track, int tick, int len);
415 class DeleteSeqpat : public Command {
416 seqpat* s;
418 public:
420 DeleteSeqpat(seqpat* zs){
421 s = zs;
424 void redo();
425 void undo();
428 class ResizeSeqpat : public Command {
429 seqpat* s1;
430 seqpat* s2;
432 public:
434 ResizeSeqpat(seqpat* zs, int dur){
435 s1 = zs;
436 s2 = new seqpat(zs);
437 s2->dur = dur;
439 ~ResizeSeqpat(){
440 delete s2;
443 void redo();
444 void undo();
447 class MoveSeqpat : public Command {
448 seqpat* s;
449 seqpat *targ1, *targ2;
450 int track1, track2;
451 int tick1, tick2;
453 public:
455 MoveSeqpat(seqpat* zs, int track, int tick);
457 void redo();
458 void undo();
461 class SplitSeqpat : public Command {
462 seqpat* s;
463 pattern* p1;
464 pattern* p2;
466 public:
468 SplitSeqpat(seqpat* zs){
469 s = zs;
470 p1 = s->p;
471 p2 = new pattern();
472 p2->ref_c = 1;
475 SplitSeqpat(){
476 if(--(p2->ref_c) == 0){
477 delete p2;
481 void redo();
482 void undo();
488 class CreateNote : public Command {
489 pattern* p;
490 mevent* e1;
491 mevent* e2;
493 public:
495 CreateNote(pattern* zp, int note, int vel, int tick, int dur){
496 p = zp;
497 e1 = new mevent(MIDI_NOTE_ON, tick, note);
498 e1->dur = dur;
499 e1->value2 = vel;
500 e2 = new mevent(MIDI_NOTE_OFF, tick+dur, note);
501 e2->value2 = 0;
502 //e->off = new mevent(MIDI_NOTE_OFF, tick+dur, note);
504 ~CreateNote(){
505 //delete e->off;
506 delete e1;
507 delete e2;
510 void redo();
511 void undo();
514 class CreateNoteOn : public Command {
515 pattern* p;
516 mevent* e1;
518 public:
520 CreateNoteOn(pattern* zp, int note, int vel, int tick, int dur){
521 p = zp;
522 e1 = new mevent(MIDI_NOTE_ON, tick, note);
523 e1->value2 = vel;
524 e1->dur = dur;
526 ~CreateNoteOn(){
527 delete e1;
530 void redo();
531 void undo();
534 class CreateNoteOff : public Command {
535 pattern* p;
536 mevent* e1;
537 mevent* e2;
539 int dur1;
540 int dur2;
542 public:
544 CreateNoteOff(pattern* zp, int note, int vel, int tick);
545 ~CreateNoteOff(){
546 delete e2;
549 void redo();
550 void undo();
553 class DeleteNote : public Command {
554 pattern* p;
555 mevent* e1;
556 mevent* e2;
558 public:
560 DeleteNote(pattern* zp, mevent* ze){
561 p = zp;
562 e1 = ze;
563 e2 = find_off(e1);
566 void redo();
567 void undo();
570 class MoveNote : public Command {
571 pattern* p;
572 mevent* e1;
573 mevent* e2;
574 int t1;
575 int t2;
576 int note1;
577 int note2;
579 void arrive(int t);
581 public:
583 MoveNote(pattern* zp, mevent* ze, int zt, int znote){
584 p = zp;
585 e1 = ze;
586 e2 = find_off(e1);
587 note1 = ze->value1;
588 note2 = znote;
589 t1 = ze->tick;
590 t2 = zt;
593 void redo();
594 void undo();
598 class ResizeNote : public Command {
599 pattern* p;
600 mevent* l1;
601 mevent* l2;
602 mevent* r1;
603 mevent* r2;
605 public:
607 ResizeNote(pattern* zp, mevent* ze, int dur);
608 ~ResizeNote(){
609 delete l2;
610 delete r2;
613 void redo();
614 void undo();
620 class CreateEvent : public Command {
621 pattern* p;
622 mevent* e;
624 public:
626 CreateEvent(pattern* zp, int type, int tick, int value1, int value2){
627 p = zp;
628 e = new mevent(type,tick,value1);
629 e->value2 = value2;
630 e->prev = tfind<mevent>(zp->events,tick);
631 e->next = e->prev->next;
633 ~CreateEvent(){
634 delete e;
637 void redo();
638 void undo();
641 class DeleteEvent : public Command {
642 mevent* e;
644 public:
646 DeleteEvent(mevent* ze){
647 e = ze;
650 void redo();
651 void undo();
654 class ChangeEvent : public Command {
655 mevent* e1;
656 mevent* e2;
658 public:
660 ChangeEvent(mevent* ze, int zv1, int zv2){
661 e1 = ze;
662 e2 = new mevent(ze);
663 e2->value1 = zv1;
664 e2->value2 = zv2;
667 void redo();
668 void undo();
673 int init_seq();
675 int play_seq(int cur_tick, void (*dispatch_event)(mevent*, int port, int tick));
676 int set_seq_pos(int new_tick);
678 void set_rec_track(int t);
679 int get_rec_track();
681 int set_default_hsv_value(float v);
683 void set_undo(Command* c);
684 void undo_push(int n);
685 void do_undo();
686 void do_redo();
688 void pattern_clear();
689 void reset_record_flags();
692 //encodes data in e as a midi event placed in buf
693 int midi_encode(mevent* e, int chan, unsigned char* buf, size_t* n);
695 //decodes midi data and creates a new mevent
696 int midi_decode(char* buf, mevent* e);
698 #endif