static void op_thresh_update(op_thresh_t* thresh) { if(thresh->state < thresh->lim) { net_activate(thresh->outs[0], thresh->state, thresh); } else { net_activate(thresh->outs[1], thresh->state, thresh); } }
// perform wrapping and output static void op_enc_perform(op_enc_t* enc) { io_t wrap = 0; io_t dif = 0; if (enc->wrap) { // wrapping... // if value needs wrapping, output the applied difference while (enc->val > enc->max) { dif = op_sub(enc->min, enc->max); wrap = op_add(wrap, dif); enc->val = op_add(enc->val, dif); } while (enc->val < enc->min) { dif = op_sub(enc->max, enc->min); wrap = op_add(wrap, dif); enc->val = op_add(enc->val, dif); } } else { // saturating... if (enc->val > enc->max) { enc->val = enc->max; dif = 1; // force wrap output } if (enc->val < enc->min) { enc->val = enc->min; dif = -1; // force wrap output } } // output the value net_activate(enc->outs[0], enc->val, enc); // output the wrap amount if (dif != 0) { net_activate(enc->outs[1], wrap, enc); } }
// wrap and output void op_accum_wrap_out(op_accum_t* accum) { io_t wrap = 0; io_t dif = 0; if (accum->wrap) { // wrapping... // if value needs wrapping, output the applied difference while (accum->val > accum->max) { dif = op_sub(accum->min, accum->max) - 1; wrap = op_add(wrap, dif); accum->val = op_add(accum->val, dif); } while (accum->val < accum->min) { dif = op_sub(accum->max, accum->min) + 1; wrap = op_add(wrap, dif); accum->val = op_add(accum->val, dif); } } else { // saturating... if (accum->val > accum->max) { wrap = dif = op_sub(accum->val, accum->max); accum->val = accum->max; } if (accum->val < accum->min) { wrap = dif = op_sub(accum->val , accum->min); accum->val = accum->min; } } // output the value net_activate(accum->outs[0], accum->val, accum); // output the wrap amount if (dif != 0) { net_activate(accum->outs[1], wrap, accum); } }
static void op_midi_note_handler(op_midi_t* op_midi, u32 data) { static u8 com; static u8 ch, num, vel; op_midi_note_t* op = (op_midi_note_t*)(op_midi->sub); // check status byte com = (data & 0xf0000000) >> 28; if (com == 0x9) { if(op->chan < 0) { num = (data & 0xff0000) >> 16; vel = (data & 0xff00) >> 8; net_activate(op->outs[0], op_from_int(num), op); net_activate(op->outs[1], op_from_int(vel), op); } else {
// retrigger all inputs void net_retrigger_inputs(void) { u32 i; netActive = 0; for(i=0; i<net->numIns; i++) { net_activate(i, net_get_in_value(i), NULL); } netActive = 1; }
// set operand B static void op_shr_in_b(op_shr_t* shr, const io_t v) { //printf("shr at %d received B %d\n", (int)shr, (int)*v); shr->b = v; shr->val = shr->a >> shr->b; if(shr->btrig) { net_activate(shr->outs[0], shr->val, shr); } }
// handle input from system void op_sw_sys_input(op_sw_t* sw, u8 v) { if (sw->tog) { // toggle mode, sw state toggles on positive input if ( (v) > 0) { if ((sw->state) == 0) { sw->state = sw->mul; } else { sw->state = 0; } net_activate(sw->outs[0], sw->state, sw); } } else { // momentary mode, sw value takes input if((v) > 0) { sw->state = sw->mul; } else { sw->state = 0; } net_activate(sw->outs[0], sw->state, sw); } }
// input multiplier static void op_sw_in_mul(op_sw_t* sw, const io_t v) { // print_dbg("\r\n op_sw_in_mul"); sw->mul = v; if (sw->state > 0) { sw->state = (v); net_activate(sw->outs[0], sw->state, sw); } }
static void op_random_in_trig(op_random_t* random, const io_t v) { random->x = random->x * random->c + random->a; random->val =random->x; if(random->val < 0) random->val *= -1; random->val = (random->val % ((random->max - random->min) + 1)) + random->min; net_activate(random->outs[0], random->val, random); // if(v > 0) { random->trig = OP_ONE; } else { random->trig = 0; } }
// set operand B static void op_mod_in_b(op_mod_t* mod, const io_t v) { //printf("mod at %d received B %d\n", (int)mod, (int)*v); if(v == 0) { mod->b = 1; } else { mod->b = v; } mod->val = (mod->a % mod->b); if(mod->btrig) { net_activate(mod->outs[0], mod->val, mod); } }
static void op_list16_in_index(op_list16_t* list16, const io_t val) { io_t v = val; if(v<0) v = 0; if(v>15) v = 15; list16->index = v; list16->val = *(list16->in_val[v+1]); net_activate(list16->outs[0], list16->val, list16); }
static void op_midi_cc_handler(op_midi_t* op_midi, u32 data) { static u8 com; static io_t ch, num, val; op_midi_cc_t* op = (op_midi_cc_t*)(op_midi->sub); // check command: status high nib com = (data & 0xf0000000) >> 28; if (com == 0xb) { // cc if(op->chan < 0) { // take all channels // check number: data 1 num = (data & 0x00ff0000) >> 16; if(num == op->num) { val = (data & 0x0000ff00) >> 8; net_activate(op->outs[0], val, op); } } else {
//------------------------------------------------- //----- static function definitions // set operand A static void op_is_in_a(op_is_t* is, const io_t v) { // printf("is at %d received A %d\n", (int)is, (int)*v); u8 i; is->a = v; if(is->edge) { i = is->eq; is->eq = (is->a == is->b); if(i != is->eq) net_activate(is->outs[0], is->eq, is); i = is->ne; is->ne = (is->a != is->b); if(i != is->ne) net_activate(is->outs[1], is->ne, is); i = is->gt; is->gt = (is->a > is->b); if(i != is->gt) net_activate(is->outs[2], is->gt, is); i = is->lt; is->lt = (is->a < is->b); if(i != is->lt) net_activate(is->outs[3], is->lt, is); } else { is->eq = (is->a == is->b); net_activate(is->outs[0], is->eq, is); is->ne = (is->a != is->b); net_activate(is->outs[1], is->ne, is); is->gt = (is->a > is->b); net_activate(is->outs[2], is->gt, is); is->lt = (is->a < is->b); net_activate(is->outs[3], is->lt, is); } }
// input event static void op_timer_in_event(op_timer_t* timer, const io_t v) { timer->event = v; /// FIXME: should check for overflow here... timer->interval = tcTicks - timer->ticks; timer->ticks = tcTicks; // calculate output value for timer from interval // output will ultimately be connected to a time param // time is specified in seconds, fixed-width, arbitrary radix // for example, from aleph-lines: // seconds in 16.16 // #define PARAM_SECONDS_MAX 0x003c0000 // #define PARAM_SECONDS_RADIX 6 /// FIXME: /// unfortunately, timer ticks are in ms. /// it would be nice if they were some 2^(-N) multiple of seconds. /// however, it would make it more painful for the METRO operator. /// for now let's pretend timer interval is 1/1024 /// reported intervals will be fast by a ratio of 1.024, /// in the example above. net_activate(timer->outs[0], timer->interval, timer); }
// poll event handler void op_delay_poll_handler(void* op) { op_delay_t* delay = (op_delay_t*)op; op_delay_unset_timer(delay); net_activate(delay->outs[0], delay->val, &(delay->super)); }
// perform wrapping and output static void op_enc_perform(op_enc_t* enc) { s32 wrap = 0; s32 dif = 0; /// FIXME: this 32-bit business is pretty foul stuff. s32 min32; s32 max32; if(enc->min < 0) { min32 = (s32)(enc->min) | 0xffff0000; } else { min32 = (s32)(enc->min); } if(enc->max < 0) { max32 = (s32)(enc->max) | 0xffff0000; } else { max32 = (s32)(enc->max); } /* /\* print_dbg("\r\n calculating enc output... min: 0x"); *\/ */ /* /\* print_dbg_hex(min32); *\/ */ /* /\* print_dbg(" , max: "); *\/ */ /* /\* print_dbg_hex(max32); *\/ */ /* /\* print_dbg(" , val: "); *\/ */ /* /\* print_dbg_hex(enc->val32); *\/ */ if (enc->wrap) { // wrapping... // if value needs wrapping, output the applied difference while (enc->val32 > max32) { print_dbg(" ... wrapping high... "); dif = min32 - max32; if(dif == 0) { dif = -1; } /* print_dbg(" , dif: "); */ /* print_dbg_hex(dif); */ wrap += dif; enc->val32 = enc->val32 + dif; /* print_dbg(" , new val: "); */ /* print_dbg_hex(enc->val32); */ } while (enc->val32 < min32) { /* print_dbg(" ... wrapping low... "); */ dif = max32 - min32; if(dif == 0) { dif = 1; } /* print_dbg(" , dif: "); */ /* print_dbg_hex(dif); */ wrap += dif; enc->val32 = enc->val32 + dif; /* print_dbg(" , new val: "); */ /* print_dbg_hex(enc->val32); */ } enc->val = op_from_int(enc->val32); } else { // saturating... if (enc->val32 > (s32)(enc->max)) { enc->val = enc->max; dif = 1; // force wrap output } else if (enc->val32 < (s32)(enc->min)) { enc->val = enc->min; dif = -1; // force wrap output } else { enc->val = op_from_int(enc->val32); } } // output the value net_activate(enc->outs[0], enc->val, enc); // output the wrap amount if (dif != 0) { net_activate(enc->outs[1], op_from_int(wrap), enc); } }
//------------------------------------------------- //----- static function definitions // set operand A static void op_shr_in_a(op_shr_t* shr, const io_t v) { // printf("shr at %d received A %d\n", (int)shr, (int)*v); shr->a = v; shr->val = shr->a >> shr->b; net_activate(shr->outs[0], shr->val, shr); }
// poll event handler void op_metro_poll_handler(void* op) { op_metro_t* metro = (op_metro_t*)op; // print_dbg("\r\n op_metro timer callback, value: 0x"); // print_dbg_hex((u32)(metro->value)); net_activate(metro->outs[0], metro->value, &(metro->super)); }
//------------------------------------------------- //----- static function definitions // set operand A static void op_mod_in_a(op_mod_t* mod, const io_t v) { // printf("mod at %d received A %d\n", (int)mod, (int)*v); mod->a = v; mod->val = (mod->a % mod->b); net_activate(mod->outs[0], mod->val, mod); }
void op_adc_sys_input(op_adc_t* adc, u8 ch, u16 val) { adc->val[ch] = val; net_activate(adc->outs[ch], val, &(adc->super)); }
static void op_step_in_step(op_step_t* op, const io_t v) { s8 i; if(op->s_cut == 0) { monomeLedBuffer[monome_xy_idx(op->s_now, 0)] = 0; if(v > 0) { for(i=0;i<v;i++) { if(op->s_now == op->s_end) op->s_now = op->s_start; else { op->s_now++; if(op->s_now == op->size) op->s_now = 0; } } } else { for(i=v;i<0;i++) { if(op->s_now == op->s_start) op->s_now = op->s_end; else if(op->s_now == 0) op->s_now = op->size - 1; else op->s_now--; } } monomeLedBuffer[monome_xy_idx(op->s_now, 0)] = 15; monome_set_quadrant_flag(0); monome_set_quadrant_flag(1); } if(op->s_cut2 == 0) { monomeLedBuffer[monome_xy_idx(op->s_now2, 2)] = 0; if(v > 0) { for(i=0;i<v;i++) { if(op->s_now2 == op->s_end2) op->s_now2 = op->s_start2; else { op->s_now2++; if(op->s_now2 == op->size) op->s_now2 = 0; } } } else { for(i=v;i<0;i++) { if(op->s_now2 == op->s_start2) op->s_now2 = op->s_end2; else if(op->s_now2 == 0) op->s_now2 = op->size - 1; else op->s_now2--; } } monomeLedBuffer[monome_xy_idx(op->s_now2, 2)] = 15; monome_set_quadrant_flag(0); monome_set_quadrant_flag(1); } op->s_cut = 0; op->s_cut2 = 0; net_activate(op->outs[0], op->steps[0][op->s_now], op); net_activate(op->outs[1], op->steps[1][op->s_now], op); net_activate(op->outs[2], op->steps[2][op->s_now], op); net_activate(op->outs[3], op->steps[3][op->s_now], op); i = (op->steps[0][op->s_now]) + (op->steps[1][op->s_now] << 1) + (op->steps[2][op->s_now] << 2) + (op->steps[3][op->s_now] << 3); net_activate(op->outs[4], i, op); net_activate(op->outs[5], op->s_now, op); i = (op->steps[0][op->s_now2]) + (op->steps[1][op->s_now2] << 1) + (op->steps[2][op->s_now2] << 2) + (op->steps[3][op->s_now2] << 3); net_activate(op->outs[6], i, op); net_activate(op->outs[7], op->s_now2, op); }
// input state static void op_route_in_val(op_route_t* route, const io_t v) { route->val = v; net_activate(route->outs[route->to], route->val, route); }