From: Paul Brossier Date: Sun, 27 Oct 2013 23:15:48 +0000 (+0100) Subject: src/utils/parameter.{c,h}: added simple parameter with linear interpolation X-Git-Tag: 0.4.0-beta1~108 X-Git-Url: https://git.aubio.org/?a=commitdiff_plain;h=650cae3e3ea4b12d4c759f824c0ca95a4895845d;p=aubio.git src/utils/parameter.{c,h}: added simple parameter with linear interpolation --- diff --git a/src/utils/parameter.c b/src/utils/parameter.c new file mode 100644 index 00000000..cd4ea1c0 --- /dev/null +++ b/src/utils/parameter.c @@ -0,0 +1,142 @@ +/* + Copyright (C) 2003-2013 Paul Brossier + + This file is part of aubio. + + aubio is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + aubio 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 aubio. If not, see . + +*/ + +#include "config.h" +#include "aubio_priv.h" +#include "parameter.h" + +#define AUBIO_PARAM_MAX_STEPS 2000 +#define AUBIO_PARAM_MIN_STEPS 1 + +struct _aubio_parameter_t { + smpl_t current_value; + smpl_t target_value; + smpl_t increment; + + smpl_t max_value; + smpl_t min_value; + + uint_t steps; +}; + +aubio_parameter_t * new_aubio_parameter (smpl_t min_value, smpl_t max_value, uint_t steps ) +{ + aubio_parameter_t * param = AUBIO_NEW(aubio_parameter_t); + + param->min_value = min_value; + param->max_value = max_value; + param->steps = steps; + + param->current_value = param->min_value; + param->target_value = param->current_value; + param->increment = 0.; + + return param; +} + +uint_t aubio_parameter_set_target_value ( aubio_parameter_t * param, smpl_t value ) +{ + uint_t err = AUBIO_OK; + if (value < param->min_value ) { + param->target_value = param->min_value; + err = AUBIO_FAIL; + } else if ( value > param->max_value ) { + param->target_value = param->max_value; + err = AUBIO_FAIL; + } else { + param->target_value = value; + } + param->increment = ( param->target_value - param->current_value ) / param->steps; + return err; +} + +uint_t aubio_parameter_set_current_value ( aubio_parameter_t * param, smpl_t value ) +{ + uint_t err = AUBIO_OK; + if (value < param->min_value ) { + param->current_value = param->min_value; + err = AUBIO_FAIL; + } else if ( value > param->max_value ) { + param->current_value = param->max_value; + err = AUBIO_FAIL; + } else { + param->current_value = value; + } + param->target_value = param->current_value; + param->increment = 0; + return err; +} + +smpl_t aubio_parameter_get_current_value ( aubio_parameter_t * s ) +{ + return s->current_value; +} + +smpl_t aubio_parameter_get_next_value ( aubio_parameter_t * s ) +{ + if ( ABS(s->current_value - s->target_value) > ABS(s->increment) ) { + s->current_value += s->increment; + } else { + s->current_value = s->target_value; + } + return s->current_value; +} + +uint_t aubio_parameter_set_steps ( aubio_parameter_t * param, uint_t steps ) +{ + if (steps < AUBIO_PARAM_MIN_STEPS || steps > AUBIO_PARAM_MAX_STEPS) { + return AUBIO_FAIL; + } + param->steps = steps; + param->increment = ( param->target_value - param->current_value ) / param->steps; + return AUBIO_OK; +} + +uint_t aubio_parameter_get_steps ( aubio_parameter_t * param ) +{ + return param->steps; +} + +uint_t aubio_parameter_set_min_value ( aubio_parameter_t * param, smpl_t min_value ) +{ + param->min_value = min_value; + return AUBIO_OK; +} + +smpl_t aubio_parameter_get_min_value ( aubio_parameter_t * param ) +{ + return param->min_value; +} + +uint_t aubio_parameter_set_max_value ( aubio_parameter_t * param, smpl_t max_value ) +{ + param->max_value = max_value; + return AUBIO_OK; +} + +smpl_t aubio_parameter_get_max_value ( aubio_parameter_t * param ) +{ + return param->max_value; +} + +void del_aubio_parameter ( aubio_parameter_t * param ) +{ + AUBIO_FREE(param); +} diff --git a/src/utils/parameter.h b/src/utils/parameter.h new file mode 100644 index 00000000..51c2cdac --- /dev/null +++ b/src/utils/parameter.h @@ -0,0 +1,160 @@ +/* + Copyright (C) 2003-2013 Paul Brossier + + This file is part of aubio. + + aubio is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef _AUBIO_PARAMETER_H +#define _AUBIO_PARAMETER_H + +/** \file + + Parameter with linear interpolation + + This object manages a parameter, with minimum and maximum values, and a + number of steps to compute linear interpolation between two values. + + \example utils/test-parameter.c + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** parameter object */ +typedef struct _aubio_parameter_t aubio_parameter_t; + +/** create new parameter object + + \param min_value the minimum value of the new parameter + \param max_value the maximum value of the new parameter + \param steps the number of steps to interpolate from the old value to the target value + + \return the newly created ::aubio_parameter_t + +*/ +aubio_parameter_t * new_aubio_parameter(smpl_t min_value, smpl_t max_value, uint_t steps); + +/** set target value of the parameter + + \param param parameter, created by ::new_aubio_parameter + \param value new target value + + \return 0 if successful, 1 otherwise + +*/ +uint_t aubio_parameter_set_target_value ( aubio_parameter_t * param, smpl_t value ); + +/** get next parameter + + \param param parameter, created by ::new_aubio_parameter + + \return new interpolated parameter value + +*/ +smpl_t aubio_parameter_get_next_value ( aubio_parameter_t * param ); + +/** get current parameter value, without interpolation + + \param param parameter, created by ::new_aubio_parameter + + \return current value + +*/ +smpl_t aubio_parameter_get_current_value ( aubio_parameter_t * param ); + +/** set current parameter value, skipping interpolation + + \param param parameter, created by ::new_aubio_parameter + \param value new parameter value + + \return 0 if successful, 1 otherwise + +*/ +uint_t aubio_parameter_set_current_value ( aubio_parameter_t * param, smpl_t value ); + +/** set number of steps used for interpolation + + \param param parameter, created by ::new_aubio_parameter + \param steps new number of steps + + \return 0 if successful, 1 otherwise + +*/ +uint_t aubio_parameter_set_steps ( aubio_parameter_t * param, uint_t steps ); + +/** get number of steps of this parameter + + \param param parameter, created by ::new_aubio_parameter + + \return number of steps + +*/ +uint_t aubio_parameter_get_steps ( aubio_parameter_t * param); + +/** set minimum value of this parameter + + \param param parameter, created by ::new_aubio_parameter + \param min_value new minimum value + + \return 0 if successful, 1 otherwise + +*/ +uint_t aubio_parameter_set_min_value ( aubio_parameter_t * param, smpl_t min_value ); + +/** get minimum value of this parameter + + \param param parameter, created by ::new_aubio_parameter + + \return minimum value + +*/ +smpl_t aubio_parameter_get_min_value ( aubio_parameter_t * param ); + +/** set maximum value of this parameter + + \param param parameter, created by ::new_aubio_parameter + \param max_value new maximum value + + \return 0 if successful, 1 otherwise + +*/ +uint_t aubio_parameter_set_max_value ( aubio_parameter_t * param, smpl_t max_value ); + +/** get maximum value of this parameter + + \param param parameter, created by ::new_aubio_parameter + + \return maximum value + +*/ +smpl_t aubio_parameter_get_max_value ( aubio_parameter_t * param ); + +/** destroy ::aubio_parameter_t object + + \param param parameter, created by ::new_aubio_parameter + +*/ +void del_aubio_parameter( aubio_parameter_t * param ); + +#ifdef __cplusplus +} +#endif + +#endif /* _AUBIO_PARAMETER_H */ + diff --git a/tests/src/utils/test-parameter.c b/tests/src/utils/test-parameter.c new file mode 100644 index 00000000..177e63d9 --- /dev/null +++ b/tests/src/utils/test-parameter.c @@ -0,0 +1,68 @@ +#include +#include "utils_tests.h" + +void get_some_steps ( aubio_parameter_t * param ) +{ + uint_t i = 0; + uint_t steps = aubio_parameter_get_steps ( param ); + + PRINT_MSG("next steps (%d) values:", steps ); + for (i = 0; i < steps; i ++ ) { + PRINT_MSG(" %f", aubio_parameter_get_next_value (param) ); + } + PRINT_MSG("\n"); + + PRINT_MSG("next 3 values:"); + for (i = 0; i < 3; i ++ ) { + PRINT_MSG(" %f", aubio_parameter_get_next_value (param) ); + } + PRINT_MSG("\n"); + +} + +int main () +{ + smpl_t max_value = 100.; + smpl_t min_value = 0.; + uint_t steps = 10; + + aubio_parameter_t * param = new_aubio_parameter ( min_value, max_value, steps ); + + PRINT_MSG("initial value: %f, steps: %d\n", aubio_parameter_get_current_value + (param) , aubio_parameter_get_steps (param) ); + + PRINT_MSG("target: max_value / 2\n"); + aubio_parameter_set_target_value ( param, max_value ); + get_some_steps ( param ); + + PRINT_MSG("target: max_value / 2\n"); + aubio_parameter_set_target_value ( param, max_value / 2 ); + get_some_steps ( param ); + + PRINT_MSG("target: max_value * 2\n"); + aubio_parameter_set_target_value ( param, max_value * 2); + get_some_steps ( param ); + + PRINT_MSG("steps: 1, target: -max\n"); + aubio_parameter_set_steps ( param, 1); + aubio_parameter_set_target_value ( param, - max_value); + get_some_steps ( param ); + + PRINT_MSG("steps: 30, current value: max, target: min\n"); + aubio_parameter_set_current_value ( param, max_value ); + aubio_parameter_set_target_value ( param, min_value ); + aubio_parameter_set_steps ( param, 7 ); + get_some_steps ( param ); + + PRINT_MSG("steps: 30, max value: max * 2, min value: -max, current value: -max, target: max\n"); + aubio_parameter_set_min_value ( param, - max_value ); + aubio_parameter_set_max_value ( param, 2. * max_value ); + aubio_parameter_set_current_value ( param, - max_value ); + aubio_parameter_set_target_value ( param, max_value ); + aubio_parameter_set_steps ( param, 10 ); + get_some_steps ( param ); + + del_aubio_parameter (param); + + return 0; +}