Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Patch mashup support

  • Loading branch information...
commit 010cf38f19549c380c4429cb39114de358265309 1 parent 8df771b
Sébastien Bourdeauducq authored November 13, 2011
5  src/compiler.c
@@ -189,8 +189,6 @@ static void load_defaults(struct compiler_sc *sc)
189 189
 {
190 190
 	int i;
191 191
 
192  
-	sc->p->require = 0;
193  
-
194 192
 	for(i=0;i<COMP_PFV_COUNT;i++)
195 193
 		sc->p->pfv_initial[i] = 0.0;
196 194
 	sc->p->pfv_initial[pfv_sx] = 1.0;
@@ -650,6 +648,9 @@ struct patch *patch_compile(const char *patch_code, report_message rmc)
650 648
 		free(sc);
651 649
 		return NULL;
652 650
 	}
  651
+	sc->p->require = 0;
  652
+	sc->p->original = NULL;
  653
+	sc->p->next = NULL;
653 654
 
654 655
 	sc->rmc = rmc;
655 656
 	sc->linenr = 0;
6  src/compiler.h
@@ -198,7 +198,6 @@ enum {
198 198
 #define REQUIRE_VIDEO	(1 << 3)
199 199
 
200 200
 struct patch {
201  
-	unsigned int require;				/* < bitmask: dmx, osc, midi, video */
202 201
 	/* per-frame */
203 202
 	float pfv_initial[COMP_PFV_COUNT]; 		/* < patch initial conditions */
204 203
 	int pfv_allocation[COMP_PFV_COUNT];		/* < where per-frame variables are mapped in PFPU regf, -1 if unmapped */
@@ -210,6 +209,11 @@ struct patch {
210 209
 	int pervertex_prog_length;			/* < how many instructions in pervertex_prog */
211 210
 	unsigned int pervertex_prog[PFPU_PROGSIZE];	/* < PFPU per-vertex microcode */
212 211
 	float pervertex_regs[PFPU_REG_COUNT];		/* < PFPU initial per-vertex regf */
  212
+	/* meta */
  213
+	unsigned int require;				/* < bitmask: dmx, osc, midi, video */
  214
+	void *original;					/* < original patch (with initial register values) */
  215
+	struct patch *next;				/* < used when chaining patches in mashups */
  216
+
213 217
 };
214 218
 
215 219
 typedef void (*report_message)(const char *);
2  src/eval.c
@@ -293,7 +293,7 @@ static rtems_task eval_task(rtems_task_argument argument)
293 293
 
294 294
 		renderer_lock_patch();
295 295
 
296  
-		p = renderer_get_patch();
  296
+		p = renderer_get_patch(1);
297 297
 
298 298
 		reinit_all_pfv(p);
299 299
 		set_pfv_from_frd(p, frd);
4  src/input.c
@@ -240,6 +240,10 @@ static int handle_midi_msg(mtk_event *e, unsigned char *msg)
240 240
 			e->type = EVENT_TYPE_MIDI_NOTEON;
241 241
 			e->press.code |= msg[1];
242 242
 			return 1;
  243
+		case 0x80: /* Note Off */
  244
+			e->type = EVENT_TYPE_MIDI_NOTEOFF;
  245
+			e->press.code |= msg[1];
  246
+			return 1;
243 247
 		case 0xb0: /* Controller */
244 248
 			e->type = EVENT_TYPE_MIDI_CONTROLLER;
245 249
 			e->press.code |= (msg[1] << 8) | msg[2];
7  src/input.h
@@ -22,9 +22,10 @@
22 22
 
23 23
 #define EVENT_TYPE_IR              (EVENT_TYPE_USER_BASE)
24 24
 #define EVENT_TYPE_MIDI_NOTEON     (EVENT_TYPE_USER_BASE+1)
25  
-#define EVENT_TYPE_MIDI_CONTROLLER (EVENT_TYPE_USER_BASE+2)
26  
-#define EVENT_TYPE_MIDI_PITCH      (EVENT_TYPE_USER_BASE+3)
27  
-#define EVENT_TYPE_OSC             (EVENT_TYPE_USER_BASE+4)
  25
+#define EVENT_TYPE_MIDI_NOTEOFF    (EVENT_TYPE_USER_BASE+2)
  26
+#define EVENT_TYPE_MIDI_CONTROLLER (EVENT_TYPE_USER_BASE+3)
  27
+#define EVENT_TYPE_MIDI_PITCH      (EVENT_TYPE_USER_BASE+4)
  28
+#define EVENT_TYPE_OSC             (EVENT_TYPE_USER_BASE+5)
28 29
 
29 30
 typedef void (*input_callback)(mtk_event *e, int count);
30 31
 
83  src/performance.c
@@ -49,9 +49,9 @@ struct patch_info {
49 49
 };
50 50
 
51 51
 static int npatches;
52  
-static int current_patch;
53 52
 static struct patch_info patches[MAX_PATCHES];
54 53
 static int simple_mode;
  54
+static int simple_mode_current;
55 55
 static int dt_mode;
56 56
 static int as_mode;
57 57
 static int input_video;
@@ -82,7 +82,7 @@ static void add_firstpatch()
82 82
 
83 83
 	filename = config_read_string("firstpatch");
84 84
 	if(filename == NULL) return;
85  
-	current_patch = add_patch(filename);
  85
+	add_patch(filename);
86 86
 }
87 87
 
88 88
 static void add_keyboard_patches()
@@ -393,6 +393,8 @@ static void event_callback(mtk_event *e, int count)
393 393
 		next = 0;
394 394
 		for(i=0;i<count;i++) {
395 395
 			if(e[i].type == EVENT_TYPE_PRESS) {
  396
+				if(e[i].press.code == MTK_KEY_F1)
  397
+					osd_event(patches[simple_mode_current].filename);
396 398
 				if(e[i].press.code == MTK_KEY_F11)
397 399
 					next = 1;
398 400
 				if(e[i].press.code == MTK_KEY_F9)
@@ -405,15 +407,15 @@ static void event_callback(mtk_event *e, int count)
405 407
 				next = 1;
406 408
 		}
407 409
 		if(next) {
408  
-			looped = current_patch;
  410
+			looped = simple_mode_current;
409 411
 			do {
410  
-				current_patch += next;
411  
-				if(current_patch == npatches)
412  
-					current_patch = 0;
413  
-				if(current_patch < 0)
414  
-					current_patch = npatches - 1;
415  
-			} while(!suitable_for_simple(patches[current_patch].p) && (looped != current_patch));
416  
-			index = current_patch;
  412
+				simple_mode_current += next;
  413
+				if(simple_mode_current == npatches)
  414
+					simple_mode_current = 0;
  415
+				if(simple_mode_current < 0)
  416
+					simple_mode_current = npatches - 1;
  417
+			} while(!suitable_for_simple(patches[simple_mode_current].p) && (looped != simple_mode_current));
  418
+			renderer_pulse_patch(patches[simple_mode_current].p);
417 419
 			if(as_mode)
418 420
 				update_next_as_time();
419 421
 		}
@@ -423,31 +425,43 @@ static void event_callback(mtk_event *e, int count)
423 425
 		for(i=0;i<count;i++) {
424 426
 			if(e[i].type == EVENT_TYPE_PRESS) {
425 427
 				index = keycode_to_index(e[i].press.code);
426  
-				if(index != -1)
  428
+				if(index != -1) {
  429
+					index = keyboard_patches[index];
  430
+					renderer_add_patch(patches[index].p);
  431
+				}
  432
+			} else if(e[i].type == EVENT_TYPE_RELEASE) {
  433
+				index = keycode_to_index(e[i].release.code);
  434
+				if(index != -1) {
427 435
 					index = keyboard_patches[index];
  436
+					renderer_del_patch(patches[index].p);
  437
+				}
428 438
 			} else if(e[i].type == EVENT_TYPE_IR) {
429 439
 				index = e[i].press.code;
430 440
 				index = ir_patches[index];
  441
+				if(index != -1)
  442
+					renderer_pulse_patch(patches[index].p);
431 443
 			} else if(e[i].type == EVENT_TYPE_MIDI_NOTEON) {
432 444
 				if(((e[i].press.code & 0x0f0000) >> 16) == midi_channel) {
433 445
 					index = e[i].press.code & 0x7f;
434 446
 					index = midi_patches[index];
  447
+					if(index != -1)
  448
+						renderer_add_patch(patches[index].p);
  449
+				}
  450
+			} else if(e[i].type == EVENT_TYPE_MIDI_NOTEOFF) {
  451
+				if(((e[i].press.code & 0x0f0000) >> 16) == midi_channel) {
  452
+					index = e[i].press.code & 0x7f;
  453
+					index = midi_patches[index];
  454
+					if(index != -1)
  455
+						renderer_del_patch(patches[index].p);
435 456
 				}
436 457
 			} else if(e[i].type == EVENT_TYPE_OSC) {
437 458
 				index = e[i].press.code & 0x3f;
438 459
 				index = osc_patches[index];
  460
+				if(index != -1)
  461
+					renderer_pulse_patch(patches[index].p);
439 462
 			}
440 463
 		}
441 464
 	}
