Rearranged the GUI.
[epichord.git] / src / seq.h
blob09d2e50f8db6a51be0e766a62c69e5f4d9cec5ca
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);
458 void redo();
459 void undo();
462 /*TODO*/
463 class SplitSeqpat : public Command {
464 seqpat* s;
465 pattern* p1;
466 pattern* p2;
468 public:
470 SplitSeqpat(seqpat* zs){
471 s = zs;
472 p1 = s->p;
473 p2 = new pattern();
474 p2->ref_c = 1;
477 SplitSeqpat(){
478 if(--(p2->ref_c) == 0){
479 delete p2;
483 void redo();
484 void undo();
488 /*TODO*/
489 class JoinSeqpat : public Command {
491 public:
493 JoinSeqpat(seqpat* zs1, seqpat* zs2){
494 //s = zs;
495 //p1 = s->p;
496 //p2 = new pattern();
497 //p2->ref_c = 1;
500 ~JoinSeqpat(){
501 //if(--(p2->ref_c) == 0){
502 // delete p2;
506 void redo();
507 void undo();
510 class ClearSeqpat : public Command {
512 seqpat* s;
513 pattern* p1;
514 pattern* p2;
516 public:
518 ClearSeqpat(seqpat* zs){
519 s = zs;
520 p1 = s->p;
521 p2 = new pattern();
522 p2->ref_c = 1;
525 ~ClearSeqpat(){
526 //delete p2
529 void redo();
530 void undo();
533 class LayerSeqpat : public Command {
535 seqpat* s;
536 pattern* p;
538 public:
540 LayerSeqpat(seqpat* zs){
541 s = zs;
542 p = new pattern();
543 p->ref_c = 1;
546 ~LayerSeqpat(){
547 //delete p2
550 void redo();
551 void undo();
557 class CreateNote : public Command {
558 pattern* p;
559 mevent* e1;
560 mevent* e2;
562 public:
564 CreateNote(pattern* zp, int note, int vel, int tick, int dur){
565 p = zp;
566 e1 = new mevent(MIDI_NOTE_ON, tick, note);
567 e1->dur = dur;
568 e1->value2 = vel;
569 e2 = new mevent(MIDI_NOTE_OFF, tick+dur, note);
570 e2->value2 = 0;
571 //e->off = new mevent(MIDI_NOTE_OFF, tick+dur, note);
573 ~CreateNote(){
574 //delete e->off;
575 delete e1;
576 delete e2;
579 void redo();
580 void undo();
583 class CreateNoteOn : public Command {
584 pattern* p;
585 mevent* e1;
587 public:
589 CreateNoteOn(pattern* zp, int note, int vel, int tick, int dur){
590 p = zp;
591 e1 = new mevent(MIDI_NOTE_ON, tick, note);
592 e1->value2 = vel;
593 e1->dur = dur;
595 ~CreateNoteOn(){
596 delete e1;
599 void redo();
600 void undo();
603 class CreateNoteOff : public Command {
604 pattern* p;
605 mevent* e1;
606 mevent* e2;
608 int dur1;
609 int dur2;
611 public:
613 CreateNoteOff(pattern* zp, int note, int vel, int tick);
614 ~CreateNoteOff(){
615 delete e2;
618 void redo();
619 void undo();
622 class DeleteNote : public Command {
623 pattern* p;
624 mevent* e1;
625 mevent* e2;
627 public:
629 DeleteNote(pattern* zp, mevent* ze){
630 p = zp;
631 e1 = ze;
632 e2 = find_off(e1);
635 void redo();
636 void undo();
639 class MoveNote : public Command {
640 pattern* p;
641 mevent* e1;
642 mevent* e2;
643 int t1;
644 int t2;
645 int note1;
646 int note2;
648 void arrive(int t);
650 public:
652 MoveNote(pattern* zp, mevent* ze, int zt, int znote){
653 p = zp;
654 e1 = ze;
655 e2 = find_off(e1);
656 note1 = ze->value1;
657 note2 = znote;
658 t1 = ze->tick;
659 t2 = zt;
662 void redo();
663 void undo();
667 class ResizeNote : public Command {
668 pattern* p;
669 mevent* l1;
670 mevent* l2;
671 mevent* r1;
672 mevent* r2;
674 public:
676 ResizeNote(pattern* zp, mevent* ze, int dur);
677 ~ResizeNote(){
678 delete l2;
679 delete r2;
682 void redo();
683 void undo();
689 class CreateEvent : public Command {
690 pattern* p;
691 mevent* e;
693 public:
695 CreateEvent(pattern* zp, int type, int tick, int value1, int value2){
696 p = zp;
697 e = new mevent(type,tick,value1);
698 e->value2 = value2;
699 e->prev = tfind<mevent>(zp->events,tick);
700 e->next = e->prev->next;
702 ~CreateEvent(){
703 delete e;
706 void redo();
707 void undo();
710 class DeleteEvent : public Command {
711 mevent* e;
713 public:
715 DeleteEvent(mevent* ze){
716 e = ze;
719 void redo();
720 void undo();
723 class ChangeEvent : public Command {
724 mevent* e1;
725 mevent* e2;
727 public:
729 ChangeEvent(mevent* ze, int zv1, int zv2){
730 e1 = ze;
731 e2 = new mevent(ze);
732 e2->value1 = zv1;
733 e2->value2 = zv2;
736 void redo();
737 void undo();
742 int play_seq(int cur_tick, void (*dispatch_event)(mevent*, int port, int tick));
743 int set_seq_pos(int new_tick);
745 void set_rec_track(int t);
746 int get_rec_track();
748 int set_default_hsv_value(float v);
750 void set_undo(Command* c);
751 void undo_push(int n);
752 void do_undo();
753 void do_redo();
754 void undo_reset();
757 void reset_record_flags();
760 //encodes data in e as a midi event placed in buf
761 int midi_encode(mevent* e, int chan, unsigned char* buf, size_t* n);
763 //decodes midi data and creates a new mevent
764 int midi_decode(char* buf, mevent* e);
766 #endif