Index: src/utils/parameter.c
===================================================================
--- src/utils/parameter.c	(revision 650cae3e3ea4b12d4c759f824c0ca95a4895845d)
+++ src/utils/parameter.c	(revision 650cae3e3ea4b12d4c759f824c0ca95a4895845d)
@@ -0,0 +1,142 @@
+/*
+  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+
+  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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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);
+}
Index: src/utils/parameter.h
===================================================================
--- src/utils/parameter.h	(revision 650cae3e3ea4b12d4c759f824c0ca95a4895845d)
+++ src/utils/parameter.h	(revision 650cae3e3ea4b12d4c759f824c0ca95a4895845d)
@@ -0,0 +1,160 @@
+/*
+  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+
+  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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 */
+
Index: tests/src/utils/test-parameter.c
===================================================================
--- tests/src/utils/test-parameter.c	(revision 650cae3e3ea4b12d4c759f824c0ca95a4895845d)
+++ tests/src/utils/test-parameter.c	(revision 650cae3e3ea4b12d4c759f824c0ca95a4895845d)
@@ -0,0 +1,68 @@
+#include <aubio.h>
+#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;
+}