442  
-	if(index != -1) {
443  
-		current_patch = index;
444  
-		renderer_set_patch(patches[current_patch].p);
445  
-	}
446  
-
447  
-	for(i=0;i<count;i++) {
448  
-		if((e[i].type == EVENT_TYPE_PRESS) && (e[i].press.code == MTK_KEY_F1))
449  
-			osd_event(patches[current_patch].filename);
450  
-	}
451 465
 }
452 466
 
453 467
 static void stop_callback()
@@ -461,6 +475,7 @@ static void refresh_callback(mtk_event *e, int count)
461 475
 {
462 476
 	rtems_interval t;
463 477
 	int looped;
  478
+	int index;
464 479
 	
465 480
 	t = rtems_clock_get_ticks_since_boot();
466 481
 	if(t >= next_update) {
@@ -472,17 +487,21 @@ static void refresh_callback(mtk_event *e, int count)
472 487
 				update_next_as_time();
473 488
 				input_add_callback(event_callback);
474 489
 				mtk_cmd(appid, "l_status.set(-text \"Ready.\")");
475  
-
476  
-				looped = current_patch;
477  
-				while(!suitable_for_simple(patches[current_patch].p)) {
478  
-					current_patch++;
479  
-					if(current_patch == npatches)
480  
-						current_patch = 0;
481  
-					if(looped == current_patch)
482  
-						break;
483  
-				}
484  
-
485  
-				if(!guirender(appid, patches[current_patch].p, stop_callback))
  490
+				
  491
+				if(simple_mode) {
  492
+					looped = simple_mode_current;
  493
+					while(!suitable_for_simple(patches[simple_mode_current].p)) {
  494
+						simple_mode_current++;
  495
+						if(simple_mode_current == npatches)
  496
+							simple_mode_current = 0;
  497
+						if(looped == simple_mode_current)
  498
+							break;
  499
+					}
  500
+					index = simple_mode_current;
  501
+				} else
  502
+					index = 0;
  503
+
  504
+				if(!guirender(appid, patches[index].p, stop_callback))
486 505
 					stop_callback();
487 506
 				return;
488 507
 			}
@@ -540,7 +559,7 @@ void start_performance(int simple, int dt, int as)
540 559
 
541 560
 	/* build patch list */
542 561
 	npatches = 0;
543  
-	current_patch = 0;
  562
+	simple_mode_current = 0;
544 563
 	if(simple) {
545 564
 		input_video = check_input_video();
546 565
 		add_simple_patches();
113  src/renderer.c
... ...
@@ -1,6 +1,6 @@
1 1
 /*
2 2
  * Flickernoise
3  
- * Copyright (C) 2010 Sebastien Bourdeauducq
  3
+ * Copyright (C) 2010, 2011 Sebastien Bourdeauducq
4 4
  *
5 5
  * This program is free software: you can redistribute it and/or modify
6 6
  * it under the terms of the GNU General Public License as published by
@@ -35,6 +35,8 @@ int renderer_vmeshlast;
35 35
 int renderer_squarew;
36 36
 int renderer_squareh;
37 37
 
  38
+static int mashup_en;
  39
+static struct patch *mashup_head;
38 40
 static struct patch *current_patch;
39 41
 static rtems_id patch_lock;
40 42
 
@@ -48,29 +50,108 @@ void renderer_unlock_patch()
48 50
 	rtems_semaphore_release(patch_lock);
49 51
 }
50 52
 
51  
-void renderer_set_patch(struct patch *p)
  53
+static struct patch *copy_patch(struct patch *p)
52 54
 {
53 55
 	struct patch *new_patch;
54  
-	struct patch *old_patch;
55  
-
  56
+	
56 57
 	/* Copy memory as the patch will be modified
57 58
 	 * by the evaluator (current regs).
58 59
 	 */
59  
-
60  
-	old_patch = current_patch;
61 60
 	new_patch = malloc(sizeof(struct patch));
62 61
 	assert(new_patch != NULL);
63 62
 	memcpy(new_patch, p, sizeof(struct patch));
  63
+	new_patch->original = p;
  64
+	new_patch->next = NULL;
  65
+	return new_patch;
  66
+}
  67
+
  68
+void renderer_pulse_patch(struct patch *p)
  69
+{
  70
+	struct patch *oldpatch;
  71
+	
  72
+	renderer_lock_patch();
  73
+	if(!mashup_en && (mashup_head->next == NULL)) {
  74
+		oldpatch = mashup_head;
  75
+		mashup_head = copy_patch(p);
  76
+		current_patch = mashup_head;
  77
+		free(oldpatch);
  78
+	}
  79
+	renderer_unlock_patch();
  80
+}
64 81
 
  82
+void renderer_add_patch(struct patch *p)
  83
+{
  84
+	struct patch *p1;
  85
+	struct patch *new_patch;
  86
+	
65 87
 	renderer_lock_patch();
66  
-	current_patch = new_patch;
  88
+	p1 = mashup_head;
  89
+	while(p1 != NULL) {
  90
+		if(p1->original == p) {
  91
+			renderer_unlock_patch();
  92
+			return;
  93
+		}
  94
+		p1 = p1->next;
  95
+	}
  96
+	new_patch = copy_patch(p);
  97
+	if(!mashup_en) {
  98
+		p1 = mashup_head;
  99
+		mashup_head = new_patch;
  100
+		current_patch = mashup_head;
  101
+		free(p1);
  102
+	} else {
  103
+		new_patch->next = mashup_head;
  104
+		mashup_head = new_patch;
  105
+	}
  106
+	mashup_en++;
67 107
 	renderer_unlock_patch();
  108
+}
68 109
 
69  
-	free(old_patch);
  110
+void renderer_del_patch(struct patch *p)
  111
+{
  112
+	struct patch *p1, *p2;
  113
+	
  114
+	renderer_lock_patch();
  115
+	mashup_en--;
  116
+	if(mashup_en < 0)
  117
+		mashup_en = 0;
  118
+	/* Never delete the only patch */
  119
+	if(mashup_head->next == NULL) {
  120
+		renderer_unlock_patch();
  121
+		return;
  122
+	}
  123
+	if(mashup_head->original == p) {
  124
+		if(mashup_head == current_patch)
  125
+			renderer_get_patch(1);
  126
+		p1 = mashup_head->next;
  127
+		free(mashup_head);
  128
+		mashup_head = p1;
  129
+	} else {
  130
+		p1 = mashup_head;
  131
+		while((p1->next != NULL) && (p1->next->original != p))
  132
+			p1 = p1->next;
  133
+		if(p1->next == NULL) {
  134
+			/* not found */
  135
+			renderer_unlock_patch();
  136
+			return;
  137
+		}
  138
+		if(p1->next == current_patch)
  139
+			renderer_get_patch(1);
  140
+		p2 = p1->next->next;
  141
+		free(p1->next);
  142
+		p1->next = p2;
  143
+	}
  144
+	renderer_unlock_patch();
70 145
 }
71 146
 
72  
-struct patch *renderer_get_patch()
  147
+struct patch *renderer_get_patch(int spin)
73 148
 {
  149
+	if(spin) {
  150
+		if(current_patch->next == NULL)
  151
+			current_patch = mashup_head;
  152
+		else
  153
+			current_patch = current_patch->next;
  154
+	}
74 155
 	return current_patch;
75 156
 }
76 157
 
@@ -87,7 +168,10 @@ void renderer_start(int framebuffer_fd, struct patch *p)
87 168
 	);
