// MSG "drag" symbol input + float sets global drag void drag_drag_set(t_drag *x, t_symbol *msg, short argc, t_atom *argv) { t_double f; atom_arg_getdouble(&f, 0, argc, argv); x->drag = danScaler(f, DRAGMIN_IN, DRAGMAX_IN, DRAGMIN_OUT, DRAGMAX_OUT, DRAGSCALER); }
// MSG "fm" symbol input, controls modulation amounts via list of 2 ints and a float (from, to, amt) void bounce_fm_set(t_bounce *x, t_symbol *msg, short argc, t_atom *argv) { t_int in, out; t_double val = 0; if(argc == 3){ in = atom_getintarg(0,argc, argv); out = atom_getintarg(1,argc, argv); atom_arg_getdouble(&val, 2, argc, argv); in -= 1, out -=1; if(in <0 || in >= x->voice_count || out <0 || out >= x->voice_count){ post("ERROR - invalid cross mod argument"); in = 0, out = 0, val = 0; } else { x->fm[in][out] = val < MAXFM ? val: MAXFM; } if(val == 0.){ // check if any other modulation is on, and set fm_on flag accordingly for(in = 0; in < x->voice_count; in++){ for(out = 0; out < x->voice_count; out++){ if(fabs(x->fm[in][out]) > 0.0001){ x->fm_on = 1; goto quit_check_loop; } } x->fm_on = 0; // only reached if no modulation is on } }else{ x->fm_on = 1; } } quit_check_loop: ; }
// MSG "fmax" symbol input + float sets maximum frequency void drag_fmax_set(t_drag *x, t_symbol *msg, short argc, t_atom *argv) { t_double f; atom_arg_getdouble(&f, 0, argc, argv); if(f<=FMAX && f>=FMIN) { x->fmax = f * 0.5; } }
// MSG "drag" symbol input + float sets global drag void drag_dragcurv_set(t_drag *x, t_symbol *msg, short argc, t_atom *argv) { t_double f; atom_arg_getdouble(&f, 0, argc, argv); if(f<=1) { x->dragCurve = DRAGCURVEMIN; } else if (f>3) { x->dragCurve = DRAGCURVEMAX; } else { x->dragCurve = f; } }
void *adsr_new(t_symbol *s, int argc, t_atom *argv) { t_adsr *x = (t_adsr *)object_alloc(adsr_class); dsp_setup((t_pxobject *)x,1); // no inputs outlet_new((t_object *)x, "signal"); x->x_obj.z_misc |= Z_NO_INPLACE; floatin((t_object *)x, 1); floatin((t_object *)x, 2); floatin((t_object *)x, 3); floatin((t_object *)x, 4); floatin((t_object *)x, 5); floatin((t_object *)x, 6); x->srate = sys_getsr(); if(!x->srate){ error("zero sampling rate, setting to 44100"); x->srate = 44100; } x->a = 10; x->d = 50; x->s = 100; x->r = 100; atom_arg_getdouble(&x->a,0,argc,argv); atom_arg_getdouble(&x->d,1,argc,argv); atom_arg_getdouble(&x->s,2,argc,argv); atom_arg_getdouble(&x->r,3,argc,argv); atom_arg_getdouble(&x->egain1,4,argc,argv); atom_arg_getdouble(&x->egain2,5,argc,argv); x->a *= .001; x->d *= .001; x->s *= .001; x->r *= .001; x->asamps = x->a * x->srate; x->dsamps = x->d * x->srate; x->ssamps = x->s * x->srate; x->rsamps = x->r * x->srate; x->tsamps = x->asamps+x->dsamps+x->ssamps+x->rsamps; x->ebreak1 = x->asamps; x->ebreak2 = x->asamps+x->dsamps; x->ebreak3 = x->asamps+x->dsamps+x->ssamps; x->egain1 = .7; x->egain2 = .1; x->counter = 0; x->click_gain = 0.0; x->mute = 0; return (x); }
// MSG "shape" symbol input + int + float sets waveshape for voice void drag_shape_set(t_drag *x, t_symbol *msg, short argc, t_atom *argv) { t_int v; t_double amt = 0; v = atom_getintarg(0,argc, argv); atom_arg_getdouble(&amt, 1, argc, argv); v-= 1; if(v < x->voice_count && v >= 0 ) { if(amt < 0) { if (amt > -0.05f) amt = -0.05f; else if (amt < -1.f) amt = -1.f; x->shape[v] = amt; } else { if (amt < 0.05f) amt = 0.05f; else if (amt > 1.f) amt = 1.f; x->shape[v] = amt; } } }
// function to create new instance and initialise its parameters void *drag_new(t_symbol *s, short argc, t_atom *argv) { t_double bound_lo = -1.0, bound_hi = 1.0; t_int i = 0, dir = -1; t_drag *x = object_alloc(drag_class); // set aside memory for the struct for the object x->mode = 0; x->drag = DRAG_DEFAULT; x->dragCurve = DRAGCURVE; x->maxcrash = log(CRASHMAX); x->fmax = FMAX * 0.5; x->bound_lo = bound_lo; x->bound_hi = bound_hi; atom_arg_getlong(&(x->voice_count), 0, argc, argv); atom_arg_getdouble(&(x->bound_lo), 1, argc, argv); atom_arg_getdouble(&(x->bound_hi), 2, argc, argv); x->mode = atom_getintarg(3,argc,argv); if(x->mode < 0) x->mode = 0; else if (x->mode > 4) x->mode = 4; atom_arg_getdouble(&(x->drag), 4, argc, argv); //protect against invalid parameters if(x->voice_count > MAX_VOICES) { x->voice_count = MAX_VOICES; } else if (x->voice_count < 1) { x->voice_count = 1; } if (x->bound_lo < BOUND_L_MIN) x->bound_lo = BOUND_L_MIN; if (x->bound_hi > BOUND_H_MAX) x->bound_lo = BOUND_H_MAX; if(x->bound_lo >= x->bound_hi) { x->bound_lo = BOUND_L_MIN; x->bound_hi = BOUND_H_MAX; post("invalid args for bounds, set to %f, %f", BOUND_L_MIN, BOUND_H_MAX); } x->drag = DRAG_DEFAULT; // add to dsp chain, set up inlets dsp_setup((t_pxobject *)x, 2*x->voice_count + 2); // upper and lower bounds, plus hz and symm per voice x->obj.z_misc |= Z_NO_INPLACE; // force independent signal vectors // allocate memory for variable arrays x->hz = (t_double **) t_getbytes(x->voice_count * sizeof(t_double *)); x->symm = (t_double **) t_getbytes(x->voice_count * sizeof(t_double *)); x->out = (t_double **) t_getbytes(x->voice_count * sizeof(t_double *)); x->hzFloat = (t_double *) t_getbytes(x->voice_count * sizeof(t_double)); x->hzActual = (t_double *) t_getbytes(x->voice_count * sizeof(t_double)); x->grad = (t_double *) t_getbytes(x->voice_count * sizeof(t_double)); x->ball_loc = (t_double *) t_getbytes(x->voice_count * sizeof(t_double)); x->crash = (t_double *) t_getbytes(x->voice_count * sizeof(t_double)); x->lastcrash = (t_double *) t_getbytes(x->voice_count * sizeof(t_double)); x->direction = (t_int *) t_getbytes(x->voice_count * sizeof(t_int)); x->hz_conn = (t_int *) t_getbytes(x->voice_count * sizeof(t_int)); x->symm_conn = (t_int *) t_getbytes(x->voice_count * sizeof(t_int)); x->dcblock_on = (t_bool *) t_getbytes(x->voice_count * sizeof(t_bool)); x->dc_prev_in = (t_double *) t_getbytes(x->voice_count * sizeof(t_double)); x->dc_prev_out = (t_double *) t_getbytes(x->voice_count * sizeof(t_double)); x->shape = (t_double *) t_getbytes(x->voice_count * sizeof(t_double)); x->sin = (t_double *) t_getbytes(LKTBL_LNGTH * sizeof(t_double)); x->sinh = (t_double *) t_getbytes(LKTBL_LNGTH * sizeof(t_double)); x->isfree = (t_bool *) t_getbytes(x->voice_count * sizeof(t_bool)); setup_lktables(x,0); // build lookup tables for waveshaper //set up outlets & and get rate for each voice from args x->ball_loc[0] = bound_lo + THINNESTPIPE; x->direction[0] = 1; for(i=0; i < x->voice_count; i++) { outlet_new((t_object *)x, "signal"); x->shape[i] = 0.1f; x->grad[i] = 2; x->hzActual[i] = x->hzFloat[i] = 100; x->ball_loc[i] = (x->ball_loc[i-1] + THINNESTPIPE); // begin near bottom of current bound dir *= -1, x->direction[i] = dir; // alternate up and down x->dcblock_on[i] = 0; x->dc_prev_in[i] = x->dc_prev_out[i] = 0.f; } // initialize remaining parameters x->srate = (t_double)sys_getsr(); #if DEBUG_ON == 1|| DEBUG_ON == 2 x->poll_count = POLL_NO_SAMPLES-1; x->stopdebug = x->debug_count = 0; #endif return x; }