From 64b41c090f5035e09b1af666a31d4ab2285fce5d Mon Sep 17 00:00:00 2001 From: Alexandros Theodotou Date: Wed, 12 Feb 2020 10:56:29 +0000 Subject: [PATCH] output custom wave in dsp --- src/zlfo.c | 50 ++++++++++++- src/zlfo_math.h | 79 ++++++++++++++++++++ src/zlfo_ui.c | 188 ++++++++++++++++-------------------------------- 3 files changed, 189 insertions(+), 128 deletions(-) diff --git a/src/zlfo.c b/src/zlfo.c index 4a48ca9..b4b894e 100644 --- a/src/zlfo.c +++ b/src/zlfo.c @@ -70,6 +70,7 @@ typedef struct ZLFO const float * triangle_on; const float * custom_on; const float * nodes[16][3]; + const float * num_nodes; /* outputs */ float * cv_out; @@ -295,6 +296,9 @@ connect_port ( case ZLFO_SAMPLE_TO_UI: self->sample_to_ui = (float *) data; break; + case ZLFO_NUM_NODES: + self->num_nodes = (float *) data; + break; default: break; } @@ -522,6 +526,21 @@ run ( ((float) self->common.period_size / grid_step_divisor); + /* sort node curves by position */ + NodeIndexElement node_indices[ + (int) *self->num_nodes]; + float nodes[16][3]; + for (int i = 0; i < 16; i++) + { + for (int j = 0; j < 3; j++) + { + nodes[i][j] = *(self->nodes[i][j]); + } + } + sort_node_indices_by_pos ( + nodes, node_indices, + (int) *self->num_nodes); + /* handle control trigger */ if (IS_TRIGGERED (self)) { @@ -596,8 +615,35 @@ run ( } if (CUSTOM_ON (self)) { - /*self->custom_out[i] =*/ - /*get_custom_val_at_x (*/ + int prev_idx = + get_prev_idx ( + node_indices, (int) * self->num_nodes, + (float) ratio); + int next_idx = + get_next_idx ( + node_indices, (int) * self->num_nodes, + (float) ratio); + + /* calculate custom */ + self->custom_out[i] = + get_custom_val_at_x ( + *self->nodes[prev_idx][0], + *self->nodes[prev_idx][1], + *self->nodes[prev_idx][2], + next_idx < 0 ? 1.f : + *self->nodes[next_idx][0], + next_idx < 0 ? + *self->nodes[0][1] : + *self->nodes[next_idx][1], + next_idx < 0 ? + *self->nodes[0][2] : + *self->nodes[next_idx][2], + shifted_current_sample, + self->common.period_size); + + /* adjust for -1 to 1 */ + self->custom_out[i] = + self->custom_out[i] * 2 - 1; } /* invert vertically */ diff --git a/src/zlfo_math.h b/src/zlfo_math.h index 2bbed38..9241938 100644 --- a/src/zlfo_math.h +++ b/src/zlfo_math.h @@ -422,4 +422,83 @@ invert_and_shift_xval ( return ret; } +/** + * This will return -1 if the next index is + * the copy of the first one at the end. + */ +static inline int +get_next_idx ( + NodeIndexElement * elements, + int num_nodes, + float ratio) +{ + float max_pos = 2.f; + int max_idx = 0; + for (int i = 0; i < num_nodes; i++) + { + if (elements[i].pos < max_pos && + elements[i].pos >= ratio) + { + max_pos = elements[i].pos; + max_idx = elements[i].index; + } + } + + /* if no match, the next index is the copy of + * the first one */ + if (max_pos > 1.9f) + { + return -1; + } + + return max_idx; +} + +static inline int +get_prev_idx ( + NodeIndexElement * elements, + int num_nodes, + float ratio) +{ + float min_pos = -1.f; + int min_idx = 0; + for (int i = 0; i < num_nodes; i++) + { + if (elements[i].pos > min_pos && + elements[i].pos < + (ratio + 0.0001f)) + { + min_pos = elements[i].pos; + min_idx = elements[i].index; + } + } + return min_idx; +} + +static int +pos_cmp (const void * a, const void * b) +{ + float pos_a = (*(NodeIndexElement*)a).pos; + float pos_b = (*(NodeIndexElement*)b).pos; + return pos_a > pos_b; +} + +static inline void +sort_node_indices_by_pos ( + float nodes[16][3], + NodeIndexElement * elements, + int num_nodes) +{ + for (int i = 0; i < num_nodes; i++) + { + /* set index and position */ + elements[i].index = i; + elements[i].pos = nodes[i][0]; + } + + qsort ( + elements, (size_t) num_nodes, + sizeof (NodeIndexElement), pos_cmp); +} + #endif diff --git a/src/zlfo_ui.c b/src/zlfo_ui.c index 83eabe8..1e1d809 100644 --- a/src/zlfo_ui.c +++ b/src/zlfo_ui.c @@ -1221,84 +1221,6 @@ add_bot_buttons ( self->app, (ZtkWidget *) control, 2); } -static int -pos_cmp (const void * a, const void * b) -{ - float pos_a = (*(NodeIndexElement*)a).pos; - float pos_b = (*(NodeIndexElement*)b).pos; - return pos_a > pos_b; -} - -static void -sort_node_indices_by_pos ( - ZLfoUi * self, - NodeIndexElement * elements) -{ - for (int i = 0; i < self->num_nodes; i++) - { - /* set index and position */ - elements[i].index = i; - elements[i].pos = self->nodes[i][0]; - } - - qsort ( - elements, (size_t) self->num_nodes, - sizeof (NodeIndexElement), pos_cmp); -} - -/** - * This will return -1 if the next index is - * the copy of the first one at the end. - */ -static int -get_next_idx ( - ZLfoUi * self, - NodeIndexElement * elements, - double ratio) -{ - float max_pos = 2.f; - int max_idx = 0; - for (int i = 0; i < self->num_nodes; i++) - { - if (elements[i].pos < max_pos && - elements[i].pos >= (float) ratio) - { - max_pos = elements[i].pos; - max_idx = elements[i].index; - } - } - - /* if no match, the next index is the copy of - * the first one */ - if (max_pos > 1.9f) - { - return -1; - } - - return max_idx; -} - -static int -get_prev_idx ( - ZLfoUi * self, - NodeIndexElement * elements, - double ratio) -{ - float min_pos = -1.f; - int min_idx = 0; - for (int i = 0; i < self->num_nodes; i++) - { - if (elements[i].pos > min_pos && - elements[i].pos < - ((float) ratio + 0.0001f)) - { - min_pos = elements[i].pos; - min_idx = elements[i].index; - } - } - return min_idx; -} - /** * Draws the graphs in curve mode. */ @@ -1321,7 +1243,9 @@ draw_graph ( /* sort node curves by position */ NodeIndexElement node_indices[self->num_nodes]; - sort_node_indices_by_pos (self, node_indices); + sort_node_indices_by_pos ( + self->nodes, node_indices, + self->num_nodes); if (self->has_change) { @@ -1423,73 +1347,85 @@ draw_graph ( } \ prev_draw_##val = draw_val - /* calculate sine */ - double sine = - (double) self->sine_cache[xvall]; - - /* calculate saw */ - double saw = - (double) self->saw_cache[xvall]; - - /* triangle can be calculated based on the - * saw */ - double triangle; - if (saw > 0.0) - triangle = - ((- saw) + 1.0) * 2.0 - 1.0; - else - triangle = - (saw + 1.0) * 2.0 - 1.0; - - /* square too */ - double square = saw < 0.0 ? -1.0 : 1.0; - double ratio = xvald / GRID_WIDTH; - int prev_idx = - get_prev_idx ( - self, node_indices, ratio); - int next_idx = - get_next_idx ( - self, node_indices, ratio); - - /* calculate custom */ - double custom = - (double) - get_custom_val_at_x ( - self->nodes[prev_idx][0], - self->nodes[prev_idx][1], - self->nodes[prev_idx][2], - next_idx < 0 ? 1.f : - self->nodes[next_idx][0], - next_idx < 0 ? - self->nodes[0][1] : - self->nodes[next_idx][1], - next_idx < 0 ? - self->nodes[0][2] : - self->nodes[next_idx][2], - (float) xvald, GRID_WIDTH); - - /* adjust for -1 to 1 */ - custom = custom * 2 - 1; if (self->sine_on) { + /* calculate sine */ + double sine = + (double) self->sine_cache[xvall]; + DRAW_VAL (sine); } if (self->saw_on) { + /* calculate saw */ + double saw = + (double) self->saw_cache[xvall]; + DRAW_VAL (saw); } if (self->triangle_on) { + double triangle; + if (ratio > 0.4999) + { + triangle = + (1.0 - ratio) * 4.0 - 1.0; + } + else + { + triangle = + ratio * 4.0 - 1.0; + } + DRAW_VAL (triangle); } if (self->square_on) { + double square; + if (ratio > 0.4999) + { + square = - 1.0; + } + else + { + square = 1.0; + } + DRAW_VAL (square); } if (self->custom_on) { + int prev_idx = + get_prev_idx ( + node_indices, self->num_nodes, + (float) ratio); + int next_idx = + get_next_idx ( + node_indices, self->num_nodes, + (float) ratio); + + /* calculate custom */ + double custom = + (double) + get_custom_val_at_x ( + self->nodes[prev_idx][0], + self->nodes[prev_idx][1], + self->nodes[prev_idx][2], + next_idx < 0 ? 1.f : + self->nodes[next_idx][0], + next_idx < 0 ? + self->nodes[0][1] : + self->nodes[next_idx][1], + next_idx < 0 ? + self->nodes[0][2] : + self->nodes[next_idx][2], + (float) xvald, GRID_WIDTH); + + /* adjust for -1 to 1 */ + custom = custom * 2 - 1; + DRAW_VAL (custom); }