88 169
 	assert(sc == RTEMS_SUCCESSFUL);
89 170
 
90  
-	renderer_set_patch(p);
  171
+	assert(mashup_head == NULL);
  172
+	mashup_head = copy_patch(p);
  173
+	current_patch = mashup_head;
  174
+	mashup_en = 0;
91 175
 
92 176
 	renderer_texsize = 512;
93 177
 	renderer_hmeshlast = 32;
@@ -104,12 +188,17 @@ void renderer_start(int framebuffer_fd, struct patch *p)
104 188
 
105 189
 void renderer_stop()
106 190
 {
  191
+	struct patch *p;
  192
+	
107 193
 	rsswall_stop();
108 194
 	sampler_stop();
109 195
 	eval_stop();
110 196
 	raster_stop();
111 197
 
112  
-	free(current_patch);
113  
-	current_patch = NULL;
  198
+	while(mashup_head != NULL) {
  199
+		p = mashup_head->next;
  200
+		free(mashup_head);
  201
+		mashup_head = p;
  202
+	}
114 203
 	rtems_semaphore_delete(patch_lock);
115 204
 }
14  src/renderer.h
@@ -26,11 +26,21 @@ extern int renderer_vmeshlast;
26 26
 extern int renderer_squarew;
27 27
 extern int renderer_squareh;
28 28
 
  29
+/*
  30
+ * Synchronization:
  31
+ * 1. call renderer_lock_patch()
  32
+ * 2. call renderer_get_patch()
  33
+ * 3. use the returned patch
  34
+ * 4. call renderer_unlock_patch()
  35
+ */
  36
+
29 37
 void renderer_lock_patch();
30 38
 void renderer_unlock_patch();
31 39
 
32  
-void renderer_set_patch(struct patch *p);
33  
-struct patch *renderer_get_patch();
  40
+void renderer_pulse_patch(struct patch *p);
  41
+void renderer_add_patch(struct patch *p);
  42
+void renderer_del_patch(struct patch *p);
  43
+struct patch *renderer_get_patch(int spin);
34 44
 
35 45
 void renderer_start(int framebuffer_fd, struct patch *p);
36 46
 void renderer_stop();

0 notes on commit 010cf38

Please sign in to comment.
Something went wrong with that request. Please try again.