// // Copyright: Copyright 2003 Craig Stuart Sapp // Programmer: Craig Stuart Sapp // Creation Date: Thu Feb 13 18:37:54 PST 2003 // Last Modified: Sat Feb 15 13:28:17 PST 2003 // Filename: snitch.c // Web Address: http://peabody.sapp.org/class/dmp2/lab/mirror/snitch.c // Syntax: C; Max4/MSP2 External Object; CodeWarrior 6.0 // OS: Mac OS 9; PPC // // Description: Mirrors the notes according to the input mirror note. // The last note played is set to be the new mirror note. // The mirror note can be changed when there are // notes currently playing. // #include "ext.h" typedef struct { t_object max_data; // Max/MSP data, MUST come first in struct long states[128]; // note states for mirroring long mirrornote; // note number of the mirror long velin; // temporary storage for input velocity void* outputKeyNumber; // output the note number of the note void* outputVelocity; // output the duration of note in milliseconds } MyObject; void* object_data = NULL; // function declarations: void* create_object (long mirror); void InputKeyNumber (MyObject* mo, long value); void InputVelocity (MyObject* mo, long value); void InputMirror (MyObject* mo, long value); ///////////////////////////////////////////////////////////////////////// // // Initialization functions // ////////////////////////////// // // main -- called once when the object is created in a patcher window. // void main(void) { setup((t_messlist**)&object_data, (method)create_object, NULL, sizeof(MyObject), NULL, A_DEFLONG, A_NOTHING); addint ((method)InputKeyNumber); // inlet 1 addinx ((method)InputVelocity, 2); // inlet 2 addinx ((method)InputMirror, 1); // inlet 3 } ////////////////////////////// // // create_object -- create the data storage for the mydiff object and // and setup input 1. // void* create_object(long initmirror) { MyObject* mo = (MyObject*)newobject(object_data); mo->mirror = initmirror; mo->velin = 0; mo->outputVelocity = intout(mo); // outlet 2 mo->outputKeyNumber = intout(mo); // outlet 1 intin(mo, 1); // inlet 3 intin(mo, 2); // inlet 2 return mo; } ///////////////////////////////////////////////////////////////////////// // // Behavior functions // ////////////////////////////// // // InputKeyNumber -- behavior of the object when a new number comes // in on inlet 1. // void InputKeyNumber(MyObject* mo, long value) { value = midilimit(value); if (mo->velin == 0) { // turn off the last mirrored note for that key outlet_int(mo->outputVelocity, 0); outlet_int(mo->outputKeyNumber, mo->states[value]); mo->states[value] = 0; } else { if (mo->state[value] != 0) { // somehow a note was left on (perhaps non-MIDI keyboard) outlet_int(mo->outputVelocity, 0); outlet_int(mo->outputKeyNumber, mo->states[value]); } mo->states[value] = 2 * mo->mirrornote - value; outlet_int(mo->outputVelocity, mo->velin); outlet_int(mo->outputKeyNumber, mo->states[value]); } InputMirror(mo, value); } ////////////////////////////// // // InputVelocity -- behavior of the object when a new number comes // in on inlet 2. // void InputVelocity(MyObject* mo, long value) { mo->velin = value; } ////////////////////////////// // // InputMirror -- input the mirror note. // void InputMirror(MyObject* mo, long value) { mo->mirrornote = value; } ////////////////////////////////////////////////////////////////////////// // // Non-interface functions // ////////////////////////////// // // midilimit -- limit data to the range from 0 to 127. // int midilimit(long value) { if (value < 0) return 0; if (value > 127) return 127; return value; }