Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: m-labs/flickernoise
base: 3437cec^
...
head fork: m-labs/flickernoise
compare: e2bebe0
Checking mergeability… Don't worry, you can still create the pull request.
  • 12 commits
  • 13 files changed
  • 0 commit comments
  • 1 contributor
View
2  src/Makefile
@@ -61,7 +61,7 @@ ifeq ($(WITH_PDF),1)
endif
OBJS += $(addprefix translations/,french.o german.o)
OBJS += $(addprefix renderer/,framedescriptor.o analyzer.o sampler.o \
- eval.o line.o wave.o font.o osd.o raster.o renderer.o \
+ eval.o line.o wave.o font.o osd.o raster.o renderer.o stimuli.o \
videoinreconf.o)
OBJS += $(addprefix compiler/,compiler.o parser_helper.o scanner.o \
parser.o symtab.o)
View
35 src/compiler/compiler.c
@@ -187,13 +187,16 @@ static void all_initials_to_pfv(struct compiler_sc *sc)
static void pfv_bind_callback(void *_sc, struct fpvm_sym *sym, int reg)
{
struct compiler_sc *sc = _sc;
+ struct sym *s = FPVM2SYM(sym);
int pfv;
- pfv = pfv_from_sym(FPVM2SYM(sym));
+ pfv = pfv_from_sym(s);
if(pfv >= 0) {
pfv_update_patch_requires(sc, pfv);
sc->p->pfv_allocation[pfv] = reg;
}
+ if(s->cvar != -1)
+ sc->p->cvars[s->cvar].pfv_reg = reg;
}
static bool init_pfv(struct compiler_sc *sc)
@@ -265,13 +268,16 @@ static void pvv_update_patch_requires(struct compiler_sc *sc, int pvv)
static void pvv_bind_callback(void *_sc, struct fpvm_sym *sym, int reg)
{
struct compiler_sc *sc = _sc;
+ struct sym *s = FPVM2SYM(sym);
int pvv;
- pvv = pvv_from_sym(FPVM2SYM(sym));
+ pvv = pvv_from_sym(s);
if(pvv >= 0) {
pvv_update_patch_requires(sc, pvv);
sc->p->pvv_allocation[pvv] = reg;
}
+ if(s->cvar != -1)
+ sc->p->cvars[s->cvar].pvv_reg = reg;
}
static bool init_pvv(struct compiler_sc *sc)
@@ -483,6 +489,9 @@ struct patch *patch_compile(const char *basedir, const char *patch_code,
sc->p->require = 0;
sc->p->original = NULL;
sc->p->next = NULL;
+ sc->p->stim = NULL;
+ sc->p->ncvars = 0;
+ sc->p->cvars = NULL;
sc->basedir = basedir;
sc->rmc = rmc;
@@ -534,6 +543,18 @@ struct patch *patch_compile_filename(const char *filename,
return p;
}
+struct cvar *patch_add_cvar(struct patch *p)
+{
+ struct cvar *cv;
+
+ p->ncvars++;
+ p->cvars = realloc(p->cvars, sizeof(struct cvar)*p->ncvars);
+ cv = p->cvars+p->ncvars-1;
+ cv->val = 0;
+ cv->pfv_reg = cv->pvv_reg = -1;
+ return cv;
+}
+
#ifndef STANDALONE
struct patch *patch_copy(struct patch *p)
@@ -553,6 +574,14 @@ struct patch *patch_copy(struct patch *p)
img->filename = strdup(img->filename);
pixbuf_inc_ref(img->pixbuf);
}
+ new_patch->stim = stim_get(p->stim);
+ if(p->ncvars) {
+ size_t size = p->ncvars*sizeof(struct cvar);
+
+ new_patch->cvars = malloc(size);
+ memcpy(new_patch->cvars, p->cvars, size);
+ }
+ stim_redirect(p->stim, &p->cvars->val, &new_patch->cvars->val);
return new_patch;
}
@@ -567,6 +596,8 @@ void patch_free(struct patch *p)
pixbuf_dec_ref(img->pixbuf);
free((void *) img->filename);
}
+ stim_put(p->stim);
+ free(p->cvars);
free(p);
}
View
58 src/compiler/compiler.h
@@ -30,6 +30,7 @@
#include <fpvm/fpvm.h>
#include "../renderer/framedescriptor.h"
+#include "../renderer/stimuli.h"
#include "../pixbuf/pixbuf.h"
enum {
@@ -225,31 +226,56 @@ struct image {
struct stat st;
};
+struct cvar {
+ float val; /* current value */
+ int pfv_reg; /* per-frame register */
+ int pvv_reg; /* per-vertex register */
+};
+
struct patch {
/* per-frame */
- struct image images[IMAGE_COUNT]; /* < images used in this patch */
- float pfv_initial[COMP_PFV_COUNT]; /* < patch initial conditions */
- int pfv_allocation[COMP_PFV_COUNT]; /* < where per-frame variables are mapped in PFPU regf, -1 if unmapped */
- int perframe_prog_length; /* < how many instructions in perframe_prog */
- unsigned int perframe_prog[PFPU_PROGSIZE]; /* < PFPU per-frame microcode */
- float perframe_regs[PFPU_REG_COUNT]; /* < PFPU initial per-frame regf */
+ struct image images[IMAGE_COUNT]; /* images used in this patch */
+ float pfv_initial[COMP_PFV_COUNT]; /* patch initial conditions */
+ int pfv_allocation[COMP_PFV_COUNT]; /* where per-frame variables
+ are mapped in PFPU regf,
+ -1 if unmapped */
+ int perframe_prog_length; /* how many instructions in
+ perframe_prog */
+ unsigned int perframe_prog[PFPU_PROGSIZE];
+ /* PFPU per-frame microcode */
+ float perframe_regs[PFPU_REG_COUNT]; /* PFPU initial per-frame
+ register file */
/* per-vertex */
- int pvv_allocation[COMP_PVV_COUNT]; /* < where per-vertex variables are mapped in PFPU regf, -1 if unmapped */
- int pervertex_prog_length; /* < how many instructions in pervertex_prog */
- unsigned int pervertex_prog[PFPU_PROGSIZE]; /* < PFPU per-vertex microcode */
- float pervertex_regs[PFPU_REG_COUNT]; /* < PFPU initial per-vertex regf */
+ int pvv_allocation[COMP_PVV_COUNT]; /* where per-vertex variables
+ are mapped in PFPU regf,
+ -1 if unmapped */
+ int pervertex_prog_length; /* how many instructions in
+ pervertex_prog */
+ unsigned int pervertex_prog[PFPU_PROGSIZE];
+ /* PFPU per-vertex microcode */
+ float pervertex_regs[PFPU_REG_COUNT]; /* PFPU initial per-vertex
+ regf */
/* meta */
- unsigned int require; /* < bitmask: dmx, osc, midi, video */
- void *original; /* < original patch (with initial register values) */
- int ref; /* reference count */
- struct patch *next; /* < used when chaining patches in mashups */
+ unsigned int require; /* bitmask: dmx, osc, midi, video */
+ void *original; /* original patch (with initial register
+ values) */
+ int ref; /* reference count */
+ struct patch *next; /* used when chaining patches in mashups */
+
+ /* unified input events */
+ struct stimuli *stim; /* control variable hierarchy */
+ int ncvars; /* number of control variables */
+ struct cvar *cvars; /* control variables */
};
typedef void (*report_message)(const char *);
void init_fpvm(struct fpvm_fragment *fragment, int vector_mode);
-struct patch *patch_compile(const char *basedir, const char *patch_code, report_message rmc);
-struct patch *patch_compile_filename(const char *filename, const char *patch_code, report_message rmc);
+struct patch *patch_compile(const char *basedir, const char *patch_code,
+ report_message rmc);
+struct patch *patch_compile_filename(const char *filename,
+ const char *patch_code, report_message rmc);
+struct cvar *patch_add_cvar(struct patch *p);
struct patch *patch_copy(struct patch *p);
void patch_free(struct patch *p);
struct patch *patch_refresh(struct patch *p);
View
1  src/compiler/idgen
@@ -51,6 +51,7 @@ sed 's/#.*//;/^ *$/d' $1 | LANG=C sort | {
.pfv_idx = $2,
.pvv_idx = $3,
.flags = SF_SYSTEM,
+ .cvar = -1,
},
EOF
i=`expr $i + 1`
View
33 src/compiler/parser.y
@@ -28,9 +28,9 @@
#include <fpvm/fpvm.h>
#include "symtab.h"
+#include "parser.h"
#include "parser_itf.h"
#include "parser_helper.h"
-#include "parser.h"
struct yyParser;
@@ -295,6 +295,36 @@ assignment ::= ident(I) TOK_ASSIGN expr(N) opt_semi. {
parse_free(N);
}
+assignment ::= ident(I) TOK_ASSIGN TOK_MIDI TOK_LPAREN expr(A) TOK_COMMA
+ expr(B) TOK_RPAREN opt_semi. {
+ /* @@@ clean up this mess later */
+ struct patch *p = *(struct patch **) state->comm->u.sc;
+ struct sym *sym = I->sym;
+ struct cvar *cvar;
+
+ free(I);
+ if(sym->cvar != -1) {
+ FAIL("duplicate control variable");
+ return;
+ }
+ if(A->op != op_constant || B->op != op_constant) {
+ FAIL("midi(chan, ctrl) arguments must be constants");
+ return;
+ }
+ cvar = patch_add_cvar(p);
+ sym->cvar = cvar-p->cvars;
+ if(!p->stim)
+ p->stim = stim_new();
+ /* @@@ check range ! */
+ if(!stim_add(p->stim, A->contents.constant, B->contents.constant,
+ &cvar->val, midi_proc_lin)) {
+ FAIL("stim_add failed\n");
+ return;
+ }
+ parse_free(A);
+ parse_free(B);
+}
+
assignment ::= TOK_IMAGEFILE(I) TOK_ASSIGN TOK_FNAME(N). {
const char *msg;
@@ -581,6 +611,7 @@ ident(O) ::= unary_misc(I). { O = symbolify(I); }
ident(O) ::= binary(I). { O = symbolify(I); }
ident(O) ::= binary_misc(I). { O = symbolify(I); }
ident(O) ::= ternary(I). { O = symbolify(I); }
+ident(O) ::= TOK_MIDI(I). { O = symbolify(I); }
unary_misc(O) ::= TOK_ABS(I). { O = I; }
unary_misc(O) ::= TOK_COS(I). { O = I; }
View
5 src/compiler/ptest/Makefile
@@ -5,7 +5,7 @@ LIBFPVM_X86 = $(MMDIR)/software/libfpvm/x86-linux
CFLAGS_STANDALONE = -DSTANDALONE=\"standalone.h\"
CFLAGS = -Wall -g -I.. -I. $(CFLAGS_STANDALONE)
OBJS = ptest.o scanner.o parser.o parser_helper.o symtab.o compiler.o \
- libfpvm.a
+ stimuli.o libfpvm.a
LDLIBS = -lm
# ----- Verbosity control -----------------------------------------------------
@@ -42,6 +42,9 @@ ptest: $(OBJS)
%.o: ../%.c
$(CC) $(CFLAGS) -c -o $@ $<
+stimuli.o: ../../renderer/stimuli.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
%.c: %.re
$(GEN) re2c -c -o $@ $<
View
2  src/compiler/scanner.re
@@ -130,6 +130,8 @@ int scan(struct scanner *s)
<N>"per_pixel"[a-z_0-9]*
{ return TOK_PER_PIXEL_UGLY; }
+ <N>"midi" { return TOK_MIDI; }
+
<N>"imagefile"[1-9] { YYSETCONDITION(yycFNAME1);
return TOK_IMAGEFILE; }
View
2  src/compiler/symtab.c
@@ -107,6 +107,7 @@ struct sym *unique(const char *s)
new->fpvm_sym.name = strdup(s);
new->pfv_idx = new->pvv_idx = -1;
new->flags = 0;
+ new->cvar = -1;
return new;
}
@@ -132,6 +133,7 @@ struct sym *unique_n(const char *s, int n)
new->fpvm_sym.name = strdup_n(s, n);
new->pfv_idx = new->pvv_idx = -1;
new->flags = 0;
+ new->cvar = -1;
return new;
}
View
2  src/compiler/symtab.h
@@ -12,6 +12,7 @@
#define SYMTAB_H
#include <fpvm/symbol.h>
+#include "compiler.h"
#define SF_SYSTEM (1 << 0)
@@ -21,6 +22,7 @@
struct sym {
struct fpvm_sym fpvm_sym;
int pfv_idx, pvv_idx; /* index; -1 if not a variable known to FN */
+ int cvar; /* -1 if not a control variable */
int flags;
};
View
13 src/renderer/eval.c
@@ -58,6 +58,8 @@ static void write_pvv(struct patch *p, int pvv, float x)
static void transfer_pvv_regs(struct patch *p)
{
+ const struct cvar *cv;
+
write_pvv(p, pvv_texsize, renderer_texsize << TMU_FIXEDPOINT_SHIFT);
write_pvv(p, pvv_hmeshsize, 1.0/(float)renderer_hmeshlast);
write_pvv(p, pvv_vmeshsize, 1.0/(float)renderer_vmeshlast);
@@ -115,6 +117,10 @@ static void transfer_pvv_regs(struct patch *p)
write_pvv(p, pvv_midi6, read_pfv(p, pfv_midi6));
write_pvv(p, pvv_midi7, read_pfv(p, pfv_midi7));
write_pvv(p, pvv_midi8, read_pfv(p, pfv_midi8));
+
+ for(cv = p->cvars; cv != p->cvars+p->ncvars; cv++)
+ if(cv->pvv_reg >= 0)
+ p->pervertex_regs[cv->pvv_reg] = cv->val;
}
static void reinit_pfv(struct patch *p, int pfv)
@@ -129,12 +135,15 @@ static void reinit_pfv(struct patch *p, int pfv)
static void reinit_all_pfv(struct patch *p)
{
int i;
+
for(i=0;i<COMP_PFV_COUNT;i++)
reinit_pfv(p, i);
}
static void set_pfv_from_frd(struct patch *p, struct frame_descriptor *frd)
{
+ const struct cvar *cv;
+
write_pfv(p, pfv_time, frd->time);
write_pfv(p, pfv_frame, frd->frame);
write_pfv(p, pfv_bass, frd->bass);
@@ -166,6 +175,10 @@ static void set_pfv_from_frd(struct patch *p, struct frame_descriptor *frd)
write_pfv(p, pfv_midi6, frd->midi[5]);
write_pfv(p, pfv_midi7, frd->midi[6]);
write_pfv(p, pfv_midi8, frd->midi[7]);
+
+ for(cv = p->cvars; cv != p->cvars+p->ncvars; cv++)
+ if(cv->pfv_reg >= 0)
+ p->perframe_regs[cv->pfv_reg] = cv->val;
}
static void set_frd_from_pfv(struct patch *p, struct frame_descriptor *frd)
View
51 src/renderer/sampler.c
@@ -31,6 +31,8 @@
#include "../osc.h"
#include "../config.h"
#include "../input.h"
+#include "renderer.h"
+#include "stimuli.h"
#include "sampler.h"
struct snd_history {
@@ -261,19 +263,52 @@ static rtems_task sampler_task(rtems_task_argument argument)
rtems_task_delete(RTEMS_SELF);
}
+static void midi_ctrl_event(struct patch *p, mtk_event *e)
+{
+ int chan, ctrl, value;
+
+ chan = (e->press.code & 0x0f0000) >> 16;
+ ctrl = (e->press.code & 0x7f00) >> 8;
+ value = e->press.code & 0x7f;
+
+ if(chan == midi_channel)
+ midi_controllers[ctrl] = value;
+ stim_midi_ctrl(p->stim, chan, ctrl, value);
+}
+
+/*
+ * @@@ convert pitch events to stimuli later. Need to decide whether giving
+ * them another stimulus type or using the control #128 hack.
+ */
+
+static void midi_pitch_event(mtk_event *e)
+{
+ int chan, value;
+
+ chan = (e->press.code & 0x0f0000) >> 16;
+ value = e->press.code & 0x7f;
+
+ if(chan == midi_channel)
+ midi_controllers[128] = value;
+}
+
static void event_callback(mtk_event *e, int count)
{
+ struct patch *p;
int i;
- for(i=0;i<count;i++) {
- if(e[i].type == EVENT_TYPE_MIDI_CONTROLLER) {
- if(((e[i].press.code & 0x0f0000) >> 16) == midi_channel)
- midi_controllers[(e[i].press.code & 0x7f00) >> 8] = e[i].press.code & 0x7f;
- } else if(e[i].type == EVENT_TYPE_MIDI_PITCH) {
- if(((e[i].press.code & 0x0f0000) >> 16) == midi_channel)
- midi_controllers[128] = e[i].press.code & 0x7f;
+ renderer_lock_patch();
+ p = renderer_get_patch(0);
+ for(i=0;i<count;i++)
+ switch(e[i].type) {
+ case EVENT_TYPE_MIDI_CONTROLLER:
+ midi_ctrl_event(p, e+i);
+ break;
+ case EVENT_TYPE_MIDI_PITCH:
+ midi_pitch_event(e+i);
+ break;
}
- }
+ renderer_unlock_patch();
}
static rtems_id sampler_task_id;
View
126 src/renderer/stimuli.c
@@ -0,0 +1,126 @@
+/*
+ * stimuli.c - Unified control input handling
+ *
+ * Copyright 2012 by Werner Almesberger
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "stimuli.h"
+
+
+void midi_proc_lin(struct s_midi_ctrl *ct, int value)
+{
+ *ct->var = (float) value/127.0;
+}
+
+
+void midi_proc_accel(struct s_midi_ctrl *ct, int value)
+{
+ if(value < 64) {
+ ct->last += value;
+ if(ct->last > 127)
+ ct->last = 127;
+ } else {
+ ct->last -= 128-value;
+ if(ct->last & 0x80)
+ ct->last = 0;
+ }
+ *ct->var = (float) ct->last/127.0;
+}
+
+
+void stim_midi_ctrl(struct stimuli *s, int chan, int ctrl, int value)
+{
+ struct s_midi_ctrl *ct;
+
+ if(s && s->midi[chan]) {
+ ct = s->midi[chan]->ctrl[ctrl];
+ if(ct)
+ ct->proc(ct, value);
+ }
+}
+
+
+int stim_add(struct stimuli *s, int chan, int ctrl, float *var,
+ void (*proc)(struct s_midi_ctrl *ct, int value))
+{
+ struct s_midi_chan *ch;
+ struct s_midi_ctrl *ct;
+
+ if(!s->midi[chan]) {
+ s->midi[chan] = calloc(1, sizeof(struct s_midi_chan));
+ if(!s->midi[chan])
+ return 0;
+ }
+ ch = s->midi[chan];
+
+ if(!ch->ctrl[ctrl]) {
+ ch->ctrl[ctrl] = calloc(1, sizeof(struct s_midi_ctrl));
+ if(!ch->ctrl[ctrl])
+ return 0;
+ }
+ ct = ch->ctrl[ctrl];
+
+ ct->proc = proc;
+ ct->var = var;
+
+ return 1;
+}
+
+
+struct stimuli *stim_new(void)
+{
+ struct stimuli *s;
+
+ s = calloc(1, sizeof(struct stimuli));
+ if(s)
+ s->ref = 1;
+ return s;
+}
+
+
+struct stimuli *stim_get(struct stimuli *s)
+{
+ if(s)
+ s->ref++;
+ return s;
+}
+
+void stim_put(struct stimuli *s)
+{
+ int i, j;
+
+ if(!s)
+ return;
+ if(--s->ref)
+ return;
+ for(i = 0; i != MIDI_CHANS; i++)
+ if(s->midi[i]) {
+ for(j = 0; j != MIDI_CTRLS; j++)
+ free(s->midi[i]->ctrl[j]);
+ free(s->midi[i]);
+ }
+ free(s);
+}
+
+void stim_redirect(struct stimuli *s, const float *old, float *new)
+{
+ int i, j;
+ struct s_midi_ctrl *ct;
+
+ if(!s)
+ return;
+ for(i = 0; i != MIDI_CHANS; i++)
+ if(s->midi[i])
+ for(j = 0; j != MIDI_CTRLS; j++) {
+ ct = s->midi[i]->ctrl[j];
+ if (ct)
+ ct->var = new+(ct->var-old);
+ }
+}
View
51 src/renderer/stimuli.h
@@ -0,0 +1,51 @@
+/*
+ * stimuli.h - Unified control input handling
+ *
+ * Copyright 2012 by Werner Almesberger
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ */
+
+#ifndef STIMULI_H
+#define STIMULI_H
+
+#include <stdint.h>
+
+
+#define MIDI_CHANS 16
+#define MIDI_CTRLS 128
+
+
+struct s_midi_ctrl {
+ void (*proc)(struct s_midi_ctrl *sct, int value);
+ float *var;
+ uint8_t last; /* for midi_proc_accel */
+};
+
+struct s_midi_chan {
+ struct s_midi_ctrl *ctrl[MIDI_CTRLS];
+};
+
+struct stimuli {
+ struct s_midi_chan *midi[MIDI_CHANS];
+ int ref;
+};
+
+
+/* Linear mapping [0, 127] -> [0, 1] */
+void midi_proc_lin(struct s_midi_ctrl *ct, int value);
+
+/* "Acceleration" (signed 7 bit delta value) with linear mapping */
+void midi_proc_accel(struct s_midi_ctrl *ct, int value);
+
+void stim_midi_ctrl(struct stimuli *s, int chan, int ctrl, int value);
+int stim_add(struct stimuli *s, int chan, int ctrl, float *var,
+ void (*proc)(struct s_midi_ctrl *ct, int value));
+struct stimuli *stim_new(void);
+struct stimuli *stim_get(struct stimuli *s);
+void stim_put(struct stimuli *s);
+void stim_redirect(struct stimuli *s, const float *old, float *new);
+
+#endif /* STIMULI_H */

No commit comments for this range

Something went wrong with that request. Please try again.