// // Copyright: Copyright 2003 Craig Stuart Sapp // Programmer: Craig Stuart Sapp // Creation Date: Thu Mar 13 09:50:15 PST 2003 // Last Modified: Thu Mar 13 10:20:48 PST 2003 // Filename: midismooth.c // Web Address: http://peabody.sapp.org/class/dmp2/lab/midismooth/midismooth.c // Syntax: C; Max4/MSP2 External Object; CodeWarrior 6.0 // OS: Mac OS 9; PPC // // Description: Smooth and scale MIDI data for audio rate control data. // with the following difference equation: // y[n] = k x[n] + (1-k) y[n-1] // #include "ext.h" #include "z_dsp.h" typedef struct { t_pxobject msp_data; // must always be the first field; used by MSP float k; // feed foward/back control gain. default is 0.001 float min; // minimum scaling value float max; // maximum scaling value long input; // last MIDI input value received; float scale; // precomputing the scale value; float scaledinput; // scaled input value float lastoutput; // last output value from filter. } MyObject; void* object_data; // pointer to data for object (created in setup()); // function declarations: void main (void); void* create_object (void); void InputMIDI (MyObject* mo, long value); void InputGain (MyObject* mo, float value); void InputMin (MyObject* mo, float value); void InputMax (MyObject* mo, float value); void MessageDSP (MyObject* mo, t_signal** signal, short* count); void MessageClear (MyObject* mo); t_int* Perform (t_int *parameters); float randfloat (void); ////////////////////////////////////////////////////////////////////////// // // Initialization functions: // void main(void) { setup((t_messlist**)&object_data, (method)create_object, (method)dsp_free, (short)sizeof(MyObject), NULL, A_NOTHING); addint((method)InputMIDI); // input 1 for processing MIDI Data addftx((method)InputGain, 3); // input 2 for filter gain addftx((method)InputMin, 2); // input 3 for output minimum addftx((method)InputMax, 1); // input 4 for output maximum addmess((method)MessageClear, "clear", A_NOTHING); addmess((method)MessageDSP, "dsp", A_CANT, A_NOTHING); dsp_initclass(); } ////////////////////////////// // // create_object -- object initializing function. // void* create_object(void) { MyObject *mo = (MyObject*)newobject(object_data); dsp_setup((t_pxobject*)mo, 0); // create no signal inputs outlet_new((t_pxobject*)mo, "signal"); // processed MIDI signal output 1 floatin(mo, 1); // input 4 for output maximum floatin(mo, 2); // input 3 for output minimum floatin(mo, 3); // input 2 for filter gain mo->k = 0.001; mo->min = 0.0; mo->max = 127.0; mo->lastoutput = 0.0; mo->input = 0; mo->scale = (mo->max-mo->min+1.0)/127.0; mo->scaledinput = 0.0; return mo; } ////////////////////////////////////////////////////////////////////////// // // Behavior functions: // ////////////////////////////// // // InputMIDI -- input a MIDI data value. // void InputMIDI(MyObject* mo, long value) { mo->input = value; mo->scaledinput = mo->input * mo->scale + mo->min; post("scaled value is: %f", mo->scaledinput); } ////////////////////////////// // // InputGain -- seed the random number generator. // void InputGain(MyObject *mo, float value) { mo->k = value; } ////////////////////////////// // // InputMin -- seed the smallest number which can be generated. // void InputMin(MyObject *mo, float value) { float temp; mo->min = value; if (mo->min > mo->max) { temp = mo->min; mo->min = mo->max; mo->max = temp; } mo->scale = (mo->max-mo->min+1.0)/127.0; mo->scaledinput = mo->input * mo->scale + mo->min; } ////////////////////////////// // // InputMax -- Set the largest number which can be generated. // void InputMax(MyObject *mo, float value) { float temp; mo->max = value; if (mo->min > mo->max) { temp = mo->min; mo->min = mo->max; mo->max = temp; } mo->scale = (mo->max-mo->min+1.0)/127.0; mo->scaledinput = mo->input * mo->scale + mo->min; } ////////////////////////////// // // MessageDSP -- What to do when a "dsp" message arrives into the object. // void MessageDSP(MyObject* mo, t_signal** signal, short* count) { #pragma unused(count) dsp_add(Perform, 4, 4, mo, signal[0]->s_vec, signal[0]->s_n); } ////////////////////////////// // // MessageClear -- set the lastoutput variable to zero. // void MessageClear(MyObject* mo) { mo->lastoutput = 0.0; } ////////////////////////////// // // Perform -- do the calculations for one sample group. // (Filter the input with the difference equation: // y[n] = k * x[n] + (1-k) * y[n-1] ). // t_int* Perform(t_int *parameters) { long pcount = (long) (parameters[1]); MyObject *mo = (MyObject*)(parameters[2]); t_float *output = (t_float*) (parameters[3]); long count = (int) (parameters[4]); long i; for (i=0; ik * mo->scaledinput + (1.0-mo->k) * mo->lastoutput; mo->lastoutput = output[i]; } return parameters+pcount+1; }