Index: include/libroardsp/filter.h
===================================================================
--- include/libroardsp/filter.h	(revision 4953)
+++ include/libroardsp/filter.h	(revision 5269)
@@ -39,17 +39,20 @@
 #include "libroardsp.h"
 
-#define ROARDSP_FILTER_NONE           0
-#define ROARDSP_FILTER_AMP            1
-#define ROARDSP_FILTER_LOWP           2
-#define ROARDSP_FILTER_HIGHP          3
-#define ROARDSP_FILTER_MODULATE       4
-#define ROARDSP_FILTER_QUANTIFY       5
-#define ROARDSP_FILTER_CLIP           6
-#define ROARDSP_FILTER_ADD            7
-#define ROARDSP_FILTER_DOWNMIX        8
-#define ROARDSP_FILTER_DCBLOCK        9
-#define ROARDSP_FILTER_SWAP          10
-#define ROARDSP_FILTER_SPEEX_PREP    11
-#define ROARDSP_FILTER_AGC           12
+                                        /* implemented? */
+#define ROARDSP_FILTER_NONE            0
+#define ROARDSP_FILTER_AMP             1 /* yes */
+#define ROARDSP_FILTER_LOWP            2 /* yes */
+#define ROARDSP_FILTER_HIGHP           3 /* yes */
+#define ROARDSP_FILTER_MODULATE        4
+#define ROARDSP_FILTER_QUANTIFY        5 /* yes */
+#define ROARDSP_FILTER_CLIP            6 /* yes */
+#define ROARDSP_FILTER_ADD             7 /* yes */
+#define ROARDSP_FILTER_DOWNMIX         8 /* yes */
+#define ROARDSP_FILTER_DCBLOCK         9
+#define ROARDSP_FILTER_SWAP           10 /* yes */
+#define ROARDSP_FILTER_SPEEX_PREP     11 /* yes */
+#define ROARDSP_FILTER_AGC            12
+#define ROARDSP_FILTER_NOISEGATE      13
+#define ROARDSP_FILTER_RESPONSE_CURVE 14
 
 // filter CTLs:
@@ -120,6 +123,6 @@
 
 // funcs:
-int    roardsp_filter_str2id(char * str);
-char * roardsp_filter_id2str(int id);
+int          roardsp_filter_str2id(const char * str);
+const char * roardsp_filter_id2str(const int id);
 int    roardsp_filter_new   (struct roardsp_filter ** filter, struct roar_stream * stream, int id);
 #define roardsp_filter_free(x) roardsp_filter_uninit((x))
Index: include/libroardsp/filters.h
===================================================================
--- include/libroardsp/filters.h	(revision 5181)
+++ include/libroardsp/filters.h	(revision 5269)
@@ -68,5 +68,5 @@
  ROARDSP_CLIP_MODE_ZERO  = 1,
  ROARDSP_CLIP_MODE_WARP  = 2,
- ROARDSP_CLIP_MODE_NOISE  = 3,
+ ROARDSP_CLIP_MODE_NOISE = 3
 };
 
@@ -94,4 +94,18 @@
 };
 
+enum roardsp_responsecurve_mode {
+ ROARDSP_RESPONSECURVE_MODE_PASS = 0, /* pass:           o = i                   */
+ ROARDSP_RESPONSECURVE_MODE_LIN  = 1, /* linear:         o = -(1-i)^(N+1) + 1    */
+ ROARDSP_RESPONSECURVE_MODE_ILIN = 2, /* inverse linear: o = i**(N+1)            */
+ ROARDSP_RESPONSECURVE_MODE_SIN  = 3, /* sin:            o = sin(pi/2 * i)^N     */
+ ROARDSP_RESPONSECURVE_MODE_ISIN = 4, /* inverse sin:    o = 1-sin((1-i)*pi/2)^N */
+ ROARDSP_RESPONSECURVE_MODE_COS  = 5, /* cos:            o = 0.5-cos(i*pi)/2     */
+ ROARDSP_RESPONSECURVE_MODE_ICOS = 6, /* inverse cos:    o = 2*i-0.5+cos(i*pi)/2 */
+};
+
+struct roardsp_responsecurve {
+ enum roardsp_responsecurve_mode mode_pos, mode_neg;
+ int32_t N;
+};
 
 // filter:
