diff options
author | Hanspeter Portner <dev@open-music-kontrollers.ch> | 2017-03-21 14:54:05 +0100 |
---|---|---|
committer | Hanspeter Portner <dev@open-music-kontrollers.ch> | 2017-03-21 14:54:05 +0100 |
commit | f3d77a9c079754914ebe1ccdfc58d0df953be8b8 (patch) | |
tree | 81de623f1457a5c5e7ed4dd7994d12ab5e5de98a | |
parent | 11088137929d6cff5e53daf76b16cbdc0471a729 (diff) | |
download | vm.lv2-f3d77a9c079754914ebe1ccdfc58d0df953be8b8.tar.xz |
implement time extension.
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | timely.lv2/timely.h | 3 | ||||
-rw-r--r-- | vm.c | 85 | ||||
-rw-r--r-- | vm.h | 6 | ||||
-rw-r--r-- | vm.ttl | 6 | ||||
-rw-r--r-- | vm_ui.c | 9 |
6 files changed, 74 insertions, 37 deletions
@@ -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; @@ -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 @@ -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 @@ -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 @@ -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; |