// initialize network at pre-allocated memory void net_init(void) { u32 i; net = (ctlnet_t*)alloc_mem(sizeof(ctlnet_t)); for(i=0; i<NET_OP_POOL_SIZE; i++) { net->opPoolMem[i] = 0x00; } net->opPool = (void*)&(net->opPoolMem); net->opPoolOffset = 0; net->numOps = 0; net->numIns = 0; net->numOuts = 0; net->numParams = 0; // unassign all I/O nodes for(i=0; i<NET_INS_MAX; i++) { net_init_inode(i); } for(i=0; i<NET_OUTS_MAX; i++) { net_init_onode(i); } print_dbg("\r\n initialized ctlnet, byte count: "); print_dbg_hex(sizeof(ctlnet_t)); add_sys_ops(); // ??? netActive = 1; }
// de-initialize network void net_deinit(void) { u32 i; print_dbg("\r\n deinitializing network"); for(i=0; i<net->numOps; i++) { op_deinit(net->ops[i]); } print_dbg("\r\n finished de-initializing network"); net->opPoolOffset = 0; net->numOps = 0; net->numIns = 0; net->numOuts = 0; net->numParams = 0; // unassign all I/O nodes for(i=0; i<NET_INS_MAX; i++) { net_init_inode(i); } for(i=0; i<NET_OUTS_MAX; i++) { net_init_onode(i); } }
// destroy last operator created s16 net_pop_op(void) { const s16 opIdx = net->numOps - 1; op_t* op = net->ops[opIdx]; int i=0; int x, y; app_pause(); // bail if system op if(net_op_flag (opIdx, eOpFlagSys)) { return 1; } // de-init op_deinit(op); // store the global index of the first input x = net_op_in_idx(opIdx, 0); y = x + op->numInputs; // check if anything connects here for(i=0; i<net->numOuts; i++) { // this check works b/c we know this is last op in list if( net->outs[i].target >= x ) { if( net->outs[i].target < y) { net_disconnect(i); } else { // net->outs[i].target -= op->numInputs; net_connect(i, net->outs[i].target - op->numInputs); } } } // erase input nodes while(x < y) { net_init_inode(x++); } // store the global index of the first output x = net_op_out_idx(opIdx, 0); y = x + op->numOutputs; // erase output nodes while(x < y) { net_init_onode(x++); } net->numIns -= op->numInputs; net->numOuts -= op->numOutputs; net->opPoolOffset -= op_registry[op->type].size; net->numOps -= 1; app_resume(); return 0; }
/// delete an arbitrary operator, and do horrible ugly management stuff void net_remove_op(const u32 idx) { /// FIXME: network processing must be halted during this procedure! op_t* op = net->ops[idx]; u8 nIns = op->numInputs; u8 nOuts = op->numOutputs; s16 firstIn, lastIn; s16 firstOut, lastOut; u32 opSize; u32 i; u8* pMem; // raw pointer to op pool memory opSize = op_registry[op->type].size; if ( nIns > 0 ) { /// find the first input idx firstIn = -1; for(i=0; i<net->numIns; i++) { if (net->ins[i].opIdx == idx) { firstIn = i; break; } } if(firstIn == -1 ) { // supposed to be a first inlet but we couldn't find it; we are f****d print_dbg("\r\n oh dang! couldn't find first inlet for deleted operator! \r\n"); } lastIn = firstIn + nIns - 1; // check if anything connects here for(i=0; i<net->numOuts; i++) { if( net->outs[i].target >= firstIn ) { if( net->outs[i].target > lastIn ) { // connections to higher inlets get moved down net->outs[i].target -= nIns; } else { // disconnect from this op's inputs net->outs[i].target = -1; } } } // if higher input nodes are used... for(i=(lastIn + 1); i<net->numIns; i++) { /// revise op Idx net->ins[i].opIdx -= 1; /// copy all the data down net->ins[i - nIns] = net->ins[i]; /// then erase net_init_inode(i); } } /// update output nodes for this op and higher firstOut = -1; lastOut = NET_OUTS_MAX; if ( nOuts > 0 ) { for(i=0; i<net->numOuts; i++) { if (net->outs[i].opIdx == idx) { if(firstOut == -1) { firstOut = i; lastOut = firstOut + nOuts - 1; } // deleted op owns this outlet, so erase it net_init_onode(i); } if( i > lastOut ) { /// for onodes above... /// revise op Idx net->outs[i].opIdx -= 1; /// copy all the data down net->outs[i - nOuts] = net->outs[i]; /// then erase net_init_onode(i); } } } //// VERY DANGEROUSly move all the op memory above this, byte by byte for( pMem = (u8*)op + opSize; (u32)pMem < ((u32)(net->opPool) + net->opPoolOffset); pMem++ ) { *((u8*)(pMem - opSize)) = *((u8*)pMem); } /// move the memory offset back net->opPoolOffset -= opSize; /// update node and op counts net->numIns -= nIns; net->numOuts -= nOuts; net->numOps -= 1; //... and, uh, don't crash? }
// destroy last operator created s16 net_pop_op(void) { const s16 opIdx = net->numOps - 1; op_t* op = net->ops[opIdx]; int i, j; int x, y; int ins; int numInsSave = net->numIns; int idxOld, idxNew; app_pause(); // bail if system op if(net_op_flag (opIdx, eOpFlagSys)) { return 1; } // de-init op_deinit(op); ins = op->numInputs; // store the global index of the first input x = net_op_in_idx(opIdx, 0); y = x + ins; // check if anything connects here for(i=0; i<net->numOuts; i++) { // this check works b/c we know this is last op in list if( net->outs[i].target >= x ) { if( net->outs[i].target < y) { net_disconnect(i); } else { /// this should take care of both param and op input targets. net_connect(i, net->outs[i].target - op->numInputs); } } } // erase input nodes while(x < y) { net_init_inode(x++); } // store the global index of the first output x = net_op_out_idx(opIdx, 0); y = x + op->numOutputs; // erase output nodes while(x < y) { net_init_onode(x++); } net->numIns -= op->numInputs; net->numOuts -= op->numOutputs; net->opPoolOffset -= op_registry[op->type].size; net->numOps -= 1; // FIXME: shift preset param data and connections to params, // since they share an indexing list with inputs and we just changed it. for(i=0; i<NET_PRESETS_MAX; ++i) { // shift parameter nodes in preset data for(j=0; j<net->numParams; ++j) { // this was the old param index idxOld = j + numInsSave; // copy to new param index idxNew = idxOld - ins; presets[i].ins[idxNew].value = presets[i].ins[idxOld].value; presets[i].ins[idxNew].enabled = presets[i].ins[idxOld].enabled; // clear the old data. presets[i].ins[idxOld].enabled = 0; presets[i].ins[idxOld].value = 0; } } app_resume(); return 0; }