// // Copyright: Copyright 2003 Craig Stuart Sapp // Programmer: Craig Stuart Sapp // Creation Date: Sat Feb 1 12:30:05 PST 2003 // Last Modified: Fri Feb 7 17:41:38 PST 2003 // Filename: markov1.c // Web Address: http://peabody.sapp.org/class/dmp2/lab/markov1/markov1.c // Syntax: C; Max4/MSP2 External Object; CodeWarrior 6.0 // OS: Mac OS 9; PPC // // Description: First-order Markov chain Max object. // #include "ext.h" #include /* included for rand() function */ #define TSIZE 12 /* for 12x12 pitch class transition table size */ typedef struct { t_object max_data; // Max/MSP data, MUST come first in struct long lastnote; // Last MIDI note received by object on 2nd input long outnote; // Last note generate from transition table long ttable[TSIZE][TSIZE]; // transition table for data void* output; // output bang function pointer } MyObject; void* object_data = NULL; // function declarations: void main (void); void* create_object (void); void InputTriggerNote (MyObject* mo, long value); void InputTrainingNote (MyObject* mo, long value); void InputBang (MyObject* mo); void MessageClear (MyObject* mo); int chooseNextNote (int lastnote, long ttable[TSIZE][TSIZE]); void setAllValuesOfTable (long table[TSIZE][TSIZE], int value); long midilimit (long value); double randfloat (void); ///////////////////////////////////////////////////////////////////////// // // 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_NOTHING); addbang((method)InputBang); addint ((method)InputTriggerNote); // inlet 1 addinx ((method)InputTrainingNote, 1); // inlet 2 addmess((method)MessageClear, "clear", A_NOTHING); } ////////////////////////////// // // create_object -- create the data storage for the mydiff object and // and setup input 1. // void* create_object(void) { MyObject* mo = (MyObject*)newobject(object_data); mo->lastnote = 60; mo->outnote = 60; setAllValuesOfTable(mo->ttable, 0); mo->output = intout(mo); // outlet 1 intin(mo, 1); // inlet 2 return mo; } ///////////////////////////////////////////////////////////////////////// // // Behavior functions // ////////////////////////////// // // InputTriggerNote -- behavior of the object when a new number comes // in on inlet 0. When a number comes in, extract the octave // and then choose a new note from the transition table. // void InputTriggerNote(MyObject* mo, long value) { int octave; value = midilimit(value); octave = value / 12; mo->outnote = 12 * octave + chooseNextNote(mo->outnote, mo->ttable); outlet_int(mo->output, mo->outnote); } ////////////////////////////// // // InputTrainingNote -- behavior of the object when a new number comes // in on inlet 1. When a number comes in, store it in the // transition table. // void InputTrainingNote(MyObject* mo, long value) { int newstate, laststate; value = midilimit(value); laststate = mo->lastnote % 12; newstate = value % 12; mo->lastnote = value; mo->ttable[laststate][newstate]++; } ////////////////////////////// // // InputBang -- behavior of the object when a "bang" message is received. // Choose another note to output, borrowing the octave from // the last note output from the object. // void InputBang(MyObject* mo) { InputTriggerNote(mo, mo->outnote); } ////////////////////////////// // // MessageClear -- clear the contents of the // void MessageClear(MyObject* mo) { setAllValuesOfTable(mo->ttable, 0); } ///////////////////////////////////////////////////////////////////////// // // Non-interface functions: // ////////////////////////////// // // midilimit -- limit a number to the range from 0 to 127. // if the input is less than 0, return 0. // if the input is greater than 127, return 127. // long midilimit(long value) { if (value < 0) return 0; if (value > 127) return 127; return value; } ////////////////////////////// // // setAllValuesOfTable -- set all values in the transition table to // the given value. // void setAllValuesOfTable(long table[TSIZE][TSIZE], int value) { int i, j; for (i=0; i