/* cd4014.c MP 20070315 */ /* Emulate a cd4014b */ #include "m_pd.h" typedef struct _cd4014 { t_object x_obj; int x_P1; int x_P2; int x_P3; int x_P4; int x_P5; int x_P6; int x_P7; int x_P8; int x_SerialIn; int x_Clk; int x_Q; int x_ParallelSerial; t_outlet *x_outQ6; t_outlet *x_outQ7; t_outlet *x_outQ8; t_inlet *x_inP1;/* extra inlets are 'live' like the first */ t_inlet *x_inP2; t_inlet *x_inP3; t_inlet *x_inP4; t_inlet *x_inP5; t_inlet *x_inP6; t_inlet *x_inP7; t_inlet *x_inP8; t_inlet *x_inParallelSerial; t_inlet *x_inSerial; } t_cd4014; static t_class *cd4014_class; void cd4014_setup(void); static void *cd4014_new(t_symbol *s, int argc, t_atom *argv); static void cd4014_free(t_cd4014 *x); static void cd4014_float(t_cd4014 *x, t_float f); static void cd4014_bang(t_cd4014 *x); static void cd4014_inP1(t_cd4014 *x, t_float f); static void cd4014_inP2(t_cd4014 *x, t_float f); static void cd4014_inP3(t_cd4014 *x, t_float f); static void cd4014_inP4(t_cd4014 *x, t_float f); static void cd4014_inP5(t_cd4014 *x, t_float f); static void cd4014_inP6(t_cd4014 *x, t_float f); static void cd4014_inP7(t_cd4014 *x, t_float f); static void cd4014_inP8(t_cd4014 *x, t_float f); static void cd4014_inParallelSerial(t_cd4014 *x, t_float f); static void cd4014_inSerial(t_cd4014 *x, t_float f); static void cd4014_update_outlets(t_cd4014 *x); static void cd4014_float(t_cd4014 *x, t_float f) { if (f == 1) { if (x->x_Clk == 0) { x->x_Clk = 1; cd4014_bang(x); } } else if (f == 0) x->x_Clk = 0; else { post("cd4014 Clock inlet accepts 1 or 0."); return; } } static void cd4014_bang(t_cd4014 *x) { if (x->x_ParallelSerial == 0) { /* shift left by one */ x->x_Q <<= 1; x->x_Q |= x->x_SerialIn; } else { /* parallel load */ x->x_Q = 128*x->x_P8 + 64*x->x_P7 + 32*x->x_P6 + 16*x->x_P5 + 8*x->x_P4 + 4*x->x_P3 + 2*x->x_P2 + x->x_P1; } cd4014_update_outlets(x); } static void cd4014_inP1(t_cd4014 *x, t_float f) { if (f == 1) x->x_P1 = 1; else if (f == 0) x->x_P1 = 0; else { post("cd4014 inlet P1 accepts 1 or 0."); return; } } static void cd4014_inP2(t_cd4014 *x, t_float f) { if (f == 1) x->x_P2 = 2; else if (f == 0) x->x_P2 = 0; else { post("cd4014 inlet P2 accepts 1 or 0."); return; } } static void cd4014_inP3(t_cd4014 *x, t_float f) { if (f == 1) x->x_P3 = 1; else if (f == 0) x->x_P3 = 0; else { post("cd4014 inlet P3 accepts 1 or 0."); return; } } static void cd4014_inP4(t_cd4014 *x, t_float f) { if (f == 1) x->x_P4 = 1; else if (f == 0) x->x_P4 = 0; else { post("cd4014 inlet P4 accepts 1 or 0."); return; } } static void cd4014_inP5(t_cd4014 *x, t_float f) { if (f == 1) x->x_P5 = 1; else if (f == 0) x->x_P5 = 0; else { post("cd4014 inlet P5 accepts 1 or 0."); return; } } static void cd4014_inP6(t_cd4014 *x, t_float f) { if (f == 1) x->x_P6 = 1; else if (f == 0) x->x_P6 = 0; else { post("cd4014 inlet P6 accepts 1 or 0."); return; } } static void cd4014_inP7(t_cd4014 *x, t_float f) { if (f == 1) x->x_P7 = 1; else if (f == 0) x->x_P7 = 0; else { post("cd4014 inlet P7 accepts 1 or 0."); return; } } static void cd4014_inP8(t_cd4014 *x, t_float f) { if (f == 1) x->x_P8 = 1; else if (f == 0) x->x_P8 = 0; else { post("cd4014 inlet P8 accepts 1 or 0."); return; } } static void cd4014_inParallelSerial(t_cd4014 *x, t_float f) { if (f == 1) x->x_ParallelSerial = 1; else if (f == 0) x->x_ParallelSerial = 0; else { post("cd4014 inlet ParallelSerial accepts 1 or 0."); return; } } static void cd4014_inSerial(t_cd4014 *x, t_float f) { if (f == 1) x->x_SerialIn = 1; else if (f == 0) x->x_SerialIn = 0; else { post("cd4014 inlet Serial accepts 1 or 0."); return; } } static void cd4014_update_outlets(t_cd4014 *x) { /* Output Q8, Q7, Q6 */ outlet_float(x->x_outQ8, ((x->x_Q & 128) != 0)?1:0); outlet_float(x->x_outQ7, ((x->x_Q & 64) != 0)?1:0); outlet_float(x->x_outQ6, ((x->x_Q & 32) != 0)?1:0); } static void cd4014_free(t_cd4014 *x) { return; } static void *cd4014_new(t_symbol *s, int argc, t_atom *argv) { t_cd4014 *x; x = (t_cd4014 *)pd_new(cd4014_class); if (x == NULL) return (x); x->x_outQ6 = outlet_new((t_object *)x, &s_float); x->x_outQ7 = outlet_new((t_object *)x, &s_float); x->x_outQ8 = outlet_new((t_object *)x, &s_float); x->x_inP1 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P1")); x->x_inP2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P2")); x->x_inP3 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P3")); x->x_inP4 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P4")); x->x_inP5 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P5")); x->x_inP6 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P6")); x->x_inP7 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P7")); x->x_inP8 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("P8")); x->x_inParallelSerial = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ParallelSerial")); x->x_inSerial = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("Serial")); return (x); } void cd4014_setup(void) { cd4014_class = class_new(gensym("cd4014"), (t_newmethod)cd4014_new, (t_method)cd4014_free, sizeof(t_cd4014), 0, 0); /* no arguments */ class_addfloat(cd4014_class, cd4014_float); class_addbang(cd4014_class, cd4014_bang); class_addmethod(cd4014_class, (t_method)cd4014_inP1, gensym("P1"), A_FLOAT, 0); class_addmethod(cd4014_class, (t_method)cd4014_inP2, gensym("P2"), A_FLOAT, 0); class_addmethod(cd4014_class, (t_method)cd4014_inP3, gensym("P3"), A_FLOAT, 0); class_addmethod(cd4014_class, (t_method)cd4014_inP4, gensym("P4"), A_FLOAT, 0); class_addmethod(cd4014_class, (t_method)cd4014_inP5, gensym("P5"), A_FLOAT, 0); class_addmethod(cd4014_class, (t_method)cd4014_inP6, gensym("P6"), A_FLOAT, 0); class_addmethod(cd4014_class, (t_method)cd4014_inP7, gensym("P7"), A_FLOAT, 0); class_addmethod(cd4014_class, (t_method)cd4014_inP8, gensym("P8"), A_FLOAT, 0); class_addmethod(cd4014_class, (t_method)cd4014_inParallelSerial, gensym("ParallelSerial"), A_FLOAT, 0); class_addmethod(cd4014_class, (t_method)cd4014_inSerial, gensym("Serial"), A_FLOAT, 0); } /* end cd4014.c */