#include "ext.h"
#include "z_dsp.h"
#include <cmath>
typedef struct {
t_pxobject msp_data;
double sum;
long count, chunk;
void* outputDb, outputRms, outputPeak;
} MyObject;
void* object_data;
void main (void);
void* create_object (long maxsize);
void InputBang (MyObject* mo);
void InputChunkSize (MyObject* mo, long value);
void MessageDSP (MyObject* mo, t_signal** signal, short* count);
void MessageClear (MyObject* mo);
t_int* Perform (t_int *parameters);
void outputAnalysis (MyObject* mo);
void main(void) {
setup((t_messlist**)&object_data, (method)create_object,
(method)dsp_free, (short)sizeof(MyObject),
NULL, A_LONG, A_NOTHING);
addinx((method)InputChunkSize, 1);
addmess((method)MessageDSP, "dsp", A_CANT, A_NOTHING);
addmess((method)MessageClear, "clear", A_NOTHING);
addbang((method)InputBang);
dsp_initclass();
}
void* create_object(long chunksize) {
MyObject *mo = (MyObject*)newobject(object_data);
dsp_setup((t_pxobject*)mo, 1);
outlet_new(mo->msp_data, "signal");
intin(mo, 1);
mo->outputPeak = floatout(mo);
mo->outputRms = floatout(mo);
mo->outputDb = floatout(mo);
mo->chunk = chunksize;
MessageClear(mo);
return mo;
}
void InputBang(MyObject* mo) {
outputAnalysis(mo);
MessageClear(mo);
}
void InputChunkSize(MyObject *mo, long value) {
mo->chunk = value;
}
void MessageDSP(MyObject* mo, t_signal** signal, short* count) {
#pragma unused(count)
int paramcount = 5;
dsp_add(Perform, paramcount,
paramcount, mo, signal[0]->s_vec, signal[0]->s_vec, signal[0]->s_n);
}
void MessageClear(MyObject* mo) {
mo->count = 0;
mo->sum = 0.0;
}
t_int* Perform(t_int *parameters) {
long paramcount = (long) (parameters[1]);
MyObject *mo = (MyObject*)(parameters[2]);
t_float *input = (t_float*) (parameters[3]);
t_float *output = (t_float*) (parameters[4]);
long count = (long) (parameters[5]);
long i;
for (i=0; i<count; i++) {
mo->sum += input[i] * input[i];
output[i] = input[i];
mo->count++;
if ((mo->count >= mo->chunk) && (mo->chunk > 0)) {
outputAnalysis(mo);
MessageClear(mo);
}
}
return parameters+paramcount+1;
}
void outputAnalysis(MyObject* mo) {
float db, rms, peak;
if (mo->sum <= 0.0) {
db = -1000.0;
} else {
db = (float)(10.0 * log10(mo->sum/mo->count));
}
rms = (float)sqrt(mo->sum / mo->count);
peak = (float)(sqrt(2) * rms);
outlet_float(mo->outputPeak, peak);
outlet_float(mo->outputRms, rms);
outlet_float(mo->outputDb, db);
}
|