// frame calculation static void calc_frame(void) { #if 1 u8 i; wavesVoice* v; for(i=0; i<WAVES_NVOICES; i++) { v = &(voice[i]); // oscillator class includes hz and mod integrators v->oscOut = shr_fr1x32( osc_next( &(v->osc) ), 2); // phase mod with fixed 1-frame delay osc_pm_in( &(v->osc), v->pmIn ); // shape mod with fixed 1-frame delay osc_wm_in( &(v->osc), v->wmIn ); // process filter integrators and set filter_svf_set_coeff( &(v->svf), filter_1p_lo_next( &(v->cutSlew) ) ); filter_svf_set_rq( &(v->svf), filter_1p_lo_next( &(v->rqSlew) ) ); // process filter v->svfOut = filter_svf_next( &(v->svf), shr_fr1x32(v->oscOut, 1) ); // process amp smoother v->amp = filter_1p_lo_next( &(v->ampSlew) ); // mix to output bus v->out = mult_fr1x32x32(v->amp, add_fr1x32(mult_fr1x32x32( v->oscOut, v->fDry), mult_fr1x32x32( v->svfOut, v->fWet) ) ); } // end voice loop /// FIXME: later, more voices, mod matrix, arbitrary mod delay. /// for now, simple direct mod feedback routing and 1-frame delay. voice[0].pmIn = voice[1].oscOut; // voice[0].wmIn = voice[1].oscOut << 1; voice[1].pmIn = voice[0].oscOut; // voice[1].wmIn = voice[0].oscOut << 1; // mix outputs using matrix mix_outputs(); #else /* // fract32 out1, out0; */ /* // osc output */ /* oscOut1 = shr_fr1x32(osc_next( &(osc1) ), 2); */ /* oscOut0 = shr_fr1x32(osc_next( &(osc0) ), 2); */ /* // phase mod feedback with 1frame delay */ /* osc_pm_in( &osc1, oscOut0 ); */ /* osc_pm_in( &osc0, oscOut1 ); */ /* // shape mod feedback with 1frame delay */ /* osc_wm_in( &osc1, oscOut0 ); */ /* osc_wm_in( &osc0, oscOut1 ); */ /* /////////// */ /* /////////// */ /* // apply filters */ /* if( !(svfCutSlew[i].sync) ) { */ /* filter_svf_set_coeff( &(svf[i]), filter_1p_lo_next(&(svfCutSlew[i])) ); */ /* } */ /* if( !(svfRqSlew[i].sync) ) { */ /* filter_svf_set_rq( &(svf[i]), filter_1p_lo_next(&(svfRqSlew[i])) ); */ /* } */ /* // svfOut1 = shl_fr1x32(filter_svf_next( &(svf1), shr_fr1x32(oscOut1, 1)), 1); */ /* // svfOut2 = shl_fr1x32(filter_svf_next( &(svf2), shr_fr1x32(oscOut2, 1)), 1); */ /* svfOut1 = filter_svf_next( &(svf1), shr_fr1x32(oscOut1, 1)); */ /* svfOut0 = filter_svf_next( &(svf0), shr_fr1x32(oscOut0, 1)); */ /* ///////// */ /* ///////// */ /* // amp smoothers */ /* oscAmp1 = filter_1p_lo_next(amp1Lp); */ /* oscAmp0 = filter_1p_lo_next(amp0Lp); */ /* // apply osc amplitudes and sum */ /* oscOut1 = mult_fr1x32x32(oscAmp1, */ /* add_fr1x32(mult_fr1x32x32( oscOut1, fdry1), */ /* mult_fr1x32x32( svfOut1, fwet1) */ /* )); */ /* oscOut0 = mult_fr1x32x32(oscAmp0, */ /* add_fr1x32(mult_fr1x32x32( oscOut0, fdry0), */ /* mult_fr1x32x32( svfOut0, fwet0) */ /* )); */ /* //// */ /* /// fixme: mono */ /* frameVal = add_fr1x32( oscOut0, oscOut1); */ /* // mix to output */ /* //...todo */ #endif }
// frame calculation static void calc_frame(void) { int i; wavesVoice* v = voice; fract32* vout = voiceOut; for(i=0; i<WAVES_NVOICES; i++) { // v = &(voice[i]); // oscillator class includes hz and mod integrators v->oscOut = shr_fr1x32( osc_next( &(v->osc) ), 2); // /set modulation - FIXME this is redundant... osc_pm_in( &(v->osc), v->pmIn ); osc_wm_in( &(v->osc), v->wmIn ); // set filter params slew32_calc(v->cutSlew); slew32_calc(v->rqSlew); filter_svf_set_coeff( &(v->svf), v->cutSlew.y ); filter_svf_set_rq( &(v->svf), v->rqSlew.y ); // process filter v->svfOut = filter_svf_next( &(v->svf), shr_fr1x32(v->oscOut, 1) ); // process amp/mix smoothing slew32_calc(v->ampSlew); slew16_calc(v->drySlew); slew16_calc(v->wetSlew); // mix dry/filter and apply amp *vout = mult_fr1x32x32( v->ampSlew.y, add_fr1x32( mult_fr1x32( trunc_fr1x32(v->oscOut), v->drySlew.y ), mult_fr1x32( trunc_fr1x32(v->svfOut), v->wetSlew.y ) ) ); // advance phase del indices v->pmDelWrIdx = (v->pmDelWrIdx + 1) & WAVES_PM_DEL_SAMPS_1; v->pmDelRdIdx = (v->pmDelRdIdx + 1) & WAVES_PM_DEL_SAMPS_1; // set pm input from delay v->pmIn = v->pmDelBuf[v->pmDelRdIdx]; // no tricky modulation routing here! v->wmIn = v->pmDelBuf[v->pmDelRdIdx]; // advance pointers vout++; v++; } // end voice loop // // simple cross-patch modulation // add delay, before filter voice[0].pmDelBuf[voice[0].pmDelWrIdx] = voice[1].oscOut; voice[1].pmDelBuf[voice[1].pmDelWrIdx] = voice[0].oscOut; /* voice[0].pmIn = voice[1].oscOut; */ /* voice[1].pmIn = voice[0].oscOut; */ // zero the outputs out[0] = out[1] = out[2] = out[3] = 0; // patch filtered oscs outputs mix_voice(); // oatch adc mix_adc(); }
// get next value (with input) extern fract32 filter_svf_next( filter_svf* f, fract32 in) { // process 2x and average fract32 out = shr_fr1x32(filter_svf_calc_frame(f, in), 1); out = add_fr1x32(out, shr_fr1x32(filter_svf_calc_frame(f, in), 1)); return out; }