From 0b24eecd57aad8329994d65d0bd146491ce4bb61 Mon Sep 17 00:00:00 2001 From: "G.raud" Date: Sat, 8 Jun 2013 22:34:12 +0200 Subject: [PATCH] control.h, control.c: new module providing control_init() and control_*() also export type control_t control_init(): new name of init_control() control_exchange(): new name of c_exchange() control_rounding(): new function njackspa.c: delete the previous definitions of control_t, init_control() and c_exchange() and call the new names plus control_rounding() JACKSPA_FLOAT, JACKSPA_INT, JACKSPA_TOGGLE: new names of VAL_FLOAT, VAL_INT, VAL_TOGGLE, to avoid name clashes --- Makefile | 2 +- control.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ control.h | 63 +++++++++++++++++++++++ njackspa.c | 167 +++---------------------------------------------------------- 4 files changed, 230 insertions(+), 161 deletions(-) create mode 100644 control.c create mode 100644 control.h diff --git a/Makefile b/Makefile index 7dc77fd..732eba2 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ LDFLAGS = -lm -ljack -ldl -g EXECUTABLES = njackspa gjackspa INSTALL_PATH = /usr/local/bin -MODULES = jackspa.o +MODULES = jackspa.o control.o OBJECTS = $(MODULES) $(EXECUTABLES:%=%.o) .PHONY : all clean install diff --git a/control.c b/control.c new file mode 100644 index 0000000..0cd3254 --- /dev/null +++ b/control.c @@ -0,0 +1,159 @@ +/* control.c - interface to the controls of a jackspa plugin instance + * Copyright © 2013 Géraud Meyer + * + * This file is part of ng-jackspa. + * + * ng-jackspa is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with ng-jackspa. If not, see . + */ + +#include +#include +#include +#include "control.h" + +LADSPA_Data control_rounding(const control_t *control, LADSPA_Data val) +{ + if (control->type == JACKSPA_INT || control->type == JACKSPA_TOGGLE) + return nearbyintf(val); + return val; +} + +void control_exchange(control_t *control) +{ + LADSPA_Data buf; + buf = *control->val; + *control->val = control->sel; + control->sel = buf; +} + +int control_init(control_t *control, state_t *state, unsigned long port) +{ + LADSPA_PortRangeHint hint = state->descriptor->PortRangeHints[port]; + LADSPA_PortRangeHintDescriptor descriptor = hint.HintDescriptor; + LADSPA_Data lower_bound = hint.LowerBound; + LADSPA_Data upper_bound = hint.UpperBound; + + control->name = state->descriptor->PortNames[port]; + control->val = &state->control_port_values[port]; + + /* control->min, control->max */ + if (LADSPA_IS_HINT_SAMPLE_RATE(descriptor)) { + int sample_rate = jack_get_sample_rate(state->jack_client); + lower_bound *= sample_rate; + upper_bound *= sample_rate; + } + if ( LADSPA_IS_HINT_BOUNDED_BELOW(descriptor) && + LADSPA_IS_HINT_BOUNDED_ABOVE(descriptor) ) + { + control->min = lower_bound; + control->max = upper_bound; + } + else if (LADSPA_IS_HINT_BOUNDED_BELOW(descriptor)) { + control->min = lower_bound; + control->max = 1.0; + } + else if (LADSPA_IS_HINT_BOUNDED_ABOVE(descriptor)) { + control->min = 0.0; + control->max = upper_bound; + } + else { + control->min = -1.0; + control->max = 1.0; + } + + /* control->def */ + if (LADSPA_IS_HINT_HAS_DEFAULT(descriptor)) { + control->def = (LADSPA_Data *)malloc(sizeof(LADSPA_Data)); + if (!control->def) { + fprintf(stderr, "memory allocation error\n"); + return 1; + } + switch (descriptor & LADSPA_HINT_DEFAULT_MASK) { + case LADSPA_HINT_DEFAULT_MINIMUM: + *control->def = lower_bound; + break; + case LADSPA_HINT_DEFAULT_LOW: + *control->def = lower_bound * 0.75 + upper_bound * 0.25; + break; + case LADSPA_HINT_DEFAULT_MIDDLE: + *control->def = lower_bound * 0.5 + upper_bound * 0.5; + break; + case LADSPA_HINT_DEFAULT_HIGH: + *control->def = lower_bound * 0.25 + upper_bound * 0.75; + break; + case LADSPA_HINT_DEFAULT_MAXIMUM: + *control->def = upper_bound; + break; + case LADSPA_HINT_DEFAULT_0: + *control->def = 0.0; + break; + case LADSPA_HINT_DEFAULT_1: + *control->def = 1.0; + break; + case LADSPA_HINT_DEFAULT_100: + *control->def = 100.0; + break; + case LADSPA_HINT_DEFAULT_440: + *control->def = 440.0; + break; + default: + fprintf(stderr, "default not found\n"); + free(control->def), control->def = NULL; + } + } + else + control->def = NULL; + + /* Check the default */ + if (control->def) { + if (*control->def < control->min) { + fprintf(stderr, "default smaller than the minimum\n"); + *control->def = control->min; + } + if (*control->def > control->max) { + fprintf(stderr, "default greater than the maximum\n"); + *control->def = control->max; + } + } + + /* control->inc & Overrides */ + if (LADSPA_IS_HINT_TOGGLED(descriptor)) { + control->min = 0.0; + control->max = 1.0; + control->inc.fine = 1.0; + control->inc.coarse = 1.0; + control->type = JACKSPA_TOGGLE; + if (control->def) *control->def = nearbyintf(*control->def); + } + else if (LADSPA_IS_HINT_INTEGER(descriptor)) { + control->min = nearbyintf(control->min); + control->max = nearbyintf(control->max); + control->inc.fine = 1.0; + control->inc.coarse = 1.0; + control->type = JACKSPA_INT; + if (control->def) *control->def = nearbyintf(*control->def); + } + else { + control->inc.fine = (control->max - control->min) / 500; + control->inc.coarse = (control->max - control->min) / 50; + control->type = JACKSPA_FLOAT; + } + + /* control->sel, control->val */ + if (control->def) control->sel = *control->def; + else control->sel = control->min; + control->alt_sel = control->sel; + *control->val = control->sel; + + return 0; +} diff --git a/control.h b/control.h new file mode 100644 index 0000000..31b4aec --- /dev/null +++ b/control.h @@ -0,0 +1,63 @@ +/* control.h - API for interfaces to the controls of a jackspa plugin instance + * Copyright © 2013 Géraud Meyer + * + * control.h is part of ng-jackspa. + * + * ng-jackspa is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef CONTROL_H +#define CONTROL_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "jackspa.h" + +enum ctype { + JACKSPA_FLOAT, + JACKSPA_INT, + JACKSPA_TOGGLE +}; + +typedef struct { + const char *name; + /* value in the plugin */ + LADSPA_Data *val; + /* values selected in the interface */ + LADSPA_Data sel; + LADSPA_Data alt_sel; + /* value range */ + LADSPA_Data min; + LADSPA_Data max; + LADSPA_Data *def; + enum ctype type; + struct { LADSPA_Data fine; LADSPA_Data coarse; } inc; +} control_t; + + +/* Return a value close to val that is valid for the given control */ +/* val is supposed to be inside the min/max of control */ +LADSPA_Data control_rounding(const control_t *control, LADSPA_Data val); + +/* Exchange the selected and the active values */ +void control_exchange(control_t *control); + +/* Compute the type, the bounds, the default value and the increments */ +int control_init(control_t *control, state_t *state, unsigned long port); + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif diff --git a/njackspa.c b/njackspa.c index dc24f3f..c49feb0 100644 --- a/njackspa.c +++ b/njackspa.c @@ -24,6 +24,7 @@ #include #include #include "jackspa.h" +#include "control.h" #define PROGRAM_NAME "njackspa" #define CON_NAME "Controls" @@ -45,35 +46,6 @@ #define ERR_OUT(format, arg...) ( endwin(), fprintf(stderr, format "\n", ## arg), refresh() ) -enum ctype { - VAL_FLOAT, - VAL_INT, - VAL_TOGGLE -}; - -typedef struct _control_t { - const char *name; - /* value in the plugin */ - LADSPA_Data *val; - /* values selected in the interface */ - LADSPA_Data sel; - LADSPA_Data alt_sel; - /* value range */ - LADSPA_Data min; - LADSPA_Data max; - LADSPA_Data *def; - enum ctype type; - struct { LADSPA_Data fine; LADSPA_Data coarse; } inc; -} control_t; - -void c_exchange(control_t *control) -{ - LADSPA_Data buf; - buf = *control->val; - *control->val = control->sel; - control->sel = buf; -} - struct window { WINDOW *window_ptr; state_t *state; @@ -91,129 +63,6 @@ void window_item_previous(struct window* w) { if (w->index > 0) w->index--; } void suppress_jack_log(const char *msg) { ; /* Just suppress Jack SPAM here ;-) */ } -int init_control(control_t *control, state_t *state, int port) -{ - LADSPA_PortRangeHint hint = state->descriptor->PortRangeHints[port]; - LADSPA_PortRangeHintDescriptor descriptor = hint.HintDescriptor; - LADSPA_Data lower_bound = hint.LowerBound; - LADSPA_Data upper_bound = hint.UpperBound; - - control->name = state->descriptor->PortNames[port]; - control->val = &state->control_port_values[port]; - - /* control->min, control->max */ - if (LADSPA_IS_HINT_SAMPLE_RATE(descriptor)) { - int sample_rate = jack_get_sample_rate(state->jack_client); - lower_bound *= sample_rate; - upper_bound *= sample_rate; - } - if ( LADSPA_IS_HINT_BOUNDED_BELOW(descriptor) && - LADSPA_IS_HINT_BOUNDED_ABOVE(descriptor) ) - { - control->min = lower_bound; - control->max = upper_bound; - } - else if (LADSPA_IS_HINT_BOUNDED_BELOW(descriptor)) { - control->min = lower_bound; - control->max = 1.0; - } - else if (LADSPA_IS_HINT_BOUNDED_ABOVE(descriptor)) { - control->min = 0.0; - control->max = upper_bound; - } - else { - control->min = -1.0; - control->max = 1.0; - } - - /* control->def */ - if (LADSPA_IS_HINT_HAS_DEFAULT(descriptor)) { - control->def = (LADSPA_Data *)malloc(sizeof(LADSPA_Data)); - if (!control->def) - return (ERR_OUT ("memory allocation error"), 1); - switch (descriptor & LADSPA_HINT_DEFAULT_MASK) { - case LADSPA_HINT_DEFAULT_MINIMUM: - *control->def = lower_bound; - break; - case LADSPA_HINT_DEFAULT_LOW: - *control->def = lower_bound * 0.75 + upper_bound * 0.25; - break; - case LADSPA_HINT_DEFAULT_MIDDLE: - *control->def = lower_bound * 0.5 + upper_bound * 0.5; - break; - case LADSPA_HINT_DEFAULT_HIGH: - *control->def = lower_bound * 0.25 + upper_bound * 0.75; - break; - case LADSPA_HINT_DEFAULT_MAXIMUM: - *control->def = upper_bound; - break; - case LADSPA_HINT_DEFAULT_0: - *control->def = 0.0; - break; - case LADSPA_HINT_DEFAULT_1: - *control->def = 1.0; - break; - case LADSPA_HINT_DEFAULT_100: - *control->def = 100.0; - break; - case LADSPA_HINT_DEFAULT_440: - *control->def = 440.0; - break; - default: - ERR_OUT ("default not found"); - free(control->def); - control->def = NULL; - } - } - else - control->def = NULL; - - /* Check the default */ - if (control->def) { - if (*control->def < control->min) { - ERR_OUT ("default smaller than the minimum"); - *control->def = control->min; - } - if (*control->def > control->max) { - ERR_OUT ("default greater than the maximum"); - *control->def = control->max; - } - } - - /* control->inc & Overrides */ - if (LADSPA_IS_HINT_TOGGLED(descriptor)) { - control->min = 0.0; - control->max = 1.0; - control->inc.fine = 1.0; - control->inc.coarse = 1.0; - control->type = VAL_TOGGLE; - if (control->def) *control->def = nearbyintf(*control->def); - } - else if (LADSPA_IS_HINT_INTEGER(descriptor)) { - control->min = nearbyintf(control->min); - control->max = nearbyintf(control->max); - control->inc.fine = 1.0; - control->inc.coarse = 1.0; - /* set_digits(0); */ - control->type = VAL_INT; - if (control->def) *control->def = nearbyintf(*control->def); - } - else { - control->inc.fine = (control->max - control->min) / 500; - control->inc.coarse = (control->max - control->min) / 50; - /* set_digits(2); */ - control->type = VAL_FLOAT; - } - - /* control->sel, control->val */ - if (control->def) control->sel = *control->def; - else control->sel = control->min; - control->alt_sel = control->sel; - *control->val = control->sel; - - return 0; -} - int build_controls(struct window *window, state_t *state) { int rc = 0; @@ -237,7 +86,7 @@ int build_controls(struct window *window, state_t *state) (*window->controls)[c] = (control_t *)malloc(sizeof(control_t)); if (!(*window->controls)[c]) return (ERR_OUT ("memory allocation error"), 1); - if (init_control((*window->controls)[c++], state, p)) + if (control_init((*window->controls)[c++], state, p)) rc = 1; } @@ -294,8 +143,8 @@ void draw_controls(struct window* window_ptr) wattroff(window_ptr->window_ptr, WA_BOLD|COLOR_PAIR(color)); wattron(window_ptr->window_ptr, COLOR_PAIR(1)); wprintw( window_ptr->window_ptr, " %s ", - (control->type == VAL_TOGGLE) ? - "?" : (control->type == VAL_INT) ? "i" : "f" ); + (control->type == JACKSPA_TOGGLE) ? + "?" : (control->type == JACKSPA_INT) ? "i" : "f" ); wattron(window_ptr->window_ptr, COLOR_PAIR(high)); snprintf(fmt, sizeof(fmt), "%%-%dF", cols/6 - 2); wprintw(window_ptr->window_ptr, fmt, control->sel); @@ -485,11 +334,11 @@ loop: *(*C)[c]->val = (*C)[c]->sel; goto loop; case 'x': - c_exchange(cl); + control_exchange(cl); goto loop; case 'X': for (c = 0; c < W->count; c++) - c_exchange((*W->controls)[c]); + control_exchange((*W->controls)[c]); goto loop; case KEY_BACKSPACE: case 'd': @@ -536,9 +385,7 @@ loop: case '8': case '9': val = ((LADSPA_Data)(k - 48)) / 10.0; - cl->sel = (1.0 - val) * cl->min + val * cl->max; - if (cl->type == VAL_INT || cl->type == VAL_TOGGLE) - cl->sel = nearbyintf(cl->sel); + cl->sel = control_rounding(cl, (1.0 - val) * cl->min + val * cl->max); goto loop; case KEY_DOWN: case 'j': -- 2.11.4.GIT