First commit

master
reales 6 years ago
commit 56df0ac2d5

@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8"?>
<JUCERPROJECT id="mxW328" name="Obxd" projectType="audioplug" version="1.4.1"
bundleIdentifier="com.Datsounds.Obxd" includeBinaryInAppConfig="1"
buildVST="1" buildVST3="0" buildAU="1" buildRTAS="0" buildAAX="0"
pluginName="OB-Xd" pluginDesc="Emulation of famous OB-X, OB-Xa and OB-8 synths"
pluginManufacturer="Datsounds" pluginManufacturerCode="Dats"
pluginCode="Obxd" pluginChannelConfigs="{0, 2}" pluginIsSynth="1"
pluginWantsMidiIn="1" pluginProducesMidiOut="0" pluginSilenceInIsSilenceOut="0"
pluginEditorRequiresKeys="0" pluginAUExportPrefix="" pluginRTASCategory="ePlugInCategory_SWGenerators"
aaxIdentifier="" pluginAAXCategory="" jucerVersion="4.3.0" companyName="2Dat"
companyWebsite="http://obxd.wordpress.com" companyEmail="" buildAUv3="0"
pluginIsMidiEffectPlugin="0" pluginAUMainType="">
<MAINGROUP id="NZ3n4V" name="Obxd">
<GROUP id="{90740217-84AB-FD0D-FBC4-CA9EA2C68D5E}" name="Source">
<GROUP id="{5F0B15D1-4D92-B2FF-5904-9CF4C3CE645F}" name="Images">
<FILE id="IV8Ubu" name="button.png" compile="0" resource="1" file="Source/Images/button.png"/>
<FILE id="gUrdhJ" name="knoblsd.png" compile="0" resource="1" file="Source/Images/knoblsd.png"/>
<FILE id="FzhdQQ" name="knobssd.png" compile="0" resource="1" file="Source/Images/knobssd.png"/>
<FILE id="syMyon" name="legato.png" compile="0" resource="1" file="Source/Images/legato.png"/>
<FILE id="kwaOoZ" name="main.png" compile="0" resource="1" file="Source/Images/main.png"/>
<FILE id="UHyt7V" name="voices.png" compile="0" resource="1" file="Source/Images/voices.png"/>
</GROUP>
<GROUP id="{6995BDF2-263F-3CA7-8CA4-4E21F325477A}" name="Gui">
<FILE id="zJoidp" name="ButtonList.h" compile="0" resource="0" file="Source/Gui/ButtonList.h"/>
<FILE id="lB2ss0" name="Knob.h" compile="0" resource="0" file="Source/Gui/Knob.h"/>
<FILE id="YKpBza" name="TooglableButton.h" compile="0" resource="0"
file="Source/Gui/TooglableButton.h"/>
</GROUP>
<GROUP id="{1A73CFC2-DCEB-F0B6-8B56-21F49DA2C76A}" name="Engine">
<FILE id="puIwTg" name="AdsrEnvelope.h" compile="0" resource="0" file="Source/Engine/AdsrEnvelope.h"/>
<FILE id="gX1oGg" name="APInterpolator.h" compile="0" resource="0"
file="Source/Engine/APInterpolator.h"/>
<FILE id="QrrECt" name="AudioUtils.h" compile="0" resource="0" file="Source/Engine/AudioUtils.h"/>
<FILE id="oR4aDr" name="BlepData.h" compile="0" resource="0" file="Source/Engine/BlepData.h"/>
<FILE id="Kfut62" name="Decimator.h" compile="0" resource="0" file="Source/Engine/Decimator.h"/>
<FILE id="OGpoX0" name="DelayLine.h" compile="0" resource="0" file="Source/Engine/DelayLine.h"/>
<FILE id="MD0CpM" name="Filter.h" compile="0" resource="0" file="Source/Engine/Filter.h"/>
<FILE id="uAQRsN" name="Lfo.h" compile="0" resource="0" file="Source/Engine/Lfo.h"/>
<FILE id="hisHmA" name="midiMap.h" compile="0" resource="0" file="Source/Engine/midiMap.h"/>
<FILE id="PCXDan" name="Motherboard.h" compile="0" resource="0" file="Source/Engine/Motherboard.h"/>
<FILE id="VMrHE6" name="ObxdBank.h" compile="0" resource="0" file="Source/Engine/ObxdBank.h"/>
<FILE id="kuzEP4" name="ObxdOscillatorB.h" compile="0" resource="0"
file="Source/Engine/ObxdOscillatorB.h"/>
<FILE id="WpXJsN" name="ObxdVoice.h" compile="0" resource="0" file="Source/Engine/ObxdVoice.h"/>
<FILE id="mATgXj" name="Params.h" compile="0" resource="0" file="Source/Engine/Params.h"/>
<FILE id="gcujnI" name="ParamsEnum.h" compile="0" resource="0" file="Source/Engine/ParamsEnum.h"/>
<FILE id="rkbmLG" name="ParamSmoother.h" compile="0" resource="0" file="Source/Engine/ParamSmoother.h"/>
<FILE id="upfVOc" name="PulseOsc.h" compile="0" resource="0" file="Source/Engine/PulseOsc.h"/>
<FILE id="cJCh5P" name="SawOsc.h" compile="0" resource="0" file="Source/Engine/SawOsc.h"/>
<FILE id="gXSGsx" name="SynthEngine.h" compile="0" resource="0" file="Source/Engine/SynthEngine.h"/>
<FILE id="dJvsex" name="TriangleOsc.h" compile="0" resource="0" file="Source/Engine/TriangleOsc.h"/>
<FILE id="eM2bUm" name="VoiceQueue.h" compile="0" resource="0" file="Source/Engine/VoiceQueue.h"/>
</GROUP>
<FILE id="QQwhFQ" name="PluginProcessor.cpp" compile="1" resource="0"
file="Source/PluginProcessor.cpp"/>
<FILE id="LYHxdB" name="PluginProcessor.h" compile="0" resource="0"
file="Source/PluginProcessor.h"/>
<FILE id="VISBqh" name="PluginEditor.cpp" compile="1" resource="0"
file="Source/PluginEditor.cpp"/>
<FILE id="LkXqq2" name="PluginEditor.h" compile="0" resource="0" file="Source/PluginEditor.h"/>
</GROUP>
</MAINGROUP>
<EXPORTFORMATS>
<XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="modules/vstsdk3" extraCompilerFlags="-I../../modules/vstsdk3"
vst3Folder="modules/vstsdk3">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="Obxd" osxArchitecture="64BitUniversal"
stripLocalSymbols="0" osxCompatibility="10.6 SDK" osxSDK="default"
linkTimeOptimisation="0"/>
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="Obxd"
osxArchitecture="64BitUniversal" stripLocalSymbols="1" osxCompatibility="10.6 SDK"
osxSDK="default" linkTimeOptimisation="0"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_opengl" path="modules"/>
<MODULEPATH id="juce_gui_extra" path="modules"/>
<MODULEPATH id="juce_gui_basics" path="modules"/>
<MODULEPATH id="juce_graphics" path="modules"/>
<MODULEPATH id="juce_events" path="modules"/>
<MODULEPATH id="juce_data_structures" path="modules"/>
<MODULEPATH id="juce_core" path="modules"/>
<MODULEPATH id="juce_audio_processors" path="modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="modules"/>
<MODULEPATH id="juce_audio_formats" path="modules"/>
<MODULEPATH id="juce_audio_devices" path="modules"/>
<MODULEPATH id="juce_audio_basics" path="modules"/>
<MODULEPATH id="juce_audio_utils" path="modules"/>
</MODULEPATHS>
</XCODE_MAC>
<VS2010 targetFolder="Builds/VisualStudio2010" vstFolder="modules/vstsdk3">
<CONFIGURATIONS>
<CONFIGURATION name="Release32" winWarningLevel="2" generateManifest="1" winArchitecture="32-bit"
isDebug="0" optimisation="3" targetName="Obxd" useRuntimeLibDLL="0"/>
<CONFIGURATION name="Release64" winWarningLevel="2" generateManifest="1" winArchitecture="x64"
optimisation="3" targetName="Obxd64" useRuntimeLibDLL="0"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_opengl" path="modules"/>
<MODULEPATH id="juce_gui_extra" path="modules"/>
<MODULEPATH id="juce_gui_basics" path="modules"/>
<MODULEPATH id="juce_graphics" path="modules"/>
<MODULEPATH id="juce_events" path="modules"/>
<MODULEPATH id="juce_data_structures" path="modules"/>
<MODULEPATH id="juce_core" path="modules"/>
<MODULEPATH id="juce_audio_utils" path="modules"/>
<MODULEPATH id="juce_audio_processors" path="modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="modules"/>
<MODULEPATH id="juce_audio_formats" path="modules"/>
<MODULEPATH id="juce_audio_devices" path="modules"/>
<MODULEPATH id="juce_audio_basics" path="modules"/>
</MODULEPATHS>
</VS2010>
<LINUX_MAKE targetFolder="Builds/LinuxMakefile" vstFolder="modules/vstsdk2.4">
<CONFIGURATIONS>
<CONFIGURATION name="Release64" libraryPath="/usr/X11R6/lib/" isDebug="0" optimisation="3"
targetName="Obxd64"/>
<CONFIGURATION name="Release32" libraryPath="/usr/X11R6/lib/" linuxArchitecture="-m32"
optimisation="3" targetName="Obxd"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_opengl" path="modules"/>
<MODULEPATH id="juce_gui_extra" path="modules"/>
<MODULEPATH id="juce_gui_basics" path="modules"/>
<MODULEPATH id="juce_graphics" path="modules"/>
<MODULEPATH id="juce_events" path="modules"/>
<MODULEPATH id="juce_data_structures" path="modules"/>
<MODULEPATH id="juce_core" path="modules"/>
<MODULEPATH id="juce_audio_utils" path="modules"/>
<MODULEPATH id="juce_audio_processors" path="modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="modules"/>
<MODULEPATH id="juce_audio_formats" path="modules"/>
<MODULEPATH id="juce_audio_devices" path="modules"/>
<MODULEPATH id="juce_audio_basics" path="modules"/>
</MODULEPATHS>
</LINUX_MAKE>
<VS2013 targetFolder="Builds/VisualStudio2013">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
isDebug="1" optimisation="3" targetName="Obxd"/>
<CONFIGURATION name="Release64" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
isDebug="0" optimisation="3" targetName="Obxd64" useRuntimeLibDLL="0"/>
<CONFIGURATION name="Release32" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
isDebug="0" optimisation="3" targetName="Obxd" useRuntimeLibDLL="0"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_opengl" path="modules"/>
<MODULEPATH id="juce_gui_extra" path="modules"/>
<MODULEPATH id="juce_gui_basics" path="modules"/>
<MODULEPATH id="juce_graphics" path="modules"/>
<MODULEPATH id="juce_events" path="modules"/>
<MODULEPATH id="juce_data_structures" path="modules"/>
<MODULEPATH id="juce_core" path="modules"/>
<MODULEPATH id="juce_audio_utils" path="modules"/>
<MODULEPATH id="juce_audio_processors" path="modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="modules"/>
<MODULEPATH id="juce_audio_formats" path="modules"/>
<MODULEPATH id="juce_audio_devices" path="modules"/>
<MODULEPATH id="juce_audio_basics" path="modules"/>
</MODULEPATHS>
</VS2013>
</EXPORTFORMATS>
<MODULES>
<MODULES id="juce_audio_basics" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_audio_devices" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_audio_formats" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_audio_plugin_client" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_audio_processors" showAllCode="1" useLocalCopy="1"/>
<MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_core" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_data_structures" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_events" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_graphics" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_gui_basics" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_gui_extra" showAllCode="1" useLocalCopy="1"/>
<MODULES id="juce_opengl" showAllCode="1" useLocalCopy="1"/>
</MODULES>
<JUCEOPTIONS JUCE_QUICKTIME="disabled"/>
</JUCERPROJECT>

