aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2017-03-21 14:54:05 +0100
committerHanspeter Portner <dev@open-music-kontrollers.ch>2017-03-21 14:54:05 +0100
commitf3d77a9c079754914ebe1ccdfc58d0df953be8b8 (patch)
tree81de623f1457a5c5e7ed4dd7994d12ab5e5de98a
parent11088137929d6cff5e53daf76b16cbdc0471a729 (diff)
downloadvm.lv2-f3d77a9c079754914ebe1ccdfc58d0df953be8b8.tar.xz
implement time extension.
-rw-r--r--VERSION2
-rw-r--r--timely.lv2/timely.h3
-rw-r--r--vm.c85
-rw-r--r--vm.h6
-rw-r--r--vm.ttl6
-rw-r--r--vm_ui.c9
6 files changed, 74 insertions, 37 deletions
diff --git a/VERSION b/VERSION
index 1c427ff..9ce3f90 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.2813
+0.1.2845
diff --git a/timely.lv2/timely.h b/timely.lv2/timely.h
index 0cdf679..4e6b28d 100644
--- a/timely.lv2/timely.h
+++ b/timely.lv2/timely.h
@@ -341,6 +341,9 @@ timely_advance_body(timely_t *timely, uint32_t size, uint32_t type,
timely->cb(timely, i, timely->urid.time_barBeat, timely->data);
}
+ if( (timely->mask & TIMELY_MASK_FRAME) && (update_frame != i) )
+ timely->cb(timely, (update_frame = i), timely->urid.time_frame, timely->data);
+
timely->offset.bar += 1;
timely->offset.beat += 1;
timely->pos.frame += 1;
diff --git a/vm.c b/vm.c
index c45cedc..da5adf4 100644
--- a/vm.c
+++ b/vm.c
@@ -65,14 +65,13 @@ struct _plughandle_t {
vm_api_impl_t api [OP_MAX];
vm_stack_t stack;
- bool recalc;
- bool sync;
- bool is_dynamic;
+ bool needs_recalc;
+ bool needs_sync;
+ bool uses_time;
command_t cmds [ITEMS_MAX];
- num_t srate;
- int64_t frame;
+ timely_t timely;
};
static inline void
@@ -131,12 +130,13 @@ _intercept_graph(void *data, LV2_Atom_Forge *forge, int64_t frames,
plughandle_t *handle = data;
handle->graph_size = impl->value.size;
- handle->recalc = true;
+ handle->needs_recalc = true;
- handle->is_dynamic = vm_deserialize(handle->api, &handle->forge, handle->cmds,
+ handle->uses_time = vm_deserialize(handle->api, &handle->forge, handle->cmds,
impl->value.size, impl->value.body);
- handle->sync = true;
+ handle->needs_sync = true;
+ handle->needs_recalc = true;
}
static const props_def_t defs [MAX_NPROPS] = {
@@ -150,6 +150,15 @@ static const props_def_t defs [MAX_NPROPS] = {
}
};
+static void
+_cb(timely_t *timely, int64_t frames, LV2_URID type, void *data)
+{
+ plughandle_t *handle = data;
+
+ if(handle->uses_time)
+ handle->needs_recalc = true;
+}
+
static LV2_Handle
instantiate(const LV2_Descriptor* descriptor, num_t rate,
const char *bundle_path, const LV2_Feature *const *features)
@@ -181,6 +190,17 @@ instantiate(const LV2_Descriptor* descriptor, num_t rate,
lv2_atom_forge_init(&handle->forge, handle->map);
vm_api_init(handle->api, handle->map);
+ const timely_mask_t mask = TIMELY_MASK_BAR_BEAT
+ | TIMELY_MASK_BAR
+ | TIMELY_MASK_BEAT_UNIT
+ | TIMELY_MASK_BEATS_PER_BAR
+ | TIMELY_MASK_BEATS_PER_MINUTE
+ | TIMELY_MASK_FRAME
+ | TIMELY_MASK_FRAMES_PER_SECOND
+ | TIMELY_MASK_SPEED
+ | TIMELY_MASK_BAR_BEAT_WHOLE
+ | TIMELY_MASK_BAR_WHOLE;
+ timely_init(&handle->timely, handle->map, rate, mask, _cb, handle);
if(!props_init(&handle->props, MAX_NPROPS, descriptor->URI, handle->map, handle))
{
@@ -196,8 +216,7 @@ instantiate(const LV2_Descriptor* descriptor, num_t rate,
return NULL;
}
- handle->recalc = true;
- handle->srate = rate;
+ handle->needs_recalc = true;
return handle;
}
@@ -254,25 +273,29 @@ run(LV2_Handle instance, uint32_t nsamples)
const LV2_Atom *atom= &ev->body;
const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
- props_advance(&handle->props, &handle->forge, ev->time.frames, obj, &handle->ref);
+ if(!timely_advance(&handle->timely, obj, last_t, ev->time.frames))
+ props_advance(&handle->props, &handle->forge, ev->time.frames, obj, &handle->ref);
+
+ last_t = ev->time.frames;
}
+ timely_advance(&handle->timely, NULL, last_t, nsamples);
- if(handle->sync)
+ if(handle->needs_sync)
{
props_set(&handle->props, &handle->forge, nsamples - 1, handle->vm_graph, &handle->ref);
- handle->sync = false;
+ handle->needs_sync = false;
}
for(unsigned i = 0; i < CTRL_MAX; i++)
{
if(handle->in0[i] != *handle->in[i])
{
- handle->recalc = true;
+ handle->needs_recalc = true;
handle->in0[i] = *handle->in[i];
}
}
- if(handle->recalc || handle->is_dynamic)
+ if(handle->needs_recalc)
{
_stack_clear(&handle->stack);
@@ -562,41 +585,51 @@ run(LV2_Handle instance, uint32_t nsamples)
// time
case OP_BAR_BEAT:
{
- //TODO
+ const num_t c = TIMELY_BAR_BEAT(&handle->timely);
+ _stack_push(&handle->stack, c);
} break;
case OP_BAR:
{
- //TODO
+ const num_t c = TIMELY_BAR(&handle->timely);
+ _stack_push(&handle->stack, c);
} break;
case OP_BEAT:
{
- //TODO
+ const num_t bar = TIMELY_BAR(&handle->timely);
+ const num_t beats_per_bar = TIMELY_BEATS_PER_BAR(&handle->timely);
+ const num_t bar_beat = TIMELY_BAR_BEAT(&handle->timely);
+ const num_t c = bar*beats_per_bar + bar_beat;
+ _stack_push(&handle->stack, c);
} break;
case OP_BEAT_UNIT:
{
- //TODO
+ const num_t c = TIMELY_BEAT_UNIT(&handle->timely);
+ _stack_push(&handle->stack, c);
} break;
case OP_BPB:
{
- //TODO
+ const num_t c = TIMELY_BEATS_PER_BAR(&handle->timely);
+ _stack_push(&handle->stack, c);
} break;
case OP_BPM:
{
- //TODO
+ const num_t c = TIMELY_BEATS_PER_MINUTE(&handle->timely);
+ _stack_push(&handle->stack, c);
} break;
case OP_FRAME:
{
- num_t c = handle->frame; //FIXME use time:frame
+ const num_t c = TIMELY_FRAME(&handle->timely);
_stack_push(&handle->stack, c);
} break;
case OP_FPS:
{
- num_t c = handle->srate; //FIXME use time:framesPerSecond
+ const num_t c = TIMELY_FRAMES_PER_SECOND(&handle->timely);
_stack_push(&handle->stack, c);
} break;
case OP_SPEED:
{
- //TODO
+ const num_t c = TIMELY_SPEED(&handle->timely);
+ _stack_push(&handle->stack, c);
} break;
case OP_NOP:
@@ -625,7 +658,7 @@ run(LV2_Handle instance, uint32_t nsamples)
printf("out %u: %f\n", i, handle->out0[i]);
#endif
- handle->recalc = false;
+ handle->needs_recalc = false;
}
if(handle->ref)
@@ -635,8 +668,6 @@ run(LV2_Handle instance, uint32_t nsamples)
for(unsigned i = 0; i < CTRL_MAX; i++)
*handle->out[i] = handle->out0[i];;
-
- handle->frame += nsamples;
}
static void
diff --git a/vm.h b/vm.h
index db0efd5..c9bc029 100644
--- a/vm.h
+++ b/vm.h
@@ -579,7 +579,7 @@ vm_deserialize(vm_api_impl_t *impl, LV2_Atom_Forge *forge,
command_t *cmd = cmds;
memset(cmds, 0x0, sizeof(command_t)*ITEMS_MAX);
- bool is_dynamic = false;
+ bool uses_time = false;
LV2_ATOM_TUPLE_BODY_FOREACH(body, size, item)
{
@@ -625,7 +625,7 @@ vm_deserialize(vm_api_impl_t *impl, LV2_Atom_Forge *forge,
|| (cmd->op == OP_FPS)
|| (cmd->op == OP_SPEED) )
{
- is_dynamic = true;
+ uses_time = true;
}
}
else
@@ -639,7 +639,7 @@ vm_deserialize(vm_api_impl_t *impl, LV2_Atom_Forge *forge,
break;
}
- return is_dynamic;
+ return uses_time;
}
#endif // _VM_LV2_H
diff --git a/vm.ttl b/vm.ttl
index 5c4a31b..be17448 100644
--- a/vm.ttl
+++ b/vm.ttl
@@ -353,12 +353,10 @@ vm:lfo
vm:graph [
a atom:Tuple ;
rdf:value (
- # Phase := (Frame % (SampleRate * Control0) ) / (SampleRate * Control0)
- time:framesPerSecond
+ # Phase := (Beat % Control0 ) / Control0
0 vm:opInput
- vm:opMul
vm:opPush
- time:frame
+ time:beat
vm:opSwap
vm:opMod
vm:opSwap
diff --git a/vm_ui.c b/vm_ui.c
index 95ee4ec..021f3b3 100644
--- a/vm_ui.c
+++ b/vm_ui.c
@@ -262,7 +262,8 @@ _expose(struct nk_context *ctx, struct nk_rect wbounds, void *data)
const command_enum_t old_cmd_type = cmd->type;
int cmd_type = old_cmd_type;
- nk_combobox(ctx, command_labels, COMMAND_MAX, &cmd_type, dy, nk_vec2(nk_widget_width(ctx), dy*COMMAND_MAX)); //FIXME
+ nk_combobox(ctx, command_labels, COMMAND_MAX, &cmd_type,
+ dy, nk_vec2(nk_widget_width(ctx), dy*14));
if(old_cmd_type != cmd_type)
{
cmd->type = cmd_type;
@@ -328,7 +329,7 @@ _expose(struct nk_context *ctx, struct nk_rect wbounds, void *data)
const char *desc = show_mnemo && vm_api_def[cmd->op].mnemo
? vm_api_def[cmd->op].mnemo
: vm_api_def[cmd->op].label;
- if(nk_combo_begin_label(ctx, desc, nk_vec2(nk_widget_width(ctx), dy*OP_MAX))) //FIXME
+ if(nk_combo_begin_label(ctx, desc, nk_vec2(nk_widget_width(ctx), dy*14)))
{
nk_layout_row_dynamic(ctx, dy, 1);
for(unsigned op = 0; op < OP_MAX; op++)
@@ -362,6 +363,10 @@ _expose(struct nk_context *ctx, struct nk_rect wbounds, void *data)
}
}
+ // add spacing so we can see the whole combobox of last elements
+ nk_layout_row_dynamic(ctx, dy, 1);
+ nk_spacing(ctx, 10);
+
if(sync)
{
atom_ser_t *ser = &handle->ser;