Browse Source

readd separate output for each wave

master
Alexandros Theodotou 3 years ago
parent
commit
e6ab8a0954
Signed by: alex
GPG Key ID: 022EAE42313D70F3
  1. 2
      subprojects/ztoolkit.wrap
  2. 154
      zlfo.c
  3. 9
      zlfo_common.h
  4. 52
      zlfo_ttl_gen.c
  5. 251
      zlfo_ui.c

2
subprojects/ztoolkit.wrap

@ -1,3 +1,3 @@ @@ -1,3 +1,3 @@
[wrap-git]
url = https://git.zrythm.org/git/ztoolkit
revision = 42de23e755eacbfe8177c0dabbac76a1aa73b4c3
revision = 108d606e475154ddf232f5fbac2343ad742c619b

154
zlfo.c

@ -47,11 +47,18 @@ typedef struct ZLFO @@ -47,11 +47,18 @@ typedef struct ZLFO
const float * freerun;
const float * sync_rate;
const float * sync_rate_type;
const float * hinvert;
const float * vinvert;
const float * nodes[ZLFO_NUM_NODES][3];
/* outputs */
float * cv_out;
float * audio_out;
float * sine_out;
float * saw_out;
float * triangle_out;
float * square_out;
float * rnd_out;
float * custom_out;
/** Frequency during the last run. */
float last_freq;
@ -182,26 +189,30 @@ connect_port ( @@ -182,26 +189,30 @@ connect_port (
case ZLFO_SYNC_RATE_TYPE:
self->sync_rate_type = (const float *) data;
break;
#if 0
case ZLFO_SINE:
self->sine = (float *) data;
case ZLFO_HINVERT:
self->hinvert = (const float *) data;
break;
case ZLFO_SAW_UP:
self->saw_up = (float *) data;
case ZLFO_VINVERT:
self->vinvert = (const float *) data;
break;
case ZLFO_SAW_DOWN:
self->saw_down = (float *) data;
case ZLFO_SINE_OUT:
self->sine_out = (float *) data;
break;
case ZLFO_TRIANGLE:
self->triangle = (float *) data;
case ZLFO_SAW_OUT:
self->saw_out = (float *) data;
break;
case ZLFO_SQUARE:
self->square = (float *) data;
case ZLFO_TRIANGLE_OUT:
self->triangle_out = (float *) data;
break;
case ZLFO_RANDOM:
self->random = (float *) data;
case ZLFO_SQUARE_OUT:
self->square_out = (float *) data;
break;
case ZLFO_RND_OUT:
self->rnd_out = (float *) data;
break;
case ZLFO_CUSTOM_OUT:
self->custom_out = (float *) data;
break;
#endif
default:
break;
}
@ -218,6 +229,47 @@ connect_port ( @@ -218,6 +229,47 @@ connect_port (
}
}
static void
send_messages_to_ui (
ZLFO * self)
{
/* set up forge to write directly to notify
* output port */
const uint32_t notify_capacity =
self->notify->atom.size;
lv2_atom_forge_set_buffer (
&self->forge, (uint8_t*) self->notify,
notify_capacity);
/* start a sequence in the notify output port */
lv2_atom_forge_sequence_head (
&self->forge, &self->notify_frame, 0);
/* forge container object of type "ui_state" */
lv2_atom_forge_frame_time (&self->forge, 0);
LV2_Atom_Forge_Frame frame;
lv2_atom_forge_object (
&self->forge, &frame, 1,
self->uris.ui_state);
/* append property for current sample */
lv2_atom_forge_key (
&self->forge,
self->uris.ui_state_current_sample);
lv2_atom_forge_long (
&self->forge, self->current_sample);
/* append samplerate */
lv2_atom_forge_key (
&self->forge,
self->uris.ui_state_samplerate);
lv2_atom_forge_double (
&self->forge, self->samplerate);
/* finish object */
lv2_atom_forge_pop (&self->forge, &frame);
}
static void
recalc_multipliers (
ZLFO * self)
@ -280,47 +332,6 @@ activate ( @@ -280,47 +332,6 @@ activate (
recalc_multipliers (self);
}
static void
send_messages_to_ui (
ZLFO * self)
{
/* set up forge to write directly to notify
* output port */
const uint32_t notify_capacity =
self->notify->atom.size;
lv2_atom_forge_set_buffer (
&self->forge, (uint8_t*) self->notify,
notify_capacity);
/* start a sequence in the notify output port */
lv2_atom_forge_sequence_head (
&self->forge, &self->notify_frame, 0);
/* forge container object of type "ui_state" */
lv2_atom_forge_frame_time (&self->forge, 0);
LV2_Atom_Forge_Frame frame;
lv2_atom_forge_object (
&self->forge, &frame, 1,
self->uris.ui_state);
/* append property for current sample */
lv2_atom_forge_key (
&self->forge,
self->uris.ui_state_current_sample);
lv2_atom_forge_long (
&self->forge, self->current_sample);
/* append samplerate */
lv2_atom_forge_key (
&self->forge,
self->uris.ui_state_samplerate);
lv2_atom_forge_double (
&self->forge, self->samplerate);
/* finish object */
lv2_atom_forge_pop (&self->forge, &frame);
}
static void
run (
LV2_Handle instance,
@ -337,40 +348,33 @@ run ( @@ -337,40 +348,33 @@ run (
for (uint32_t i = 0; i < n_samples; i++)
{
#if 0
/* handle sine */
self->sine[i] =
self->sine_out[i] =
sinf (
((float) self->samples_processed *
((float) self->current_sample *
self->sine_multiplier));
/* handle saw up */
self->saw_up[i] =
self->saw_out[i] =
fmodf (
(float) self->samples_processed *
(float) self->current_sample *
self->saw_up_multiplier, 1.f) * 2.f - 1.f;
/* saw down is the opposite of saw up */
self->saw_down[i] = - self->saw_up[i];
/* triangle can be calculated based on the saw */
if (self->saw_up[i] < 0.f)
self->triangle[i] =
(self->saw_up[i] + 1.f) * 2.f - 1.f;
else
self->triangle[i] =
(self->saw_down[i] + 1.f) * 2.f - 1.f;
/* triangle can be calculated based on the
* saw */
if (self->saw_out[i] < 0.f)
self->triangle_out[i] =
(self->saw_out[i] + 1.f) * 2.f - 1.f;
/* square too */
self->square[i] =
self->saw_up[i] < 0.f ? -1.f : 1.f;
self->square_out[i] =
self->saw_out[i] < 0.f ? -1.f : 1.f;
/* TODO */
self->random[i] = 0.f;
self->rnd_out[i] = 0.f;
/*self->random[i] =*/
/*((float) rand () / (float) ((float) RAND_MAX / 2.f)) -*/
/*1.f;*/
#endif
self->current_sample++;
if (self->current_sample ==

9
zlfo_common.h

@ -80,6 +80,8 @@ typedef enum PortIndex @@ -80,6 +80,8 @@ typedef enum PortIndex
ZLFO_RANGE_MAX,
ZLFO_STEP_MODE,
ZLFO_FREE_RUNNING,
ZLFO_HINVERT,
ZLFO_VINVERT,
ZLFO_NODE_1_POS,
ZLFO_NODE_1_VAL,
ZLFO_NODE_1_CURVE,
@ -129,7 +131,12 @@ typedef enum PortIndex @@ -129,7 +131,12 @@ typedef enum PortIndex
ZLFO_NODE_16_VAL,
ZLFO_NODE_16_CURVE,
ZLFO_NUM_NODES,
ZLFO_CV_OUT,
ZLFO_SINE_OUT,
ZLFO_TRIANGLE_OUT,
ZLFO_SAW_OUT,
ZLFO_SQUARE_OUT,
ZLFO_RND_OUT,
ZLFO_CUSTOM_OUT,
NUM_ZLFO_PORTS,
} PortIndex;

52
zlfo_ttl_gen.c

@ -185,6 +185,18 @@ int main ( @@ -185,6 +185,18 @@ int main (
type = PORT_TYPE_TOGGLE;
def = 1.f;
break;
case ZLFO_HINVERT:
strcpy (symbol, "hinvert");
strcpy (name, "H invert");
strcpy (comment, "Horizontal invert");
type = PORT_TYPE_TOGGLE;
break;
case ZLFO_VINVERT:
strcpy (symbol, "vinvert");
strcpy (name, "V invert");
strcpy (comment, "Vertical invert");
type = PORT_TYPE_TOGGLE;
break;
case ZLFO_NUM_NODES:
strcpy (symbol, "num_nodes");
strcpy (name, "Node count");
@ -286,14 +298,46 @@ int main ( @@ -286,14 +298,46 @@ int main (
" ] , [\n");
}
/* write cv out and audio out */
/* write cv outs */
fprintf (f,
" a lv2:OutputPort ,\n\
lv2:CVPort ;\n\
lv2:index %d ;\n\
lv2:symbol \"cv_out\" ;\n\
lv2:name \"CV output\" ;\n\
] .\n\n", ZLFO_CV_OUT);
lv2:symbol \"sine_out\" ;\n\
lv2:name \"Sine\" ;\n\
] , [\n\
a lv2:OutputPort ,\n\
lv2:CVPort ;\n\
lv2:index %d ;\n\
lv2:symbol \"triangle_out\" ;\n\
lv2:name \"Triangle\" ;\n\
] , [\n\
a lv2:OutputPort ,\n\
lv2:CVPort ;\n\
lv2:index %d ;\n\
lv2:symbol \"saw_out\" ;\n\
lv2:name \"Saw\" ;\n\
] , [\n\
a lv2:OutputPort ,\n\
lv2:CVPort ;\n\
lv2:index %d ;\n\
lv2:symbol \"square_out\" ;\n\
lv2:name \"Square\" ;\n\
] , [\n\
a lv2:OutputPort ,\n\
lv2:CVPort ;\n\
lv2:index %d ;\n\
lv2:symbol \"rnd_out\" ;\n\
lv2:name \"Noise\" ;\n\
] , [\n\
a lv2:OutputPort ,\n\
lv2:CVPort ;\n\
lv2:index %d ;\n\
lv2:symbol \"custom_out\" ;\n\
lv2:name \"Custom\" ;\n\
] .\n\n",
ZLFO_SINE_OUT, ZLFO_TRIANGLE_OUT, ZLFO_SAW_OUT,
ZLFO_SQUARE_OUT, ZLFO_RND_OUT, ZLFO_CUSTOM_OUT);
/* write UI */
fprintf (f,

251
zlfo_ui.c

@ -142,6 +142,19 @@ typedef enum DrawDataType @@ -142,6 +142,19 @@ typedef enum DrawDataType
DATA_TYPE_LBL,
} DrawDataType;
/**
* Wave mode for editing.
*/
typedef enum WaveMode
{
WAVE_SINE,
WAVE_SAW,
WAVE_TRIANGLE,
WAVE_SQUARE,
WAVE_RND,
WAVE_CUSTOM,
} WaveMode;
typedef struct ZLfoUi
{
/** Port values. */
@ -151,6 +164,8 @@ typedef struct ZLfoUi @@ -151,6 +164,8 @@ typedef struct ZLfoUi
float range_max;
int step_mode;
int freerun;
int hinvert;
int vinvert;
float sync_rate;
float sync_rate_type;
float nodes[16][3];
@ -159,6 +174,7 @@ typedef struct ZLfoUi @@ -159,6 +174,7 @@ typedef struct ZLfoUi
/** Non-port values */
long current_sample;
double samplerate;
WaveMode wave_mode;
LV2UI_Write_Function write;
LV2UI_Controller controller;
@ -346,6 +362,63 @@ on_btn_clicked ( @@ -346,6 +362,63 @@ on_btn_clicked (
break;
}
break;
case DATA_TYPE_BTN_LEFT:
switch (data->val)
{
case LEFT_BTN_SINE:
if (self->wave_mode == WAVE_SINE)
{
self->wave_mode = WAVE_CUSTOM;
}
else
{
self->wave_mode = WAVE_SINE;
}
break;
case LEFT_BTN_SAW:
if (self->wave_mode == WAVE_SAW)
{
self->wave_mode = WAVE_CUSTOM;
}
else
{
self->wave_mode = WAVE_SAW;
}
break;
case LEFT_BTN_TRIANGLE:
if (self->wave_mode == WAVE_TRIANGLE)
{
self->wave_mode = WAVE_CUSTOM;
}
else
{
self->wave_mode = WAVE_TRIANGLE;
}
break;
case LEFT_BTN_RND:
if (self->wave_mode == WAVE_RND)
{
self->wave_mode = WAVE_CUSTOM;
}
else
{
self->wave_mode = WAVE_RND;
}
break;
case LEFT_BTN_SQUARE:
if (self->wave_mode == WAVE_SQUARE)
{
self->wave_mode = WAVE_CUSTOM;
}
else
{
self->wave_mode = WAVE_SQUARE;
}
break;
default:
break;
}
break;
case DATA_TYPE_BTN_BOT:
switch (data->val)
{
@ -428,6 +501,77 @@ on_sync_rate_type_clicked ( @@ -428,6 +501,77 @@ on_sync_rate_type_clicked (
}
}
static int
get_button_active (
ZtkButton * btn,
DrawData * data)
{
ZLfoUi * self = data->zlfo_ui;
switch (data->type)
{
case DATA_TYPE_BTN_TOP:
switch (data->val)
{
case TOP_BTN_CURVE:
return !self->step_mode;
break;
case TOP_BTN_STEP:
return self->step_mode;
break;
}
break;
case DATA_TYPE_BTN_LEFT:
switch (data->val)
{
case LEFT_BTN_SINE:
return self->wave_mode == WAVE_SINE;
break;
case LEFT_BTN_TRIANGLE:
return self->wave_mode == WAVE_TRIANGLE;
break;
case LEFT_BTN_SAW:
return self->wave_mode == WAVE_SAW;
break;
case LEFT_BTN_SQUARE:
return self->wave_mode == WAVE_SQUARE;
break;
case LEFT_BTN_RND:
return self->wave_mode == WAVE_RND;
break;
default:
break;
}
break;
case DATA_TYPE_BTN_BOT:
switch (data->val)
{
case BOT_BTN_SYNC:
return !self->freerun;
break;
case BOT_BTN_FREE:
return self->freerun;
break;
}
break;
case DATA_TYPE_BTN_GRID:
switch (data->val)
{
case GRID_BTN_HMIRROR:
return self->hinvert;
break;
case GRID_BTN_VMIRROR:
return self->vinvert;
break;
}
break;
case DATA_TYPE_LBL:
break;
}
return 0;
}
static void
add_left_buttons (
ZLfoUi * self)
@ -450,6 +594,10 @@ add_left_buttons ( @@ -450,6 +594,10 @@ add_left_buttons (
&rect,
(ZtkWidgetActivateCallback)
on_btn_clicked, data);
ztk_button_make_toggled (
btn,
(ZtkButtonToggledGetter)
get_button_active);
ztk_button_set_background_colors (
btn,
&zlfo_ui_theme.button_normal,
@ -485,48 +633,6 @@ add_left_buttons ( @@ -485,48 +633,6 @@ add_left_buttons (
}
}
static int
get_button_active (
ZtkButton * btn,
DrawData * data)
{
ZLfoUi * self = data->zlfo_ui;
switch (data->type)
{
case DATA_TYPE_BTN_TOP:
switch (data->val)
{
case TOP_BTN_CURVE:
return !self->step_mode;
break;
case TOP_BTN_STEP:
return self->step_mode;
break;
}
break;
case DATA_TYPE_BTN_LEFT:
break;
case DATA_TYPE_BTN_BOT:
switch (data->val)
{
case BOT_BTN_SYNC:
return !self->freerun;
break;
case BOT_BTN_FREE:
return self->freerun;
break;
}
break;
case DATA_TYPE_BTN_GRID:
break;
case DATA_TYPE_LBL:
break;
}
return 0;
}
static void
top_and_bot_btn_bg_cb (
ZtkWidget * w,
@ -924,7 +1030,7 @@ add_bot_buttons ( @@ -924,7 +1030,7 @@ add_bot_buttons (
ZTK_CTRL_DRAG_VERTICAL,
self, MIN_FREQ, MAX_FREQ, MIN_FREQ);
((ZtkWidget *) control)->user_data = self;
control->sensitivity = 0.008f;
control->sensitivity = 0.005f;
((ZtkWidget *) control)->button_event_cb =
(ZtkWidgetButtonEventCallback)
freq_control_btn_event_cb;
@ -1004,26 +1110,29 @@ mid_region_bg_draw_cb ( @@ -1004,26 +1110,29 @@ mid_region_bg_draw_cb (
cairo_stroke (cr);
#endif
/* draw node curves */
zlfo_ui_theme_set_cr_color (cr, line);
cairo_set_line_width (cr, 6);
for (int i = 0; i < self->num_nodes - 1; i++)
if (self->wave_mode == WAVE_CUSTOM)
{
ZtkWidget * nodew = self->node_widgets[i];
ZtkWidget * next_nodew =
self->node_widgets[i + 1];
cairo_move_to (
cr,
nodew->rect.x + nodew->rect.width / 2,
nodew->rect.y + nodew->rect.height / 2);
cairo_line_to (
cr,
next_nodew->rect.x +
next_nodew->rect.width / 2,
next_nodew->rect.y +
next_nodew->rect.height / 2);
cairo_stroke (cr);
/* draw node curves */
zlfo_ui_theme_set_cr_color (cr, line);
cairo_set_line_width (cr, 6);
for (int i = 0; i < self->num_nodes - 1; i++)
{
ZtkWidget * nodew = self->node_widgets[i];
ZtkWidget * next_nodew =
self->node_widgets[i + 1];
cairo_move_to (
cr,
nodew->rect.x + nodew->rect.width / 2,
nodew->rect.y + nodew->rect.height / 2);
cairo_line_to (
cr,
next_nodew->rect.x +
next_nodew->rect.width / 2,
next_nodew->rect.y +
next_nodew->rect.height / 2);
cairo_stroke (cr);
}
}
}
@ -1126,7 +1235,8 @@ node_update_cb ( @@ -1126,7 +1235,8 @@ node_update_cb (
ZLfoUi * self = data->zlfo_ui;
/* set visibility */
if (data->idx < self->num_nodes)
if (data->idx < self->num_nodes &&
self->wave_mode == WAVE_CUSTOM)
{
ztk_widget_set_visible (w, 1);
}
@ -1714,7 +1824,7 @@ add_grid_controls ( @@ -1714,7 +1824,7 @@ add_grid_controls (
(ZtkWidgetDrawCallback) grid_btn_draw_cb,
NULL, data);
ztk_app_add_widget (
self->app, (ZtkWidget *) da, 1);
self->app, (ZtkWidget *) da, 4);
}
/* add shift control */
@ -1732,7 +1842,7 @@ add_grid_controls ( @@ -1732,7 +1842,7 @@ add_grid_controls (
control->sensitivity = 0.02f;
ztk_control_set_relative_mode (control, 0);
ztk_app_add_widget (
self->app, (ZtkWidget *) control, 1);
self->app, (ZtkWidget *) control, 4);
/* add labels */
padding = 2;
@ -1810,6 +1920,9 @@ instantiate ( @@ -1810,6 +1920,9 @@ instantiate (
self->controller = controller;
self->dragging_node = -1;
/* FIXME save this in state */
self->wave_mode = WAVE_SINE;
#ifndef RELEASE
ztk_log_set_level (ZTK_LOG_LEVEL_DEBUG);
#endif
@ -1928,6 +2041,14 @@ port_event ( @@ -1928,6 +2041,14 @@ port_event (
self->sync_rate_type =
* (const float *) buffer;
break;
case ZLFO_HINVERT:
self->hinvert =
(int) * (const float *) buffer;
break;
case ZLFO_VINVERT:
self->vinvert =
(int) * (const float *) buffer;
break;
case ZLFO_NUM_NODES:
self->num_nodes =
(int) * (const float *) buffer;

Loading…
Cancel
Save