// insert a split after an output node // return out11 of split if original out was unconnected, // otherwise connect out1 of split to old target and return out2 s16 net_split_out(s16 outIdx) { // saved target s16 target = net->outs[outIdx].target; // index of added split operator s16 split; if( target < 0) { // no target split = net_add_op(eOpSplit); if(split < 0) { // failed to add, do nothing return outIdx; } else { // FIXME: net_op_in_idx is pretty slow net_connect(outIdx, net_op_in_idx(split, 0)); return net_op_out_idx(split, 0); } // add ok } else { // had target; reroute split = net_add_op(eOpSplit); if(split < 0) { // failed to add, do nothing return outIdx; } else { // FIXME: net_op_in_idx is pretty slow net_connect(outIdx, net_op_in_idx(split, 0)); net_connect(net_op_out_idx(split, 0), target); return net_op_out_idx(split, 1); } // add ok } }
// insert a split after an output node // return out11 of split if original out was unconnected, // otherwise connect out1 of split to old target and return out2 s16 net_split_out(s16 outIdx) { // saved target s16 target = net->outs[outIdx].target; // index of added split operator s16 split; if( target < 0) { // no target split = net_add_op(eOpSplit); if(split < 0) { // failed to add, do nothing return outIdx; } else { // FIXME: net_op_in_idx is pretty slow net_connect(outIdx, net_op_in_idx(split, 0)); return net_op_out_idx(split, 0); } // add ok } else { // had target; reroute split = net_add_op(eOpSplit); // fix for github issue #219 // get the target again, because maybe it was a DSP param // (if it was, its index will have shifted. // patch and presets have been updated, but local var has not.) target = net->outs[outIdx].target; if(split < 0) { // failed to add, do nothing return outIdx; } else { // FIXME: net_op_in_idx is pretty slow net_connect(outIdx, net_op_in_idx(split, 0)); net_connect(net_op_out_idx(split, 0), target); return net_op_out_idx(split, 1); } // add ok } }
void handle_key_2(s32 val) { if(val == 0) { return; } if(check_key(2)) { if(altMode) { // delete last created operator net_pop_op(); } else { // create new operator of selected type net_add_op(userOpTypes[newOpType]); // change selection to last op *pageSelect = net_num_ops() - 1; } redraw_ops(); } show_foot(); }
static void net_read_json_ops(json_t* o) { int count = json_integer_value(json_object_get(o, "count")); int i, j; json_t* arr = json_object_get(o, "data"); op_id_t id; op_t* op; json_t* p; /// binary state data.. u8* src; u8 bin[0x10000]; int binCount; // sanity check if(count != json_array_size(arr)) { printf("\r\n warning, mismatched count / size in ops list ( %d / %d )", count, (int)json_array_size(arr)); } // clear out any extant user ops in the network net_deinit(); for( i=0; i<count; i++) { p = json_array_get(arr, i); id = (op_id_t)json_integer_value(json_object_get(p, "type")); // add operator of indicated type net_add_op(id); // unpickle the state, if needed op = net->ops[net->numOps - 1]; if(op->unpickle != NULL) { json_t* state = json_object_get(p, "state"); binCount = json_array_size(state); for(j=0; j<binCount; j++) { bin[j] = (u8)(json_integer_value(json_array_get(state, j))); } src = bin; src = (*(op->unpickle))(op, src); // sanity check if(binCount != ((u32)src - (u32)bin)) { printf("warning! mis-sized byte array in operator state unpickle?"); printf("\r\n bin: 0x%08x ; src: 0x%08x ", (u32)bin, (u32)src); } } } }
static void add_sys_ops(void) { /// FIXME: /* dangerous for scene storage, will break in the unlikely event that op pool is assigned differently. should either: a) reassign these pointers after unpickling probably by index like the old hack, or b) don't pickle system ops at all, only their inputs. still needs to make a fixed assumption about order. ... i dunno */ // 4 encoders net_add_op(eOpEnc); opSysEnc[0] = (op_enc_t*)net->ops[net->numOps - 1]; net_add_op(eOpEnc); opSysEnc[1] = (op_enc_t*)net->ops[net->numOps - 1]; net_add_op(eOpEnc); opSysEnc[2] = (op_enc_t*)net->ops[net->numOps - 1]; net_add_op(eOpEnc); opSysEnc[3] = (op_enc_t*)net->ops[net->numOps - 1]; // 4 function switches net_add_op(eOpSwitch); opSysSw[0] = (op_sw_t*)net->ops[net->numOps - 1]; net_add_op(eOpSwitch); opSysSw[1] = (op_sw_t*)net->ops[net->numOps - 1]; net_add_op(eOpSwitch); opSysSw[2] = (op_sw_t*)net->ops[net->numOps - 1]; net_add_op(eOpSwitch); opSysSw[3] = (op_sw_t*)net->ops[net->numOps - 1]; // 2 footswitches net_add_op(eOpSwitch); opSysSw[4] = (op_sw_t*)net->ops[net->numOps - 1]; net_add_op(eOpSwitch); opSysSw[5] = (op_sw_t*)net->ops[net->numOps - 1]; // 1 adc net_add_op(eOpAdc); opSysAdc = (op_adc_t*)net->ops[net->numOps -1]; // 1 preset receiver net_add_op(eOpPreset); opSysPreset = (op_preset_t*)net->ops[net->numOps -1]; }
// unpickle the network! u8* net_unpickle(const u8* src) { u32 i, count, val; op_id_t id; op_t* op; // reset operator count, param count, pool offset, etc // no system operators after this net_deinit(); // get count of operators // (use 4 bytes for alignment) src = unpickle_32(src, &count); #ifdef PRINT_PICKLE print_dbg("\r\n count of ops: "); print_dbg_ulong(count); #endif // loop over operators for(i=0; i<count; ++i) { // get operator class id src = unpickle_32(src, &val); id = (op_id_t)val; #ifdef PRINT_PICKLE print_dbg("\r\n adding op, class id: "); print_dbg_ulong(id); #endif // add and initialize from class id /// .. this should update the operator count, inodes and onodes net_add_op(id); // unpickle operator state (if needed) op = net->ops[net->numOps - 1]; if(op->unpickle != NULL) { #ifdef PRINT_PICKLE print_dbg(" ... unpickling op .... "); print_dbg_ulong(id); #endif src = (*(op->unpickle))(op, src); } } #if 1 /// copy ALL i/o nodes, even unused! print_dbg("\r\n reading all input nodes "); for(i=0; i < (NET_INS_MAX); ++i) { #ifdef PRINT_PICKLE print_dbg("\r\n unpickling input node, idx: "); print_dbg_ulong(i); #endif src = inode_unpickle(src, &(net->ins[i])); } #ifdef PRINT_PICKLE print_dbg("\r\n reading all output nodes"); #endif // read output nodes for(i=0; i < NET_OUTS_MAX; ++i) { #ifdef PRINT_PICKLE print_dbg("\r\n unpickling output node, idx: "); print_dbg_ulong(i); #endif src = onode_unpickle(src, &(net->outs[i])); if(i < net->numOuts) { if(net->outs[i].target >= 0) { // reconnect so the parent operator knows what to do net_connect(i, net->outs[i].target); } } } #else #error broken input node unserialization /* /\* #ifdef PRINT_PICKLE *\/ */ /* /\* print_dbg("\r\n reading input nodes, count: "); *\/ */ /* /\* print_dbg_ulong(net->numIns); *\/ */ /* /\* #endif *\/ */ /* for(i=0; i < (net->numIns); ++i) { */ /* src = inode_unpickle(src, &(net->ins[i])); */ /* } */ /* /\* #ifdef PRINT_PICKLE *\/ */ /* /\* print_dbg("\r\n reading output nodes, count: "); *\/ */ /* /\* print_dbg_ulong(net->numOuts); *\/ */ /* /\* #endif *\/ */ /* // read output nodes */ /* for(i=0; i < net->numOuts; ++i) { */ /* src = onode_unpickle(src, &(net->outs[i])); */ /* // reconnect so the parent operator knows what to do */ /* net_connect(i, net->outs[i].target); */ /* } */ #endif // get count of parameters src = unpickle_32(src, &val); net->numParams = (u16)val; #ifdef PRINT_PICKLE print_dbg("\r\n reading params, count: "); print_dbg_ulong(net->numParams); #endif // read parameter nodes (includes value and descriptor) for(i=0; i<(net->numParams); ++i) { #ifdef PRINT_PICKLE print_dbg("\r\n unpickling param, idx: "); print_dbg_ulong(i); #endif src = param_unpickle(&(net->params[i]), src); } return (u8*)src; }
// unpickle the network! u8* net_unpickle(const u8* src) { u32 i, count, val; op_id_t id; op_t* op; // reset operator count, param count, pool offset, etc // no system operators after this net_deinit(); // get count of operators // (use 4 bytes for alignment) src = unpickle_32(src, &count); print_dbg("\r\n count of ops: "); print_dbg_ulong(count); // loop over operators for(i=0; i<count; ++i) { // get operator class id src = unpickle_32(src, &val); id = (op_id_t)val; // add and initialize from class id /// .. this should update the operator count, inodes and onodes print_dbg("\r\n adding op, class id: "); print_dbg_ulong(id); net_add_op(id); // unpickle operator state (if needed) op = net->ops[net->numOps - 1]; if(op->unpickle != NULL) { print_dbg(" ... unpickling op .... "); print_dbg_ulong(id); src = (*(op->unpickle))(op, src); } } // read input nodes // for(i=0; i < (net->numIns + net->numParams); ++i) { ///// FIXME: /// tried adding the params to input list here, for play-mode flag /// but somehow, this breaks stuff. #if 1 /// copy ALL i/o nodes, even unused print_dbg("\r\n reading all input nodes "); for(i=0; i < (NET_INS_MAX); ++i) { print_dbg("\r\n unpickling input node, idx: "); print_dbg_ulong(i); src = inode_unpickle(src, &(net->ins[i])); } print_dbg("\r\n reading all output nodes"); // read output nodes for(i=0; i < NET_OUTS_MAX; ++i) { print_dbg("\r\n unpickling output node, idx: "); print_dbg_ulong(i); src = onode_unpickle(src, &(net->outs[i])); if(i < net->numOuts) { if(net->outs[i].target >= 0) { // reconnect so the parent operator knows what to do net_connect(i, net->outs[i].target); } } } #else print_dbg("\r\n reading input nodes, count: "); print_dbg_ulong(net->numIns); for(i=0; i < (net->numIns); ++i) { src = inode_unpickle(src, &(net->ins[i])); } print_dbg("\r\n reading output nodes, count: "); print_dbg_ulong(net->numOuts); // read output nodes for(i=0; i < net->numOuts; ++i) { src = onode_unpickle(src, &(net->outs[i])); // reconnect so the parent operator knows what to do net_connect(i, net->outs[i].target); } #endif // get count of parameters src = unpickle_32(src, &val); net->numParams = (u16)val; print_dbg("\r\n reading params, count: "); print_dbg_ulong(net->numParams); // read parameter nodes (includes value and descriptor) for(i=0; i<(net->numParams); ++i) { print_dbg("\r\n unpickling param, idx: "); print_dbg_ulong(i); src = param_unpickle(&(net->params[i]), src); } return (u8*)src; }