Tested lrotate chunk.
[crush-sequencer.git] / seq.c
blob2e5fdcff2b67123521ac18c11fda97941522f3d2
1 #include <stdlib.h>
2 #include <stdio.h>
4 #include <seq.h>
6 #define BUFFER_SIZE 256
8 typedef struct undo_op undo_op;
10 struct ring_buffer {
11 int front;
12 int back;
13 struct buffer_slot {
14 unsigned p1;
15 unsigned p2;
16 unsigned p3;
17 unsigned p4;
18 unsigned p5;
19 } buf[BUFFER_SIZE];
22 struct undo_op {
23 int commit;
24 void (*redo)(undo_op* op);
25 void (*undo)(undo_op* op);
26 void (*collect)(undo_op* op);
27 unsigned p1;
28 unsigned p2;
29 void* v1;
30 void* v2;
31 void* v3;
32 void* v4;
33 struct undo_op* next;
34 struct undo_op* prev;
37 struct unstick_node {
38 int port;
39 int chan;
40 int note;
41 struct unstick_node* next;
44 enum seq_state {
45 SEQ_STOP,
46 SEQ_PLAY
49 enum {
50 NOTE_ON = 0x90,
51 NOTE_OFF = 0x80,
52 CONTROLLER = 0xB0,
53 PROGRAM = 0xC0,
57 /* internal procedures */
58 static int default_out_of_memory(void);
59 static void* default_malloc(size_t s);
60 static void default_free(void* z);
61 static void* qmalloc(size_t s);
62 static void qfree(void* z);
65 static void emergency_cutoff(void);
66 static void chan_cutoff(int chan);
67 static void selective_cutoff(int chan, int note);
70 static void init_buffer(struct ring_buffer* b);
71 static void write_buffer(struct ring_buffer* b, unsigned p1, unsigned p2, unsigned p3, unsigned p4, unsigned p5);
72 static int read_buffer(struct ring_buffer* b, unsigned* p1, unsigned* p2, unsigned* p3, unsigned* p4, unsigned* p5);
74 static chunk_list* mk_chunk_list(chunk* ck);
75 static chunk_list* chunk_list_copy(chunk_list* ls);
76 static void chunk_refup(chunk* ck);
77 static void chunk_refdown(chunk* ck);
78 static int rfind_track(track* tr);
79 static track* find_track(int n);
80 static chunk* find_chunk_by_tick(track* tr, unsigned tick);
81 static track* mk_track(void);
82 static block* mk_block(unsigned tick, unsigned length, chunk* ck);
84 static void error(const char* msg);
86 static void move_seq_pointers(unsigned tick);
88 static event* mk_event(unsigned tick, int type, int u, int v);
91 static void advance_play_head(unsigned samples);
92 static int core_sequence(
93 track** tr_out,event** ev_out, unsigned* samp_out,
94 unsigned N, unsigned D, unsigned sample_limit
96 static int calc_next_event(event**, block**, track**, unsigned*);
97 static void dispatch_event(
98 int* port, int* type, int* chan, int* u, int* v,
99 int port_, int type_, int chan_, int u_, int v_
102 static undo_op* mk_undo_op();
103 static void dummy_undo(undo_op* op);
104 static void undo_collect(void);
105 static void undo_push(undo_op* op);
107 static void redo_add_track(undo_op* op);
108 static void undo_add_track(undo_op* op);
109 static void collect_add_track(undo_op* op);
111 static void redo_delete_track(undo_op* op);
112 static void undo_delete_track(undo_op* op);
113 static void collect_delete_track(undo_op* op);
115 static void redo_insert_block(undo_op* op);
116 static void undo_insert_block(undo_op* op);
117 static void collect_insert_block(undo_op* op);
119 static void redo_resize_block(undo_op* op);
120 static void undo_resize_block(undo_op* op);
121 static void collect_resize_block(undo_op* op);
123 static void redo_delete_block(undo_op* op);
124 static void undo_delete_block(undo_op* op);
125 static void collect_delete_block(undo_op* op);
127 static void redo_push_chunk(undo_op* op);
128 static void undo_push_chunk(undo_op* op);
129 static void collect_push_chunk(undo_op* op);
131 static void redo_rrotate_chunk(undo_op* op);
132 static void undo_rrotate_chunk(undo_op* op);
133 static void collect_rrotate_chunk(undo_op* op);
135 static void redo_lrotate_chunk(undo_op* op);
136 static void undo_lrotate_chunk(undo_op* op);
137 static void collect_lrotate_chunk(undo_op* op);
139 static void redo_insert_event(undo_op* op);
140 static void undo_insert_event(undo_op* op);
141 static void collect_insert_event(undo_op* op);
143 static void redo_delete_event(undo_op* op);
144 static void undo_delete_event(undo_op* op);
145 static void collect_delete_event(undo_op* op);
148 static void stick_note(int port, int chan, int note);
149 static void unstick_note(int port, int chan, int note);
150 static int unstick_all(int* port, int* chan, int* note);
153 /* sequencer state */
154 static struct ring_buffer in_buf; /* recording */
155 static struct ring_buffer out_buf; /* instant queue */
156 static track* the_tracks = NULL;
157 static unsigned tick_now = 0;
158 static unsigned tick_err = 0;
159 static unsigned sample_rate = 44100;
160 static unsigned ticks_per_beat = 384;
161 static unsigned beats_per_minute = 120;
162 static struct undo_op* undo_stack = NULL;
163 static struct undo_op* undo_ptr = NULL;
164 static enum seq_state state = SEQ_STOP;
165 static unsigned loop_begin = 0;
166 static unsigned loop_end = 384 * 2 * 4;
167 static unsigned loop_flag = 0;
168 static int record_flag = 0;
169 static int rec_track_n = 0;
170 static track* record_track = NULL;
172 static track* glbl_track_itor = NULL;
173 static block* glbl_block_itor = NULL;
174 static event* glbl_event_itor = NULL;
176 static void* (*malloc_ptr)(size_t s);
177 static void (*free_ptr)(void* z);
178 static int (*out_of_memory_ptr)(void);
180 static unsigned char emergency_storage[256];
182 static struct unstick_node* unstick_frees;
183 static struct unstick_node* unstick_stuck;
184 static int unstick_flag = 0;
189 void seq_dump(void){
190 track* tr = NULL;
191 block* bl = NULL;
192 chunk* ck = NULL;
193 chunk_list* cl = NULL;
194 event* ev = NULL;
195 int tr_i;
196 int ck_i;
198 undo_op* un = NULL;
199 int undo_i = 0;
202 printf("crush sequencer\n\n");
205 printf("undo stack:\n");
206 un=undo_stack->next;
207 while(un){
208 printf("un %p: %p %p\n", un, un->v1, un->v2);
209 un=un->next;
211 if(undo_ptr==undo_stack) {
212 printf("unptr: root\n");
214 else {
215 printf("unptr: %p\n", undo_ptr);
219 printf("sequence:\n");
220 tr=the_tracks->next;
221 tr_i=0;
222 if(tr==NULL){ printf(" nothing\n"); }
223 else while(tr) {
224 printf("%d track:\n", tr_i++);
225 bl=tr->blocks->next;
226 while(bl) {
227 printf(" %d block (length %d):\n", bl->tick, bl->length);
228 cl = bl->chunks;
229 ck_i = 0;
230 while(cl) {
231 ck = cl->ptr;
232 ev = ck->events->next;
233 if(bl->chunk_ptr == cl){
234 printf(" +%d chunk:\n", ck_i++);
236 else{
237 printf(" %d chunk:\n", ck_i++);
239 while(ev) {
240 printf(" %d (0x%02x,%d,%d)\n", ev->tick, ev->type, ev->u, ev->v);
241 ev=ev->next;
243 cl=cl->next;
245 bl=bl->next;
247 tr=tr->next;
249 printf("\n");
251 printf("alloc routine = %s\n", malloc_ptr == default_malloc ? "default" : "custom");
252 printf("out of memory routine = %s\n", out_of_memory_ptr == default_out_of_memory ? "default" : "custom");
253 printf("free routine = %s\n\n", free_ptr == default_free ? "default" : "custom");
255 printf("in buffer = \n");
256 printf("out buffer = \n\n");
258 printf("now = %u\n", tick_now);
259 printf("err = %u\n", tick_err);
260 printf("srate = %u\n", sample_rate);
261 printf("tpb = %u\n", ticks_per_beat);
262 printf("bpm = %u\n", beats_per_minute);
263 printf("state = %s\n", state==SEQ_PLAY ? "PLAY" : "STOP");
264 printf("loop begin = %u\n", loop_begin);
265 printf("loop end = %u\n", loop_end);
266 printf("looping = %u\n", loop_flag);
267 printf("recording = %u\n", record_flag);
268 printf("rec track = %u\n", rec_track_n);
269 printf("unstick = %u\n\n", unstick_flag);
272 /* play / stop */
273 void seq_play(int on_off){
274 if(on_off){
275 state = SEQ_PLAY;
277 else{
278 state = SEQ_STOP;
282 unsigned seq_poll(void){
283 return tick_now;
286 void seq_seek(unsigned tick){
287 if(tick > tick_now){
288 move_seq_pointers(tick);
289 tick_now = tick;
291 else{
292 tick_now = tick;
293 move_seq_pointers(tick);
295 seq_all_notes_off();
298 void seq_reset(void){
299 seq_seek(0);
302 void seq_record(int on_off){
303 record_flag = on_off;
306 void seq_loop(int on_off){
307 loop_flag = on_off;
310 void seq_loop_limits(unsigned tick1, unsigned tick2){
311 loop_begin = tick1;
312 loop_end = tick2;
315 void seq_time_config(unsigned sr, unsigned tpb, unsigned bpm){
316 sample_rate = sr;
317 ticks_per_beat = tpb;
318 beats_per_minute = bpm;
321 void seq_all_notes_off(void){
322 unstick_flag = 1;
325 /* */
326 void seq_init(void* (*aloc)(size_t), void (*fr)(void*), int (*oom)(void)){
327 init_buffer(&in_buf);
328 init_buffer(&out_buf);
330 out_of_memory_ptr = oom ? oom : default_out_of_memory;
331 malloc_ptr = aloc ? aloc : default_malloc;
332 free_ptr = fr ? fr : default_free;
334 the_tracks = mk_track();
335 tick_now = 0;
336 tick_err = 0;
337 sample_rate = 44100;
338 ticks_per_beat = 384;
339 beats_per_minute = 120;
340 undo_stack = mk_undo_op();
341 undo_ptr = undo_stack;
342 state = SEQ_STOP;
343 loop_begin = 0;
344 loop_end = 384 * 4 * 2;
345 loop_flag = 0;
346 record_track = NULL;
347 record_flag = 0;
350 void seq_uninit(void){
351 seq_clear_all();
352 qfree(the_tracks->blocks->chunks);
353 qfree(the_tracks->blocks);
354 qfree(the_tracks);
355 qfree(undo_stack);
358 int seq_undo(void){
359 if(undo_ptr == undo_stack){
360 return -1;
362 while(1){
363 if(undo_ptr == undo_stack) break;
364 undo_ptr->undo(undo_ptr);
365 undo_ptr = undo_ptr->prev;
366 if(undo_ptr->commit == 1) break;
368 return 0;
371 int seq_redo(void){
372 if(undo_ptr->next == NULL){
373 return -1;
375 while(1){
376 undo_ptr = undo_ptr->next;
377 if(undo_ptr->commit) break;
378 undo_ptr->redo(undo_ptr);
379 if(undo_ptr->next == NULL) break;
381 return 0;
384 void seq_commit(void){
385 undo_op* op = mk_undo_op();
386 op->commit = 1;
387 undo_push(op);
390 void seq_clear_all(void){
391 track* tr;
392 block* bl;
393 chunk* ck;
394 chunk_list* cl;
395 event* ev;
396 undo_op* un;
397 void* next;
399 seq_play(0);
400 seq_reset();
401 seq_all_notes_off();
403 /* clear future undo stack */
404 undo_collect();
406 /* then clear remaining structures directly */
407 tr = the_tracks->next;
408 while(tr){
409 bl = tr->blocks->next;
410 while(bl){
411 cl = bl->chunks;
412 while(cl){
413 if(cl->ptr->ref_c == 1){
414 ev = cl->ptr->events;
415 while(ev){
416 next = ev->next;
417 qfree(ev);
418 ev = next;
420 qfree(cl->ptr);
422 else{
423 cl->ptr->ref_c -= 1;
425 next = cl->next;
426 qfree(cl);
427 cl = next;
429 next = bl->next;
430 qfree(bl);
431 bl = next;
433 next = tr->next;
434 qfree(tr->blocks->chunks);
435 qfree(tr->blocks);
436 qfree(tr);
437 tr = next;
440 un = undo_stack->next;
441 while(un){
442 next = un->next;
443 qfree(un);
444 un = next;
446 undo_stack->next = NULL;
447 undo_ptr = undo_stack;
449 the_tracks->next = NULL;
452 void seq_instant(track* tr, int type, int u, int v){
453 int tr_number = rfind_track(tr);
454 write_buffer(&out_buf, tr->port, type, tr->chan, u, v);
457 chunk* seq_mk_chunk(void){
458 chunk* ck = qmalloc(sizeof(chunk));
459 ck->r = 255;
460 ck->g = 255;
461 ck->b = 255;
462 ck->ref_c = 0;
463 ck->events = mk_event(0,0,0,0);
464 return ck;
468 /* these operations can be undone */
469 void seq_add_track(void){
470 track* tr = mk_track();
471 track* ptr = the_tracks;
472 undo_op* op;
473 while(ptr->next != NULL){
474 ptr = ptr->next;
477 op = mk_undo_op();
478 op->v1 = tr;
479 op->v2 = ptr;
480 op->redo = redo_add_track;
481 op->undo = undo_add_track;
482 op->collect = collect_add_track;
483 undo_push(op);
486 void seq_delete_track(track* tr){
487 track* ptr = the_tracks;
488 undo_op* op;
489 while(ptr->next && ptr->next != tr){
490 ptr = ptr->next;
492 if(ptr->next == NULL){
493 fprintf(stderr, "delete: track note found\n");
494 return;
497 op = mk_undo_op();
498 op->v1 = tr;
499 op->v2 = ptr;
500 op->redo = redo_delete_track;
501 op->undo = undo_delete_track;
502 op->collect = collect_delete_track;
503 undo_push(op);
506 void seq_insert_block(track* tr, unsigned tick, unsigned length, chunk* ck){
507 block* ptr = tr->blocks;
508 block* bl = mk_block(tick, length, ck);
509 undo_op* op = mk_undo_op();
510 while(ptr->next && ptr->next->tick < tick){
511 ptr = ptr->next;
514 op->v1 = bl;
515 op->v2 = ptr;
516 op->redo = redo_insert_block;
517 op->undo = undo_insert_block;
518 op->collect = collect_insert_block;
519 chunk_refup(ck);
520 undo_push(op);
523 void seq_delete_block(track* tr, block* bl){
524 block* pred = tr->blocks;
525 undo_op* op = mk_undo_op();
527 while(pred->next && pred->next != bl){
528 pred = pred->next;
530 if(pred->next == NULL){
531 fprintf(stderr, "delete: block not found\n");
532 return;
535 op->v1 = bl;
536 op->v2 = pred;
537 op->redo = redo_delete_block;
538 op->undo = undo_delete_block;
539 op->collect = collect_delete_block;
540 undo_push(op);
543 void seq_copy_block(block* bl, track* tr, unsigned tick){
544 block* ptr = tr->blocks;
545 block* cpy = mk_block(tick, bl->length, NULL);
546 undo_op* op = mk_undo_op();
547 while(ptr->next && ptr->next->tick < tick){
548 ptr = ptr->next;
551 qfree(cpy->chunks);//undo part of construction
552 cpy->length = bl->length;
553 cpy->chunks = chunk_list_copy(bl->chunks);
554 cpy->chunk_ptr = cpy->chunks;
555 cpy->event_ptr = cpy->chunk_ptr->ptr->events->next;
557 op->v1 = cpy;
558 op->v2 = ptr;
559 /* we can utilize the insert operations here */
560 op->redo = redo_insert_block;
561 op->undo = undo_insert_block;
562 op->collect = collect_insert_block;
563 undo_push(op);
566 void seq_resize_block(block* bl, unsigned length){
567 undo_op* op = mk_undo_op();
568 op->v1 = bl;
569 op->p1 = bl->length;
570 op->p2 = length;
571 op->redo = redo_resize_block;
572 op->undo = undo_resize_block;
573 op->collect = collect_resize_block;
574 undo_push(op);
577 void seq_push_chunk(block* bl, chunk* ck){
578 chunk_list* ptr = bl->chunks;
579 undo_op* op = mk_undo_op();
580 unsigned i;
582 op->v1 = mk_chunk_list(ck);
583 while(ptr->next != NULL){
584 ptr = ptr->next;
586 op->v2 = ptr;
587 op->v3 = bl;
588 op->v4 = bl->chunk_ptr;
589 op->redo = redo_push_chunk;
590 op->undo = undo_push_chunk;
591 op->collect = collect_push_chunk;
592 chunk_refup(ck);
593 undo_push(op);
596 void seq_rrotate_chunk(block* bl){
597 undo_op* op = mk_undo_op();
598 op->v1 = bl;
599 op->redo = redo_rrotate_chunk;
600 op->undo = undo_rrotate_chunk;
601 op->collect = collect_rrotate_chunk;
602 undo_push(op);
605 void seq_lrotate_chunk(block* bl){
606 undo_op* op = mk_undo_op();
607 op->v1 = bl;
608 op->redo = redo_lrotate_chunk;
609 op->undo = undo_lrotate_chunk;
610 op->collect = collect_lrotate_chunk;
611 undo_push(op);
614 void seq_insert_event(chunk* ck, unsigned tick, int type, int u, int v){
615 event* ev = mk_event(tick, type, u, v);
616 event* ptr = ck->events;
617 undo_op* op;
619 while(ptr->next && ptr->next->tick < tick){
620 ptr = ptr->next;
623 op = mk_undo_op();
624 op->v1 = ev;
625 op->v2 = ptr;
626 op->redo = redo_insert_event;
627 op->undo = undo_insert_event;
628 op->collect = collect_insert_event;
629 undo_push(op);
632 void seq_delete_event(chunk* ck, event* ev){
633 event* ptr = ck->events;
634 undo_op* op;
635 while(ptr->next && ptr->next != ev){
636 ptr = ptr->next;
638 if(ptr->next == NULL){
639 fprintf(stderr, "delete: event not found\n");
640 return;
643 op = mk_undo_op();
644 op->v1 = ev;
645 op->v2 = ptr;
646 op->redo = redo_delete_event;
647 op->undo = undo_delete_event;
648 op->collect = collect_delete_event;
649 undo_push(op);
652 void seq_accept_recording(void){
653 unsigned tick, type, u, v, unused;
654 chunk* ck;
655 track* record_track = find_track(rec_track_n);
657 if(record_track == NULL) return;
659 while(!read_buffer(&in_buf, &tick, &type, &u, &v, &unused)){
660 ck = find_chunk_by_tick(record_track, tick);
661 seq_insert_event(ck, tick, type, u, v);
665 /* sequencer state reading */
666 int seq_layer_number(block* bl){
667 int i = 0;
668 chunk_list* ptr = bl->chunks->next;
669 while(ptr && ptr != bl->chunk_ptr){
670 i = i+1;
671 ptr = ptr->next;
673 return i;
676 void seq_walk_tracks(void){
677 glbl_track_itor = the_tracks->next;
680 track* seq_next_track(void){
681 track* ptr = glbl_track_itor;
682 if(glbl_track_itor == NULL){
683 return NULL;
685 else{
686 glbl_track_itor = glbl_track_itor->next;
687 return ptr;
691 void seq_walk_blocks(track* tr){
692 glbl_block_itor = tr->blocks->next;
695 block* seq_next_block(void){
696 block* ptr = glbl_block_itor;
697 if(glbl_block_itor == NULL){
698 return NULL;
700 else{
701 glbl_block_itor = glbl_block_itor->next;
702 return ptr;
706 void seq_walk_events(chunk* ck){
707 glbl_event_itor = ck->events->next;
710 event* seq_next_event(void){
711 event* ptr = glbl_event_itor;
712 if(glbl_event_itor == NULL){
713 return NULL;
715 else{
716 glbl_event_itor = glbl_event_itor->next;
717 return ptr;
724 /* audio thread operations */
725 int seq_advance(
726 unsigned samples,
727 unsigned* used,
728 int* port,
729 int* type,
730 int* chan,
731 int* u,
732 int* v
734 unsigned N = beats_per_minute * ticks_per_beat;
735 unsigned D = sample_rate * 60;
736 unsigned a, b, c, d, e;
738 track* tr;
739 event* ev;
740 unsigned samp_out;
742 if(unstick_flag){ /* check for emergency cutoff */
743 /* if(unstick_all(port, chan, u)){
744 *used = 0;
745 *type = NOTE_OFF;
746 return 1;
748 else{
749 unstick_flag = 0;
751 unstick_flag = 0;
754 if(read_buffer(&out_buf, &a, &b, &c, &d, &e)){
755 /* do immediate events */
756 *used = 0;
757 dispatch_event(port, type, chan, u, v,
758 a, b, c, d, e);
759 return 1;
763 /* advance to the next event, possibly looping */
764 /* return 0 if no event, 1 otherwise */
765 if(core_sequence(&tr, &ev, &samp_out, N, D, samples) == 1){
766 *used = samp_out;
767 dispatch_event(port, type, chan, u, v,
768 tr->port, ev->type, tr->chan, ev->u, ev->v);
769 return 1;
771 else{
772 *used = samples;
773 return 0;
779 static void advance_play_head(unsigned samples){
784 static int core_sequence(
785 track** tr_out,
786 event** ev_out,
787 unsigned* samp_out,
788 unsigned N,
789 unsigned D,
790 unsigned sample_limit
793 get next event, or nothing, or loop end
795 nothing - return 0
796 event - if within sample_limit, advance and return 1
797 loop - if within sample_limit, advance, reset and return core_sequence
801 track* tr;
802 block* bl;
803 chunk* ck;
804 event* ev;
805 unsigned tick;
806 unsigned samples;
807 unsigned now = tick_now;
808 int kind = calc_next_event(&ev, &bl, &tr, &tick);
810 if(kind == 0){ /* nothing */
811 advance_play_head(sample_limit);
812 return 0;
814 else if(kind == 1){ /* event */
815 samples = (tick - now) * D / N;
816 advance_play_head(samples);
817 *tr_out = tr;
818 *ev_out = ev;
820 bl->event_ptr = ev->next;
821 if(ev->next == NULL){
822 tr->block_ptr = bl->next;
823 ck = tr->block_ptr->chunk_ptr->ptr;
824 tr->block_ptr->event_ptr = ck->events->next;
827 return 1;
829 else if(kind == 2){ /* loop endpoint */
830 samples = (tick - now) * D / N;
831 advance_play_head(samples);
832 //move to loop start
833 error("core sequence");
834 return 0;
835 //return core_sequence(...);
837 else {
838 error("core_sequence: ???");
839 return 0;
845 void seq_record_event(int type, int chan, int u, int v){
846 int track_num = rec_track_n;
847 unsigned tick = seq_poll();
848 write_buffer(&in_buf, tick, type, u, v, 0);
854 /* internal procedures */
855 static int default_out_of_memory(void){
856 fprintf(stderr, "OUT OF MEMORY (sequencer)");
857 exit(13);
860 static void* default_malloc(size_t s){
861 return malloc(s);
864 static void default_free(void* z){
865 free(z);
868 static void* qmalloc(size_t s){
869 void* ptr = malloc_ptr(s);
870 if(ptr == NULL){
871 if(out_of_memory_ptr() == 0){
872 /* recovered */
873 return qmalloc(s);
875 else{
876 fprintf(
877 stderr,
878 "sequencer unable to recover from out of memory\n"
880 return emergency_storage;
883 else{
884 return ptr;
888 static void qfree(void* z){
889 free_ptr(z);
892 static void init_buffer(struct ring_buffer* b){
893 b->front = 0;
894 b->back = 0;
897 static void write_buffer(
898 struct ring_buffer* b,
899 unsigned p1,
900 unsigned p2,
901 unsigned p3,
902 unsigned p4,
903 unsigned p5
905 struct buffer_slot s = {p1, p2, p3, p4, p5};
906 int f = b->front;
907 int k = b->back;
908 if(f - k == 1 || k+BUFFER_SIZE - f == 1){
909 return;
911 else{
912 b->buf[k] = s;
913 b->back = (k + 1) % BUFFER_SIZE;
917 static int read_buffer(
918 struct ring_buffer* b,
919 unsigned* p1,
920 unsigned* p2,
921 unsigned* p3,
922 unsigned* p4,
923 unsigned* p5
925 int k = b->back;
926 int f = b->front;
927 if(f == k){
928 return 0;
930 else{
931 *p1 = b->buf[f].p1;
932 *p2 = b->buf[f].p2;
933 *p3 = b->buf[f].p3;
934 *p4 = b->buf[f].p4;
935 *p5 = b->buf[f].p5;
937 b->front = (f + 1) % BUFFER_SIZE;
938 return 1;
942 static chunk_list* mk_chunk_list(chunk* ck){
943 chunk_list* ls = qmalloc(sizeof(chunk_list));
944 ls->next = NULL;
945 ls->ptr = ck;
946 return ls;
949 static chunk_list* chunk_list_copy(chunk_list* ls){
950 chunk_list* ptr = ls;
951 chunk_list* ret = mk_chunk_list(ptr->ptr);
952 chunk_list* ptr2 = ret;
954 chunk_refup(ptr->ptr);
955 ptr = ptr->next;
956 while(ptr){
957 ptr2->next = mk_chunk_list(ptr->ptr);
958 chunk_refup(ptr->ptr);
959 ptr = ptr->next;
960 ptr2 = ptr2->next;
962 return ret;
965 static track* mk_track(void){
966 track* ptr = qmalloc(sizeof(track));
967 ptr->port = 0;
968 ptr->chan = 0;
969 ptr->blocks = mk_block(0, 0, NULL);
970 ptr->block_ptr = NULL;
971 ptr->next = NULL;
972 return ptr;
975 static block* mk_block(unsigned tick, unsigned length, chunk* ck){
976 block* ptr = qmalloc(sizeof(block));
977 ptr->tick = tick;
978 ptr->length = length;
979 ptr->event_ptr = NULL;
980 ptr->next = NULL;
981 ptr->chunks = mk_chunk_list(ck);
982 ptr->chunk_ptr = ptr->chunks;
983 return ptr;
988 static void chunk_refup(chunk* ck){
989 ck->ref_c += 1;
992 static void chunk_refdown(chunk* ck){
993 event* ptr = ck->events;
994 event* next = NULL;
996 ck->ref_c -= 1;
997 if(ck->ref_c > 0) return;
999 qfree(ck->events);
1000 qfree(ck);
1003 static int rfind_track(track* tr){
1004 track* ptr = the_tracks->next;
1005 int i = 0;
1006 while(ptr){
1007 if(ptr == tr) return i;
1008 ptr = ptr->next;
1010 return -1;
1013 static track* find_track(int n){
1014 /* FIXME */
1015 error("find_track?");
1016 return NULL;
1019 static chunk* find_chunk_by_tick(track* tr, unsigned tick){
1020 /* TODO */
1021 error("find_chunk_by_tick?");
1022 return NULL;
1027 static void move_seq_pointers(unsigned tick){
1032 static event* mk_event(unsigned tick, int type, int u, int v){
1033 event* ev = qmalloc(sizeof(event));
1034 ev->tick = tick;
1035 ev->type = type;
1036 ev->u = u;
1037 ev->v = v;
1038 ev->next = NULL;
1039 return ev;
1042 static undo_op* mk_undo_op(){
1043 undo_op* op = qmalloc(sizeof(undo_op));
1044 op->commit = 0;
1045 op->next = NULL;
1046 op->prev = undo_ptr;
1047 op->redo = dummy_undo;
1048 op->undo = dummy_undo;
1049 op->collect = dummy_undo;
1050 op->p1 = 0;
1051 op->p2 = 0;
1052 op->v1 = NULL;
1053 op->v2 = NULL;
1054 op->v3 = NULL;
1055 return op;
1058 static void dummy_undo(undo_op* op){
1059 /* no effect */
1062 static void undo_collect(){
1063 undo_op* ptr = undo_ptr;
1064 undo_op* prev = NULL;
1065 while(ptr->next != NULL){
1066 ptr = ptr->next;
1068 while(ptr != undo_ptr){
1069 prev = ptr->prev;
1070 ptr->collect(ptr);
1071 qfree(ptr);
1072 ptr = prev;
1074 undo_ptr->next = NULL;
1077 static void undo_push(undo_op* op){
1078 undo_collect();
1079 undo_ptr->next = op;
1080 seq_redo();
1085 /* */
1086 /* editting and uneditting procedures */
1087 /* */
1089 static void redo_add_track(undo_op* op){
1090 track* tr = op->v1;
1091 track* pred = op->v2;
1092 if(pred->next != NULL){
1093 fprintf(stderr, "add track inconsistent\n");
1094 return;
1096 pred->next = tr;
1099 static void undo_add_track(undo_op* op){
1100 track* tr = op->v1;
1101 track* pred = op->v2;
1102 if(tr->next != NULL){
1103 fprintf(stderr, "undo add track inconsistent\n");
1104 return;
1106 pred->next = NULL;
1109 static void collect_add_track(undo_op* op){
1110 track* tr = op->v1;
1111 qfree(tr->blocks->chunks);
1112 qfree(tr->blocks);
1113 qfree(tr);
1116 static void redo_delete_track(undo_op* op){
1117 track* pred = op->v2;
1118 pred->next = pred->next->next;
1121 static void undo_delete_track(undo_op* op){
1122 track* tr = op->v1;
1123 track* pred = op->v2;
1124 tr->next = pred->next;
1125 pred->next = tr;
1128 static void collect_delete_track(undo_op* op){
1129 /* no effect */
1130 /* proof: either the corresponding create op
1131 * has been collected or it will not be collected.
1132 * if yes, then the track has been freed.
1133 * if no, the track is still there and should not be freed.
1134 * */
1137 static void redo_insert_block(undo_op* op){
1138 block* bl = op->v1;
1139 block* pred = op->v2;
1141 bl->next = pred->next;
1142 pred->next = bl;
1145 static void undo_insert_block(undo_op* op){
1146 block* pred = op->v2;
1147 pred->next = pred->next->next;
1150 static void collect_insert_block(undo_op* op){
1151 block* bl = op->v1;
1152 chunk_list* ptr = bl->chunks;
1153 chunk_list* next;
1155 while(ptr){
1156 next = ptr->next;
1157 chunk_refdown(ptr->ptr);
1158 qfree(ptr);
1159 ptr = next;
1162 qfree(bl);
1166 static void redo_resize_block(undo_op* op){
1167 block* bl = op->v1;
1168 unsigned l2 = op->p2;
1169 bl->length = l2;
1172 static void undo_resize_block(undo_op* op){
1173 block* bl = op->v1;
1174 unsigned l1 = op->p1;
1175 bl->length = l1;
1178 static void collect_resize_block(undo_op* op){
1179 /* no effect */
1183 static void redo_delete_block(undo_op* op){
1184 block* pred = op->v2;
1185 block* bl = op->v1;
1186 pred->next = bl->next;
1189 static void undo_delete_block(undo_op* op){
1190 block* pred = op->v2;
1191 block* bl = op->v1;
1192 bl->next = pred->next;
1193 pred->next = bl;
1196 static void collect_delete_block(undo_op* op){
1197 /* do nothing */
1201 static void redo_push_chunk(undo_op* op){
1202 chunk_list* pred = op->v2;
1203 chunk_list* cl = op->v1;
1204 block* bl = op->v3;
1205 pred->next = cl;
1206 bl->chunk_ptr = cl;
1209 static void undo_push_chunk(undo_op* op){
1210 chunk_list* pred = op->v2;
1211 block* bl = op->v3;
1212 chunk_list* ptr = bl->chunks;
1214 pred->next = NULL;
1215 bl->chunk_ptr = op->v4;
1218 static void collect_push_chunk(undo_op* op){
1219 chunk_list* cl = op->v1;
1220 chunk_refdown(cl->ptr);
1221 qfree(cl);
1224 static void redo_rrotate_chunk(undo_op* op){
1225 block* bl = op->v1;
1226 if(bl->chunk_ptr->next == NULL){
1227 bl->chunk_ptr = bl->chunks;
1229 else{
1230 bl->chunk_ptr = bl->chunk_ptr->next;
1234 static void undo_rrotate_chunk(undo_op* op){
1235 block* bl = op->v1;
1236 chunk_list* cl = bl->chunks;
1237 if(bl->chunk_ptr == bl->chunks){
1238 while(cl->next != NULL){
1239 cl = cl->next;
1241 bl->chunk_ptr = cl;
1243 else{
1244 while(cl->next != bl->chunk_ptr){
1245 cl = cl->next;
1247 bl->chunk_ptr = cl;
1251 static void collect_rrotate_chunk(undo_op* op){
1252 /* do nothing */
1255 static void redo_lrotate_chunk(undo_op* op){
1256 undo_rrotate_chunk(op);
1259 static void undo_lrotate_chunk(undo_op* op){
1260 redo_rrotate_chunk(op);
1263 static void collect_lrotate_chunk(undo_op* op){
1264 /* do nothing */
1267 static void redo_insert_event(undo_op* op){
1268 event* ev = op->v1;
1269 event* pred = op->v2;
1270 ev->next = pred->next;
1271 pred->next = ev;
1274 static void undo_insert_event(undo_op* op){
1275 event* pred = op->v2;
1276 pred->next = pred->next->next;
1279 static void collect_insert_event(undo_op* op){
1280 qfree(op->v1);
1283 static void redo_delete_event(undo_op* op){
1284 event* pred = op->v2;
1285 pred->next = pred->next->next;
1288 static void undo_delete_event(undo_op* op){
1289 event* ev = op->v1;
1290 event* pred = op->v2;
1291 ev->next = pred->next;
1292 pred->next = ev;
1295 static void collect_delete_event(undo_op* op){
1296 /* no effect */
1297 /* proof: if a delete event is collected, then
1298 * it means the the delete was undone. either the
1299 * corresponding create op is being collected or
1300 * it isnt. if it is, the event is not there and
1301 * cannot be recovered, and is freed. if it isnt
1302 * the event is still there and nothing happens.
1303 * */
1312 static void dispatch_event(
1313 int* port, int* type, int* chan, int* u, int* v,
1314 int port_, int type_, int chan_, int u_, int v_
1316 *port = port_;
1317 *type = type_;
1318 *chan = chan_;
1319 *u = u_;
1320 *v = v_;
1322 if(type_ == NOTE_ON){
1323 stick_note(port_, chan_, u_);
1325 else if(type_ == NOTE_OFF){
1326 unstick_note(port_, chan_, u_);
1332 static void handle_cutoff(int* port, int* type, int* chan, int* u, int* v){
1333 //look for any remembered NOTE_ONs
1334 //write a corresponding port, NOTE_OFF, chan, u
1335 //to the output pointers.
1337 //now wheres that data structure
1344 static void stick_note(int port, int chan, int note){
1345 struct unstick_node* ptr = unstick_frees->next;
1346 if(ptr == NULL){
1347 return;
1349 unstick_frees->next = ptr->next;
1350 ptr->port = port;
1351 ptr->chan = chan;
1352 ptr->note = note;
1353 ptr->next = unstick_stuck->next;
1354 unstick_stuck->next = ptr;
1357 static void unstick_note(int port, int chan, int note){
1358 struct unstick_node* ptr = unstick_stuck;
1359 struct unstick_node* found;
1360 while(ptr->next){
1362 ptr->port == port &&
1363 ptr->chan == chan &&
1364 ptr->note == note ){
1365 found = ptr->next;
1366 ptr->next = found->next;
1367 found->next = unstick_frees->next;
1368 unstick_frees->next = found;
1369 return;
1371 ptr = ptr->next;
1375 static int unstick_all(int* port, int* chan, int* note){
1376 error("unstick_all not written");
1378 struct unstick_node* ptr;
1379 if(unstick_stuck->next == NULL){
1380 return 0;
1382 else{
1383 *port = ptr->port;
1384 *chan = ptr->chan;
1385 *note = ptr->note;
1386 unstick_stuck->next = ptr->next;
1387 ptr->next = unstick_frees->next;
1388 unstick_frees->next = ptr;
1389 return 1;
1392 return 0;
1396 static int calc_next_event(
1397 event** ev_out,
1398 block** bl_out,
1399 track** tr_out,
1400 unsigned* ticks_out
1402 track* tr = the_tracks->next;
1403 block* bl;
1404 chunk* ck;
1405 event* ev_min = NULL;
1406 event* ev;
1408 unsigned now = tick_now;
1410 while(tr){
1411 bl = tr->block_ptr;
1412 if(ev_min == NULL
1413 || bl->event_ptr->tick + bl->tick < ev_min->tick){
1414 ev = bl->event_ptr;
1415 *ev_out = ev;
1416 *bl_out = bl;
1417 *tr_out = tr;
1418 *ticks_out = ev->tick + bl->tick - now;
1419 ev_min = ev;
1421 tr = tr->next;
1424 if(ev_min == NULL){
1425 if(loop_flag){
1426 *ticks_out = loop_end;
1427 return 2;
1429 else{
1430 return 0;
1433 else if(loop_flag && loop_end < ev_min->tick + bl->tick){
1434 *ticks_out = loop_end - now;
1435 return 2;
1437 else{
1438 return 1;
1446 static void error(const char* msg){
1447 fprintf(stderr, msg);
1448 exit(40);