@@ -176,4 +190,11 @@
 #endif
 
+int roardsp_responsecurve_init  (struct roardsp_filter * filter, struct roar_stream * stream, int id);
+int roardsp_responsecurve_uninit(struct roardsp_filter * filter);
+int roardsp_responsecurve_calc32(struct roardsp_filter * filter, void * data, size_t samples);
+int roardsp_responsecurve_calc16(struct roardsp_filter * filter, void * data, size_t samples);
+int roardsp_responsecurve_calc8 (struct roardsp_filter * filter, void * data, size_t samples);
+int roardsp_responsecurve_ctl   (struct roardsp_filter * filter, int cmd, void * data);
+int roardsp_responsecurve_reset (struct roardsp_filter * filter, int what);
 
 #endif
Index: libroardsp/Makefile
===================================================================
--- libroardsp/Makefile	(revision 4748)
+++ libroardsp/Makefile	(revision 5269)
@@ -7,5 +7,5 @@
 OBJS=libroardsp.o convert.o midside.o poly.o filter.o filterchain.o remove.o transcode.o vio_transcode.o rms.o fader.o mixer.o amp.o interleave.o channels.o resampler_poly3.o float.o
 OLDROAR=midi.o
-FILTER=filter_lowp.o filter_highp.o filter_amp.o filter_quantify.o filter_add.o filter_clip.o filter_downmix.o filter_dcblock.o filter_swap.o filter_agc.o filter_speex_prep.o
+FILTER=filter_lowp.o filter_highp.o filter_amp.o filter_quantify.o filter_add.o filter_clip.o filter_downmix.o filter_dcblock.o filter_swap.o filter_agc.o filter_speex_prep.o filter_responsecurve.o
 MIDI=synth.o
 CODECS=alaw.o mulaw.o
Index: libroardsp/filter.c
===================================================================
--- libroardsp/filter.c	(revision 5181)
+++ libroardsp/filter.c	(revision 5269)
@@ -69,4 +69,9 @@
            {NULL, NULL, NULL},{NULL, NULL, NULL},{NULL, roardsp_speex_prep_calc161, NULL},{NULL, NULL, NULL},{NULL, NULL, NULL}}},
 #endif
+ {ROARDSP_FILTER_RESPONSE_CURVE, "ResponseCurve", roardsp_responsecurve_init, roardsp_responsecurve_uninit,
+                                                  roardsp_responsecurve_ctl, roardsp_responsecurve_reset, {
+           {NULL, NULL, NULL},{roardsp_responsecurve_calc8, NULL, NULL},{roardsp_responsecurve_calc16, NULL, NULL},
+           {NULL, NULL, NULL},{roardsp_responsecurve_calc32, NULL, NULL}
+ }},
  {-1, NULL, NULL, NULL, NULL, NULL, {
       // ?                  8Bit               16Bit              24Bit              32Bit
@@ -75,5 +80,5 @@
 };
 
-int    roardsp_filter_str2id(char * str) {
+int    roardsp_filter_str2id(const char * str) {
  struct _roardsp_filterlist * l = _roardsp_filterlist;
 
@@ -88,5 +93,5 @@
 }
 
-char * roardsp_filter_id2str(int id) {
+const char * roardsp_filter_id2str(const int id) {
  struct _roardsp_filterlist * l = _roardsp_filterlist;
 
@@ -170,4 +175,6 @@
  filter->reset  = l->reset;
 
+ ROAR_DBG("roardsp_filter_init(filter=%p, stream=%p, id=%i): bytes=%i", filter, stream, id, bytes);
+
  if ( filter->channels < 3 )
   calc = l->calc[bytes][filter->channels];
Index: libroardsp/filter_responsecurve.c
===================================================================
--- libroardsp/filter_responsecurve.c	(revision 5269)
+++ libroardsp/filter_responsecurve.c	(revision 5269)
@@ -0,0 +1,185 @@
+//filter_amp.c:
+
+/*
+ *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2011
+ *
+ *  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"
+
+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));
+
+ 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) {
+ 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) {
+ return 0.5 - cos(i * M_PI)/2.;
+}
+
+static double __func_icos(double i, double 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;
+}
+
+//ll
