Changed the backend api somewhat. Added bpm==0 check.
[epichord.git] / src / seq.h
blobe15b12f9437e4396b4462a8713d8b0ec46f16832
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 mevent* l2;
661 mevent* r1;
662 mevent* r2;
664 public:
666 ResizeNote(pattern* zp, mevent* ze, int dur);
667 ~ResizeNote(){
668 delete l2;
669 delete r2;
672 void redo();
673 void undo();
679 class CreateEvent : public Command {
680 pattern* p;
681 mevent* e;
683 public:
685 CreateEvent(pattern* zp, int type, int tick, int value1, int value2){
686 p = zp;
687 e = new mevent(type,tick,value1);
688 e->value2 = value2;
689 e->prev = tfind<mevent>(zp->events,tick);
690 e->next = e->prev->next;
692 ~CreateEvent(){
693 delete e;
696 void redo();
697 void undo();
700 class DeleteEvent : public Command {
701 mevent* e;
703 public:
705 DeleteEvent(mevent* ze){
706 e = ze;
709 void redo();
710 void undo();
713 class ChangeEvent : public Command {
714 mevent* e1;
715 mevent* e2;
717 public:
719 ChangeEvent(mevent* ze, int zv1, int zv2){
720 e1 = ze;
721 e2 = new mevent(ze);
722 e2->value1 = zv1;
723 e2->value2 = zv2;
726 void redo();
727 void undo();
732 int play_seq(int cur_tick);
733 int set_seq_pos(int new_tick);
735 void set_rec_track(int t);
736 int get_rec_track();
738 int set_default_hsv_value(float v);
740 void set_undo(Command* c);
741 void undo_push(int n);
742 void do_undo();
743 void do_redo();
744 void undo_reset();
747 void reset_record_flags();
750 //encodes data in e as a midi event placed in buf
751 int midi_encode(mevent* e, int chan, unsigned char* buf, size_t* n);
753 //decodes midi data and creates a new mevent
754 int midi_decode(char* buf, mevent* e);
756 #endif