aboutsummaryrefslogtreecommitdiff
path: root/transient~.c
diff options
context:
space:
mode:
Diffstat (limited to 'transient~.c')
-rw-r--r--transient~.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/transient~.c b/transient~.c
new file mode 100644
index 0000000..160ad52
--- /dev/null
+++ b/transient~.c
@@ -0,0 +1,133 @@
+// sigpack
+// for
+// pure-data
+// by weiss
+// www.weiss-archiv.de
+
+#include "m_pd.h"
+#include <math.h>
+#include <string.h>
+#ifdef _MSC_VER
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#define BUFFER_SIZE 10240
+#define SSTAB 0.00001f
+#define ASTAB 0.02f
+//Truncate-to-zero modulo (ANSI C doesn`t specify) will only work
+//if -m < v < 2m
+#define MOD(v,m) (v<0?v+m:(v>=m?v-m:v))
+
+// ------------------------ transient~ -----------------------------
+// transient mangler
+// code from swh_plugins by steve harris www.plugin.org.uk
+
+static t_class *transient_tilde_class;
+
+typedef struct _transient_tilde
+{
+ t_object x_obj;
+ t_sample x_attack;//-1 - 1
+ t_sample x_sustain;//-1 - 1
+ float *x_buffer;
+ int x_buffer_pos;
+ long x_count;
+ float x_fast_buffer_sum;
+ float x_fast_track;
+ float x_medi_buffer_sum;
+ float x_medi_track;
+ int x_sample_rate;
+ float x_slow_buffer_sum;
+ float x_slow_track;
+ float x_f;
+} t_transient_tilde;
+
+static void *transient_tilde_new(t_floatarg attack, t_floatarg sustain)
+{
+ t_transient_tilde *x = (t_transient_tilde *)pd_new(transient_tilde_class);
+ x->x_attack = attack;
+ x->x_sustain = sustain;
+ outlet_new(&x->x_obj, gensym("signal"));
+ floatinlet_new(&x->x_obj, &x->x_attack);
+ floatinlet_new(&x->x_obj, &x->x_sustain);
+ //memset(x->x_buffer, '/0', BUFFER_SIZE * sizeof(float));
+ x->x_buffer = getbytes(BUFFER_SIZE * sizeof(float));
+ x->x_fast_buffer_sum = 0.1;
+ x->x_medi_buffer_sum = 0.1;
+ x->x_slow_buffer_sum = 0.1;
+ x->x_buffer_pos = 0;
+ x->x_fast_track = 0.0;
+ x->x_medi_track = 0.0;
+ x->x_slow_track = 0.0;
+ x->x_count = 0;
+ x->x_sample_rate = sys_getsr();
+ x->x_f = 0;
+ if (attack) x->x_attack = attack;
+ else x->x_attack = 0.0;
+ if (sustain) x->x_sustain = sustain;
+ else x->x_sustain = 0.0;
+ return (x);
+}
+
+static t_int *transient_tilde_perform(t_int *w)
+{
+ t_transient_tilde *x = (t_transient_tilde *)(w[1]);
+ t_float *in = (t_float *)(w[2]);
+ t_float *out = (t_float *)(w[3]);
+ int n = (int)(w[4]);
+ float f;
+ const int fast_sum_size = (2 * x->x_sample_rate) / 1000;
+ const int medi_sum_size = (25 * x->x_sample_rate) / 1000;
+ const int slow_sum_size = (100 * x->x_sample_rate) / 1000;
+ const float fast_track_lag = 1.5f / fast_sum_size;
+ const float medi_track_lag = 1.0f / medi_sum_size;
+ const float slow_track_lag = 1.3f / slow_sum_size;
+ float ratio;
+
+ while (n--)
+ {
+ f = *in++;
+ x->x_buffer[x->x_buffer_pos] = fabs(f);
+ x->x_fast_buffer_sum += x->x_buffer[x->x_buffer_pos];
+ x->x_medi_buffer_sum += x->x_buffer[x->x_buffer_pos];
+ x->x_slow_buffer_sum += x->x_buffer[x->x_buffer_pos];
+ x->x_fast_buffer_sum -= x->x_buffer[MOD(x->x_buffer_pos - fast_sum_size, BUFFER_SIZE)];
+ x->x_medi_buffer_sum -= x->x_buffer[MOD(x->x_buffer_pos - medi_sum_size, BUFFER_SIZE)];
+ x->x_slow_buffer_sum -= x->x_buffer[MOD(x->x_buffer_pos - slow_sum_size, BUFFER_SIZE)];
+ if(x->x_count++ > slow_sum_size) {
+ x->x_fast_track += (x->x_fast_buffer_sum/fast_sum_size - x->x_fast_track) * fast_track_lag;
+ x->x_medi_track += (x->x_medi_buffer_sum/medi_sum_size - x->x_medi_track) * medi_track_lag;
+ x->x_slow_track += (x->x_slow_buffer_sum/slow_sum_size - x->x_slow_track) * slow_track_lag;
+ }
+ //Attack
+ ratio = (x->x_fast_track + ASTAB) / (x->x_medi_track + ASTAB);
+ if (ratio * x->x_attack > 1.0f) {
+ f *= ratio * x->x_attack;
+ } else if (ratio * x->x_attack < 1.0f) {
+ f /= ratio * -x->x_attack;
+ }
+ //Sustain
+ ratio = (x->x_slow_track + SSTAB) / (x->x_medi_track + SSTAB);
+ if (ratio * x->x_sustain > 1.0f) {
+ f *= ratio * x->x_sustain;
+ } else if (ratio * x->x_sustain < -1.0f) {
+ f /= ratio * x->x_sustain;
+ }
+ *out++ = f;
+ x->x_buffer_pos = (x->x_buffer_pos +1) % BUFFER_SIZE;
+ }
+ return (w+5);
+}
+
+static void transient_tilde_dsp(t_transient_tilde *x, t_signal **sp)
+{
+ dsp_add(transient_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+void transient_tilde_setup(void)
+{
+ transient_tilde_class = class_new(gensym("transient~"), (t_newmethod)transient_tilde_new, 0,
+ sizeof(t_transient_tilde), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(transient_tilde_class, t_transient_tilde, x_f);
+ class_addmethod(transient_tilde_class, (t_method)transient_tilde_dsp, gensym("dsp"), 0);
+}