void set_filter(int channel, filterType_t type, fixed param1,fixed param2,int mix,bool bassyMapping) { filter_t* flt=&filter[channel]; if(flt->type!=type) //reset only on filter type change (maybe no reset would make interresting bugs) { flt->height[0]=0; //idle state flt->height[1]=0; //idle state flt->speed[0]=0; //paused (to avoid having it goind crazy) flt->speed[1]=0; //paused (to avoid having it goind crazy) flt->hipdelay[0]=0 ; flt->hipdelay[1]=0 ; flt->type=type; } flt->dirt=fp_mul(i2fp(100),i2fp(1)-param1)+fp_mul(i2fp(5000),param1) ; flt->mix =fp_mul(i2fp(mix),fp_inv_255) ; if (param1 != flt->parm1) { flt->parm1=param1; //adjust parm to get the most of the parameters, as the fx are more useful with near-limit parameters. if (bassyMapping) { static const fixed fpFreqDivider = fl2fp(1/22050.0f); static const fixed fpZeroSix = fl2fp(0.6f); static const fixed fpThreeOne = fl2fp(3.1f); fixed power = fp_add(fpZeroSix,fp_mul(param1,fpThreeOne)); fixed frequency = fl2fp(pow(10.0f,fp2fl(power))) ; frequency=fp_mul(frequency,fpFreqDivider); flt->freq=frequency; } else { flt->freq=fp_mul(param1,param1); //0 - .5 - 1 => 0 - .25 - 1 } } if (param2 != flt->parm2) { flt->parm2=param2; flt->reso=i2fp(1)-param2 ; flt->reso=fp_sub(fl2fp(1.f),fp_mul(flt->reso,fp_mul(flt->reso,flt->reso))); //0 - .5 - 1 => 0 - .93 - 1 } }
void init_filters(void) { for(int i=0; i<8; i++) { //set sensible default values //lowpass filter where everything passes with no resonance set_filter(i,FLT_LOWPASS,i2fp(1),i2fp(0),i2fp(0),false); } fp_inv_255=fl2fp(1.0f/255) ; filters_inited=true; }
void SynthController::SetParameterValue(const SynthController::Parameter& parameter, const fixed& value) { bool envSetup = false; switch(parameter) { case WAVE_SELECT: oscillator_.SetShape(value); break; case WAVE_LOOP_START: oscillator_.SetLoopStart(value); break; case WAVE_LOOP_END: oscillator_.SetLoopWidth(value); break; case WAVE_OCTAVE: { int32_t octave = 0; if (value < fl2fp(0.33f)) { octave = -1; } if (value > fl2fp(0.66f)) { octave = 1; } oscillator_.SetOctave(octave); break; } case ANALOG_OSC_ON: enableAnalog_ = value > fl2fp(0.5f); break; case ANALOG_PITCH_FINE_TUNE: analogPitchFineTune_ = fp2fl(value)*256 - 128 ; break; case PITCH_GLIDE: { const fixed GLIDE_MULTIPLIER = fl2fp(0.4f); fixed glideFactor = (value != 0 ) ? fp_sub(GLIDE_MULTIPLIER, fp_mul(value, GLIDE_MULTIPLIER)) : SET_GLIDE_OFF; anaPitchControl_.SetGlide(glideFactor); digiPitchControl_.SetGlide(glideFactor); break; } case NOISE_MIX: noiseMix_ = value; updateLevels(); break; case KEYBOARD_MODE: { NoteControl::Mode mode = (NoteControl::Mode)int(fp2fl(value)*NoteControl::LAST*0.999f); noteControl_.SetMode(mode); break; } case ENV_ATTACK: attack_ = MAX_ENVELOPE_TICK*fp2fl(value); envSetup = true; break; case ENV_DECAY: { fixed scaledDecay = fp_add(value, ENVELOPE_SCALE); decay_ = MAX_ENVELOPE_TICK*fp2fl(scaledDecay); envSetup = true; } break; case ENV_SUSTAIN: { fixed scaledSustain = fp_add(value, ENVELOPE_SCALE); if (scaledSustain > FP_ONE) { scaledSustain = FP_ONE; } sustain_ = scaledSustain; envSetup = true; } break; case ENV_RELEASE: release_ = MAX_ENVELOPE_TICK*fp2fl(value); envSetup = true; break; case VCA_ENV_GATER: envelope_.SetScaler(value); break; case VCF_ENV_MOD: cutoffEnvMod_ = value; break; case AMP_GAIN: gain_ = value; updateLevels(); break; } if (envSetup) { envelope_.Setup(attack_, decay_, sustain_, release_); } }
updateTargetPitches(); if (noteControl_.ShouldKillEnvelope()) { envelope_.Stop(); } } void SynthController::updateTargetPitches() { digiPitchControl_.SetTarget(noteControl_.GetDigitalTargetNote()); anaPitchControl_.SetTarget(noteControl_.GetAnalogTargetNote()); } static const uint32_t MAX_ENVELOPE_TICK = 2000; static const fixed ENVELOPE_SCALE = fl2fp(0.007874015748031f); //----------------------------------------------------------- void SynthController::SetParameterValue(const SynthController::Parameter& parameter, const fixed& value) { bool envSetup = false; switch(parameter) { case WAVE_SELECT: oscillator_.SetShape(value); break; case WAVE_LOOP_START: oscillator_.SetLoopStart(value);