@ -0,0 +1,45 @@
/*
==============================================================================
This file is part of Obxd synthesizer.
Copyright © 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
This file may be licensed under the terms of of the
GNU General Public License Version 2 (the ``GPL'').
Software distributed under the License is distributed
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
express or implied. See the GPL for the specific language
governing rights and limitations.
You should have received a copy of the GPL along with this
program. If not, go to http://www.gnu.org/licenses/gpl.html
or write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
==============================================================================
*/
#pragma once
#include "SynthEngine.h"
class ApInterpolator
{
private:
const float Nu;
float zd;
float li;
public :
ApInterpolator() : Nu(( 1 - 0.5) /(1 + 0.5))
{
zd = 0;
li=0;
};
inline float getInterp(float in)
{
float out = Nu * ( in - zd) + li;
zd = out;
li = in;
return out;
}
};

@ -0,0 +1,150 @@
/*
==============================================================================
This file is part of Obxd synthesizer.
Copyright © 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
This file may be licensed under the terms of of the
GNU General Public License Version 2 (the ``GPL'').
Software distributed under the License is distributed
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
express or implied. See the GPL for the specific language
governing rights and limitations.
You should have received a copy of the GPL along with this
program. If not, go to http://www.gnu.org/licenses/gpl.html
or write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
==============================================================================
*/
#pragma once
#include "ObxdVoice.h"
class AdsrEnvelope
{
private:
float Value;
float attack, decay, sustain, release;
float ua,ud,us,ur;
float coef;
int state;//1 - attack 2- decay 3 - sustain 4 - release 5-silence
float SampleRate;
float uf;
public:
AdsrEnvelope()
{
uf = 1;
Value = 0.0;
attack=decay=sustain=release=0.0001;
ua=ud=us=ur=0.0001;
coef = 0;
state = 5;
SampleRate = 44000;
}
void ResetEnvelopeState()
{
Value = 0.0;
state = 5;
}
void setSampleRate(float sr)
{
SampleRate = sr;
}
void setUniqueDeriviance(float der)
{
uf = der;
setAttack(ua);
setDecay(ud);
setSustain(us);
setRelease(ur);
}
void setAttack(float atk)
{
ua = atk;
attack = atk*uf;
if(state == 1)
coef = (float)((log(0.001) - log(1.3)) / (SampleRate * (atk) / 1000));
}
void setDecay(float dec)
{
ud = dec;
decay = dec*uf;
if(state == 2)
coef = (float)((log(jmin(sustain + 0.0001,0.99)) - log(1.0)) / (SampleRate * (dec) / 1000));
}
void setSustain(float sust)
{
us = sust;
sustain = sust;
if(state == 2)
coef = (float)((log(jmin(sustain + 0.0001,0.99)) - log(1.0)) / (SampleRate * (decay) / 1000));
}
void setRelease(float rel)
{
ur = rel;
release = rel*uf;
if(state == 4)
coef = (float)((log(0.00001) - log(Value + 0.0001)) / (SampleRate * (rel) / 1000));
}
void triggerAttack()
{
state = 1;
//Value = Value +0.00001f;
coef = (float)((log(0.001) - log(1.3)) / (SampleRate * (attack)/1000 ));
}
void triggerRelease()
{
if(state!=4)
coef = (float)((log(0.00001) - log(Value+0.0001)) / (SampleRate * (release) / 1000));
state = 4;
}
inline bool isActive()
{
return state!=5;
}
inline float processSample()
{
switch (state)
{
case 1:
if (Value - 1 > -0.1)
{
Value = jmin(Value, 0.99f);
state = 2;
coef = (float)((log(jmin(sustain + 0.0001, 0.99)) - log(1.0)) / (SampleRate * (decay) / 1000));
goto dec;
}
else
{
Value = Value - (1-Value)*(coef);
}
break;
case 2:
dec:
if (Value - sustain < 10e-6)
{
state = 3;
}
else
{
Value =Value + Value * coef;
}
break;
case 3: Value = jmin(sustain, 0.9f);
break;
case 4:
if (Value > 20e-6)
Value = Value + Value * coef + dc;
else state = 5;
break;
case 5:
Value = 0.0f;
break;
}
return Value;
}
};

