// // Copyright: Copyright 2003 Craig Stuart Sapp // Programmer: Craig Stuart Sapp // Creation Date: Tue Mar 11 10:16:26 PST 2003 // Last Modified: Tue Mar 11 10:16:28 PST 2003 // Filename: osc.c // Web Address: http://peabody.sapp.org/class/dmp2/lab/osc/osc.c // Syntax: C; Max4/MSP2 External Object; CodeWarrior 6.0 // OS: Mac OS 9; PPC // // Description: A non-wavetable sinewave oscillator generating object. // #include "ext.h" #include "z_dsp.h" #include /* included for use of cos() function */ #ifndef TWOPI #define TWOPI 6.28318530718 #endif typedef struct { t_pxobject msp_data; // must always be the first field; used by MSP float currentphase; // the current phase of the oscillator float phaseincrement; // related to the frequency input } MyObject; void* object_data; // pointer to data for object (created in setup()); // function declarations: void main (void); void* create_object (void); void MessageDSP (MyObject* mo, t_signal** signal, short* count); void InputFrequency (MyObject* mo, float value); void InputPhase (MyObject* mo, float value); 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); addfloat((method)InputFrequency); // input 1 addftx((method)InputPhase, 1); // input 2 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, 1); // create one signal input (ignored) outlet_new((t_pxobject*)mo, "signal"); // output 1 floatin(mo, 1); // input 2 InputPhase(mo, 0.0); InputFrequency(mo, 440.0); return mo; } ////////////////////////////////////////////////////////////////////////// // // Behavior functions: // ////////////////////////////// // // MessageDSP -- What to do when a "dsp" message arrives into the object. // void MessageDSP(MyObject* mo, t_signal** signal, short* count) { #pragma unused(mo) #pragma unused(count) dsp_add(Perform, 5, 5, mo, signal[0]->s_vec, signal[1]->s_vec, signal[0]->s_n); } ////////////////////////////// // // InputFrequency -- handle input of the frequency in Hertz. // the Max/MSP function sys_getsr() returns the sampling rate. // void InputFrequency(MyObject *mo, float value) { static float factor = TWOPI / sys_getsr(); mo->phaseincrement = value * factor; } ////////////////////////////// // // InputPhase -- set the exact phase of the oscillator. // the phase is in radians, where 0 and 2 pi are the same phase position. // void InputPhase(MyObject *mo, float value) { mo->currentphase = value; } ////////////////////////////// // // Perform -- do the calculations for one sample group. // t_int* Perform(t_int *parameters) { long pcount = (long) (parameters[1]); MyObject *mo = (MyObject*)(parameters[2]); t_float *input = (t_float*) (parameters[3]); t_float *output = (t_float*) (parameters[4]); long count = (int) (parameters[5]); long i; // the input is ignored, but Max/MSP crashes when it is not created. for (i=0; icurrentphase); mo->currentphase += mo->phaseincrement; } // prevent round-off error from occuring with floats. if (mo->currentphase > TWOPI) { mo->currentphase -= TWOPI; } return parameters+pcount+1; }