6 #define BUFFER_SIZE 256
8 typedef struct undo_op undo_op
;
24 void (*redo
)(undo_op
* op
);
25 void (*undo
)(undo_op
* op
);
26 void (*collect
)(undo_op
* op
);
41 struct unstick_node
* next
;
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;
193 chunk_list
* cl
= NULL
;
202 printf("crush sequencer\n\n");
205 printf("undo stack:\n");
208 printf("un %p: %p %p\n", un
, un
->v1
, un
->v2
);
211 if(undo_ptr
==undo_stack
) {
212 printf("unptr: root\n");
215 printf("unptr: %p\n", undo_ptr
);
219 printf("sequence:\n");
222 if(tr
==NULL
){ printf(" nothing\n"); }
224 printf("%d track:\n", tr_i
++);
227 printf(" %d block (length %d):\n", bl
->tick
, bl
->length
);
232 ev
= ck
->events
->next
;
233 if(bl
->chunk_ptr
== cl
){
234 printf(" +%d chunk:\n", ck_i
++);
237 printf(" %d chunk:\n", ck_i
++);
240 printf(" %d (0x%02x,%d,%d)\n", ev
->tick
, ev
->type
, ev
->u
, ev
->v
);
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
);
273 void seq_play(int on_off
){
282 unsigned seq_poll(void){
286 void seq_seek(unsigned tick
){
288 move_seq_pointers(tick
);
293 move_seq_pointers(tick
);
298 void seq_reset(void){
302 void seq_record(int on_off
){
303 record_flag
= on_off
;
306 void seq_loop(int on_off
){
310 void seq_loop_limits(unsigned tick1
, unsigned tick2
){
315 void seq_time_config(unsigned sr
, unsigned tpb
, unsigned bpm
){
317 ticks_per_beat
= tpb
;
318 beats_per_minute
= bpm
;
321 void seq_all_notes_off(void){
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();
338 ticks_per_beat
= 384;
339 beats_per_minute
= 120;
340 undo_stack
= mk_undo_op();
341 undo_ptr
= undo_stack
;
344 loop_end
= 384 * 4 * 2;
350 void seq_uninit(void){
352 qfree(the_tracks
->blocks
->chunks
);
353 qfree(the_tracks
->blocks
);
359 if(undo_ptr
== undo_stack
){
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;
372 if(undo_ptr
->next
== NULL
){
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;
384 void seq_commit(void){
385 undo_op
* op
= mk_undo_op();
390 void seq_clear_all(void){
403 /* clear future undo stack */
406 /* then clear remaining structures directly */
407 tr
= the_tracks
->next
;
409 bl
= tr
->blocks
->next
;
413 if(cl
->ptr
->ref_c
== 1){
414 ev
= cl
->ptr
->events
;
434 qfree(tr
->blocks
->chunks
);
440 un
= undo_stack
->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
));
463 ck
->events
= mk_event(0,0,0,0);
468 /* these operations can be undone */
469 void seq_add_track(void){
470 track
* tr
= mk_track();
471 track
* ptr
= the_tracks
;
473 while(ptr
->next
!= NULL
){
480 op
->redo
= redo_add_track
;
481 op
->undo
= undo_add_track
;
482 op
->collect
= collect_add_track
;
486 void seq_delete_track(track
* tr
){
487 track
* ptr
= the_tracks
;
489 while(ptr
->next
&& ptr
->next
!= tr
){
492 if(ptr
->next
== NULL
){
493 fprintf(stderr
, "delete: track note found\n");
500 op
->redo
= redo_delete_track
;
501 op
->undo
= undo_delete_track
;
502 op
->collect
= collect_delete_track
;
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
){
516 op
->redo
= redo_insert_block
;
517 op
->undo
= undo_insert_block
;
518 op
->collect
= collect_insert_block
;
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
){
530 if(pred
->next
== NULL
){
531 fprintf(stderr
, "delete: block not found\n");
537 op
->redo
= redo_delete_block
;
538 op
->undo
= undo_delete_block
;
539 op
->collect
= collect_delete_block
;
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
){
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
;
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
;
566 void seq_resize_block(block
* bl
, unsigned length
){
567 undo_op
* op
= mk_undo_op();
571 op
->redo
= redo_resize_block
;
572 op
->undo
= undo_resize_block
;
573 op
->collect
= collect_resize_block
;
577 void seq_push_chunk(block
* bl
, chunk
* ck
){
578 chunk_list
* ptr
= bl
->chunks
;
579 undo_op
* op
= mk_undo_op();
582 op
->v1
= mk_chunk_list(ck
);
583 while(ptr
->next
!= NULL
){
588 op
->v4
= bl
->chunk_ptr
;
589 op
->redo
= redo_push_chunk
;
590 op
->undo
= undo_push_chunk
;
591 op
->collect
= collect_push_chunk
;
596 void seq_rrotate_chunk(block
* bl
){
597 undo_op
* op
= mk_undo_op();
599 op
->redo
= redo_rrotate_chunk
;
600 op
->undo
= undo_rrotate_chunk
;
601 op
->collect
= collect_rrotate_chunk
;
605 void seq_lrotate_chunk(block
* bl
){
606 undo_op
* op
= mk_undo_op();
608 op
->redo
= redo_lrotate_chunk
;
609 op
->undo
= undo_lrotate_chunk
;
610 op
->collect
= collect_lrotate_chunk
;
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
;
619 while(ptr
->next
&& ptr
->next
->tick
< tick
){
626 op
->redo
= redo_insert_event
;
627 op
->undo
= undo_insert_event
;
628 op
->collect
= collect_insert_event
;
632 void seq_delete_event(chunk
* ck
, event
* ev
){
633 event
* ptr
= ck
->events
;
635 while(ptr
->next
&& ptr
->next
!= ev
){
638 if(ptr
->next
== NULL
){
639 fprintf(stderr
, "delete: event not found\n");
646 op
->redo
= redo_delete_event
;
647 op
->undo
= undo_delete_event
;
648 op
->collect
= collect_delete_event
;
652 void seq_accept_recording(void){
653 unsigned tick
, type
, u
, v
, unused
;
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
){
668 chunk_list
* ptr
= bl
->chunks
->next
;
669 while(ptr
&& ptr
!= bl
->chunk_ptr
){
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
){
686 glbl_track_itor
= glbl_track_itor
->next
;
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
){
701 glbl_block_itor
= glbl_block_itor
->next
;
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
){
716 glbl_event_itor
= glbl_event_itor
->next
;
724 /* audio thread operations */
734 unsigned N
= beats_per_minute
* ticks_per_beat
;
735 unsigned D
= sample_rate
* 60;
736 unsigned a
, b
, c
, d
, e
;
742 if(unstick_flag
){ /* check for emergency cutoff */
743 /* if(unstick_all(port, chan, u)){
754 if(read_buffer(&out_buf
, &a
, &b
, &c
, &d
, &e
)){
755 /* do immediate events */
757 dispatch_event(port
, type
, chan
, u
, v
,
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){
767 dispatch_event(port
, type
, chan
, u
, v
,
768 tr
->port
, ev
->type
, tr
->chan
, ev
->u
, ev
->v
);
779 static void advance_play_head(unsigned samples
){
784 static int core_sequence(
790 unsigned sample_limit
793 get next event, or nothing, or loop end
796 event - if within sample_limit, advance and return 1
797 loop - if within sample_limit, advance, reset and return core_sequence
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
);
814 else if(kind
== 1){ /* event */
815 samples
= (tick
- now
) * D
/ N
;
816 advance_play_head(samples
);
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
;
829 else if(kind
== 2){ /* loop endpoint */
830 samples
= (tick
- now
) * D
/ N
;
831 advance_play_head(samples
);
833 error("core sequence");
835 //return core_sequence(...);
838 error("core_sequence: ???");
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)");
860 static void* default_malloc(size_t s
){
864 static void default_free(void* z
){
868 static void* qmalloc(size_t s
){
869 void* ptr
= malloc_ptr(s
);
871 if(out_of_memory_ptr() == 0){
878 "sequencer unable to recover from out of memory\n"
880 return emergency_storage
;
888 static void qfree(void* z
){
892 static void init_buffer(struct ring_buffer
* b
){
897 static void write_buffer(
898 struct ring_buffer
* b
,
905 struct buffer_slot s
= {p1
, p2
, p3
, p4
, p5
};
908 if(f
- k
== 1 || k
+BUFFER_SIZE
- f
== 1){
913 b
->back
= (k
+ 1) % BUFFER_SIZE
;
917 static int read_buffer(
918 struct ring_buffer
* b
,
937 b
->front
= (f
+ 1) % BUFFER_SIZE
;
942 static chunk_list
* mk_chunk_list(chunk
* ck
){
943 chunk_list
* ls
= qmalloc(sizeof(chunk_list
));
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
);
957 ptr2
->next
= mk_chunk_list(ptr
->ptr
);
958 chunk_refup(ptr
->ptr
);
965 static track
* mk_track(void){
966 track
* ptr
= qmalloc(sizeof(track
));
969 ptr
->blocks
= mk_block(0, 0, NULL
);
970 ptr
->block_ptr
= NULL
;
975 static block
* mk_block(unsigned tick
, unsigned length
, chunk
* ck
){
976 block
* ptr
= qmalloc(sizeof(block
));
978 ptr
->length
= length
;
979 ptr
->event_ptr
= NULL
;
981 ptr
->chunks
= mk_chunk_list(ck
);
982 ptr
->chunk_ptr
= ptr
->chunks
;
988 static void chunk_refup(chunk
* ck
){
992 static void chunk_refdown(chunk
* ck
){
993 event
* ptr
= ck
->events
;
997 if(ck
->ref_c
> 0) return;
1003 static int rfind_track(track
* tr
){
1004 track
* ptr
= the_tracks
->next
;
1007 if(ptr
== tr
) return i
;
1013 static track
* find_track(int n
){
1015 error("find_track?");
1019 static chunk
* find_chunk_by_tick(track
* tr
, unsigned tick
){
1021 error("find_chunk_by_tick?");
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
));
1042 static undo_op
* mk_undo_op(){
1043 undo_op
* op
= qmalloc(sizeof(undo_op
));
1046 op
->prev
= undo_ptr
;
1047 op
->redo
= dummy_undo
;
1048 op
->undo
= dummy_undo
;
1049 op
->collect
= dummy_undo
;
1058 static void dummy_undo(undo_op
* op
){
1062 static void undo_collect(){
1063 undo_op
* ptr
= undo_ptr
;
1064 undo_op
* prev
= NULL
;
1065 while(ptr
->next
!= NULL
){
1068 while(ptr
!= undo_ptr
){
1074 undo_ptr
->next
= NULL
;
1077 static void undo_push(undo_op
* op
){
1079 undo_ptr
->next
= op
;
1086 /* editting and uneditting procedures */
1089 static void redo_add_track(undo_op
* op
){
1091 track
* pred
= op
->v2
;
1092 if(pred
->next
!= NULL
){
1093 fprintf(stderr
, "add track inconsistent\n");
1099 static void undo_add_track(undo_op
* op
){
1101 track
* pred
= op
->v2
;
1102 if(tr
->next
!= NULL
){
1103 fprintf(stderr
, "undo add track inconsistent\n");
1109 static void collect_add_track(undo_op
* op
){
1111 qfree(tr
->blocks
->chunks
);
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
){
1123 track
* pred
= op
->v2
;
1124 tr
->next
= pred
->next
;
1128 static void collect_delete_track(undo_op
* op
){
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.
1137 static void redo_insert_block(undo_op
* op
){
1139 block
* pred
= op
->v2
;
1141 bl
->next
= pred
->next
;
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
){
1152 chunk_list
* ptr
= bl
->chunks
;
1157 chunk_refdown(ptr
->ptr
);
1166 static void redo_resize_block(undo_op
* op
){
1168 unsigned l2
= op
->p2
;
1172 static void undo_resize_block(undo_op
* op
){
1174 unsigned l1
= op
->p1
;
1178 static void collect_resize_block(undo_op
* op
){
1183 static void redo_delete_block(undo_op
* op
){
1184 block
* pred
= op
->v2
;
1186 pred
->next
= bl
->next
;
1189 static void undo_delete_block(undo_op
* op
){
1190 block
* pred
= op
->v2
;
1192 bl
->next
= pred
->next
;
1196 static void collect_delete_block(undo_op
* op
){
1201 static void redo_push_chunk(undo_op
* op
){
1202 chunk_list
* pred
= op
->v2
;
1203 chunk_list
* cl
= op
->v1
;
1209 static void undo_push_chunk(undo_op
* op
){
1210 chunk_list
* pred
= op
->v2
;
1212 chunk_list
* ptr
= bl
->chunks
;
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
);
1224 static void redo_rrotate_chunk(undo_op
* op
){
1226 if(bl
->chunk_ptr
->next
== NULL
){
1227 bl
->chunk_ptr
= bl
->chunks
;
1230 bl
->chunk_ptr
= bl
->chunk_ptr
->next
;
1234 static void undo_rrotate_chunk(undo_op
* op
){
1236 chunk_list
* cl
= bl
->chunks
;
1237 if(bl
->chunk_ptr
== bl
->chunks
){
1238 while(cl
->next
!= NULL
){
1244 while(cl
->next
!= bl
->chunk_ptr
){
1251 static void collect_rrotate_chunk(undo_op
* op
){
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
){
1267 static void redo_insert_event(undo_op
* op
){
1269 event
* pred
= op
->v2
;
1270 ev
->next
= pred
->next
;
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
){
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
){
1290 event
* pred
= op
->v2
;
1291 ev
->next
= pred
->next
;
1295 static void collect_delete_event(undo_op
* op
){
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.
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_
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
;
1349 unstick_frees
->next
= ptr
->next
;
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
;
1362 ptr
->port
== port
&&
1363 ptr
->chan
== chan
&&
1364 ptr
->note
== note
){
1366 ptr
->next
= found
->next
;
1367 found
->next
= unstick_frees
->next
;
1368 unstick_frees
->next
= found
;
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){
1386 unstick_stuck->next = ptr->next;
1387 ptr->next = unstick_frees->next;
1388 unstick_frees->next = ptr;
1396 static int calc_next_event(
1402 track
* tr
= the_tracks
->next
;
1405 event
* ev_min
= NULL
;
1408 unsigned now
= tick_now
;
1413 || bl
->event_ptr
->tick
+ bl
->tick
< ev_min
->tick
){
1418 *ticks_out
= ev
->tick
+ bl
->tick
- now
;
1426 *ticks_out
= loop_end
;
1433 else if(loop_flag
&& loop_end
< ev_min
->tick
+ bl
->tick
){
1434 *ticks_out
= loop_end
- now
;
1446 static void error(const char* msg
){
1447 fprintf(stderr
, msg
);