void SynthController::updateCutoff() { fixed envValue = envelope_.GetValue(); fixed envContrib = fp_sub(FP_ONE, envValue); envContrib = fp_mul(envContrib, cutoffEnvMod_); envContrib = fp_sub(FP_ONE, envContrib); fixed current = fp_mul(cutoff_, envContrib); hwParameters_.cutoff_ = int(fp2fl(current)*255); }
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 SynthController::PitchControl::Trigger() { if (target_ != SET_NOTE_OFF) { if ((glide_ != SET_GLIDE_OFF) && (value_ != target_) && (value_ != SET_NOTE_OFF)) { float offset = fp2fl(glide_); if (target_ > value_) { value_ += offset; if (value_ >= target_) { value_ = target_; } } else { value_ -= offset; if (value_ <= target_) { value_ = target_; } } } else { value_ = target_; } } else { value_ = SET_NOTE_OFF; } }
void SynthController::SetPitchBend(const fixed& value) { static const uint8_t PITCH_BEND_SEMITONE_INTERVAL = 5.0f; noteBend_ = fp2fl(value)*PITCH_BEND_SEMITONE_INTERVAL; }
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_); } }