/* ZynAddSubFX - a software synthesizer ADnoteParameters.C - Parameters for ADnote (ADsynth) Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License (version 2) for more details. You should have received a copy of the GNU General Public License (version 2) along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "ADnoteParameters.h" ADnoteParameters::ADnoteParameters(FFTwrapper *fft_):Presets(){ setpresettype("Padsyth"); fft=fft_; GlobalPar.FreqEnvelope=new EnvelopeParams(0,0); GlobalPar.FreqEnvelope->ASRinit(64,50,64,60); GlobalPar.FreqLfo=new LFOParams(70,0,64,0,0,0,0,0); GlobalPar.AmpEnvelope=new EnvelopeParams(64,1); GlobalPar.AmpEnvelope->ADSRinit_dB(0,40,127,25); GlobalPar.AmpLfo=new LFOParams(80,0,64,0,0,0,0,1); GlobalPar.GlobalFilter=new FilterParams(2,94,40); GlobalPar.FilterEnvelope=new EnvelopeParams(0,1); GlobalPar.FilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); GlobalPar.FilterLfo=new LFOParams(80,0,64,0,0,0,0,2); GlobalPar.Reson=new Resonance(); for (int nvoice=0;nvoicedefaults(); GlobalPar.FreqLfo->defaults(); GlobalPar.PBandwidth=64; /* Amplitude Global Parameters */ GlobalPar.PVolume=90; GlobalPar.PPanning=64;//center GlobalPar.PAmpVelocityScaleFunction=64; GlobalPar.AmpEnvelope->defaults(); GlobalPar.AmpLfo->defaults(); GlobalPar.PPunchStrength=0; GlobalPar.PPunchTime=60; GlobalPar.PPunchStretch=64; GlobalPar.PPunchVelocitySensing=72; GlobalPar.Hrandgrouping=0; /* Filter Global Parameters*/ GlobalPar.PFilterVelocityScale=64; GlobalPar.PFilterVelocityScaleFunction=64; GlobalPar.GlobalFilter->defaults(); GlobalPar.FilterEnvelope->defaults(); GlobalPar.FilterLfo->defaults(); GlobalPar.Reson->defaults(); for (int nvoice=0;nvoicedefaults(); VoicePar[nvoice].FMSmp->defaults(); VoicePar[nvoice].AmpEnvelope->defaults(); VoicePar[nvoice].AmpLfo->defaults(); VoicePar[nvoice].FreqEnvelope->defaults(); VoicePar[nvoice].FreqLfo->defaults(); VoicePar[nvoice].VoiceFilter->defaults(); VoicePar[nvoice].FilterEnvelope->defaults(); VoicePar[nvoice].FilterLfo->defaults(); VoicePar[nvoice].FMFreqEnvelope->defaults(); VoicePar[nvoice].FMAmpEnvelope->defaults(); }; /* * Init the voice parameters */ void ADnoteParameters::EnableVoice(int nvoice){ VoicePar[nvoice].OscilSmp=new OscilGen(fft,GlobalPar.Reson); VoicePar[nvoice].FMSmp=new OscilGen(fft,NULL); VoicePar[nvoice].AmpEnvelope=new EnvelopeParams(64,1); VoicePar[nvoice].AmpEnvelope->ADSRinit_dB(0,100,127,100); VoicePar[nvoice].AmpLfo=new LFOParams(90,32,64,0,0,30,0,1); VoicePar[nvoice].FreqEnvelope=new EnvelopeParams(0,0); VoicePar[nvoice].FreqEnvelope->ASRinit(30,40,64,60); VoicePar[nvoice].FreqLfo=new LFOParams(50,40,0,0,0,0,0,0); VoicePar[nvoice].VoiceFilter=new FilterParams(2,50,60); VoicePar[nvoice].FilterEnvelope=new EnvelopeParams(0,0); VoicePar[nvoice].FilterEnvelope->ADSRinit_filter(90,70,40,70,10,40); VoicePar[nvoice].FilterLfo=new LFOParams(50,20,64,0,0,0,0,2); VoicePar[nvoice].FMFreqEnvelope=new EnvelopeParams(0,0); VoicePar[nvoice].FMFreqEnvelope->ASRinit(20,90,40,80); VoicePar[nvoice].FMAmpEnvelope=new EnvelopeParams(64,1); VoicePar[nvoice].FMAmpEnvelope->ADSRinit(80,90,127,100); }; /* * Get the Multiplier of the fine detunes of the voices */ REALTYPE ADnoteParameters::getBandwidthDetuneMultiplier(){ REALTYPE bw=(GlobalPar.PBandwidth-64.0)/64.0; bw=pow(2.0,bw*pow(fabs(bw),0.2)*5.0); return(bw); }; /* * Kill the voice */ void ADnoteParameters::KillVoice(int nvoice){ delete (VoicePar[nvoice].OscilSmp); delete (VoicePar[nvoice].FMSmp); delete (VoicePar[nvoice].AmpEnvelope); delete (VoicePar[nvoice].AmpLfo); delete (VoicePar[nvoice].FreqEnvelope); delete (VoicePar[nvoice].FreqLfo); delete (VoicePar[nvoice].VoiceFilter); delete (VoicePar[nvoice].FilterEnvelope); delete (VoicePar[nvoice].FilterLfo); delete (VoicePar[nvoice].FMFreqEnvelope); delete (VoicePar[nvoice].FMAmpEnvelope); }; ADnoteParameters::~ADnoteParameters(){ delete(GlobalPar.FreqEnvelope); delete(GlobalPar.FreqLfo); delete(GlobalPar.AmpEnvelope); delete(GlobalPar.AmpLfo); delete(GlobalPar.GlobalFilter); delete(GlobalPar.FilterEnvelope); delete(GlobalPar.FilterLfo); delete(GlobalPar.Reson); for (int nvoice=0;nvoice=NUM_VOICES) return; int oscilused=0,fmoscilused=0;//if the oscil or fmoscil are used by another voice for (int i=0;iaddparbool("enabled",VoicePar[nvoice].Enabled); if (((VoicePar[nvoice].Enabled==0)&&(oscilused==0)&&(fmoscilused==0))&&(xml->minimal)) return; xml->addpar("type",VoicePar[nvoice].Type); xml->addpar("delay",VoicePar[nvoice].PDelay); xml->addparbool("resonance",VoicePar[nvoice].Presonance); xml->addpar("ext_oscil",VoicePar[nvoice].Pextoscil); xml->addpar("ext_fm_oscil",VoicePar[nvoice].PextFMoscil); xml->addpar("oscil_phase",VoicePar[nvoice].Poscilphase); xml->addpar("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); xml->addparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); xml->addparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); xml->addpar("fm_enabled",VoicePar[nvoice].PFMEnabled); xml->beginbranch("OSCIL"); VoicePar[nvoice].OscilSmp->add2XML(xml); xml->endbranch(); xml->beginbranch("AMPLITUDE_PARAMETERS"); xml->addpar("panning",VoicePar[nvoice].PPanning); xml->addpar("volume",VoicePar[nvoice].PVolume); xml->addparbool("volume_minus",VoicePar[nvoice].PVolumeminus); xml->addpar("velocity_sensing",VoicePar[nvoice].PAmpVelocityScaleFunction); xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled); if ((VoicePar[nvoice].PAmpEnvelopeEnabled!=0)||(!xml->minimal)){ xml->beginbranch("AMPLITUDE_ENVELOPE"); VoicePar[nvoice].AmpEnvelope->add2XML(xml); xml->endbranch(); }; xml->addparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled); if ((VoicePar[nvoice].PAmpLfoEnabled!=0)||(!xml->minimal)){ xml->beginbranch("AMPLITUDE_LFO"); VoicePar[nvoice].AmpLfo->add2XML(xml); xml->endbranch(); }; xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); xml->addparbool("fixed_freq",VoicePar[nvoice].Pfixedfreq); xml->addpar("fixed_freq_et",VoicePar[nvoice].PfixedfreqET); xml->addpar("detune",VoicePar[nvoice].PDetune); xml->addpar("coarse_detune",VoicePar[nvoice].PCoarseDetune); xml->addpar("detune_type",VoicePar[nvoice].PDetuneType); xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFreqEnvelopeEnabled); if ((VoicePar[nvoice].PFreqEnvelopeEnabled!=0)||(!xml->minimal)){ xml->beginbranch("FREQUENCY_ENVELOPE"); VoicePar[nvoice].FreqEnvelope->add2XML(xml); xml->endbranch(); }; xml->addparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled); if ((VoicePar[nvoice].PFreqLfoEnabled!=0)||(!xml->minimal)){ xml->beginbranch("FREQUENCY_LFO"); VoicePar[nvoice].FreqLfo->add2XML(xml); xml->endbranch(); }; xml->endbranch(); if ((VoicePar[nvoice].PFilterEnabled!=0)||(!xml->minimal)){ xml->beginbranch("FILTER_PARAMETERS"); xml->beginbranch("FILTER"); VoicePar[nvoice].VoiceFilter->add2XML(xml); xml->endbranch(); xml->addparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled); if ((VoicePar[nvoice].PFilterEnvelopeEnabled!=0)||(!xml->minimal)){ xml->beginbranch("FILTER_ENVELOPE"); VoicePar[nvoice].FilterEnvelope->add2XML(xml); xml->endbranch(); }; xml->addparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled); if ((VoicePar[nvoice].PFilterLfoEnabled!=0)||(!xml->minimal)){ xml->beginbranch("FILTER_LFO"); VoicePar[nvoice].FilterLfo->add2XML(xml); xml->endbranch(); }; xml->endbranch(); }; if ((VoicePar[nvoice].PFMEnabled!=0)||(fmoscilused!=0)||(!xml->minimal)){ xml->beginbranch("FM_PARAMETERS"); xml->addpar("input_voice",VoicePar[nvoice].PFMVoice); xml->addpar("volume",VoicePar[nvoice].PFMVolume); xml->addpar("volume_damp",VoicePar[nvoice].PFMVolumeDamp); xml->addpar("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction); xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled); if ((VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0)||(!xml->minimal)){ xml->beginbranch("AMPLITUDE_ENVELOPE"); VoicePar[nvoice].FMAmpEnvelope->add2XML(xml); xml->endbranch(); }; xml->beginbranch("MODULATOR"); xml->addpar("detune",VoicePar[nvoice].PFMDetune); xml->addpar("coarse_detune",VoicePar[nvoice].PFMCoarseDetune); xml->addpar("detune_type",VoicePar[nvoice].PFMDetuneType); xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled); if ((VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0)||(!xml->minimal)){ xml->beginbranch("FREQUENCY_ENVELOPE"); VoicePar[nvoice].FMFreqEnvelope->add2XML(xml); xml->endbranch(); }; xml->beginbranch("OSCIL"); VoicePar[nvoice].FMSmp->add2XML(xml); xml->endbranch(); xml->endbranch(); xml->endbranch(); }; }; void ADnoteParameters::add2XML(XMLwrapper *xml){ xml->addparbool("stereo",GlobalPar.PStereo); xml->beginbranch("AMPLITUDE_PARAMETERS"); xml->addpar("volume",GlobalPar.PVolume); xml->addpar("panning",GlobalPar.PPanning); xml->addpar("velocity_sensing",GlobalPar.PAmpVelocityScaleFunction); xml->addpar("punch_strength",GlobalPar.PPunchStrength); xml->addpar("punch_time",GlobalPar.PPunchTime); xml->addpar("punch_stretch",GlobalPar.PPunchStretch); xml->addpar("punch_velocity_sensing",GlobalPar.PPunchVelocitySensing); xml->addpar("harmonic_randomness_grouping",GlobalPar.Hrandgrouping); xml->beginbranch("AMPLITUDE_ENVELOPE"); GlobalPar.AmpEnvelope->add2XML(xml); xml->endbranch(); xml->beginbranch("AMPLITUDE_LFO"); GlobalPar.AmpLfo->add2XML(xml); xml->endbranch(); xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); xml->addpar("detune",GlobalPar.PDetune); xml->addpar("coarse_detune",GlobalPar.PCoarseDetune); xml->addpar("detune_type",GlobalPar.PDetuneType); xml->addpar("bandwidth",GlobalPar.PBandwidth); xml->beginbranch("FREQUENCY_ENVELOPE"); GlobalPar.FreqEnvelope->add2XML(xml); xml->endbranch(); xml->beginbranch("FREQUENCY_LFO"); GlobalPar.FreqLfo->add2XML(xml); xml->endbranch(); xml->endbranch(); xml->beginbranch("FILTER_PARAMETERS"); xml->addpar("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); xml->addpar("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); xml->beginbranch("FILTER"); GlobalPar.GlobalFilter->add2XML(xml); xml->endbranch(); xml->beginbranch("FILTER_ENVELOPE"); GlobalPar.FilterEnvelope->add2XML(xml); xml->endbranch(); xml->beginbranch("FILTER_LFO"); GlobalPar.FilterLfo->add2XML(xml); xml->endbranch(); xml->endbranch(); xml->beginbranch("RESONANCE"); GlobalPar.Reson->add2XML(xml); xml->endbranch(); for (int nvoice=0;nvoicebeginbranch("VOICE",nvoice); add2XMLsection(xml,nvoice); xml->endbranch(); }; }; void ADnoteParameters::getfromXML(XMLwrapper *xml){ GlobalPar.PStereo=xml->getparbool("stereo",GlobalPar.PStereo); if (xml->enterbranch("AMPLITUDE_PARAMETERS")){ GlobalPar.PVolume=xml->getpar127("volume",GlobalPar.PVolume); GlobalPar.PPanning=xml->getpar127("panning",GlobalPar.PPanning); GlobalPar.PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",GlobalPar.PAmpVelocityScaleFunction); GlobalPar.PPunchStrength=xml->getpar127("punch_strength",GlobalPar.PPunchStrength); GlobalPar.PPunchTime=xml->getpar127("punch_time",GlobalPar.PPunchTime); GlobalPar.PPunchStretch=xml->getpar127("punch_stretch",GlobalPar.PPunchStretch); GlobalPar.PPunchVelocitySensing=xml->getpar127("punch_velocity_sensing",GlobalPar.PPunchVelocitySensing); GlobalPar.Hrandgrouping=xml->getpar127("harmonic_randomness_grouping",GlobalPar.Hrandgrouping); if (xml->enterbranch("AMPLITUDE_ENVELOPE")){ GlobalPar.AmpEnvelope->getfromXML(xml); xml->exitbranch(); }; if (xml->enterbranch("AMPLITUDE_LFO")){ GlobalPar.AmpLfo->getfromXML(xml); xml->exitbranch(); }; xml->exitbranch(); }; if (xml->enterbranch("FREQUENCY_PARAMETERS")){ GlobalPar.PDetune=xml->getpar("detune",GlobalPar.PDetune,0,16383); GlobalPar.PCoarseDetune=xml->getpar("coarse_detune",GlobalPar.PCoarseDetune,0,16383); GlobalPar.PDetuneType=xml->getpar127("detune_type",GlobalPar.PDetuneType); GlobalPar.PBandwidth=xml->getpar127("bandwidth",GlobalPar.PBandwidth); xml->enterbranch("FREQUENCY_ENVELOPE"); GlobalPar.FreqEnvelope->getfromXML(xml); xml->exitbranch(); xml->enterbranch("FREQUENCY_LFO"); GlobalPar.FreqLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); }; if (xml->enterbranch("FILTER_PARAMETERS")){ GlobalPar.PFilterVelocityScale=xml->getpar127("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); GlobalPar.PFilterVelocityScaleFunction=xml->getpar127("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); xml->enterbranch("FILTER"); GlobalPar.GlobalFilter->getfromXML(xml); xml->exitbranch(); xml->enterbranch("FILTER_ENVELOPE"); GlobalPar.FilterEnvelope->getfromXML(xml); xml->exitbranch(); xml->enterbranch("FILTER_LFO"); GlobalPar.FilterLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); }; if (xml->enterbranch("RESONANCE")){ GlobalPar.Reson->getfromXML(xml); xml->exitbranch(); }; for (int nvoice=0;nvoiceenterbranch("VOICE",nvoice)==0) continue; getfromXMLsection(xml,nvoice); xml->exitbranch(); }; }; void ADnoteParameters::getfromXMLsection(XMLwrapper *xml,int n){ int nvoice=n; if (nvoice>=NUM_VOICES) return; VoicePar[nvoice].Enabled=xml->getparbool("enabled",0); VoicePar[nvoice].Type=xml->getpar127("type",VoicePar[nvoice].Type); VoicePar[nvoice].PDelay=xml->getpar127("delay",VoicePar[nvoice].PDelay); VoicePar[nvoice].Presonance=xml->getparbool("resonance",VoicePar[nvoice].Presonance); VoicePar[nvoice].Pextoscil=xml->getpar("ext_oscil",-1,-1,nvoice-1); VoicePar[nvoice].PextFMoscil=xml->getpar("ext_fm_oscil",-1,-1,nvoice-1); VoicePar[nvoice].Poscilphase=xml->getpar127("oscil_phase",VoicePar[nvoice].Poscilphase); VoicePar[nvoice].PFMoscilphase=xml->getpar127("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); VoicePar[nvoice].PFilterEnabled=xml->getparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); VoicePar[nvoice].Pfilterbypass=xml->getparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); VoicePar[nvoice].PFMEnabled=xml->getpar127("fm_enabled",VoicePar[nvoice].PFMEnabled); if (xml->enterbranch("OSCIL")){ VoicePar[nvoice].OscilSmp->getfromXML(xml); xml->exitbranch(); }; if (xml->enterbranch("AMPLITUDE_PARAMETERS")){ VoicePar[nvoice].PPanning=xml->getpar127("panning",VoicePar[nvoice].PPanning); VoicePar[nvoice].PVolume=xml->getpar127("volume",VoicePar[nvoice].PVolume); VoicePar[nvoice].PVolumeminus=xml->getparbool("volume_minus",VoicePar[nvoice].PVolumeminus); VoicePar[nvoice].PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",VoicePar[nvoice].PAmpVelocityScaleFunction); VoicePar[nvoice].PAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled); if (xml->enterbranch("AMPLITUDE_ENVELOPE")){ VoicePar[nvoice].AmpEnvelope->getfromXML(xml); xml->exitbranch(); }; VoicePar[nvoice].PAmpLfoEnabled=xml->getparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled); if (xml->enterbranch("AMPLITUDE_LFO")){ VoicePar[nvoice].AmpLfo->getfromXML(xml); xml->exitbranch(); }; xml->exitbranch(); }; if (xml->enterbranch("FREQUENCY_PARAMETERS")){ VoicePar[nvoice].Pfixedfreq=xml->getparbool("fixed_freq",VoicePar[nvoice].Pfixedfreq); VoicePar[nvoice].PfixedfreqET=xml->getpar127("fixed_freq_et",VoicePar[nvoice].PfixedfreqET); VoicePar[nvoice].PDetune=xml->getpar("detune",VoicePar[nvoice].PDetune,0,16383); VoicePar[nvoice].PCoarseDetune=xml->getpar("coarse_detune",VoicePar[nvoice].PCoarseDetune,0,16383); VoicePar[nvoice].PDetuneType=xml->getpar127("detune_type",VoicePar[nvoice].PDetuneType); VoicePar[nvoice].PFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",VoicePar[nvoice].PFreqEnvelopeEnabled); if (xml->enterbranch("FREQUENCY_ENVELOPE")){ VoicePar[nvoice].FreqEnvelope->getfromXML(xml); xml->exitbranch(); }; VoicePar[nvoice].PFreqLfoEnabled=xml->getparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled); if (xml->enterbranch("FREQUENCY_LFO")){ VoicePar[nvoice].FreqLfo->getfromXML(xml); xml->exitbranch(); }; xml->exitbranch(); }; if (xml->enterbranch("FILTER_PARAMETERS")){ if (xml->enterbranch("FILTER")){ VoicePar[nvoice].VoiceFilter->getfromXML(xml); xml->exitbranch(); }; VoicePar[nvoice].PFilterEnvelopeEnabled=xml->getparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled); if (xml->enterbranch("FILTER_ENVELOPE")){ VoicePar[nvoice].FilterEnvelope->getfromXML(xml); xml->exitbranch(); }; VoicePar[nvoice].PFilterLfoEnabled=xml->getparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled); if (xml->enterbranch("FILTER_LFO")){ VoicePar[nvoice].FilterLfo->getfromXML(xml); xml->exitbranch(); }; xml->exitbranch(); }; if (xml->enterbranch("FM_PARAMETERS")){ VoicePar[nvoice].PFMVoice=xml->getpar("input_voice",VoicePar[nvoice].PFMVoice,-1,nvoice-1); VoicePar[nvoice].PFMVolume=xml->getpar127("volume",VoicePar[nvoice].PFMVolume); VoicePar[nvoice].PFMVolumeDamp=xml->getpar127("volume_damp",VoicePar[nvoice].PFMVolumeDamp); VoicePar[nvoice].PFMVelocityScaleFunction=xml->getpar127("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction); VoicePar[nvoice].PFMAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled); if (xml->enterbranch("AMPLITUDE_ENVELOPE")){ VoicePar[nvoice].FMAmpEnvelope->getfromXML(xml); xml->exitbranch(); }; if (xml->enterbranch("MODULATOR")){ VoicePar[nvoice].PFMDetune=xml->getpar("detune",VoicePar[nvoice].PFMDetune,0,16383); VoicePar[nvoice].PFMCoarseDetune=xml->getpar("coarse_detune",VoicePar[nvoice].PFMCoarseDetune,0,16383); VoicePar[nvoice].PFMDetuneType=xml->getpar127("detune_type",VoicePar[nvoice].PFMDetuneType); VoicePar[nvoice].PFMFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled); if (xml->enterbranch("FREQUENCY_ENVELOPE")){ VoicePar[nvoice].FMFreqEnvelope->getfromXML(xml); xml->exitbranch(); }; if (xml->enterbranch("OSCIL")){ VoicePar[nvoice].FMSmp->getfromXML(xml); xml->exitbranch(); }; xml->exitbranch(); }; xml->exitbranch(); }; };