//filter_amp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2013 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp 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 software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #ifdef ROAR_HAVE_LIBM int roardsp_responsecurve_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct roardsp_responsecurve * self = roar_mm_malloc(sizeof(struct roardsp_responsecurve)); (void)stream, (void)id; ROAR_DBG("roardsp_responsecurve_init(filter=%p, stream=%p, id=%i) = ?", filter, stream, id); if ( self == NULL ) return -1; memset(self, 0, sizeof(struct roardsp_responsecurve)); filter->inst = (void*) self; roardsp_filter_reset(filter, ROARDSP_RESET_FULL); return 0; } int roardsp_responsecurve_uninit(struct roardsp_filter * filter) { roar_mm_free(filter->inst); return 0; } static double __func_pass(double i, double N) { (void)N; return i; } static double __func_linear(double i, double N) { return -pow(1. - i, N + 1.) + 1.; } static double __func_ilinear(double i, double N) { return pow(i, N + 1.); } static double __func_sin(double i, double N) { return pow(sin(M_PI_2 * i), N); } static double __func_isin(double i, double N) { return 1. - pow(sin((1. - i) * M_PI_2), N); } static double __func_cos(double i, double N) { (void)N; return 0.5 - cos(i * M_PI)/2.; } static double __func_icos(double i, double N) { (void)N; return 2.*i - 0.5 + cos(i * M_PI)/2.; } static inline double _oddify(double x, double N, double (*func)(double, double)) { if ( x < 0. ) { return -func(0. - x, N); } else { return func(x, N); } } static inline double _calc(double x, struct roardsp_responsecurve * self, double N) { double (*func)(double, double) = NULL; enum roardsp_responsecurve_mode mode; if ( x > 0. ) { mode = self->mode_pos; } else { mode = self->mode_neg; } switch (mode) { case ROARDSP_RESPONSECURVE_MODE_PASS: func = __func_pass; break; case ROARDSP_RESPONSECURVE_MODE_LIN: func = __func_linear; break; case ROARDSP_RESPONSECURVE_MODE_ILIN: func = __func_ilinear; break; case ROARDSP_RESPONSECURVE_MODE_SIN: func = __func_sin; break; case ROARDSP_RESPONSECURVE_MODE_ISIN: func = __func_isin; break; case ROARDSP_RESPONSECURVE_MODE_COS: func = __func_cos; break; case ROARDSP_RESPONSECURVE_MODE_ICOS: func = __func_icos; break; default: func = __func_linear; break; } return _oddify(x, N, func); } #define _calcX(bits,fact) \ int roardsp_responsecurve_calc##bits (struct roardsp_filter * filter, void * data, size_t samples) { \ struct roardsp_responsecurve * self = (struct roardsp_responsecurve *) filter->inst; \ int##bits##_t * samp = (int##bits##_t *) data; \ register double s; \ size_t i; \ \ for (i = 0; i < samples; i++) { \ s = samp[i]; \ s /= (double)(fact); \ s = _calc(s, self, self->N); \ s *= (double)(fact); \ samp[i] = s; \ }; \ \ return 0; \ } _calcX(8,128.) _calcX(16,32768.) _calcX(32,2147483648.) int roardsp_responsecurve_ctl (struct roardsp_filter * filter, int cmd, void * data) { struct roardsp_responsecurve * self = (struct roardsp_responsecurve *) filter->inst; int32_t old; if ( cmd == ROARDSP_FCTL_N ) { old = self->N; self->N = *(int32_t*)data; *(int32_t*)data = old; } else if ( cmd == ROARDSP_FCTL_MODE ) { old = self->mode_pos; self->mode_pos = *(int32_t*)data; *(int32_t*)data = old; } else if ( cmd == ROARDSP_FCTL_Q ) { old = self->mode_neg; self->mode_neg = *(int32_t*)data; *(int32_t*)data = old; } else { return -1; } return 0; } int roardsp_responsecurve_reset (struct roardsp_filter * filter, int what) { struct roardsp_responsecurve * self; if ( filter == NULL ) return -1; if ( filter->inst == NULL ) return -1; self = filter->inst; switch (what) { case ROARDSP_RESET_NONE: case ROARDSP_RESET_STATE: return 0; break; case ROARDSP_RESET_FULL: self->mode_pos = self->mode_neg = ROARDSP_RESPONSECURVE_MODE_LIN; self->N = 1; return 0; break; default: return -1; } return -1; } #endif //ll