@ -0,0 +1,90 @@
/*
==============================================================================
This file is part of Obxd synthesizer.
Copyright © 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
This file may be licensed under the terms of of the
GNU General Public License Version 2 (the ``GPL'').
Software distributed under the License is distributed
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
express or implied. See the GPL for the specific language
governing rights and limitations.
You should have received a copy of the GPL along with this
program. If not, go to http://www.gnu.org/licenses/gpl.html
or write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
==============================================================================
*/
#pragma once
#include "SynthEngine.h"
const float sq2_12 = 1.0594630943592953f;
const float dc = 1e-18;
const float ln2 = 0.69314718056f;
const float mult = ln2 / 12.0;
inline static float getPitch(float index)
{
//Lookup table is not that effective compared to SSE exp
//SSE should be on
//const int mulres = 2;
//const int lowerBound = -94;
//const int upperBound = 94;
//const int lutlen = (upperBound-lowerBound)*2;
return 440 * expf(mult * index);
//static const float lut [lutlen]={1.929,1.986,2.044,2.104,2.165,2.229,2.294,2.361,2.431,2.502,2.575,2.651,2.728,2.808,2.891,2.975,3.062,3.152,3.245,3.340,3.437,3.538,3.642,3.749,3.858,3.972,4.088,4.208,4.331,4.458,4.589,4.723,4.861,5.004,5.150,5.301,5.457,5.617,5.781,5.951,6.125,6.304,6.489,6.679,6.875,7.076,7.284,7.497,7.717,7.943,8.176,8.415,8.662,8.916,9.177,9.446,9.723,10.008,10.301,10.603,10.913,11.233,11.562,11.901,12.250,12.609,12.978,13.359,13.750,14.153,14.568,14.994,15.434,15.886,16.352,16.831,17.324,17.832,18.354,18.892,19.445,20.015,20.602,21.205,21.827,22.466,23.125,23.802,24.500,25.218,25.957,26.717,27.500,28.306,29.135,29.989,30.868,31.772,32.703,33.661,34.648,35.663,36.708,37.784,38.891,40.030,41.203,42.411,43.654,44.933,46.249,47.605,48.999,50.435,51.913,53.434,55.000,56.612,58.270,59.978,61.735,63.544,65.406,67.323,69.296,71.326,73.416,75.567,77.782,80.061,82.407,84.822,87.307,89.865,92.499,95.209,97.999,100.870,103.826,106.869,110.000,113.223,116.541,119.956,123.471,127.089,130.813,134.646,138.591,142.652,146.832,151.135,155.563,160.122,164.814,169.643,174.614,179.731,184.997,190.418,195.998,201.741,207.652,213.737,220.000,226.446,233.082,239.912,246.942,254.178,261.626,269.292,277.183,285.305,293.665,302.270,311.127,320.244,329.628,339.286,349.228,359.461,369.994,380.836,391.995,403.482,415.305,427.474,440.000,452.893,466.164,479.823,493.883,508.355,523.251,538.584,554.365,570.609,587.330,604.540,622.254,640.487,659.255,678.573,698.456,718.923,739.989,761.672,783.991,806.964,830.609,854.948,880.000,905.786,932.328,959.647,987.767,1016.710,1046.502,1077.167,1108.731,1141.219,1174.659,1209.079,1244.508,1280.975,1318.510,1357.146,1396.913,1437.846,1479.978,1523.344,1567.982,1613.927,1661.219,1709.896,1760.000,1811.572,1864.655,1919.294,1975.533,2033.421,2093.005,2154.334,2217.461,2282.438,2349.318,2418.158,2489.016,2561.950,2637.020,2714.291,2793.826,2875.691,2959.955,3046.689,3135.964,3227.854,3322.438,3419.792,3520.000,3623.144,3729.310,3838.587,3951.066,4066.842,4186.009,4308.668,4434.922,4564.875,4698.636,4836.317,4978.032,5123.899,5274.041,5428.582,5587.652,5751.382,5919.911,6093.377,6271.927,6455.709,6644.875,6839.585,7040.000,7246.288,7458.620,7677.174,7902.133,8133.683,8372.018,8617.337,8869.844,9129.751,9397.273,9672.634,9956.064,10247.798,10548.082,10857.164,11175.304,11502.765,11839.822,12186.755,12543.854,12911.417,13289.750,13679.170,14080.000,14492.576,14917.241,15354.349,15804.266,16267.366,16744.036,17234.674,17739.689,18259.501,18794.545,19345.268,19912.127,20495.597,21096.164,21714.329,22350.607,23005.530,23679.643,24373.510,25087.708,25822.834,26579.501,27358.340,28160.000,28985.151,29834.481,30708.698,31608.532,32534.732,33488.073,34469.348,35479.377,36519.002,37589.091,38690.535,39824.254,40991.194,42192.328,43428.657,44701.214,46011.060,47359.287,48747.020,50175.416,51645.668,53159.002,54716.680,56320.001,57970.303,59668.962,61417.396,63217.063,65069.465,66976.146,68938.697,70958.755,73038.005,75178.182,77381.071,79648.509,81982.388,84384.656,86857.315,89402.429,92022.120,94718.574,97494.040};
//if(index > 92.0)
// return lut[lutlen-1];
//if(index < -94.0)
// return lut[0];
//index = (index - lowerBound)*mulres;
//int mi = floor(index);
//float ofs = index-mi;
//
// return lut[mi] + (lut[mi+1] - lut[mi]) * ofs;
};
inline static float tptlpupw(float & state , float inp , float cutoff , float srInv)
{
cutoff = (cutoff * srInv)*juce::float_Pi;
double v = (inp - state) * cutoff / (1 + cutoff);
double res = v + state;
state = res + v;
return res;
}
inline static float tptlp(float& state,float inp,float cutoff,float srInv)
{
cutoff = tan(cutoff * (srInv)* (juce::float_Pi)) ;
double v = (inp - state) * cutoff / (1 + cutoff);
double res = v + state;
state = res + v;
return res;
};
inline static float tptpc(float& state,float inp,float cutoff)
{
double v = (inp - state) * cutoff / (1 + cutoff);
double res = v + state;
state = res + v;
return res;
}
inline static float linsc(float param,const float min,const float max)
{
return (param) * (max - min) + min;
}
inline static float logsc(float param, const float min,const float max,const float rolloff = 19.0f)
{
return ((expf(param * logf(rolloff+1)) - 1.0f) / (rolloff)) * (max-min) + min;
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,86 @@
#pragma once
//MusicDsp
// T.Rochebois
//still indev
class Decimator17
{
private:
const float h0,h1,h3,h5,h7,h9,h11,h13,h15,h17;
float R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15,R16,R17;
public:
Decimator17()
: h0(0.5)
, h1(0.314356238)
, h3(-0.0947515890)
, h5(0.0463142134)
, h7(-0.0240881704)
, h9(0.0120250406)
, h11(-0.00543170841)
, h13(0.00207426259)
, h15(-0.000572688237)
, h17(5.18944944e-005)
{
R1=R2=R3=R4=R5=R6=R7=R8=R9=R10=R11=R12=R13=R14=R15=R16=R17=0;
}
float Calc(const float x0,const float x1)
{
float h17x0 = h17 *x0;
float h15x0 = h15 *x0;
float h13x0 = h13 *x0;
float h11x0= h11 *x0;
float h9x0=h9*x0;
float h7x0=h7*x0;
float h5x0=h5*x0;
float h3x0=h3*x0;
float h1x0=h1*x0;
float R18=R17+h17x0;
R17 = R16 + h15x0;
R16 = R15 + h13x0;
R15 = R14 + h11x0;
R14 = R13 + h9x0;
R13 = R12 + h7x0;
R12 = R11 + h5x0;
R11 = R10 + h3x0;
R10 = R9 + h1x0;
R9 = R8 + h1x0 + h0*x1;
R8 = R7 + h3x0;
R7 = R6 + h5x0;
R6 = R5 + h7x0;
R5 = R4 + h9x0;
R4 = R3 + h11x0;
R3 = R2 + h13x0;
R2 = R1 + h15x0;
R1 = h17x0;
return R18;
}
};
class Decimator9
{
private:
const float h0,h1,h3,h5,h7,h9;
float R1,R2,R3,R4,R5,R6,R7,R8,R9;
public:
Decimator9() : h0(8192/16384.0f),h1(5042/16384.0f),h3(-1277/16384.0f),h5(429/16384.0f),h7(-116/16384.0f),h9(18/16384.0f)
{
R1=R2=R3=R4=R5=R6=R7=R8=R9=0.0f;
}
inline float Calc(const float x0,const float x1)
{
float h9x0=h9*x0;
float h7x0=h7*x0;
float h5x0=h5*x0;
float h3x0=h3*x0;
float h1x0=h1*x0;
float R10=R9+h9x0;
R9=R8+h7x0;
R8=R7+h5x0;
R7=R6+h3x0;
R6=R5+h1x0;
R5=R4+h1x0+h0*x1;
R4=R3+h3x0;
R3=R2+h5x0;
R2=R1+h7x0;
R1=h9x0;
return R10;
}
};

@ -0,0 +1,71 @@
/*
==============================================================================
This file is part of Obxd synthesizer.
Copyright © 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
This file may be licensed under the terms of of the
GNU General Public License Version 2 (the ``GPL'').
Software distributed under the License is distributed
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
express or implied. See the GPL for the specific language
governing rights and limitations.
You should have received a copy of the GPL along with this
program. If not, go to http://www.gnu.org/licenses/gpl.html
or write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
==============================================================================
*/
#pragma once
#include "SynthEngine.h"
//Always feed first then get delayed sample!
#define DEMAX 64
template<unsigned int DM> class DelayLine
{
private:
float dl[DEMAX];
int iidx;
public:
DelayLine()
{
iidx = 0;
zeromem(dl,sizeof(float)*DEMAX);
//jassert(DM > DMAX);
}
inline float feedReturn(float sm)
{
dl[iidx] = sm;
iidx--;
iidx=(iidx&(DEMAX-1));
return dl[(iidx + DM)&(DEMAX-1)];
}
inline void fillZeroes()
{
zeromem(dl,DEMAX*sizeof(float));
}
};
template<unsigned int DM> class DelayLineBoolean
{
private:
bool dl[DEMAX];
int iidx;
public:
DelayLineBoolean()
{
iidx = 0;
zeromem(dl,sizeof(bool)*DEMAX);
}
inline float feedReturn(bool sm)
{
dl[iidx] = sm;
iidx--;
iidx=(iidx&(DEMAX-1));
return dl[(iidx + DM)&(DEMAX-1)];
}
};

@ -0,0 +1,185 @@
/*
==============================================================================
This file is part of Obxd synthesizer.
Copyright © 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
This file may be licensed under the terms of of the
GNU General Public License Version 2 (the ``GPL'').
Software distributed under the License is distributed
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
express or implied. See the GPL for the specific language
governing rights and limitations.
You should have received a copy of the GPL along with this
program. If not, go to http://www.gnu.org/licenses/gpl.html
or write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
==============================================================================
*/
#pragma once
#include "ObxdVoice.h"
#include <math.h>
class Filter
{
private:
float s1,s2,s3,s4;
float R;
float R24;
float rcor,rcorInv;
float rcor24,rcor24Inv;
//24 db multimode
float mmt;
int mmch;
public:
float SampleRate;
float sampleRateInv;
bool bandPassSw;
float mm;
bool selfOscPush;
Filter()
{
selfOscPush = false;
bandPassSw = false;
mm=0;
s1=s2=s3=s4=0;
SampleRate = 44000;
sampleRateInv = 1 / SampleRate;
rcor =500.0 / 44000;
rcorInv = 1 / rcor;
rcor24 = 970.0 / 44000;
rcor24Inv = 1 / rcor24;
R=1;
R24=0;
}
void setMultimode(float m)
{
mm = m;
mmch = (int)(mm * 3);
mmt = mm*3-mmch;
}
inline void setSampleRate(float sr)
{
SampleRate = sr;
sampleRateInv = 1/SampleRate;
float rcrate =sqrt((44000/SampleRate));
rcor = (500.0 / 44000)*rcrate;
rcor24 = (970.0 / 44000)*rcrate;
rcorInv = 1 / rcor;
rcor24Inv = 1 / rcor24;
}
inline void setResonance(float res)
{
R = 1-res;
R24 =( 3.5 * res);
}
inline float diodePairResistanceApprox(float x)
{
return (((((0.0103592f)*x + 0.00920833f)*x + 0.185f)*x + 0.05f )*x + 1.0f);
//Taylor approx of slightly mismatched diode pair
}
//resolve 0-delay feedback
inline float NR(float sample, float g)
{
//calculating feedback non-linear transconducance and compensated for R (-1)
//Boosting non-linearity
float tCfb;
if(!selfOscPush)
tCfb = diodePairResistanceApprox(s1*0.0876f) - 1.0f;
else
tCfb = diodePairResistanceApprox(s1*0.0876f) - 1.035f;
//float tCfb = 0;
//disable non-linearity == digital filter
//resolve linear feedback
float y = ((sample - 2*(s1*(R+tCfb)) - g*s1 - s2)/(1+ g*(2*(R+tCfb)+ g)));
//float y = ((sample - 2*(s1*(R+tCfb)) - g2*s1 - s2)/(1+ g1*(2*(R+tCfb)+ g2)));
return y;
}
inline float Apply(float sample,float g)
{
float gpw = tanf(g *sampleRateInv * juce::float_Pi);
g = gpw;
//float v = ((sample- R * s1*2 - g2*s1 - s2)/(1+ R*g1*2 + g1*g2));
float v = NR(sample,g);
float y1 = v*g + s1;
s1 = v*g + y1;
float y2 = y1*g + s2;
s2 = y1*g + y2;
float mc;
if(!bandPassSw)
mc = (1-mm)*y2 + (mm)*v;
else
{
mc =2 * ( mm < 0.5 ?
((0.5 - mm) * y2 + (mm) * y1):
((1-mm) * y1 + (mm-0.5) * v)
);
}
return mc;
}
inline float NR24(float sample,float g,float lpc)
{
float ml = 1 / (1+g);
float S = (lpc*(lpc*(lpc*s1 + s2) + s3) +s4)*ml;
float G = lpc*lpc*lpc*lpc;
float y = (sample - R24 * S) / (1 + R24*G);
return y;
}
inline float Apply4Pole(float sample,float g)
{
float g1 = (float)tan(g *sampleRateInv * juce::float_Pi);
g = g1;
float lpc = g / (1 + g);
float y0 = NR24(sample,g,lpc);
//first low pass in cascade
double v = (y0 - s1) * lpc;
double res = v + s1;
s1 = res + v;
//damping
s1 =atan(s1*rcor24)*rcor24Inv;
float y1= res;
float y2 = tptpc(s2,y1,g);
float y3 = tptpc(s3,y2,g);
float y4 = tptpc(s4,y3,g);
float mc;
switch(mmch)
{
case 0:
mc = ((1 - mmt) * y4 + (mmt) * y3);
break;
case 1:
mc = ((1 - mmt) * y3 + (mmt) * y2);
break;
case 2:
mc = ((1 - mmt) * y2 + (mmt) * y1);
break;
case 3:
mc = y1;
break;
default:
mc=0;
break;
}
//half volume comp
return mc * (1 + R24 * 0.45);
}
};

@ -0,0 +1,159 @@
/*
==============================================================================
This file is part of Obxd synthesizer.
Copyright © 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
This file may be licensed under the terms of of the
GNU General Public License Version 2 (the ``GPL'').
Software distributed under the License is distributed
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
express or implied. See the GPL for the specific language
governing rights and limitations.
You should have received a copy of the GPL along with this
program. If not, go to http://www.gnu.org/licenses/gpl.html
or write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
==============================================================================
*/
#pragma once
#include "SynthEngine.h"
class Lfo
{
private:
float phase;
float s, sq, sh;
float s1;
Random rg;
float SampleRate;
float SampleRateInv;
float syncRate;
bool synced;
public:
float Frequency;
float phaseInc;
float frUnsc;//frequency value without sync
float rawParam;
int waveForm;
Lfo()
{
phaseInc = 0;
frUnsc=0;
syncRate = 1;
rawParam=0;
synced = false;
s1=0;
Frequency=1;
phase=0;
s=sq=sh=0;
rg=Random();
}
void setSynced()
{
synced = true;
recalcRate(rawParam);
}
void setUnsynced()
{
synced = false;
phaseInc = frUnsc;
}
void hostSyncRetrigger(float bpm,float quaters)
{
if(synced)
{
phaseInc = (bpm/60.0)*syncRate;
phase = phaseInc*quaters;
phase = (fmod(phase,1)*float_Pi*2-float_Pi);
}
}
inline float getVal()
{
float Res = 0;
if((waveForm &1) !=0 )
Res+=s;
if((waveForm&2)!=0)
Res+=sq;
if((waveForm&4)!=0)
Res+=sh;
return tptlpupw(s1, Res,3000,SampleRateInv);
}
void setSamlpeRate(float sr)
{
SampleRate=sr;
SampleRateInv = 1 / SampleRate;
}
inline void update()
{
phase+=((phaseInc * float_Pi*2 * SampleRateInv));
sq = (phase>0?1:-1);
s = sin(phase);
if(phase > float_Pi)
{
phase-=2*float_Pi;
sh = rg.nextFloat()*2-1;
}
}
void setFrequency(float val)
{
frUnsc = val;
if(!synced)
phaseInc = val;
}
void setRawParam(float param)//used for synced rate changes
{
rawParam = param;
if(synced)
{
recalcRate(param);
}
}
void recalcRate(float param)
{
const int ratesCount = 9;
int parval = (int)(param*(ratesCount-1));
float rt = 1;
switch(parval)
{
case 0:
rt = 1.0 / 8;
break;
case 1:
rt = 1.0 / 4;
break;
case 2:
rt = 1.0 / 3;
break;
case 3:
rt = 1.0 / 2;
break;
case 4:
rt = 1.0;
break;
case 5:
rt = 3.0 / 2;
break;
case 6:
rt = 2;
break;
case 7:
rt = 3;
break;
case 8:
rt = 4;
break;
default:
rt = 1;
break;
}
syncRate = rt;
}
};

@ -0,0 +1,380 @@
/*
==============================================================================
This file is part of Obxd synthesizer.
Copyright <EFBFBD> 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
This file may be licensed under the terms of of the
GNU General Public License Version 2 (the ``GPL'').
Software distributed under the License is distributed
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
express or implied. See the GPL for the specific language
governing rights and limitations.
You should have received a copy of the GPL along with this
program. If not, go to http://www.gnu.org/licenses/gpl.html
or write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
==============================================================================
*/
#pragma once
#include <climits>
#include "VoiceQueue.h"
#include "SynthEngine.h"
#include "Lfo.h"
class Motherboard
{
private:
VoiceQueue vq;
int totalvc;
bool wasUni;
bool awaitingkeys[129];
int priorities[129];
Decimator17 left,right;
int asPlayedCounter;
float lkl,lkr;
float sampleRate,sampleRateInv;
//JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Motherboard)
public:
bool asPlayedMode;
Lfo mlfo,vibratoLfo;
float vibratoAmount;
bool vibratoEnabled;
float Volume;
const static int MAX_VOICES=8;
float pannings[MAX_VOICES];
ObxdVoice voices[MAX_VOICES];
bool uni;
bool Oversample;
bool economyMode;
Motherboard(): left(),right()
{
economyMode = true;
lkl=lkr=0;
vibratoEnabled = true;
asPlayedMode = false;
asPlayedCounter = 0;
for(int i = 0 ; i < 129 ; i++)
{
awaitingkeys[i] = false;
priorities[i] = 0;
}
vibratoAmount = 0;
Oversample=false;
mlfo= Lfo();
vibratoLfo=Lfo();
vibratoLfo.waveForm = 1;
uni = false;
wasUni = false;
Volume=0;
// voices = new ObxdVoice* [MAX_VOICES];
// pannings = new float[MAX_VOICES];
totalvc = MAX_VOICES;
vq = VoiceQueue(MAX_VOICES,voices);
for(int i = 0 ; i < MAX_VOICES;++i)
{
pannings[i]= 0.5;
}
}
~Motherboard()
{
//delete pannings;
//for(int i = 0 ; i < MAX_VOICES;++i)
//{
// delete voices[i];
//}
//delete voices;
}
void setVoiceCount(int count)
{
for(int i = count ; i < MAX_VOICES;i++)
{
voices[i].NoteOff();
voices[i].ResetEnvelope();
}
vq.reInit(count);
totalvc = count;
}
void unisonOn()
{
//for(int i = 0 ; i < 110;i++)
// awaitingkeys[i] = false;
}
void setSampleRate(float sr)
{
sampleRate = sr;
sampleRateInv = 1 / sampleRate;
mlfo.setSamlpeRate(sr);
vibratoLfo.setSamlpeRate(sr);
for(int i = 0 ; i < MAX_VOICES;++i)
{
voices[i].setSampleRate(sr);
}
SetOversample(Oversample);
}
void sustainOn()
{
for(int i = 0 ; i < MAX_VOICES;i++)
{
ObxdVoice* p = vq.getNext();
p->sustOn();
}
}
void sustainOff()
{
for(int i = 0 ; i < MAX_VOICES;i++)
{
ObxdVoice* p = vq.getNext();
p->sustOff();
}
}
void setNoteOn(int noteNo,float velocity)
{
asPlayedCounter++;
priorities[noteNo] = asPlayedCounter;
bool processed=false;
if (wasUni != uni)
unisonOn();
if (uni)
{
if(!asPlayedMode)
{
int minmidi = 129;
for(int i = 0 ; i < totalvc; i++)
{
ObxdVoice* p = vq.getNext();
if(p->midiIndx < minmidi && p->Active)
{
minmidi = p->midiIndx;
}
}
if(minmidi < noteNo)
{
awaitingkeys[noteNo] = true;
}
else
{
for(int i = 0 ; i < totalvc;i++)
{
ObxdVoice* p = vq.getNext();
if(p->midiIndx > noteNo && p->Active)
{
awaitingkeys[p->midiIndx] = true;
p->NoteOn(noteNo,-0.5);
}
else
{
p->NoteOn(noteNo,velocity);
}
}
}
processed = true;
}
else
{
for(int i = 0 ; i < totalvc; i++)
{
ObxdVoice* p = vq.getNext();
if(p->Active)
{
awaitingkeys[p->midiIndx] = true;
p->NoteOn(noteNo,-0.5);
}
else
{
p->NoteOn(noteNo,velocity);
}
}
processed = true;
}
}
else
{
for (int i = 0; i < totalvc && !processed; i++)
{
ObxdVoice* p = vq.getNext();
if (!p->Active)
{
p->NoteOn(noteNo,velocity);
processed = true;
}
}
}
// if voice steal occured
if(!processed)
{
//
if(!asPlayedMode)
{
int maxmidi = 0;
ObxdVoice* highestVoiceAvalible = NULL;
for(int i = 0 ; i < totalvc; i++)
{
ObxdVoice* p = vq.getNext();
if(p->midiIndx > maxmidi)
{
maxmidi = p->midiIndx;
highestVoiceAvalible = p;
}
}
if(maxmidi < noteNo)
{
awaitingkeys[noteNo] = true;
}
else
{
highestVoiceAvalible->NoteOn(noteNo,-0.5);
awaitingkeys[maxmidi] = true;
}
}
else
{
int minPriority = INT_MAX;
ObxdVoice* minPriorityVoice = NULL;
for(int i = 0 ; i < totalvc; i++)
{
ObxdVoice* p = vq.getNext();
if(priorities[p->midiIndx] <minPriority)
{
minPriority = priorities[p->midiIndx];
minPriorityVoice = p;
}
}
awaitingkeys[minPriorityVoice->midiIndx] = true;
minPriorityVoice->NoteOn(noteNo,-0.5);
}
}
wasUni = uni;
}
void setNoteOff(int noteNo)
{
awaitingkeys[noteNo] = false;
int reallocKey = 0;
//Voice release case
if(!asPlayedMode)
{
while(reallocKey < 129 &&(!awaitingkeys[reallocKey]))
{
reallocKey++;
}
}
else
{
reallocKey = 129;
int maxPriority = INT_MIN;
for(int i = 0 ; i < 129;i++)
{
if(awaitingkeys[i] && (maxPriority < priorities[i]))
{
reallocKey = i;
maxPriority = priorities[i];
}
}
}
if(reallocKey !=129)
{
for(int i = 0 ; i < totalvc; i++)
{
ObxdVoice* p = vq.getNext();
if((p->midiIndx == noteNo) && (p->Active))
{
p->NoteOn(reallocKey,-0.5);
awaitingkeys[reallocKey] = false;
}
}
}
else
//No realloc
{
for (int i = 0; i < totalvc; i++)
{
ObxdVoice* n = vq.getNext();
if (n->midiIndx==noteNo && n->Active)
{
n->NoteOff();
}
}
}
}
void SetOversample(bool over)
{
if(over==true)
{
mlfo.setSamlpeRate(sampleRate*2);
vibratoLfo.setSamlpeRate(sampleRate*2);
}
else
{
mlfo.setSamlpeRate(sampleRate);
vibratoLfo.setSamlpeRate(sampleRate);
}
for(int i = 0 ; i < MAX_VOICES;i++)
{
voices[i].setHQ(over);
if(over)
voices[i].setSampleRate(sampleRate*2);
else
voices[i].setSampleRate(sampleRate);
}
Oversample = over;
}
inline float processSynthVoice(ObxdVoice& b,float lfoIn,float vibIn )
{
if(economyMode)
b.checkAdsrState();
if(b.shouldProcessed||(!economyMode))
{
b.lfoIn=lfoIn;
b.lfoVibratoIn=vibIn;
return b.ProcessSample();
}
return 0;
}
void processSample(float* sm1,float* sm2)
{
mlfo.update();
vibratoLfo.update();
float vl=0,vr=0;
float vlo = 0 , vro = 0 ;
float lfovalue = mlfo.getVal();
float viblfo = vibratoEnabled?(vibratoLfo.getVal() * vibratoAmount):0;
float lfovalue2=0,viblfo2;
if(Oversample)
{
mlfo.update();
vibratoLfo.update();
lfovalue2 = mlfo.getVal();
viblfo2 = vibratoEnabled?(vibratoLfo.getVal() * vibratoAmount):0;
}
for(int i = 0 ; i < totalvc;i++)
{
float x1 = processSynthVoice(voices[i],lfovalue,viblfo);
if(Oversample)
{
float x2 = processSynthVoice(voices[i],lfovalue2,viblfo2);
vlo+=x2*(1-pannings[i]);
vro+=x2*(pannings[i]);
}
vl+=x1*(1-pannings[i]);
vr+=x1*(pannings[i]);
}
if(Oversample)
{
vl = left.Calc(vl,vlo);
vr = right.Calc(vr,vro);
}
*sm1 = vl*Volume;
*sm2 = vr*Volume;
}
};

@ -0,0 +1,39 @@
/*
==============================================================================
This file is part of Obxd synthesizer.
Copyright © 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
This file may be licensed under the terms of of the
GNU General Public License Version 2 (the ``GPL'').
Software distributed under the License is distributed
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
express or implied. See the GPL for the specific language
governing rights and limitations.
You should have received a copy of the GPL along with this
program. If not, go to http://www.gnu.org/licenses/gpl.html
or write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
==============================================================================
*/
#pragma once
#include "ObxdVoice.h"
#include "ParamsEnum.h"
const int PROGRAMCOUNT = 128;
class ObxdBank
{
public:
ObxdParams programs[PROGRAMCOUNT];
ObxdParams* currentProgramPtr;
int currentProgram;
ObxdBank()
{
currentProgram=0;
currentProgramPtr = programs+currentProgram;
}
};

@ -0,0 +1,253 @@
/*
==============================================================================
This file is part of Obxd synthesizer.
Copyright <EFBFBD> 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
This file may be licensed under the terms of of the
GNU General Public License Version 2 (the ``GPL'').
Software distributed under the License is distributed
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
express or implied. See the GPL for the specific language
governing rights and limitations.
You should have received a copy of the GPL along with this
program. If not, go to http://www.gnu.org/licenses/gpl.html
or write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
==============================================================================
*/
#pragma once
#include "ObxdVoice.h"
#include "SynthEngine.h"
#include "AudioUtils.h"
#include "BlepData.h"
#include "DelayLine.h"
#include "SawOsc.h"
#include "PulseOsc.h"
#include "TriangleOsc.h"
class ObxdOscillatorB
{
private:
float SampleRate;
float pitch1;
float pitch2;
float sampleRateInv;
float x1,x2;
float osc1Factor;
float osc2Factor;
float pw1w,pw2w;
//blep const
const int n;
const int hsam;
//delay line implements fixed sample delay
DelayLine<Samples> del1,del2;
DelayLine<Samples> xmodd;
DelayLineBoolean<Samples> syncd;
DelayLine<Samples> syncFracd;
DelayLine<Samples> cvd;
Random wn;
SawOsc o1s,o2s;
PulseOsc o1p,o2p;
TriangleOsc o1t,o2t;
public:
float tune;//+-1
int oct;
float dirt;
float notePlaying;
float totalDetune;
float osc2Det;
float pulseWidth;
float pw1,pw2;
bool quantizeCw;
float o1mx,o2mx;
float nmx;
float pto1,pto2;