diff --git a/examples/Assets/DSPDemos_Common.h b/examples/Assets/DSPDemos_Common.h index 4c5d67548b..589d597be9 100644 --- a/examples/Assets/DSPDemos_Common.h +++ b/examples/Assets/DSPDemos_Common.h @@ -312,8 +312,8 @@ struct DSPDemo : public AudioSource, inputSource->getNextAudioBlock (bufferToFill); - dsp::AudioBlock block (*bufferToFill.buffer, - (size_t) bufferToFill.startSample); + AudioBlock block (*bufferToFill.buffer, + (size_t) bufferToFill.startSample); ScopedLock audioLock (audioCallbackLock); this->process (ProcessContextReplacing (block)); diff --git a/examples/Assets/Impulse1.wav b/examples/Assets/Impulse1.wav deleted file mode 100644 index 98d402cd04..0000000000 Binary files a/examples/Assets/Impulse1.wav and /dev/null differ diff --git a/examples/Assets/Impulse2.wav b/examples/Assets/Impulse2.wav deleted file mode 100644 index c548b22cdd..0000000000 Binary files a/examples/Assets/Impulse2.wav and /dev/null differ diff --git a/examples/Assets/reverb_ir.wav b/examples/Assets/reverb_ir.wav new file mode 100644 index 0000000000..281884b4a9 Binary files /dev/null and b/examples/Assets/reverb_ir.wav differ diff --git a/examples/DSP/StateVariableFilterDemo.h b/examples/DSP/StateVariableFilterDemo.h index aa6158b44d..db40e3048a 100644 --- a/examples/DSP/StateVariableFilterDemo.h +++ b/examples/DSP/StateVariableFilterDemo.h @@ -59,8 +59,6 @@ struct StateVariableFilterDemoDSP void prepare (const ProcessSpec& spec) { sampleRate = spec.sampleRate; - - filter.state = new StateVariableFilter::Parameters; filter.prepare (spec); } @@ -78,18 +76,21 @@ struct StateVariableFilterDemoDSP { if (sampleRate != 0.0) { - auto cutoff = static_cast (cutoffParam.getCurrentValue()); - auto resonance = static_cast (qParam.getCurrentValue()); - auto type = static_cast::Type> (typeParam.getCurrentSelectedID() - 1); - - filter.state->type = type; - filter.state->setCutOffFrequency (sampleRate, cutoff, resonance); + filter.setCutoffFrequency (static_cast (cutoffParam.getCurrentValue())); + filter.setResonance (static_cast (qParam.getCurrentValue())); + + switch (typeParam.getCurrentSelectedID() - 1) + { + case 0: filter.setType (StateVariableTPTFilterType::lowpass); break; + case 1: filter.setType (StateVariableTPTFilterType::bandpass); break; + case 2: filter.setType (StateVariableTPTFilterType::highpass); break; + default: jassertfalse; break; + }; } } //============================================================================== - ProcessorDuplicator, - StateVariableFilter::Parameters> filter; + StateVariableTPTFilter filter; ChoiceParameter typeParam {{ "Low-pass", "Band-pass", "High-pass" }, 1, "Type" }; SliderParameter cutoffParam {{ 20.0, 20000.0 }, 0.5, 440.0f, "Cutoff", "Hz" }; diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index 71331edca7..7a30259853 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -117,16 +117,17 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" "../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" + "../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" + "../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.mm" "../../../../../modules/juce_audio_basics/juce_audio_basics.h" @@ -1078,27 +1079,51 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_dsp/native/juce_neon_SIMDNativeOps.h" "../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp" "../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.h" - "../../../../../modules/juce_dsp/processors/juce_Bias.h" + "../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.h" + "../../../../../modules/juce_dsp/processors/juce_DelayLine.cpp" + "../../../../../modules/juce_dsp/processors/juce_DelayLine.h" + "../../../../../modules/juce_dsp/processors/juce_DryWetMixer.cpp" + "../../../../../modules/juce_dsp/processors/juce_DryWetMixer.h" "../../../../../modules/juce_dsp/processors/juce_FIRFilter.cpp" "../../../../../modules/juce_dsp/processors/juce_FIRFilter.h" "../../../../../modules/juce_dsp/processors/juce_FIRFilter_test.cpp" - "../../../../../modules/juce_dsp/processors/juce_Gain.h" + "../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h" "../../../../../modules/juce_dsp/processors/juce_IIRFilter.cpp" "../../../../../modules/juce_dsp/processors/juce_IIRFilter.h" "../../../../../modules/juce_dsp/processors/juce_IIRFilter_Impl.h" - "../../../../../modules/juce_dsp/processors/juce_LadderFilter.cpp" - "../../../../../modules/juce_dsp/processors/juce_LadderFilter.h" - "../../../../../modules/juce_dsp/processors/juce_Oscillator.h" + "../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h" "../../../../../modules/juce_dsp/processors/juce_Oversampling.cpp" "../../../../../modules/juce_dsp/processors/juce_Oversampling.h" + "../../../../../modules/juce_dsp/processors/juce_Panner.cpp" + "../../../../../modules/juce_dsp/processors/juce_Panner.h" "../../../../../modules/juce_dsp/processors/juce_ProcessContext.h" "../../../../../modules/juce_dsp/processors/juce_ProcessorChain.h" "../../../../../modules/juce_dsp/processors/juce_ProcessorChain_test.cpp" "../../../../../modules/juce_dsp/processors/juce_ProcessorDuplicator.h" "../../../../../modules/juce_dsp/processors/juce_ProcessorWrapper.h" - "../../../../../modules/juce_dsp/processors/juce_Reverb.h" "../../../../../modules/juce_dsp/processors/juce_StateVariableFilter.h" - "../../../../../modules/juce_dsp/processors/juce_WaveShaper.h" + "../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.h" + "../../../../../modules/juce_dsp/widgets/juce_Bias.h" + "../../../../../modules/juce_dsp/widgets/juce_Chorus.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Chorus.h" + "../../../../../modules/juce_dsp/widgets/juce_Compressor.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Compressor.h" + "../../../../../modules/juce_dsp/widgets/juce_Gain.h" + "../../../../../modules/juce_dsp/widgets/juce_LadderFilter.cpp" + "../../../../../modules/juce_dsp/widgets/juce_LadderFilter.h" + "../../../../../modules/juce_dsp/widgets/juce_Limiter.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Limiter.h" + "../../../../../modules/juce_dsp/widgets/juce_NoiseGate.cpp" + "../../../../../modules/juce_dsp/widgets/juce_NoiseGate.h" + "../../../../../modules/juce_dsp/widgets/juce_Oscillator.h" + "../../../../../modules/juce_dsp/widgets/juce_Phaser.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Phaser.h" + "../../../../../modules/juce_dsp/widgets/juce_Reverb.h" + "../../../../../modules/juce_dsp/widgets/juce_WaveShaper.h" "../../../../../modules/juce_dsp/juce_dsp.cpp" "../../../../../modules/juce_dsp/juce_dsp.mm" "../../../../../modules/juce_dsp/juce_dsp.h" @@ -1841,16 +1866,17 @@ set_source_files_properties("../../../../../modules/juce_audio_basics/sources/ju set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2802,27 +2828,51 @@ set_source_files_properties("../../../../../modules/juce_dsp/native/juce_neon_SI set_source_files_properties("../../../../../modules/juce_dsp/native/juce_neon_SIMDNativeOps.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Bias.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DelayLine.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DelayLine.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DryWetMixer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DryWetMixer.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Gain.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter_Impl.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LadderFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LadderFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oscillator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oversampling.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oversampling.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Panner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Panner.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessContext.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorChain.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorChain_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorDuplicator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorWrapper.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_WaveShaper.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Bias.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Chorus.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Chorus.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Compressor.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Compressor.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Gain.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_LadderFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_LadderFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Limiter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Limiter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_NoiseGate.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_NoiseGate.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Oscillator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Phaser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Phaser.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_WaveShaper.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse1.wav b/examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse1.wav deleted file mode 100644 index 98d402cd04..0000000000 Binary files a/examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse1.wav and /dev/null differ diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse2.wav b/examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse2.wav deleted file mode 100644 index c548b22cdd..0000000000 Binary files a/examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse2.wav and /dev/null differ diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/reverb_ir.wav b/examples/DemoRunner/Builds/Android/app/src/main/assets/reverb_ir.wav new file mode 100644 index 0000000000..281884b4a9 Binary files /dev/null and b/examples/DemoRunner/Builds/Android/app/src/main/assets/reverb_ir.wav differ diff --git a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj index 34b9341edc..0b86ac9981 100644 --- a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj @@ -242,10 +242,10 @@ true - + true - + true @@ -254,6 +254,9 @@ true + + true + true @@ -1427,24 +1430,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + true + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -2453,10 +2492,10 @@ - + - + @@ -2983,21 +3022,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + diff --git a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters index 9867f02d9b..1ec8388045 100644 --- a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters @@ -374,6 +374,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -676,10 +679,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -688,6 +691,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -1915,24 +1921,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -3141,16 +3183,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -4731,13 +4773,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4746,13 +4794,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4767,15 +4815,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj index b758445937..55dc65aab8 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj @@ -242,10 +242,10 @@ true - + true - + true @@ -254,6 +254,9 @@ true + + true + true @@ -1427,24 +1430,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + true + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -2453,10 +2492,10 @@ - + - + @@ -2983,21 +3022,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters index b63a5a9e35..cbab95c68b 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters @@ -374,6 +374,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -676,10 +679,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -688,6 +691,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -1915,24 +1921,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -3141,16 +3183,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -4731,13 +4773,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4746,13 +4794,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4767,15 +4815,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index da5e8887eb..2039a25a0d 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -242,10 +242,10 @@ true - + true - + true @@ -254,6 +254,9 @@ true + + true + true @@ -1427,24 +1430,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + true + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -2453,10 +2492,10 @@ - + - + @@ -2983,21 +3022,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index 6eb8769081..b9f848a1eb 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -374,6 +374,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -676,10 +679,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -688,6 +691,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -1915,24 +1921,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -3141,16 +3183,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -4731,13 +4773,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4746,13 +4794,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4767,15 +4815,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp diff --git a/examples/Plugins/DSPModulePluginDemo.h b/examples/Plugins/DSPModulePluginDemo.h index f1ea735558..51fc046248 100644 --- a/examples/Plugins/DSPModulePluginDemo.h +++ b/examples/Plugins/DSPModulePluginDemo.h @@ -27,7 +27,7 @@ version: 1.0.0 vendor: JUCE website: http://juce.com - description: Audio plugin using the DSP module. + description: An audio plugin using the DSP module. dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, juce_audio_plugin_client, juce_audio_processors, @@ -50,516 +50,1835 @@ #include "../Assets/DemoUtilities.h" +namespace ID +{ + #define PARAMETER_ID(str) constexpr const char* str { #str }; + + PARAMETER_ID (inputGain) + PARAMETER_ID (outputGain) + PARAMETER_ID (pan) + PARAMETER_ID (distortionEnabled) + PARAMETER_ID (distortionType) + PARAMETER_ID (distortionOversampler) + PARAMETER_ID (distortionLowpass) + PARAMETER_ID (distortionHighpass) + PARAMETER_ID (distortionInGain) + PARAMETER_ID (distortionCompGain) + PARAMETER_ID (distortionMix) + PARAMETER_ID (multiBandEnabled) + PARAMETER_ID (multiBandFreq) + PARAMETER_ID (multiBandLowVolume) + PARAMETER_ID (multiBandHighVolume) + PARAMETER_ID (compressorEnabled) + PARAMETER_ID (compressorThreshold) + PARAMETER_ID (compressorRatio) + PARAMETER_ID (compressorAttack) + PARAMETER_ID (compressorRelease) + PARAMETER_ID (noiseGateEnabled) + PARAMETER_ID (noiseGateThreshold) + PARAMETER_ID (noiseGateRatio) + PARAMETER_ID (noiseGateAttack) + PARAMETER_ID (noiseGateRelease) + PARAMETER_ID (limiterEnabled) + PARAMETER_ID (limiterThreshold) + PARAMETER_ID (limiterRelease) + PARAMETER_ID (directDelayEnabled) + PARAMETER_ID (directDelayType) + PARAMETER_ID (directDelayValue) + PARAMETER_ID (directDelaySmoothing) + PARAMETER_ID (directDelayMix) + PARAMETER_ID (delayEffectEnabled) + PARAMETER_ID (delayEffectType) + PARAMETER_ID (delayEffectValue) + PARAMETER_ID (delayEffectSmoothing) + PARAMETER_ID (delayEffectLowpass) + PARAMETER_ID (delayEffectFeedback) + PARAMETER_ID (delayEffectMix) + PARAMETER_ID (phaserEnabled) + PARAMETER_ID (phaserRate) + PARAMETER_ID (phaserDepth) + PARAMETER_ID (phaserCentreFrequency) + PARAMETER_ID (phaserFeedback) + PARAMETER_ID (phaserMix) + PARAMETER_ID (chorusEnabled) + PARAMETER_ID (chorusRate) + PARAMETER_ID (chorusDepth) + PARAMETER_ID (chorusCentreDelay) + PARAMETER_ID (chorusFeedback) + PARAMETER_ID (chorusMix) + PARAMETER_ID (ladderEnabled) + PARAMETER_ID (ladderCutoff) + PARAMETER_ID (ladderResonance) + PARAMETER_ID (ladderDrive) + PARAMETER_ID (ladderMode) + + #undef PARAMETER_ID +} + +template +constexpr void forEach (Func&& func, Items&&... items) + noexcept (noexcept (std::initializer_list { (func (std::forward (items)), 0)... })) +{ + (void) std::initializer_list { ((void) func (std::forward (items)), 0)... }; +} + +template +void addAllAndMakeVisible (Component& target, Components&... children) +{ + forEach ([&] (Component& child) { target.addAndMakeVisible (child); }, children...); +} + +template +void prepareAll (const dsp::ProcessSpec& spec, Processors&... processors) +{ + forEach ([&] (auto& proc) { proc.prepare (spec); }, processors...); +} + +template +void resetAll (Processors&... processors) +{ + forEach ([] (auto& proc) { proc.reset(); }, processors...); +} + //============================================================================== -struct ParameterSlider : public Slider, - public Timer +class DspModulePluginDemo : public AudioProcessor, + private ValueTree::Listener { - ParameterSlider (AudioProcessorParameter& p) - : Slider (p.getName (256)), param (p) +public: + DspModulePluginDemo() { - setRange (0.0, 1.0, 0.0); - startTimerHz (30); - updateSliderPos(); + apvts.state.addListener (this); + + forEach ([] (dsp::Gain& gain) { gain.setRampDurationSeconds (0.05); }, + dsp::get (chain), + dsp::get (chain)); + + dsp::get (chain).setRule (dsp::PannerRule::linear); } - void valueChanged() override + //============================================================================== + void prepareToPlay (double sampleRate, int samplesPerBlock) override { - if (isMouseButtonDown()) - param.setValueNotifyingHost ((float) Slider::getValue()); - else - param.setValue ((float) Slider::getValue()); - } + if (jmin (getTotalNumInputChannels(), getTotalNumOutputChannels()) == 0) + return; - void timerCallback() override { updateSliderPos(); } + chain.prepare ({ sampleRate, (uint32) samplesPerBlock, (uint32) getTotalNumOutputChannels() }); - void startedDragging() override { param.beginChangeGesture(); } - void stoppedDragging() override { param.endChangeGesture(); } + reset(); + } - double getValueFromText (const String& text) override { return param.getValueForText (text); } - String getTextFromValue (double value) override { return param.getText ((float) value, 1024) + " " + param.getLabel(); } + void reset() override + { + chain.reset(); + update(); + } - void updateSliderPos() + void releaseResources() override {} + + void processBlock (AudioBuffer& buffer, MidiBuffer&) override { - auto newValue = param.getValue(); + if (jmin (getTotalNumInputChannels(), getTotalNumOutputChannels()) == 0) + return; + + ScopedNoDenormals noDenormals; + + if (requiresUpdate.load()) + update(); + + const auto totalNumInputChannels = getTotalNumInputChannels(); + const auto totalNumOutputChannels = getTotalNumOutputChannels(); - if (newValue != (float) Slider::getValue() && ! isMouseButtonDown()) - Slider::setValue (newValue); + const auto numChannels = jmax (totalNumInputChannels, totalNumOutputChannels); + + auto inoutBlock = dsp::AudioBlock (buffer).getSubsetChannelBlock (0, (size_t) numChannels); + chain.process (dsp::ProcessContextReplacing (inoutBlock)); } - AudioProcessorParameter& param; -}; + void processBlock (AudioBuffer&, MidiBuffer&) override {} -//============================================================================== -/** - This class handles the audio processing for the DSP module plugin demo. -*/ -class DspModulePluginDemoAudioProcessor : public AudioProcessor -{ -public: //============================================================================== - DspModulePluginDemoAudioProcessor() - : AudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::stereo(), true) - .withOutput ("Output", AudioChannelSet::stereo(), true)), - lowPassFilter (dsp::IIR::Coefficients::makeFirstOrderLowPass (48000.0, 20000.0f)), - highPassFilter (dsp::IIR::Coefficients::makeFirstOrderHighPass (48000.0, 20.0f)), - waveShapers { { std::tanh }, { dsp::FastMathApproximations::tanh } }, - clipping { clip } - { - // Oversampling 2 times with IIR filtering - oversampling.reset (new dsp::Oversampling (2, 1, dsp::Oversampling::filterHalfBandPolyphaseIIR, false)); + AudioProcessorEditor* createEditor() override { return nullptr; } + bool hasEditor() const override { return false; } - addParameter (inputVolumeParam = new AudioParameterFloat ("INPUT", "Input Volume", { 0.0f, 60.0f, 0.0f, 1.0f }, 0.0f, "dB")); - addParameter (highPassFilterFreqParam = new AudioParameterFloat ("HPFREQ", "Pre Highpass Freq.", { 20.0f, 20000.0f, 0.0f, 0.5f }, 20.0f, "Hz")); - addParameter (lowPassFilterFreqParam = new AudioParameterFloat ("LPFREQ", "Post Lowpass Freq.", { 20.0f, 20000.0f, 0.0f, 0.5f }, 20000.0f, "Hz")); + //============================================================================== + const String getName() const override { return "DSPModulePluginDemo"; } - addParameter (stereoParam = new AudioParameterChoice ("STEREO", "Stereo Processing", { "Always mono", "Yes" }, 1)); - addParameter (slopeParam = new AudioParameterChoice ("SLOPE", "Slope", { "-6 dB / octave", "-12 dB / octave" }, 0)); - addParameter (waveshaperParam = new AudioParameterChoice ("WVSHP", "Waveshaper", { "std::tanh", "Fast tanh approx." }, 0)); + bool acceptsMidi() const override { return false; } + bool producesMidi() const override { return false; } + bool isMidiEffect() const override { return false; } - addParameter (cabinetTypeParam = new AudioParameterChoice ("CABTYPE", "Cabinet Type", { "Guitar amplifier 8'' cabinet ", - "Cassette recorder cabinet" }, 0)); + double getTailLengthSeconds() const override { return 0.0; } + + //============================================================================== + int getNumPrograms() override { return 1; } + int getCurrentProgram() override { return 0; } + void setCurrentProgram (int) override {} + const String getProgramName (int) override { return {}; } - addParameter (cabinetSimParam = new AudioParameterBool ("CABSIM", "Cabinet Sim", false)); - addParameter (oversamplingParam = new AudioParameterBool ("OVERS", "Oversampling", false)); + void changeProgramName (int, const String&) override {} - addParameter (outputVolumeParam = new AudioParameterFloat ("OUTPUT", "Output Volume", { -40.0f, 40.0f, 0.0f, 1.0f }, 0.0f, "dB")); + //============================================================================== + void getStateInformation (MemoryBlock& destData) override + { + copyXmlToBinary (*apvts.copyState().createXml(), destData); + } - cabinetType.set (0); + void setStateInformation (const void* data, int sizeInBytes) override + { + apvts.replaceState (ValueTree::fromXml (*getXmlFromBinary (data, sizeInBytes))); } //============================================================================== - bool isBusesLayoutSupported (const BusesLayout& layouts) const override - { - // This is the place where you check if the layout is supported. - // In this template code we only support mono or stereo. - if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono() && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo()) - return false; + AudioProcessorValueTreeState apvts { *this, nullptr, "state", createParameters() }; - // This checks if the input layout matches the output layout - if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet()) - return false; + // We store this here so that the editor retains its state if it is closed and reopened + int indexTab = 0; - return true; +private: + //============================================================================== + void valueTreePropertyChanged (ValueTree&, const Identifier&) override + { + requiresUpdate.store (true); } - void prepareToPlay (double sampleRate, int samplesPerBlock) override + // This struct holds references to the raw parameter values, so that we don't have to look up + // the parameters (involving string comparisons and map lookups!) every time a parameter + // changes. + struct ParameterValues { - auto channels = static_cast (jmin (getMainBusNumInputChannels(), getMainBusNumOutputChannels())); - dsp::ProcessSpec spec { sampleRate, static_cast (samplesPerBlock), channels }; + explicit ParameterValues (AudioProcessorValueTreeState& state) + : inputGain (*state.getRawParameterValue (ID::inputGain)), + outputGain (*state.getRawParameterValue (ID::outputGain)), + pan (*state.getRawParameterValue (ID::pan)), + distortionEnabled (*state.getRawParameterValue (ID::distortionEnabled)), + distortionType (*state.getRawParameterValue (ID::distortionType)), + distortionOversampler (*state.getRawParameterValue (ID::distortionOversampler)), + distortionLowpass (*state.getRawParameterValue (ID::distortionLowpass)), + distortionHighpass (*state.getRawParameterValue (ID::distortionHighpass)), + distortionInGain (*state.getRawParameterValue (ID::distortionInGain)), + distortionCompGain (*state.getRawParameterValue (ID::distortionCompGain)), + distortionMix (*state.getRawParameterValue (ID::distortionMix)), + multiBandEnabled (*state.getRawParameterValue (ID::multiBandEnabled)), + multiBandFreq (*state.getRawParameterValue (ID::multiBandFreq)), + multiBandLowVolume (*state.getRawParameterValue (ID::multiBandLowVolume)), + multiBandHighVolume (*state.getRawParameterValue (ID::multiBandHighVolume)), + compressorEnabled (*state.getRawParameterValue (ID::compressorEnabled)), + compressorThreshold (*state.getRawParameterValue (ID::compressorThreshold)), + compressorRatio (*state.getRawParameterValue (ID::compressorRatio)), + compressorAttack (*state.getRawParameterValue (ID::compressorAttack)), + compressorRelease (*state.getRawParameterValue (ID::compressorRelease)), + noiseGateEnabled (*state.getRawParameterValue (ID::noiseGateEnabled)), + noiseGateThreshold (*state.getRawParameterValue (ID::noiseGateThreshold)), + noiseGateRatio (*state.getRawParameterValue (ID::noiseGateRatio)), + noiseGateAttack (*state.getRawParameterValue (ID::noiseGateAttack)), + noiseGateRelease (*state.getRawParameterValue (ID::noiseGateRelease)), + limiterEnabled (*state.getRawParameterValue (ID::limiterEnabled)), + limiterThreshold (*state.getRawParameterValue (ID::limiterThreshold)), + limiterRelease (*state.getRawParameterValue (ID::limiterRelease)), + directDelayEnabled (*state.getRawParameterValue (ID::directDelayEnabled)), + directDelayType (*state.getRawParameterValue (ID::directDelayType)), + directDelayValue (*state.getRawParameterValue (ID::directDelayValue)), + directDelaySmoothing (*state.getRawParameterValue (ID::directDelaySmoothing)), + directDelayMix (*state.getRawParameterValue (ID::directDelayMix)), + delayEffectEnabled (*state.getRawParameterValue (ID::delayEffectEnabled)), + delayEffectType (*state.getRawParameterValue (ID::delayEffectType)), + delayEffectValue (*state.getRawParameterValue (ID::delayEffectValue)), + delayEffectSmoothing (*state.getRawParameterValue (ID::delayEffectSmoothing)), + delayEffectLowpass (*state.getRawParameterValue (ID::delayEffectLowpass)), + delayEffectFeedback (*state.getRawParameterValue (ID::delayEffectFeedback)), + delayEffectMix (*state.getRawParameterValue (ID::delayEffectMix)), + phaserEnabled (*state.getRawParameterValue (ID::phaserEnabled)), + phaserRate (*state.getRawParameterValue (ID::phaserRate)), + phaserDepth (*state.getRawParameterValue (ID::phaserDepth)), + phaserCentreFrequency (*state.getRawParameterValue (ID::phaserCentreFrequency)), + phaserFeedback (*state.getRawParameterValue (ID::phaserFeedback)), + phaserMix (*state.getRawParameterValue (ID::phaserMix)), + chorusEnabled (*state.getRawParameterValue (ID::chorusEnabled)), + chorusRate (*state.getRawParameterValue (ID::chorusRate)), + chorusDepth (*state.getRawParameterValue (ID::chorusDepth)), + chorusCentreDelay (*state.getRawParameterValue (ID::chorusCentreDelay)), + chorusFeedback (*state.getRawParameterValue (ID::chorusFeedback)), + chorusMix (*state.getRawParameterValue (ID::chorusMix)), + ladderEnabled (*state.getRawParameterValue (ID::ladderEnabled)), + ladderCutoff (*state.getRawParameterValue (ID::ladderCutoff)), + ladderResonance (*state.getRawParameterValue (ID::ladderResonance)), + ladderDrive (*state.getRawParameterValue (ID::ladderDrive)), + ladderMode (*state.getRawParameterValue (ID::ladderMode)) + {} + + std::atomic& inputGain; + std::atomic& outputGain; + std::atomic& pan; + + std::atomic& distortionEnabled; + std::atomic& distortionType; + std::atomic& distortionOversampler; + std::atomic& distortionLowpass; + std::atomic& distortionHighpass; + std::atomic& distortionInGain; + std::atomic& distortionCompGain; + std::atomic& distortionMix; + + std::atomic& multiBandEnabled; + std::atomic& multiBandFreq; + std::atomic& multiBandLowVolume; + std::atomic& multiBandHighVolume; + + std::atomic& compressorEnabled; + std::atomic& compressorThreshold; + std::atomic& compressorRatio; + std::atomic& compressorAttack; + std::atomic& compressorRelease; + + std::atomic& noiseGateEnabled; + std::atomic& noiseGateThreshold; + std::atomic& noiseGateRatio; + std::atomic& noiseGateAttack; + std::atomic& noiseGateRelease; + + std::atomic& limiterEnabled; + std::atomic& limiterThreshold; + std::atomic& limiterRelease; + + std::atomic& directDelayEnabled; + std::atomic& directDelayType; + std::atomic& directDelayValue; + std::atomic& directDelaySmoothing; + std::atomic& directDelayMix; + + std::atomic& delayEffectEnabled; + std::atomic& delayEffectType; + std::atomic& delayEffectValue; + std::atomic& delayEffectSmoothing; + std::atomic& delayEffectLowpass; + std::atomic& delayEffectFeedback; + std::atomic& delayEffectMix; + + std::atomic& phaserEnabled; + std::atomic& phaserRate; + std::atomic& phaserDepth; + std::atomic& phaserCentreFrequency; + std::atomic& phaserFeedback; + std::atomic& phaserMix; + + std::atomic& chorusEnabled; + std::atomic& chorusRate; + std::atomic& chorusDepth; + std::atomic& chorusCentreDelay; + std::atomic& chorusFeedback; + std::atomic& chorusMix; + + std::atomic& ladderEnabled; + std::atomic& ladderCutoff; + std::atomic& ladderResonance; + std::atomic& ladderDrive; + std::atomic& ladderMode; + }; - lowPassFilter .prepare (spec); - highPassFilter.prepare (spec); + ParameterValues parameters { apvts }; - inputVolume .prepare (spec); - outputVolume.prepare (spec); + //============================================================================== + void update() + { + { + DistortionProcessor& distortion = dsp::get (chain); - convolution.prepare (spec); - cabinetType.set (-1); + if (distortion.currentIndexOversampling != parameters.distortionOversampler.load()) + { + distortion.currentIndexOversampling = roundToInt (parameters.distortionOversampler.load()); + prepareToPlay (getSampleRate(), getBlockSize()); + return; + } - oversampling->initProcessing (static_cast (samplesPerBlock)); + distortion.currentIndexWaveshaper = roundToInt (parameters.distortionType.load()); + distortion.lowpass .setCutoffFrequency (parameters.distortionLowpass); + distortion.highpass.setCutoffFrequency (parameters.distortionHighpass); + distortion.distGain.setGainDecibels (parameters.distortionInGain); + distortion.compGain.setGainDecibels (parameters.distortionCompGain); + distortion.mixer.setWetMixProportion (parameters.distortionMix / 100.0f); + dsp::setBypassed (chain, parameters.distortionEnabled.load() == 0.0f); + } - updateParameters(); - reset(); - } + dsp::get (chain).setGainDecibels (parameters.inputGain); + dsp::get (chain).setGainDecibels (parameters.outputGain); + dsp::get (chain).setPan (parameters.pan / 100.0f); - void releaseResources() override {} + { + MultiBandProcessor& multiband = dsp::get (chain); + const auto multibandFreq = parameters.multiBandFreq.load(); + multiband.lowpass .setCutoffFrequency (multibandFreq); + multiband.highpass.setCutoffFrequency (multibandFreq); + const auto enabled = parameters.multiBandEnabled.load() != 0.0f; + multiband.lowVolume .setGainDecibels (enabled ? parameters.multiBandLowVolume .load() : 0.0f); + multiband.highVolume.setGainDecibels (enabled ? parameters.multiBandHighVolume.load() : 0.0f); + dsp::setBypassed (chain, ! enabled); + } - void processBlock (AudioBuffer& inoutBuffer, MidiBuffer&) override - { - auto totalNumInputChannels = getTotalNumInputChannels(); - auto totalNumOutputChannels = getTotalNumOutputChannels(); + { + dsp::Compressor& compressor = dsp::get (chain); + compressor.setThreshold (parameters.compressorThreshold); + compressor.setRatio (parameters.compressorRatio); + compressor.setAttack (parameters.compressorAttack); + compressor.setRelease (parameters.compressorRelease); + dsp::setBypassed (chain, parameters.compressorEnabled.load() == 0.0f); + } - auto numSamples = inoutBuffer.getNumSamples(); + { + dsp::NoiseGate& noiseGate = dsp::get (chain); + noiseGate.setThreshold (parameters.noiseGateThreshold); + noiseGate.setRatio (parameters.noiseGateRatio); + noiseGate.setAttack (parameters.noiseGateAttack); + noiseGate.setRelease (parameters.noiseGateRelease); + dsp::setBypassed (chain, parameters.noiseGateEnabled.load() == 0.0f); + } - for (auto i = jmin (2, totalNumInputChannels); i < totalNumOutputChannels; ++i) - inoutBuffer.clear (i, 0, numSamples); + { + dsp::Limiter& limiter = dsp::get (chain); + limiter.setThreshold (parameters.limiterThreshold); + limiter.setRelease (parameters.limiterRelease); + dsp::setBypassed (chain, parameters.limiterEnabled.load() == 0.0f); + } + + { + DirectDelayProcessor& delay = dsp::get (chain); + delay.delayLineDirectType = roundToInt (parameters.directDelayType.load()); + + std::fill (delay.delayDirectValue.begin(), + delay.delayDirectValue.end(), + (double) parameters.directDelayValue); + + delay.smoothFilter.setCutoffFrequency (1000.0 / parameters.directDelaySmoothing); + delay.mixer.setWetMixProportion (parameters.directDelayMix / 100.0f); + dsp::setBypassed (chain, parameters.directDelayEnabled.load() == 0.0f); + } + + { + DelayEffectProcessor& delay = dsp::get (chain); + delay.delayEffectType = roundToInt (parameters.delayEffectType.load()); + + std::fill (delay.delayEffectValue.begin(), + delay.delayEffectValue.end(), + (double) parameters.delayEffectValue / 1000.0 * getSampleRate()); - updateParameters(); + const auto feedbackGain = Decibels::decibelsToGain (parameters.delayEffectFeedback.load(), -100.0f); - dsp::AudioBlock block (inoutBuffer); + for (auto& volume : delay.delayFeedbackVolume) + volume.setTargetValue (feedbackGain); + + delay.smoothFilter.setCutoffFrequency (1000.0 / parameters.delayEffectSmoothing); + delay.lowpass.setCutoffFrequency (parameters.delayEffectLowpass); + delay.mixer.setWetMixProportion (parameters.delayEffectMix / 100.0f); + dsp::setBypassed (chain, parameters.delayEffectEnabled.load() == 0.0f); + } - if (stereoParam->getIndex() == 1) { - // Stereo processing mode: - if (block.getNumChannels() > 2) - block = block.getSubsetChannelBlock (0, 2); + dsp::Phaser& phaser = dsp::get (chain); + phaser.setRate (parameters.phaserRate); + phaser.setDepth (parameters.phaserDepth / 100.0f); + phaser.setCentreFrequency (parameters.phaserCentreFrequency); + phaser.setFeedback (parameters.phaserFeedback / 100.0f * 0.95f); + phaser.setMix (parameters.phaserMix / 100.0f); + dsp::setBypassed (chain, parameters.phaserEnabled.load() == 0.0f); + } - process (dsp::ProcessContextReplacing (block)); + { + dsp::Chorus& chorus = dsp::get (chain); + chorus.setRate (parameters.chorusRate); + chorus.setDepth (parameters.chorusDepth / 100.0f); + chorus.setCentreDelay (parameters.chorusCentreDelay); + chorus.setFeedback (parameters.chorusFeedback / 100.0f * 0.95f); + chorus.setMix (parameters.chorusMix / 100.0f); + dsp::setBypassed (chain, parameters.chorusEnabled.load() == 0.0f); } - else + { - // Mono processing mode: - auto firstChan = block.getSingleChannelBlock (0); + dsp::LadderFilter& ladder = dsp::get (chain); - process (dsp::ProcessContextReplacing (firstChan)); + ladder.setCutoffFrequencyHz (parameters.ladderCutoff); + ladder.setResonance (parameters.ladderResonance / 100.0f); + ladder.setDrive (Decibels::decibelsToGain (parameters.ladderDrive.load())); - for (size_t chan = 1; chan < block.getNumChannels(); ++chan) - block.getSingleChannelBlock (chan).copyFrom (firstChan); + ladder.setMode ([&] + { + switch (roundToInt (parameters.ladderMode.load())) + { + case 0: return dsp::LadderFilterMode::LPF12; + case 1: return dsp::LadderFilterMode::LPF24; + case 2: return dsp::LadderFilterMode::HPF12; + case 3: return dsp::LadderFilterMode::HPF24; + case 4: return dsp::LadderFilterMode::BPF12; + } + + return dsp::LadderFilterMode::BPF24; + }()); + + dsp::setBypassed (chain, parameters.ladderEnabled.load() == 0.0f); } - } - using AudioProcessor::processBlock; + requiresUpdate.store (false); + } - void reset() override + //============================================================================== + static String getPanningTextForValue (float value) { - lowPassFilter .reset(); - highPassFilter.reset(); - convolution .reset(); - oversampling->reset(); + if (value == 0.5f) + return "center"; + + if (value < 0.5f) + return String (roundToInt ((0.5f - value) * 200.0f)) + "%L"; + + return String (roundToInt ((value - 0.5f) * 200.0f)) + "%R"; } - //============================================================================== - bool hasEditor() const override { return true; } + static float getPanningValueForText (String strText) + { + if (strText.compareIgnoreCase ("center") == 0 || strText.compareIgnoreCase ("c") == 0) + return 0.5f; - AudioProcessorEditor* createEditor() override + strText = strText.trim(); + + if (strText.indexOfIgnoreCase ("%L") != -1) + { + auto percentage = (float) strText.substring (0, strText.indexOf ("%")).getDoubleValue(); + return (100.0f - percentage) / 100.0f * 0.5f; + } + + if (strText.indexOfIgnoreCase ("%R") != -1) + { + auto percentage = (float) strText.substring (0, strText.indexOf ("%")).getDoubleValue(); + return percentage / 100.0f * 0.5f + 0.5f; + } + + return 0.5f; + } + + static AudioProcessorValueTreeState::ParameterLayout createParameters() { - return new DspModulePluginDemoAudioProcessorEditor (*this); + using Parameter = AudioProcessorValueTreeState::Parameter; + + auto valueToTextFunction = [] (float x) { return String (x, 2); }; + auto textToValueFunction = [] (const String& str) { return str.getFloatValue(); }; + + auto valueToTextPanFunction = [] (float x) { return getPanningTextForValue ((x + 100.0f) / 200.0f); }; + auto textToValuePanFunction = [] (const String& str) { return getPanningValueForText (str) * 200.0f - 100.0f; }; + + AudioProcessorValueTreeState::ParameterLayout layout; + + layout.add (std::make_unique (ID::inputGain, + "Input", + "dB", + NormalisableRange (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::outputGain, + "Output", + "dB", + NormalisableRange (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::pan, + "Panning", + "", + NormalisableRange (-100.0f, 100.0f), + 0.0f, + valueToTextPanFunction, + textToValuePanFunction)); + + layout.add (std::make_unique (ID::distortionEnabled, "Distortion", true, "")); + + layout.add (std::make_unique (ID::distortionType, + "Waveshaper", + StringArray { "std::tanh", "Approx. tanh" }, + 0)); + + layout.add (std::make_unique (ID::distortionInGain, + "Gain", + "dB", + NormalisableRange (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::distortionLowpass, + "Post Low-pass", + "Hz", + NormalisableRange (20.0f, 22000.0f, 0.0f, 0.25f), + 22000.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::distortionHighpass, + "Pre High-pass", + "Hz", + NormalisableRange (20.0f, 22000.0f, 0.0f, 0.25f), + 20.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::distortionCompGain, + "Compensat.", + "dB", + NormalisableRange (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::distortionMix, + "Mix", + "%", + NormalisableRange (0.0f, 100.0f), + 100.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::distortionOversampler, + "Oversampling", + StringArray { "2X", + "4X", + "8X", + "2X compensated", + "4X compensated", + "8X compensated" }, + 1)); + + layout.add (std::make_unique (ID::multiBandEnabled, "Multi-band", false, "")); + + layout.add (std::make_unique (ID::multiBandFreq, + "Sep. Freq.", + "Hz", + NormalisableRange (20.0f, 22000.0f, 0.0f, 0.25f), + 2000.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::multiBandLowVolume, + "Low volume", + "dB", + NormalisableRange (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::multiBandHighVolume, + "High volume", + "dB", + NormalisableRange (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::compressorEnabled, "Comp.", false, "")); + + layout.add (std::make_unique (ID::compressorThreshold, + "Threshold", + "dB", + NormalisableRange (-100.0f, 0.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::compressorRatio, + "Ratio", + ":1", + NormalisableRange (1.0f, 100.0f, 0.0f, 0.25f), + 1.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::compressorAttack, + "Attack", + "ms", + NormalisableRange (0.01f, 1000.0f, 0.0f, 0.25f), + 1.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::compressorRelease, + "Release", + "ms", + NormalisableRange (10.0f, 10000.0f, 0.0f, 0.25f), + 100.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::noiseGateEnabled, "Gate", false, "")); + + layout.add (std::make_unique (ID::noiseGateThreshold, + "Threshold", + "dB", + NormalisableRange (-100.0f, 0.0f), + -100.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::noiseGateRatio, + "Ratio", + ":1", + NormalisableRange (1.0f, 100.0f, 0.0f, 0.25f), + 10.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::noiseGateAttack, + "Attack", + "ms", + NormalisableRange (0.01f, 1000.0f, 0.0f, 0.25f), + 1.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::noiseGateRelease, + "Release", + "ms", + NormalisableRange (10.0f, 10000.0f, 0.0f, 0.25f), + 100.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::limiterEnabled, "Limiter", false, "")); + + layout.add (std::make_unique (ID::limiterThreshold, + "Threshold", + "dB", + NormalisableRange (-40.0f, 0.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::limiterRelease, + "Release", + "ms", + NormalisableRange (10.0f, 10000.0f, 0.0f, 0.25f), + 100.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::directDelayEnabled, "DL Dir.", false, "")); + + layout.add (std::make_unique (ID::directDelayType, + "DL Type", + StringArray { "None", + "Linear", + "Lagrange", + "Thiran" }, + 1)); + + layout.add (std::make_unique (ID::directDelayValue, + "Delay", + "smps", + NormalisableRange (0.0f, 44100.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::directDelaySmoothing, + "Smooth", + "ms", + NormalisableRange (20.0f, 10000.0f, 0.0f, 0.25f), + 200.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::directDelayMix, + "Delay Mix", + "%", + NormalisableRange (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::delayEffectEnabled, "DL Effect", false, "")); + + layout.add (std::make_unique (ID::delayEffectType, + "DL Type", + StringArray { "None", + "Linear", + "Lagrange", + "Thiran" }, + 1)); + + layout.add (std::make_unique (ID::delayEffectValue, + "Delay", + "ms", + NormalisableRange (0.01f, 1000.0f), + 100.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::delayEffectSmoothing, + "Smooth", + "ms", + NormalisableRange (20.0f, 10000.0f, 0.0f, 0.25f), + 400.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::delayEffectLowpass, + "Low-pass", + "Hz", + NormalisableRange (20.0f, 22000.0f, 0.0f, 0.25f), + 22000.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::delayEffectMix, + "Delay Mix", + "%", + NormalisableRange (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::delayEffectFeedback, + "Feedback", + "dB", + NormalisableRange (-100.0f, 0.0f), + -100.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::phaserEnabled, "Phaser", false, "")); + + layout.add (std::make_unique (ID::phaserRate, + "Rate", + "Hz", + NormalisableRange (0.05f, 20.0f, 0.0f, 0.25f), + 1.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::phaserDepth, + "Depth", + "%", + NormalisableRange (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::phaserCentreFrequency, + "Center", + "Hz", + NormalisableRange (20.0f, 20000.0f, 0.0f, 0.25f), + 600.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::phaserFeedback, + "Feedback", + "%", + NormalisableRange (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::phaserMix, + "Mix", + "%", + NormalisableRange (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::chorusEnabled, "Chorus", false, "")); + + layout.add (std::make_unique (ID::chorusRate, + "Rate", + "Hz", + NormalisableRange (0.05f, 20.0f, 0.0f, 0.25f), + 1.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::chorusDepth, + "Depth", + "%", + NormalisableRange (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::chorusCentreDelay, + "Center", + "ms", + NormalisableRange (1.0f, 100.0f, 0.0f, 0.25f), + 7.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::chorusFeedback, + "Feedback", + "%", + NormalisableRange (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::chorusMix, + "Mix", + "%", + NormalisableRange (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::ladderEnabled, "Ladder", false, "")); + + layout.add (std::make_unique (ID::ladderMode, + "Mode", + StringArray { "LP12", + "LP24", + "HP12", + "HP24", + "BP12", + "BP24" }, + 1)); + + layout.add (std::make_unique (ID::ladderCutoff, + "Frequency", + "Hz", + NormalisableRange (10.0f, 22000.0f, 0.0f, 0.25f), + 1000.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::ladderResonance, + "Resonance", + "%", + NormalisableRange (0.0f, 100.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + layout.add (std::make_unique (ID::ladderDrive, + "Drive", + "dB", + NormalisableRange (0.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction)); + + return layout; } //============================================================================== - bool acceptsMidi() const override { return false; } - bool producesMidi() const override { return false; } - const String getName() const override { return "DSPModulePluginDemo"; } - double getTailLengthSeconds() const override { return 0.0; } + struct DistortionProcessor + { + DistortionProcessor() + { + forEach ([] (dsp::Gain& gain) { gain.setRampDurationSeconds (0.05); }, + distGain, + compGain); - //============================================================================== - int getNumPrograms() override { return 1; } - int getCurrentProgram() override { return 0; } - void setCurrentProgram (int) override {} - const String getProgramName (int) override { return {}; } - void changeProgramName (int, const String&) override {} + lowpass.setType (dsp::FirstOrderTPTFilterType::lowpass); + highpass.setType (dsp::FirstOrderTPTFilterType::highpass); + mixer.setMixingRule (dsp::DryWetMixingRule::linear); + } - //============================================================================== - void getStateInformation (MemoryBlock&) override {} - void setStateInformation (const void*, int) override {} + void prepare (const dsp::ProcessSpec& spec) + { + for (auto& oversampler : oversamplers) + oversampler.initProcessing (spec.maximumBlockSize); - //============================================================================== - void updateParameters() + prepareAll (spec, lowpass, highpass, distGain, compGain, mixer); + } + + void reset() + { + for (auto& oversampler : oversamplers) + oversampler.reset(); + + resetAll (lowpass, highpass, distGain, compGain, mixer); + } + + float getLatency() const + { + return oversamplers[size_t (currentIndexOversampling)].getLatencyInSamples(); + } + + template + void process (Context& context) + { + if (context.isBypassed) + return; + + const auto& inputBlock = context.getInputBlock(); + + mixer.setWetLatency (getLatency()); + mixer.pushDrySamples (inputBlock); + + distGain.process (context); + highpass.process (context); + + auto ovBlock = oversamplers[size_t (currentIndexOversampling)].processSamplesUp (inputBlock); + + dsp::ProcessContextReplacing waveshaperContext (ovBlock); + + if (isPositiveAndBelow (currentIndexWaveshaper, waveShapers.size())) + { + waveShapers[size_t (currentIndexWaveshaper)].process (waveshaperContext); + + if (currentIndexWaveshaper == 1) + clipping.process (waveshaperContext); + + waveshaperContext.getOutputBlock() *= 0.7f; + } + + auto& outputBlock = context.getOutputBlock(); + oversamplers[size_t (currentIndexOversampling)].processSamplesDown (outputBlock); + + lowpass.process (context); + compGain.process (context); + mixer.mixWetSamples (outputBlock); + } + + std::array, 6> oversamplers + { { + { 2, 1, dsp::Oversampling::filterHalfBandPolyphaseIIR, true, false }, + { 2, 2, dsp::Oversampling::filterHalfBandPolyphaseIIR, true, false }, + { 2, 3, dsp::Oversampling::filterHalfBandPolyphaseIIR, true, false }, + + { 2, 1, dsp::Oversampling::filterHalfBandPolyphaseIIR, true, true }, + { 2, 2, dsp::Oversampling::filterHalfBandPolyphaseIIR, true, true }, + { 2, 3, dsp::Oversampling::filterHalfBandPolyphaseIIR, true, true }, + } }; + + dsp::FirstOrderTPTFilter lowpass, highpass; + dsp::Gain distGain, compGain; + dsp::DryWetMixer mixer { 10 }; + std::array, 2> waveShapers { { { std::tanh }, + { dsp::FastMathApproximations::tanh } } }; + dsp::WaveShaper clipping; + int currentIndexOversampling = 0; + int currentIndexWaveshaper = 0; + }; + + struct MultiBandProcessor { - auto newOversampling = oversamplingParam->get(); - if (newOversampling != audioCurrentlyOversampled) + MultiBandProcessor() + { + forEach ([] (dsp::Gain& gain) { gain.setRampDurationSeconds (0.05); }, + lowVolume, + highVolume); + + lowpass .setType (dsp::LinkwitzRileyFilterType::lowpass); + highpass.setType (dsp::LinkwitzRileyFilterType::highpass); + } + + void prepare (const dsp::ProcessSpec& spec) { - audioCurrentlyOversampled = newOversampling; - oversampling->reset(); + prepareAll (spec, lowpass, highpass, lowVolume, highVolume); + bufferSeparation.setSize (4, int (spec.maximumBlockSize), false, false, true); } - //============================================================================== - auto inputdB = Decibels::decibelsToGain (inputVolumeParam->get()); - auto outputdB = Decibels::decibelsToGain (outputVolumeParam->get()); + void reset() + { + resetAll (lowpass, highpass, lowVolume, highVolume); + } + + template + void process (Context& context) + { + const auto& inputBlock = context.getInputBlock(); + + const auto numSamples = inputBlock.getNumSamples(); + const auto numChannels = inputBlock.getNumChannels(); + + auto sepBlock = dsp::AudioBlock (bufferSeparation).getSubBlock (0, (size_t) numSamples); + + auto sepLowBlock = sepBlock.getSubsetChannelBlock (0, (size_t) numChannels); + auto sepHighBlock = sepBlock.getSubsetChannelBlock (2, (size_t) numChannels); + + sepLowBlock .copyFrom (inputBlock); + sepHighBlock.copyFrom (inputBlock); + + auto contextLow = dsp::ProcessContextReplacing (sepLowBlock); + contextLow.isBypassed = context.isBypassed; + lowpass .process (contextLow); + lowVolume.process (contextLow); + + auto contextHigh = dsp::ProcessContextReplacing (sepHighBlock); + contextHigh.isBypassed = context.isBypassed; + highpass .process (contextHigh); + highVolume.process (contextHigh); - if (inputVolume .getGainLinear() != inputdB) inputVolume.setGainLinear (inputdB); - if (outputVolume.getGainLinear() != outputdB) outputVolume.setGainLinear (outputdB); + if (! context.isBypassed) + { + sepLowBlock.add (sepHighBlock); + context.getOutputBlock().copyFrom (sepLowBlock); + } + } - auto newSlopeType = slopeParam->getIndex(); + dsp::LinkwitzRileyFilter lowpass, highpass; + dsp::Gain lowVolume, highVolume; + AudioBuffer bufferSeparation; + }; - if (newSlopeType == 0) + struct DirectDelayProcessor + { + DirectDelayProcessor() { - *lowPassFilter .state = *dsp::IIR::Coefficients::makeFirstOrderLowPass (getSampleRate(), lowPassFilterFreqParam->get()); - *highPassFilter.state = *dsp::IIR::Coefficients::makeFirstOrderHighPass (getSampleRate(), highPassFilterFreqParam->get()); + smoothFilter.setType (dsp::FirstOrderTPTFilterType::lowpass); + mixer.setMixingRule (dsp::DryWetMixingRule::linear); } - else + + void prepare (const dsp::ProcessSpec& spec) { - *lowPassFilter .state = *dsp::IIR::Coefficients::makeLowPass (getSampleRate(), lowPassFilterFreqParam->get()); - *highPassFilter.state = *dsp::IIR::Coefficients::makeHighPass (getSampleRate(), highPassFilterFreqParam->get()); + prepareAll (spec, noInterpolation, linear, lagrange, thiran, smoothFilter, mixer); } - //============================================================================== - auto type = cabinetTypeParam->getIndex(); - auto currentType = cabinetType.get(); + void reset() + { + resetAll (noInterpolation, linear, lagrange, thiran, smoothFilter, mixer); + } - if (type != currentType) + template + void process (Context& context) { - cabinetType.set (type); + if (context.isBypassed) + return; + + const auto& inputBlock = context.getInputBlock(); + const auto& outputBlock = context.getOutputBlock(); + + mixer.pushDrySamples (inputBlock); - auto maxSize = static_cast (roundToInt (getSampleRate() * (8192.0 / 44100.0))); - auto assetName = (type == 0 ? "Impulse1.wav" : "Impulse2.wav"); + const auto numChannels = inputBlock.getNumChannels(); + const auto numSamples = inputBlock.getNumSamples(); - if (auto assetInputStream = createAssetInputStream (assetName)) + for (size_t channel = 0; channel < numChannels; ++channel) { - currentCabinetData.reset(); - assetInputStream->readIntoMemoryBlock (currentCabinetData); + auto* samplesIn = inputBlock .getChannelPointer (channel); + auto* samplesOut = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + { + const auto delay = smoothFilter.processSample (int (channel), delayDirectValue[channel]); + + samplesOut[i] = [&] + { + switch (delayLineDirectType) + { + case 0: + noInterpolation.pushSample (int (channel), samplesIn[i]); + noInterpolation.setDelay ((float) delay); + return noInterpolation.popSample (int (channel)); + + case 1: + linear.pushSample (int (channel), samplesIn[i]); + linear.setDelay ((float) delay); + return linear.popSample (int (channel)); + + case 2: + lagrange.pushSample (int (channel), samplesIn[i]); + lagrange.setDelay ((float) delay); + return lagrange.popSample (int (channel)); + + case 3: + thiran.pushSample (int (channel), samplesIn[i]); + thiran.setDelay ((float) delay); + return thiran.popSample (int (channel)); + } + + jassertfalse; + return 0.0f; + }(); + } + } + + mixer.mixWetSamples (outputBlock); + } + + static constexpr auto directDelayBufferSize = 44100; + dsp::DelayLine noInterpolation { directDelayBufferSize }; + dsp::DelayLine linear { directDelayBufferSize }; + dsp::DelayLine lagrange { directDelayBufferSize }; + dsp::DelayLine thiran { directDelayBufferSize }; + + // Double precision to avoid some approximation issues + dsp::FirstOrderTPTFilter smoothFilter; - convolution.loadImpulseResponse (currentCabinetData.getData(), currentCabinetData.getSize(), - false, true, maxSize); + dsp::DryWetMixer mixer; + std::array delayDirectValue { {} }; + + int delayLineDirectType = 1; + }; + + struct DelayEffectProcessor + { + DelayEffectProcessor() + { + smoothFilter.setType (dsp::FirstOrderTPTFilterType::lowpass); + lowpass.setType (dsp::FirstOrderTPTFilterType::lowpass); + mixer.setMixingRule (dsp::DryWetMixingRule::linear); + } + + void prepare (const dsp::ProcessSpec& spec) + { + prepareAll (spec, noInterpolation, linear, lagrange, thiran, smoothFilter, lowpass, mixer); + + for (auto& volume : delayFeedbackVolume) + volume.reset (spec.sampleRate, 0.05); + } + + void reset() + { + resetAll (noInterpolation, linear, lagrange, thiran, smoothFilter, lowpass, mixer); + std::fill (lastDelayEffectOutput.begin(), lastDelayEffectOutput.end(), 0.0f); + } + + template + void process (Context& context) + { + if (context.isBypassed) + return; + + const auto& inputBlock = context.getInputBlock(); + const auto& outputBlock = context.getOutputBlock(); + const auto numSamples = inputBlock.getNumSamples(); + const auto numChannels = inputBlock.getNumChannels(); + + mixer.pushDrySamples (inputBlock); + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* samplesIn = inputBlock .getChannelPointer (channel); + auto* samplesOut = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + { + auto input = samplesIn[i] - lastDelayEffectOutput[channel]; + + auto delay = smoothFilter.processSample (int (channel), delayEffectValue[channel]); + + const auto output = [&] + { + switch (delayEffectType) + { + case 0: + noInterpolation.pushSample (int (channel), input); + noInterpolation.setDelay ((float) delay); + return noInterpolation.popSample (int (channel)); + + case 1: + linear.pushSample (int (channel), input); + linear.setDelay ((float) delay); + return linear.popSample (int (channel)); + + case 2: + lagrange.pushSample (int (channel), input); + lagrange.setDelay ((float) delay); + return lagrange.popSample (int (channel)); + + case 3: + thiran.pushSample (int (channel), input); + thiran.setDelay ((float) delay); + return thiran.popSample (int (channel)); + } + + jassertfalse; + return 0.0f; + }(); + + const auto processed = lowpass.processSample (int (channel), output); + + samplesOut[i] = processed; + lastDelayEffectOutput[channel] = processed * delayFeedbackVolume[channel].getNextValue(); + } } + + mixer.mixWetSamples (outputBlock); } - cabinetIsBypassed = ! cabinetSimParam->get(); + static constexpr auto effectDelaySamples = 192000; + dsp::DelayLine noInterpolation { effectDelaySamples }; + dsp::DelayLine linear { effectDelaySamples }; + dsp::DelayLine lagrange { effectDelaySamples }; + dsp::DelayLine thiran { effectDelaySamples }; - } + // Double precision to avoid some approximation issues + dsp::FirstOrderTPTFilter smoothFilter; - static inline float clip (float x) { return jmax (-1.0f, jmin (1.0f, x)); } + std::array delayEffectValue; + + std::array, 2> delayFeedbackVolume; + dsp::FirstOrderTPTFilter lowpass; + dsp::DryWetMixer mixer; + std::array lastDelayEffectOutput; + + int delayEffectType = 1; + }; + + using Chain = dsp::ProcessorChain, + dsp::Gain, + DirectDelayProcessor, + MultiBandProcessor, + dsp::Compressor, + dsp::Phaser, + dsp::Chorus, + DistortionProcessor, + dsp::LadderFilter, + DelayEffectProcessor, + dsp::Limiter, + dsp::Gain, + dsp::Panner>; + Chain chain; + + // We use this enum to index into the chain above + enum ProcessorIndices + { + noiseGateIndex, + inputGainIndex, + directDelayIndex, + multiBandIndex, + compressorIndex, + phaserIndex, + chorusIndex, + distortionIndex, + ladderIndex, + delayEffectIndex, + limiterIndex, + outputGainIndex, + pannerIndex + }; //============================================================================== - AudioParameterFloat* inputVolumeParam; - AudioParameterFloat* outputVolumeParam; - AudioParameterFloat* lowPassFilterFreqParam; - AudioParameterFloat* highPassFilterFreqParam; + std::atomic requiresUpdate { true }; - AudioParameterChoice* stereoParam; - AudioParameterChoice* slopeParam; - AudioParameterChoice* waveshaperParam; - AudioParameterChoice* cabinetTypeParam; + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DspModulePluginDemo) +}; - AudioParameterBool* cabinetSimParam; - AudioParameterBool* oversamplingParam; +//============================================================================== +class DspModulePluginDemoEditor : public AudioProcessorEditor +{ +public: + explicit DspModulePluginDemoEditor (DspModulePluginDemo& p) + : AudioProcessorEditor (&p), + proc (p) + { + comboEffect.addSectionHeading ("Main"); + comboEffect.addItem ("Distortion", TabDistortion); + comboEffect.addItem ("Multi-band", TabMultiBand); + + comboEffect.addSectionHeading ("Dynamics"); + comboEffect.addItem ("Compressor", TabCompressor); + comboEffect.addItem ("Noise gate", TabNoiseGate); + comboEffect.addItem ("Limiter", TabLimiter); + + comboEffect.addSectionHeading ("Delay"); + comboEffect.addItem ("Delay line direct", TabDelayLineDirect); + comboEffect.addItem ("Delay line effect", TabDelayLineEffect); + + comboEffect.addSectionHeading ("Others"); + comboEffect.addItem ("Phaser", TabPhaser); + comboEffect.addItem ("Chorus", TabChorus); + comboEffect.addItem ("Ladder filter", TabLadder); + + comboEffect.setSelectedId (proc.indexTab + 1, dontSendNotification); + comboEffect.onChange = [this] + { + proc.indexTab = comboEffect.getSelectedId() - 1; + updateVisibility(); + }; + + addAllAndMakeVisible (*this, + comboEffect, + labelEffect, + basicControls, + distortionControls, + multibandControls, + compressorControls, + noiseGateControls, + limiterControls, + directDelayControls, + delayEffectControls, + phaserControls, + chorusControls, + ladderControls); + labelEffect.setJustificationType (Justification::centredRight); + labelEffect.attachToComponent (&comboEffect, true); + + updateVisibility(); + + setSize (800, 430); + } -private: //============================================================================== - /** - This is the editor component that will be displayed. - */ - class DspModulePluginDemoAudioProcessorEditor : public AudioProcessorEditor + void paint (Graphics& g) override + { + auto rect = getLocalBounds(); + + auto rectTop = rect.removeFromTop (topSize); + auto rectBottom = rect.removeFromBottom (bottomSize); + + auto rectEffects = rect.removeFromBottom (tabSize); + auto rectChoice = rect.removeFromBottom (midSize); + + g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); + g.fillRect (rect); + + g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId).brighter (0.2f)); + g.fillRect (rectEffects); + + g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId).darker (0.2f)); + g.fillRect (rectTop); + g.fillRect (rectBottom); + g.fillRect (rectChoice); + + g.setColour (Colours::white); + g.setFont (Font (20.0f).italicised().withExtraKerningFactor (0.1f)); + g.drawFittedText ("DSP MODULE DEMO", rectTop.reduced (10, 0), Justification::centredLeft, 1); + } + + void resized() override + { + auto rect = getLocalBounds(); + rect.removeFromTop (topSize); + rect.removeFromBottom (bottomSize); + + auto rectEffects = rect.removeFromBottom (tabSize); + auto rectChoice = rect.removeFromBottom (midSize); + + comboEffect.setBounds (rectChoice.withSizeKeepingCentre (200, 24)); + + rect.reduce (80, 0); + rectEffects.reduce (20, 0); + + basicControls.setBounds (rect); + + forEach ([&] (Component& comp) { comp.setBounds (rectEffects); }, + distortionControls, + multibandControls, + compressorControls, + noiseGateControls, + limiterControls, + directDelayControls, + delayEffectControls, + phaserControls, + chorusControls, + ladderControls); + } + +private: + class AttachedSlider : public Component { public: - //============================================================================== - DspModulePluginDemoAudioProcessorEditor (DspModulePluginDemoAudioProcessor& p) - : AudioProcessorEditor (&p), - dspProcessor (p), - inputVolumeLabel ({}, dspProcessor.inputVolumeParam->name), - outputVolumeLabel ({}, dspProcessor.outputVolumeParam->name), - lowPassFilterFreqLabel ({}, dspProcessor.lowPassFilterFreqParam->name), - highPassFilterFreqLabel ({}, dspProcessor.highPassFilterFreqParam->name), - stereoLabel ({}, dspProcessor.stereoParam->name), - slopeLabel ({}, dspProcessor.slopeParam->name), - waveshaperLabel ({}, dspProcessor.waveshaperParam->name), - cabinetTypeLabel ({}, dspProcessor.cabinetTypeParam->name) - { - //============================================================================== - inputVolumeSlider .reset (new ParameterSlider (*dspProcessor.inputVolumeParam)); - outputVolumeSlider .reset (new ParameterSlider (*dspProcessor.outputVolumeParam)); - lowPassFilterFreqSlider .reset (new ParameterSlider (*dspProcessor.lowPassFilterFreqParam)); - highPassFilterFreqSlider.reset (new ParameterSlider (*dspProcessor.highPassFilterFreqParam)); + AttachedSlider (AudioProcessorValueTreeState& state, StringRef strID) + : label ("", state.getParameter (strID)->name), + attachment (state, strID, slider) + { + addAllAndMakeVisible (*this, slider, label); - addAndMakeVisible (inputVolumeSlider .get()); - addAndMakeVisible (outputVolumeSlider .get()); - addAndMakeVisible (lowPassFilterFreqSlider .get()); - addAndMakeVisible (highPassFilterFreqSlider.get()); + slider.setTextValueSuffix (" " + state.getParameter (strID)->label); - addAndMakeVisible (inputVolumeLabel); - inputVolumeLabel.setJustificationType (Justification::centredLeft); - inputVolumeLabel.attachToComponent (inputVolumeSlider.get(), true); + label.attachToComponent (&slider, false); + label.setJustificationType (Justification::centred); + } - addAndMakeVisible (outputVolumeLabel); - outputVolumeLabel.setJustificationType (Justification::centredLeft); - outputVolumeLabel.attachToComponent (outputVolumeSlider.get(), true); + void resized() override { slider.setBounds (getLocalBounds().reduced (0, 40)); } - addAndMakeVisible (lowPassFilterFreqLabel); - lowPassFilterFreqLabel.setJustificationType (Justification::centredLeft); - lowPassFilterFreqLabel.attachToComponent (lowPassFilterFreqSlider.get(), true); + private: + Slider slider { Slider::RotaryVerticalDrag, Slider::TextBoxBelow }; + Label label; + AudioProcessorValueTreeState::SliderAttachment attachment; + }; - addAndMakeVisible (highPassFilterFreqLabel); - highPassFilterFreqLabel.setJustificationType (Justification::centredLeft); - highPassFilterFreqLabel.attachToComponent (highPassFilterFreqSlider.get(), true); + class AttachedToggle : public Component + { + public: + AttachedToggle (AudioProcessorValueTreeState& state, StringRef strID) + : toggle (state.getParameter (strID)->name), + attachment (state, strID, toggle) + { + addAndMakeVisible (toggle); + } - //============================================================================== - addAndMakeVisible (stereoBox); + void resized() override { toggle.setBounds (getLocalBounds()); } - auto i = 1; - for (auto choice : dspProcessor.stereoParam->choices) - stereoBox.addItem (choice, i++); + private: + ToggleButton toggle; + AudioProcessorValueTreeState::ButtonAttachment attachment; + }; - stereoBox.onChange = [this] { dspProcessor.stereoParam->operator= (stereoBox.getSelectedItemIndex()); }; - stereoBox.setSelectedId (dspProcessor.stereoParam->getIndex() + 1); + class AttachedCombo : public Component + { + public: + AttachedCombo (AudioProcessorValueTreeState& state, StringRef strID) + : combo (state, strID), + label ("", state.getParameter (strID)->name), + attachment (state, strID, combo) + { + addAllAndMakeVisible (*this, combo, label); - addAndMakeVisible (stereoLabel); - stereoLabel.setJustificationType (Justification::centredLeft); - stereoLabel.attachToComponent (&stereoBox, true); + label.attachToComponent (&combo, false); + label.setJustificationType (Justification::centred); + } - //============================================================================== - addAndMakeVisible(slopeBox); + void resized() override + { + combo.setBounds (getLocalBounds().withSizeKeepingCentre (jmin (getWidth(), 150), 24)); + } - i = 1; - for (auto choice : dspProcessor.slopeParam->choices) - slopeBox.addItem(choice, i++); + private: + struct ComboWithItems : public ComboBox + { + ComboWithItems (AudioProcessorValueTreeState& state, StringRef strID) + { + // Adding the list here in the constructor means that the combo + // is already populated when we construct the attachment below + addItemList (dynamic_cast (state.getParameter (strID))->choices, 1); + } + }; - slopeBox.onChange = [this] { dspProcessor.slopeParam->operator= (slopeBox.getSelectedItemIndex()); }; - slopeBox.setSelectedId(dspProcessor.slopeParam->getIndex() + 1); + ComboWithItems combo; + Label label; + AudioProcessorValueTreeState::ComboBoxAttachment attachment; + }; - addAndMakeVisible(slopeLabel); - slopeLabel.setJustificationType(Justification::centredLeft); - slopeLabel.attachToComponent(&slopeBox, true); + //============================================================================== + void updateVisibility() + { + const auto indexEffect = comboEffect.getSelectedId(); - //============================================================================== - addAndMakeVisible (waveshaperBox); + const auto op = [&] (const std::tuple& tup) + { + Component& comp = std::get<0> (tup); + const int tabIndex = std::get<1> (tup); + comp.setVisible (tabIndex == indexEffect); + }; + + forEach (op, + std::forward_as_tuple (distortionControls, TabDistortion), + std::forward_as_tuple (multibandControls, TabMultiBand), + std::forward_as_tuple (compressorControls, TabCompressor), + std::forward_as_tuple (noiseGateControls, TabNoiseGate), + std::forward_as_tuple (limiterControls, TabLimiter), + std::forward_as_tuple (directDelayControls, TabDelayLineDirect), + std::forward_as_tuple (delayEffectControls, TabDelayLineEffect), + std::forward_as_tuple (phaserControls, TabPhaser), + std::forward_as_tuple (chorusControls, TabChorus), + std::forward_as_tuple (ladderControls, TabLadder)); + } - i = 1; - for (auto choice : dspProcessor.waveshaperParam->choices) - waveshaperBox.addItem (choice, i++); + enum EffectsTabs + { + TabDistortion = 1, + TabMultiBand, + TabCompressor, + TabNoiseGate, + TabLimiter, + TabDelayLineDirect, + TabDelayLineEffect, + TabPhaser, + TabChorus, + TabLadder + }; - waveshaperBox.onChange = [this] { dspProcessor.waveshaperParam->operator= (waveshaperBox.getSelectedItemIndex()); }; - waveshaperBox.setSelectedId (dspProcessor.waveshaperParam->getIndex() + 1); + //============================================================================== + ComboBox comboEffect; + Label labelEffect { "Audio effect: " }; - addAndMakeVisible (waveshaperLabel); - waveshaperLabel.setJustificationType (Justification::centredLeft); - waveshaperLabel.attachToComponent (&waveshaperBox, true); + struct GetTrackInfo + { + // Combo boxes need a lot of room + Grid::TrackInfo operator() (AttachedCombo&) const { return 120_px; } - //============================================================================== - addAndMakeVisible (cabinetTypeBox); + // Toggles are a bit smaller + Grid::TrackInfo operator() (AttachedToggle&) const { return 80_px; } - i = 1; - for (auto choice : dspProcessor.cabinetTypeParam->choices) - cabinetTypeBox.addItem (choice, i++); + // Sliders take up as much room as they can + Grid::TrackInfo operator() (AttachedSlider&) const { return 1_fr; } + }; - cabinetTypeBox.onChange = [this] { dspProcessor.cabinetTypeParam->operator= (cabinetTypeBox.getSelectedItemIndex()); }; - cabinetTypeBox.setSelectedId (dspProcessor.cabinetTypeParam->getIndex() + 1); + template + static void performLayout (const Rectangle& bounds, Components&... components) + { + Grid grid; + using Track = Grid::TrackInfo; - addAndMakeVisible (cabinetTypeLabel); - cabinetTypeLabel.setJustificationType (Justification::centredLeft); - cabinetTypeLabel.attachToComponent (&cabinetTypeBox, true); + grid.autoColumns = Track (1_fr); + grid.autoRows = Track (1_fr); + grid.columnGap = Grid::Px (10); + grid.rowGap = Grid::Px (0); + grid.autoFlow = Grid::AutoFlow::column; - //============================================================================== - addAndMakeVisible (cabinetSimButton); - cabinetSimButton.onClick = [this] { dspProcessor.cabinetSimParam->operator= (cabinetSimButton.getToggleState()); }; - cabinetSimButton.setButtonText (dspProcessor.cabinetSimParam->name); - cabinetSimButton.setToggleState (dspProcessor.cabinetSimParam->get(), NotificationType::dontSendNotification); + grid.templateColumns = { GetTrackInfo{} (components)... }; + grid.items = { GridItem (components)... }; - addAndMakeVisible (oversamplingButton); - oversamplingButton.onClick = [this] { dspProcessor.oversamplingParam->operator= (oversamplingButton.getToggleState()); }; - oversamplingButton.setButtonText (dspProcessor.oversamplingParam->name); - oversamplingButton.setToggleState (dspProcessor.oversamplingParam->get(), NotificationType::dontSendNotification); + grid.performLayout (bounds); + } - //============================================================================== - setSize (600, 400); + struct BasicControls : public Component + { + explicit BasicControls (AudioProcessorValueTreeState& state) + : pan (state, ID::pan), + input (state, ID::inputGain), + output (state, ID::outputGain) + { + addAllAndMakeVisible (*this, pan, input, output); } - //============================================================================== - void paint (Graphics& g) override + void resized() override { - g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); - g.fillAll(); + performLayout (getLocalBounds(), input, output, pan); } - void resized() override + AttachedSlider pan, input, output; + }; + + struct DistortionControls : public Component + { + explicit DistortionControls (AudioProcessorValueTreeState& state) + : toggle (state, ID::distortionEnabled), + lowpass (state, ID::distortionLowpass), + highpass (state, ID::distortionHighpass), + mix (state, ID::distortionMix), + gain (state, ID::distortionInGain), + compv (state, ID::distortionCompGain), + type (state, ID::distortionType), + oversampling (state, ID::distortionOversampler) { - auto bounds = getLocalBounds().reduced (10); - bounds.removeFromTop (10); - bounds.removeFromLeft (125); + addAllAndMakeVisible (*this, toggle, type, lowpass, highpass, mix, gain, compv, oversampling); + } - //============================================================================== - inputVolumeSlider->setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (5); + void resized() override + { + performLayout (getLocalBounds(), toggle, type, gain, highpass, lowpass, compv, mix, oversampling); + } - outputVolumeSlider->setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (15); + AttachedToggle toggle; + AttachedSlider lowpass, highpass, mix, gain, compv; + AttachedCombo type, oversampling; + }; - highPassFilterFreqSlider->setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (5); + struct MultiBandControls : public Component + { + explicit MultiBandControls (AudioProcessorValueTreeState& state) + : toggle (state, ID::multiBandEnabled), + low (state, ID::multiBandLowVolume), + high (state, ID::multiBandHighVolume), + lRFreq (state, ID::multiBandFreq) + { + addAllAndMakeVisible (*this, toggle, low, high, lRFreq); + } - lowPassFilterFreqSlider->setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (15); + void resized() override + { + performLayout (getLocalBounds(), toggle, lRFreq, low, high); + } - //============================================================================== - stereoBox.setBounds (bounds.removeFromTop(30)); - bounds.removeFromTop (5); + AttachedToggle toggle; + AttachedSlider low, high, lRFreq; + }; - slopeBox.setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (5); + struct CompressorControls : public Component + { + explicit CompressorControls (AudioProcessorValueTreeState& state) + : toggle (state, ID::compressorEnabled), + threshold (state, ID::compressorThreshold), + ratio (state, ID::compressorRatio), + attack (state, ID::compressorAttack), + release (state, ID::compressorRelease) + { + addAllAndMakeVisible (*this, toggle, threshold, ratio, attack, release); + } - waveshaperBox.setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (5); + void resized() override + { + performLayout (getLocalBounds(), toggle, threshold, ratio, attack, release); + } - cabinetTypeBox.setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (15); + AttachedToggle toggle; + AttachedSlider threshold, ratio, attack, release; + }; - //============================================================================== - auto buttonSlice = bounds.removeFromTop (30); - cabinetSimButton.setSize (200, buttonSlice.getHeight()); - cabinetSimButton.setCentrePosition (buttonSlice.getCentre()); - bounds.removeFromTop(5); + struct NoiseGateControls : public Component + { + explicit NoiseGateControls (AudioProcessorValueTreeState& state) + : toggle (state, ID::noiseGateEnabled), + threshold (state, ID::noiseGateThreshold), + ratio (state, ID::noiseGateRatio), + attack (state, ID::noiseGateAttack), + release (state, ID::noiseGateRelease) + { + addAllAndMakeVisible (*this, toggle, threshold, ratio, attack, release); + } - buttonSlice = bounds.removeFromTop (30); - oversamplingButton.setSize(200, buttonSlice.getHeight()); - oversamplingButton.setCentrePosition(buttonSlice.getCentre()); + void resized() override + { + performLayout (getLocalBounds(), toggle, threshold, ratio, attack, release); } - private: - //============================================================================== - DspModulePluginDemoAudioProcessor& dspProcessor; + AttachedToggle toggle; + AttachedSlider threshold, ratio, attack, release; + }; - std::unique_ptr inputVolumeSlider, outputVolumeSlider, - lowPassFilterFreqSlider, highPassFilterFreqSlider; - ComboBox stereoBox, slopeBox, waveshaperBox, cabinetTypeBox; - ToggleButton cabinetSimButton, oversamplingButton; + struct LimiterControls : public Component + { + explicit LimiterControls (AudioProcessorValueTreeState& state) + : toggle (state, ID::limiterEnabled), + threshold (state, ID::limiterThreshold), + release (state, ID::limiterRelease) + { + addAllAndMakeVisible (*this, toggle, threshold, release); + } - Label inputVolumeLabel, outputVolumeLabel, lowPassFilterFreqLabel, - highPassFilterFreqLabel, stereoLabel, slopeLabel, waveshaperLabel, - cabinetTypeLabel; + void resized() override + { + performLayout (getLocalBounds(), toggle, threshold, release); + } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DspModulePluginDemoAudioProcessorEditor) + AttachedToggle toggle; + AttachedSlider threshold, release; }; - //============================================================================== - void process (dsp::ProcessContextReplacing context) noexcept + struct DirectDelayControls : public Component { - ScopedNoDenormals noDenormals; - - // Input volume applied with a SmoothedValue - inputVolume.process (context); + explicit DirectDelayControls (AudioProcessorValueTreeState& state) + : toggle (state, ID::directDelayEnabled), + type (state, ID::directDelayType), + delay (state, ID::directDelayValue), + smooth (state, ID::directDelaySmoothing), + mix (state, ID::directDelayMix) + { + addAllAndMakeVisible (*this, toggle, type, delay, smooth, mix); + } - // Pre-highpass filtering, very useful for distortion audio effects - // Note : try frequencies around 700 Hz - highPassFilter.process (context); + void resized() override + { + performLayout (getLocalBounds(), toggle, type, delay, smooth, mix); + } - // Upsampling - dsp::AudioBlock oversampledBlock; + AttachedToggle toggle; + AttachedCombo type; + AttachedSlider delay, smooth, mix; + }; - setLatencySamples (audioCurrentlyOversampled ? roundToInt (oversampling->getLatencyInSamples()) : 0); + struct DelayEffectControls : public Component + { + explicit DelayEffectControls (AudioProcessorValueTreeState& state) + : toggle (state, ID::delayEffectEnabled), + type (state, ID::delayEffectType), + value (state, ID::delayEffectValue), + smooth (state, ID::delayEffectSmoothing), + lowpass (state, ID::delayEffectLowpass), + feedback (state, ID::delayEffectFeedback), + mix (state, ID::delayEffectMix) + { + addAllAndMakeVisible (*this, toggle, type, value, smooth, lowpass, feedback, mix); + } - if (audioCurrentlyOversampled) - oversampledBlock = oversampling->processSamplesUp (context.getOutputBlock()); + void resized() override + { + performLayout (getLocalBounds(), toggle, type, value, smooth, lowpass, feedback, mix); + } - auto waveshaperContext = audioCurrentlyOversampled ? dsp::ProcessContextReplacing (oversampledBlock) - : context; + AttachedToggle toggle; + AttachedCombo type; + AttachedSlider value, smooth, lowpass, feedback, mix; + }; - // Waveshaper processing, for distortion generation, thanks to the input gain - // The fast tanh can be used instead of std::tanh to reduce the CPU load - auto waveshaperIndex = waveshaperParam->getIndex(); + struct PhaserControls : public Component + { + explicit PhaserControls (AudioProcessorValueTreeState& state) + : toggle (state, ID::phaserEnabled), + rate (state, ID::phaserRate), + depth (state, ID::phaserDepth), + centre (state, ID::phaserCentreFrequency), + feedback (state, ID::phaserFeedback), + mix (state, ID::phaserMix) + { + addAllAndMakeVisible (*this, toggle, rate, depth, centre, feedback, mix); + } - if (isPositiveAndBelow (waveshaperIndex, numWaveShapers) ) + void resized() override { - waveShapers[waveshaperIndex].process (waveshaperContext); + performLayout (getLocalBounds(), toggle, rate, depth, centre, feedback, mix); + } - if (waveshaperIndex == 1) - clipping.process (waveshaperContext); + AttachedToggle toggle; + AttachedSlider rate, depth, centre, feedback, mix; + }; + + struct ChorusControls : public Component + { + explicit ChorusControls (AudioProcessorValueTreeState& state) + : toggle (state, ID::chorusEnabled), + rate (state, ID::chorusRate), + depth (state, ID::chorusDepth), + centre (state, ID::chorusCentreDelay), + feedback (state, ID::chorusFeedback), + mix (state, ID::chorusMix) + { + addAllAndMakeVisible (*this, toggle, rate, depth, centre, feedback, mix); + } - waveshaperContext.getOutputBlock() *= 0.7f; + void resized() override + { + performLayout (getLocalBounds(), toggle, rate, depth, centre, feedback, mix); } - // Downsampling - if (audioCurrentlyOversampled) - oversampling->processSamplesDown (context.getOutputBlock()); + AttachedToggle toggle; + AttachedSlider rate, depth, centre, feedback, mix; + }; - // Post-lowpass filtering - lowPassFilter.process (context); + struct LadderControls : public Component + { + explicit LadderControls (AudioProcessorValueTreeState& state) + : toggle (state, ID::ladderEnabled), + mode (state, ID::ladderMode), + freq (state, ID::ladderCutoff), + resonance (state, ID::ladderResonance), + drive (state, ID::ladderDrive) + { + addAllAndMakeVisible (*this, toggle, mode, freq, resonance, drive); + } - // Convolution with the impulse response of a guitar cabinet - auto wasBypassed = context.isBypassed; - context.isBypassed = context.isBypassed || cabinetIsBypassed; - convolution.process (context); - context.isBypassed = wasBypassed; + void resized() override + { + performLayout (getLocalBounds(), toggle, mode, freq, resonance, drive); + } - // Output volume applied with a SmoothedValue - outputVolume.process (context); - } + AttachedToggle toggle; + AttachedCombo mode; + AttachedSlider freq, resonance, drive; + }; //============================================================================== - dsp::ProcessorDuplicator, dsp::IIR::Coefficients> lowPassFilter, highPassFilter; - dsp::Convolution convolution; - MemoryBlock currentCabinetData; - - static constexpr size_t numWaveShapers = 2; - dsp::WaveShaper waveShapers[numWaveShapers]; - dsp::WaveShaper clipping; + static constexpr auto topSize = 40, + bottomSize = 40, + midSize = 40, + tabSize = 155; - dsp::Gain inputVolume, outputVolume; + //============================================================================== + DspModulePluginDemo& proc; + + BasicControls basicControls { proc.apvts }; + DistortionControls distortionControls { proc.apvts }; + MultiBandControls multibandControls { proc.apvts }; + CompressorControls compressorControls { proc.apvts }; + NoiseGateControls noiseGateControls { proc.apvts }; + LimiterControls limiterControls { proc.apvts }; + DirectDelayControls directDelayControls { proc.apvts }; + DelayEffectControls delayEffectControls { proc.apvts }; + PhaserControls phaserControls { proc.apvts }; + ChorusControls chorusControls { proc.apvts }; + LadderControls ladderControls { proc.apvts }; - std::unique_ptr> oversampling; - bool audioCurrentlyOversampled = false; + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DspModulePluginDemoEditor) +}; - Atomic cabinetType; - bool cabinetIsBypassed = false; +struct DspModulePluginDemoAudioProcessor : public DspModulePluginDemo +{ + AudioProcessorEditor* createEditor() override + { + return new DspModulePluginDemoEditor (*this); + } - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DspModulePluginDemoAudioProcessor) + bool hasEditor() const override { return true; } }; diff --git a/examples/Plugins/MidiLoggerPluginDemo.h b/examples/Plugins/MidiLoggerPluginDemo.h index 77ad482257..7a8508f923 100644 --- a/examples/Plugins/MidiLoggerPluginDemo.h +++ b/examples/Plugins/MidiLoggerPluginDemo.h @@ -235,7 +235,7 @@ public: bool hasEditor() const override { return true; } AudioProcessorEditor* createEditor() override { return new Editor (*this); } - const String getName() const override { return "MIDILogger"; } + const String getName() const override { return "MIDI Logger"; } bool acceptsMidi() const override { return true; } bool producesMidi() const override { return true; } double getTailLengthSeconds() const override { return 0.0; } diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index 6c84a7689b..5fd6cbb869 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -98,16 +98,17 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" "../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" + "../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" + "../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.mm" "../../../../../modules/juce_audio_basics/juce_audio_basics.h" @@ -1506,16 +1507,17 @@ set_source_files_properties("../../../../../modules/juce_audio_basics/sources/ju set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.h" PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj index 1d072bc9c4..e8b4cf4e80 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj @@ -223,10 +223,10 @@ true - + true - + true @@ -235,6 +235,9 @@ true + + true + true @@ -2047,10 +2050,10 @@ - + - + diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj.filters index e7c0c87387..ca6aa84887 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj.filters @@ -508,10 +508,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -520,6 +520,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -2535,16 +2538,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index a3e34d5fa8..0b936e6459 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -115,16 +115,17 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" "../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" + "../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" + "../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.mm" "../../../../../modules/juce_audio_basics/juce_audio_basics.h" @@ -934,27 +935,51 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_dsp/native/juce_neon_SIMDNativeOps.h" "../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp" "../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.h" - "../../../../../modules/juce_dsp/processors/juce_Bias.h" + "../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.h" + "../../../../../modules/juce_dsp/processors/juce_DelayLine.cpp" + "../../../../../modules/juce_dsp/processors/juce_DelayLine.h" + "../../../../../modules/juce_dsp/processors/juce_DryWetMixer.cpp" + "../../../../../modules/juce_dsp/processors/juce_DryWetMixer.h" "../../../../../modules/juce_dsp/processors/juce_FIRFilter.cpp" "../../../../../modules/juce_dsp/processors/juce_FIRFilter.h" "../../../../../modules/juce_dsp/processors/juce_FIRFilter_test.cpp" - "../../../../../modules/juce_dsp/processors/juce_Gain.h" + "../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h" "../../../../../modules/juce_dsp/processors/juce_IIRFilter.cpp" "../../../../../modules/juce_dsp/processors/juce_IIRFilter.h" "../../../../../modules/juce_dsp/processors/juce_IIRFilter_Impl.h" - "../../../../../modules/juce_dsp/processors/juce_LadderFilter.cpp" - "../../../../../modules/juce_dsp/processors/juce_LadderFilter.h" - "../../../../../modules/juce_dsp/processors/juce_Oscillator.h" + "../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h" "../../../../../modules/juce_dsp/processors/juce_Oversampling.cpp" "../../../../../modules/juce_dsp/processors/juce_Oversampling.h" + "../../../../../modules/juce_dsp/processors/juce_Panner.cpp" + "../../../../../modules/juce_dsp/processors/juce_Panner.h" "../../../../../modules/juce_dsp/processors/juce_ProcessContext.h" "../../../../../modules/juce_dsp/processors/juce_ProcessorChain.h" "../../../../../modules/juce_dsp/processors/juce_ProcessorChain_test.cpp" "../../../../../modules/juce_dsp/processors/juce_ProcessorDuplicator.h" "../../../../../modules/juce_dsp/processors/juce_ProcessorWrapper.h" - "../../../../../modules/juce_dsp/processors/juce_Reverb.h" "../../../../../modules/juce_dsp/processors/juce_StateVariableFilter.h" - "../../../../../modules/juce_dsp/processors/juce_WaveShaper.h" + "../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.h" + "../../../../../modules/juce_dsp/widgets/juce_Bias.h" + "../../../../../modules/juce_dsp/widgets/juce_Chorus.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Chorus.h" + "../../../../../modules/juce_dsp/widgets/juce_Compressor.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Compressor.h" + "../../../../../modules/juce_dsp/widgets/juce_Gain.h" + "../../../../../modules/juce_dsp/widgets/juce_LadderFilter.cpp" + "../../../../../modules/juce_dsp/widgets/juce_LadderFilter.h" + "../../../../../modules/juce_dsp/widgets/juce_Limiter.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Limiter.h" + "../../../../../modules/juce_dsp/widgets/juce_NoiseGate.cpp" + "../../../../../modules/juce_dsp/widgets/juce_NoiseGate.h" + "../../../../../modules/juce_dsp/widgets/juce_Oscillator.h" + "../../../../../modules/juce_dsp/widgets/juce_Phaser.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Phaser.h" + "../../../../../modules/juce_dsp/widgets/juce_Reverb.h" + "../../../../../modules/juce_dsp/widgets/juce_WaveShaper.h" "../../../../../modules/juce_dsp/juce_dsp.cpp" "../../../../../modules/juce_dsp/juce_dsp.mm" "../../../../../modules/juce_dsp/juce_dsp.h" @@ -1654,16 +1679,17 @@ set_source_files_properties("../../../../../modules/juce_audio_basics/sources/ju set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2473,27 +2499,51 @@ set_source_files_properties("../../../../../modules/juce_dsp/native/juce_neon_SI set_source_files_properties("../../../../../modules/juce_dsp/native/juce_neon_SIMDNativeOps.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Bias.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DelayLine.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DelayLine.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DryWetMixer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DryWetMixer.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Gain.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter_Impl.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LadderFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LadderFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oscillator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oversampling.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oversampling.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Panner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Panner.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessContext.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorChain.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorChain_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorDuplicator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorWrapper.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_WaveShaper.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Bias.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Chorus.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Chorus.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Compressor.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Compressor.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Gain.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_LadderFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_LadderFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Limiter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Limiter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_NoiseGate.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_NoiseGate.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Oscillator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Phaser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Phaser.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_WaveShaper.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj index 18672b7509..07d54ed376 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj @@ -230,10 +230,10 @@ true - + true - + true @@ -242,6 +242,9 @@ true + + true + true @@ -1220,24 +1223,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + true + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -2190,10 +2229,10 @@ - + - + @@ -2647,21 +2686,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters index b68f2d2aeb..38fdba80ef 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters @@ -314,6 +314,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -586,10 +589,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -598,6 +601,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -1630,24 +1636,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -2781,16 +2823,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -4152,13 +4194,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4167,13 +4215,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4188,15 +4236,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj index 28617459cf..858a4fd42a 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj @@ -230,10 +230,10 @@ true - + true - + true @@ -242,6 +242,9 @@ true + + true + true @@ -1220,24 +1223,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + true + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -2190,10 +2229,10 @@ - + - + @@ -2647,21 +2686,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters index a7db45264f..b3ba2bee37 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters @@ -314,6 +314,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -586,10 +589,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -598,6 +601,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -1630,24 +1636,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -2781,16 +2823,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -4152,13 +4194,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4167,13 +4215,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4188,15 +4236,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index 3e204cef44..aa757ea964 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -230,10 +230,10 @@ true - + true - + true @@ -242,6 +242,9 @@ true + + true + true @@ -1220,24 +1223,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + true + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -2190,10 +2229,10 @@ - + - + @@ -2647,21 +2686,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index 3aaa7a4583..3f20abf9e6 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -314,6 +314,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -586,10 +589,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -598,6 +601,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -1630,24 +1636,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -2781,16 +2823,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -4152,13 +4194,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4167,13 +4215,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4188,15 +4236,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp diff --git a/extras/AudioPluginHost/CMakeLists.txt b/extras/AudioPluginHost/CMakeLists.txt index 7e288b5e6e..95f92b74b8 100644 --- a/extras/AudioPluginHost/CMakeLists.txt +++ b/extras/AudioPluginHost/CMakeLists.txt @@ -52,3 +52,7 @@ target_link_libraries(AudioPluginHost PRIVATE juce::juce_dsp juce::juce_opengl juce::juce_video) + +if(CMAKE_SYSTEM_NAME STREQUAL "iOS") + juce_add_bundle_resources_directory(AudioPluginHost ../../examples/Assets) +endif() diff --git a/extras/Build/CMake/JUCEConfig.cmake.in b/extras/Build/CMake/JUCEConfig.cmake.in index 5207058d92..7744edc643 100644 --- a/extras/Build/CMake/JUCEConfig.cmake.in +++ b/extras/Build/CMake/JUCEConfig.cmake.in @@ -1,7 +1,7 @@ # ============================================================================== # # This file is part of the JUCE library. -# Copyright (c) 2017 - ROLI Ltd. +# Copyright (c) 2020 - Raw Material Software Limited # # JUCE is an open source library subject to commercial or open-source # licensing. diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 29293e87c6..7086feb335 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -102,16 +102,17 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" "../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" + "../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" + "../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.mm" "../../../../../modules/juce_audio_basics/juce_audio_basics.h" @@ -1585,16 +1586,17 @@ set_source_files_properties("../../../../../modules/juce_audio_basics/sources/ju set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.h" PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj index 4f5ababf79..ff2a57d1f2 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj @@ -223,10 +223,10 @@ true - + true - + true @@ -235,6 +235,9 @@ true + + true + true @@ -2132,10 +2135,10 @@ - + - + diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj.filters index c8ae8119b7..1713ecfff3 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj.filters @@ -538,10 +538,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -550,6 +550,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -2670,16 +2673,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj index cef4ae3a2b..0cc5d787be 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj @@ -239,10 +239,10 @@ true - + true - + true @@ -251,6 +251,9 @@ true + + true + true @@ -1283,24 +1286,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + true + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -2303,10 +2342,10 @@ - + - + @@ -2785,21 +2824,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters index 25e2315dd5..88b9ebed4e 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -338,6 +338,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -625,10 +628,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -637,6 +640,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -1723,24 +1729,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -2931,16 +2973,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -4377,13 +4419,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4392,13 +4440,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4413,15 +4461,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index 7617069b10..a27581ad11 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -239,10 +239,10 @@ true - + true - + true @@ -251,6 +251,9 @@ true + + true + true @@ -1283,24 +1286,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + true + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -2303,10 +2342,10 @@ - + - + @@ -2785,21 +2824,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index 6090599833..e64d57000f 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -338,6 +338,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -625,10 +628,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -637,6 +640,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -1723,24 +1729,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -2931,16 +2973,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -4377,13 +4419,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4392,13 +4440,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4413,15 +4461,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp diff --git a/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj index b10892c463..fb0a6b9fbc 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj @@ -222,10 +222,10 @@ true - + true - + true @@ -234,6 +234,9 @@ true + + true + true @@ -2108,10 +2111,10 @@ - + - + diff --git a/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj.filters index a9da2e00e2..46cbea29ed 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj.filters @@ -535,10 +535,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -547,6 +547,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -2637,16 +2640,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities diff --git a/modules/juce_audio_basics/juce_audio_basics.cpp b/modules/juce_audio_basics/juce_audio_basics.cpp index b44855f387..9fe3e779c5 100644 --- a/modules/juce_audio_basics/juce_audio_basics.cpp +++ b/modules/juce_audio_basics/juce_audio_basics.cpp @@ -59,7 +59,8 @@ #include "buffers/juce_AudioProcessLoadMeasurer.cpp" #include "utilities/juce_IIRFilter.cpp" #include "utilities/juce_LagrangeInterpolator.cpp" -#include "utilities/juce_CatmullRomInterpolator.cpp" +#include "utilities/juce_WindowedSincInterpolator.cpp" +#include "utilities/juce_Interpolators.cpp" #include "utilities/juce_SmoothedValue.cpp" #include "midi/juce_MidiBuffer.cpp" #include "midi/juce_MidiFile.cpp" diff --git a/modules/juce_audio_basics/juce_audio_basics.h b/modules/juce_audio_basics/juce_audio_basics.h index 6c26bfda88..ce3a1c1d5f 100644 --- a/modules/juce_audio_basics/juce_audio_basics.h +++ b/modules/juce_audio_basics/juce_audio_basics.h @@ -88,8 +88,8 @@ #include "buffers/juce_AudioProcessLoadMeasurer.h" #include "utilities/juce_Decibels.h" #include "utilities/juce_IIRFilter.h" -#include "utilities/juce_LagrangeInterpolator.h" -#include "utilities/juce_CatmullRomInterpolator.h" +#include "utilities/juce_GenericInterpolator.h" +#include "utilities/juce_Interpolators.h" #include "utilities/juce_SmoothedValue.h" #include "utilities/juce_Reverb.h" #include "utilities/juce_ADSR.h" diff --git a/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp b/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp index 220a38dd6e..abb1e1fd46 100644 --- a/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp @@ -24,7 +24,7 @@ namespace juce { MemoryAudioSource::MemoryAudioSource (AudioBuffer& bufferToUse, bool copyMemory, bool shouldLoop) - : isLooping (shouldLoop) + : isCurrentlyLooping (shouldLoop) { if (copyMemory) buffer.makeCopyOf (bufferToUse); @@ -50,7 +50,7 @@ void MemoryAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferT auto n = buffer.getNumSamples(), m = bufferToFill.numSamples; int i; - for (i = position; (i < n || isLooping) && (pos < m); i += max) + for (i = position; (i < n || isCurrentlyLooping) && (pos < m); i += max) { max = jmin (m - pos, n - (i % n)); @@ -70,4 +70,31 @@ void MemoryAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferT position = (i % n); } +//============================================================================== +void MemoryAudioSource::setNextReadPosition (int64 newPosition) +{ + position = (int) newPosition; +} + +int64 MemoryAudioSource::getNextReadPosition() const +{ + return position; +} + +int64 MemoryAudioSource::getTotalLength() const +{ + return buffer.getNumSamples(); +} + +//============================================================================== +bool MemoryAudioSource::isLooping() const +{ + return isCurrentlyLooping; +} + +void MemoryAudioSource::setLooping (bool shouldLoop) +{ + isCurrentlyLooping = shouldLoop; +} + } // namespace juce diff --git a/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h b/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h index f8b1883e33..414cc65c3c 100644 --- a/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h @@ -29,7 +29,7 @@ namespace juce @tags{Audio} */ -class JUCE_API MemoryAudioSource : public AudioSource +class JUCE_API MemoryAudioSource : public PositionableAudioSource { public: //============================================================================== @@ -52,11 +52,28 @@ public: /** Implementation of the AudioSource method. */ void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override; + //============================================================================== + /** Implementation of the PositionableAudioSource method. */ + void setNextReadPosition (int64 newPosition) override; + + /** Implementation of the PositionableAudioSource method. */ + int64 getNextReadPosition() const override; + + /** Implementation of the PositionableAudioSource method. */ + int64 getTotalLength() const override; + + //============================================================================== + /** Implementation of the PositionableAudioSource method. */ + bool isLooping() const override; + + /** Implementation of the PositionableAudioSource method. */ + void setLooping (bool shouldLoop) override; + private: //============================================================================== AudioBuffer buffer; int position = 0; - bool isLooping; + bool isCurrentlyLooping; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryAudioSource) diff --git a/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp b/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp deleted file mode 100644 index 3f5ea5139a..0000000000 --- a/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2020 - Raw Material Software Limited - - JUCE is an open source library subject to commercial or open-source - licensing. - - The code included in this file is provided under the terms of the ISC license - http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or - without fee is hereby granted provided that the above copyright notice and - this permission notice appear in all copies. - - JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER - EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE - DISCLAIMED. - - ============================================================================== -*/ - -namespace juce -{ - -struct CatmullRomAlgorithm -{ - static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept - { - auto y0 = inputs[3]; - auto y1 = inputs[2]; - auto y2 = inputs[1]; - auto y3 = inputs[0]; - - auto halfY0 = 0.5f * y0; - auto halfY3 = 0.5f * y3; - - return y1 + offset * ((0.5f * y2 - halfY0) - + (offset * (((y0 + 2.0f * y2) - (halfY3 + 2.5f * y1)) - + (offset * ((halfY3 + 1.5f * y1) - (halfY0 + 1.5f * y2)))))); - } -}; - -CatmullRomInterpolator::CatmullRomInterpolator() noexcept { reset(); } -CatmullRomInterpolator::~CatmullRomInterpolator() noexcept {} - -void CatmullRomInterpolator::reset() noexcept -{ - subSamplePos = 1.0; - - for (auto& s : lastInputSamples) - s = 0; -} - -int CatmullRomInterpolator::process (double actualRatio, const float* in, float* out, int numOut, int available, int wrap) noexcept -{ - return interpolate (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, available, wrap); -} - -int CatmullRomInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept -{ - return interpolate (lastInputSamples, subSamplePos, actualRatio, in, out, numOut); -} - -int CatmullRomInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, int available, int wrap, float gain) noexcept -{ - return interpolateAdding (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, available, wrap, gain); -} - -int CatmullRomInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, float gain) noexcept -{ - return interpolateAdding (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain); -} - -} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h b/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h deleted file mode 100644 index 292783714a..0000000000 --- a/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2020 - Raw Material Software Limited - - JUCE is an open source library subject to commercial or open-source - licensing. - - The code included in this file is provided under the terms of the ISC license - http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or - without fee is hereby granted provided that the above copyright notice and - this permission notice appear in all copies. - - JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER - EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE - DISCLAIMED. - - ============================================================================== -*/ - -namespace juce -{ - -/** - Interpolator for resampling a stream of floats using Catmull-Rom interpolation. - - Note that the resampler is stateful, so when there's a break in the continuity - of the input stream you're feeding it, you should call reset() before feeding - it any new data. And like with any other stateful filter, if you're resampling - multiple channels, make sure each one uses its own CatmullRomInterpolator - object. - - @see LagrangeInterpolator - - @tags{Audio} -*/ -class JUCE_API CatmullRomInterpolator -{ -public: - CatmullRomInterpolator() noexcept; - ~CatmullRomInterpolator() noexcept; - - CatmullRomInterpolator (CatmullRomInterpolator&&) noexcept = default; - CatmullRomInterpolator& operator= (CatmullRomInterpolator&&) noexcept = default; - - /** Resets the state of the interpolator. - Call this when there's a break in the continuity of the input data stream. - */ - void reset() noexcept; - - /** Resamples a stream of samples. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results into - @param numOutputSamplesToProduce the number of output samples that should be created - - @returns the actual number of input samples that were used - */ - int process (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce) noexcept; - - /** Resamples a stream of samples. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results into - @param numOutputSamplesToProduce the number of output samples that should be created - @param available the number of available input samples. If it needs more samples - than available, it either wraps back for wrapAround samples, or - it feeds zeroes - @param wrapAround if the stream exceeds available samples, it wraps back for - wrapAround samples. If wrapAround is set to 0, it will feed zeroes. - - @returns the actual number of input samples that were used - */ - int process (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - int available, - int wrapAround) noexcept; - - /** Resamples a stream of samples, adding the results to the output data - with a gain. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results to - the result values will be added - to any pre-existing data in this buffer after being multiplied by - the gain factor - @param numOutputSamplesToProduce the number of output samples that should be created - @param gain a gain factor to multiply the resulting samples by before - adding them to the destination buffer - - @returns the actual number of input samples that were used - */ - int processAdding (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - float gain) noexcept; - - /** Resamples a stream of samples, adding the results to the output data - with a gain. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results to - the result values will be added - to any pre-existing data in this buffer after being multiplied by - the gain factor - @param numOutputSamplesToProduce the number of output samples that should be created - @param available the number of available input samples. If it needs more samples - than available, it either wraps back for wrapAround samples, or - it feeds zeroes - @param wrapAround if the stream exceeds available samples, it wraps back for - wrapAround samples. If wrapAround is set to 0, it will feed zeroes. - @param gain a gain factor to multiply the resulting samples by before - adding them to the destination buffer - - @returns the actual number of input samples that were used - */ - int processAdding (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - int available, - int wrapAround, - float gain) noexcept; - -private: - float lastInputSamples[5]; - double subSamplePos; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CatmullRomInterpolator) -}; - -} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_GenericInterpolator.h b/modules/juce_audio_basics/utilities/juce_GenericInterpolator.h new file mode 100644 index 0000000000..74475c6d96 --- /dev/null +++ b/modules/juce_audio_basics/utilities/juce_GenericInterpolator.h @@ -0,0 +1,493 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +/** + An interpolator base class for resampling streams of floats. + + Note that the resamplers are stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own interpolator object. + + @see LagrangeInterpolator, CatmullRomInterpolator, WindowedSincInterpolator, + LinearInterpolator, ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +template +class JUCE_API GenericInterpolator +{ +public: + GenericInterpolator() noexcept { reset(); } + + GenericInterpolator (GenericInterpolator&&) noexcept = default; + GenericInterpolator& operator= (GenericInterpolator&&) noexcept = default; + + /** Returns the latency of the interpolation algorithm in isolation. + + In the context of resampling the total latency of a process using + the interpolator is the base latency divided by the speed ratio. + */ + static constexpr float getBaseLatency() noexcept + { + return InterpolatorTraits::algorithmicLatency; + } + + /** Resets the state of the interpolator. + + Call this when there's a break in the continuity of the input data stream. + */ + void reset() noexcept + { + indexBuffer = 0; + subSamplePos = 1.0; + std::fill (std::begin (lastInputSamples), std::end (lastInputSamples), 0.0f); + } + + /** Resamples a stream of samples. + + @param speedRatio the number of input samples to use for each output sample + @param inputSamples the source data to read from. This must contain at + least (speedRatio * numOutputSamplesToProduce) samples. + @param outputSamples the buffer to write the results into + @param numOutputSamplesToProduce the number of output samples that should be created + + @returns the actual number of input samples that were used + */ + int process (double speedRatio, + const float* inputSamples, + float* outputSamples, + int numOutputSamplesToProduce) noexcept + { + return interpolate (speedRatio, inputSamples, outputSamples, numOutputSamplesToProduce); + } + + /** Resamples a stream of samples. + + @param speedRatio the number of input samples to use for each output sample + @param inputSamples the source data to read from. This must contain at + least (speedRatio * numOutputSamplesToProduce) samples. + @param outputSamples the buffer to write the results into + @param numOutputSamplesToProduce the number of output samples that should be created + @param numInputSamplesAvailable the number of available input samples. If it needs more samples + than available, it either wraps back for wrapAround samples, or + it feeds zeroes + @param wrapAround if the stream exceeds available samples, it wraps back for + wrapAround samples. If wrapAround is set to 0, it will feed zeroes. + + @returns the actual number of input samples that were used + */ + int process (double speedRatio, + const float* inputSamples, + float* outputSamples, + int numOutputSamplesToProduce, + int numInputSamplesAvailable, + int wrapAround) noexcept + { + return interpolate (speedRatio, inputSamples, outputSamples, + numOutputSamplesToProduce, numInputSamplesAvailable, wrapAround); + } + + /** Resamples a stream of samples, adding the results to the output data + with a gain. + + @param speedRatio the number of input samples to use for each output sample + @param inputSamples the source data to read from. This must contain at + least (speedRatio * numOutputSamplesToProduce) samples. + @param outputSamples the buffer to write the results to - the result values will be added + to any pre-existing data in this buffer after being multiplied by + the gain factor + @param numOutputSamplesToProduce the number of output samples that should be created + @param gain a gain factor to multiply the resulting samples by before + adding them to the destination buffer + + @returns the actual number of input samples that were used + */ + int processAdding (double speedRatio, + const float* inputSamples, + float* outputSamples, + int numOutputSamplesToProduce, + float gain) noexcept + { + return interpolateAdding (speedRatio, inputSamples, outputSamples, numOutputSamplesToProduce, gain); + } + + /** Resamples a stream of samples, adding the results to the output data + with a gain. + + @param speedRatio the number of input samples to use for each output sample + @param inputSamples the source data to read from. This must contain at + least (speedRatio * numOutputSamplesToProduce) samples. + @param outputSamples the buffer to write the results to - the result values will be added + to any pre-existing data in this buffer after being multiplied by + the gain factor + @param numOutputSamplesToProduce the number of output samples that should be created + @param numInputSamplesAvailable the number of available input samples. If it needs more samples + than available, it either wraps back for wrapAround samples, or + it feeds zeroes + @param wrapAround if the stream exceeds available samples, it wraps back for + wrapAround samples. If wrapAround is set to 0, it will feed zeroes. + @param gain a gain factor to multiply the resulting samples by before + adding them to the destination buffer + + @returns the actual number of input samples that were used + */ + int processAdding (double speedRatio, + const float* inputSamples, + float* outputSamples, + int numOutputSamplesToProduce, + int numInputSamplesAvailable, + int wrapAround, + float gain) noexcept + { + return interpolateAdding (speedRatio, inputSamples, outputSamples, + numOutputSamplesToProduce, numInputSamplesAvailable, wrapAround, gain); + } + +private: + //============================================================================== + forcedinline void pushInterpolationSample (float newValue) noexcept + { + lastInputSamples[indexBuffer] = newValue; + + if (++indexBuffer == memorySize) + indexBuffer = 0; + } + + forcedinline void pushInterpolationSamples (const float* input, + int numOutputSamplesToProduce) noexcept + { + if (numOutputSamplesToProduce >= memorySize) + { + const auto* const offsetInput = input + (numOutputSamplesToProduce - memorySize); + + for (int i = 0; i < memorySize; ++i) + pushInterpolationSample (offsetInput[i]); + } + else + { + for (int i = 0; i < numOutputSamplesToProduce; ++i) + pushInterpolationSample (input[i]); + } + } + + forcedinline void pushInterpolationSamples (const float* input, + int numOutputSamplesToProduce, + int numInputSamplesAvailable, + int wrapAround) noexcept + { + if (numOutputSamplesToProduce >= memorySize) + { + if (numInputSamplesAvailable >= memorySize) + { + pushInterpolationSamples (input, + numOutputSamplesToProduce); + } + else + { + pushInterpolationSamples (input + ((numOutputSamplesToProduce - numInputSamplesAvailable) - 1), + numInputSamplesAvailable); + + if (wrapAround > 0) + { + numOutputSamplesToProduce -= wrapAround; + + pushInterpolationSamples (input + ((numOutputSamplesToProduce - (memorySize - numInputSamplesAvailable)) - 1), + memorySize - numInputSamplesAvailable); + } + else + { + for (int i = numInputSamplesAvailable; i < memorySize; ++i) + pushInterpolationSample (0.0f); + } + } + } + else + { + if (numOutputSamplesToProduce > numInputSamplesAvailable) + { + for (int i = 0; i < numInputSamplesAvailable; ++i) + pushInterpolationSample (input[i]); + + const auto extraSamples = numOutputSamplesToProduce - numInputSamplesAvailable; + + if (wrapAround > 0) + { + const auto* const offsetInput = input + (numInputSamplesAvailable - wrapAround); + + for (int i = 0; i < extraSamples; ++i) + pushInterpolationSample (offsetInput[i]); + } + else + { + for (int i = 0; i < extraSamples; ++i) + pushInterpolationSample (0.0f); + } + } + else + { + for (int i = 0; i < numOutputSamplesToProduce; ++i) + pushInterpolationSample (input[i]); + } + } + } + + //============================================================================== + int interpolate (double speedRatio, + const float* input, + float* output, + int numOutputSamplesToProduce) noexcept + { + auto pos = subSamplePos; + int numUsed = 0; + + while (numOutputSamplesToProduce > 0) + { + while (pos >= 1.0) + { + pushInterpolationSample (input[numUsed++]); + pos -= 1.0; + } + + *output++ = InterpolatorTraits::valueAtOffset (lastInputSamples, (float) pos, indexBuffer); + pos += speedRatio; + --numOutputSamplesToProduce; + } + + subSamplePos = pos; + return numUsed; + } + + int interpolate (double speedRatio, + const float* input, float* output, + int numOutputSamplesToProduce, + int numInputSamplesAvailable, + int wrap) noexcept + { + auto originalIn = input; + auto pos = subSamplePos; + bool exceeded = false; + + if (speedRatio < 1.0) + { + for (int i = numOutputSamplesToProduce; --i >= 0;) + { + if (pos >= 1.0) + { + if (exceeded) + { + pushInterpolationSample (0.0f); + } + else + { + pushInterpolationSample (*input++); + + if (--numInputSamplesAvailable <= 0) + { + if (wrap > 0) + { + input -= wrap; + numInputSamplesAvailable += wrap; + } + else + { + exceeded = true; + } + } + } + + pos -= 1.0; + } + + *output++ = InterpolatorTraits::valueAtOffset (lastInputSamples, (float) pos, indexBuffer); + pos += speedRatio; + } + } + else + { + for (int i = numOutputSamplesToProduce; --i >= 0;) + { + while (pos < speedRatio) + { + if (exceeded) + { + pushInterpolationSample (0); + } + else + { + pushInterpolationSample (*input++); + + if (--numInputSamplesAvailable <= 0) + { + if (wrap > 0) + { + input -= wrap; + numInputSamplesAvailable += wrap; + } + else + { + exceeded = true; + } + } + } + + pos += 1.0; + } + + pos -= speedRatio; + *output++ = InterpolatorTraits::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos), indexBuffer); + } + } + + subSamplePos = pos; + + if (wrap == 0) + return (int) (input - originalIn); + + return ((int) (input - originalIn) + wrap) % wrap; + } + + int interpolateAdding (double speedRatio, + const float* input, + float* output, + int numOutputSamplesToProduce, + int numInputSamplesAvailable, + int wrap, + float gain) noexcept + { + auto originalIn = input; + auto pos = subSamplePos; + bool exceeded = false; + + if (speedRatio < 1.0) + { + for (int i = numOutputSamplesToProduce; --i >= 0;) + { + if (pos >= 1.0) + { + if (exceeded) + { + pushInterpolationSample (0.0); + } + else + { + pushInterpolationSample (*input++); + + if (--numInputSamplesAvailable <= 0) + { + if (wrap > 0) + { + input -= wrap; + numInputSamplesAvailable += wrap; + } + else + { + numInputSamplesAvailable = true; + } + } + } + + pos -= 1.0; + } + + *output++ += gain * InterpolatorTraits::valueAtOffset ((float) pos); + pos += speedRatio; + } + } + else + { + for (int i = numOutputSamplesToProduce; --i >= 0;) + { + while (pos < speedRatio) + { + if (exceeded) + { + pushInterpolationSample (0.0); + } + else + { + pushInterpolationSample (*input++); + + if (--numInputSamplesAvailable <= 0) + { + if (wrap > 0) + { + input -= wrap; + numInputSamplesAvailable += wrap; + } + else + { + exceeded = true; + } + } + } + + pos += 1.0; + } + + pos -= speedRatio; + *output++ += gain * InterpolatorTraits::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos), indexBuffer); + } + } + + subSamplePos = pos; + + if (wrap == 0) + return (int) (input - originalIn); + + return ((int) (input - originalIn) + wrap) % wrap; + } + + int interpolateAdding (double speedRatio, + const float* input, + float* output, + int numOutputSamplesToProduce, + float gain) noexcept + { + auto pos = subSamplePos; + int numUsed = 0; + + while (numOutputSamplesToProduce > 0) + { + while (pos >= 1.0) + { + pushInterpolationSample (input[numUsed++]); + pos -= 1.0; + } + + *output++ += gain * InterpolatorTraits::valueAtOffset (lastInputSamples, (float) pos, indexBuffer); + pos += speedRatio; + --numOutputSamplesToProduce; + } + + subSamplePos = pos; + return numUsed; + } + + //============================================================================== + float lastInputSamples[(size_t) memorySize]; + double subSamplePos = 1.0; + int indexBuffer = 0; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GenericInterpolator) +}; + +} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_Interpolators.cpp b/modules/juce_audio_basics/utilities/juce_Interpolators.cpp new file mode 100644 index 0000000000..37a39261ff --- /dev/null +++ b/modules/juce_audio_basics/utilities/juce_Interpolators.cpp @@ -0,0 +1,184 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +#if JUCE_UNIT_TESTS + +class InterpolatorTests : public UnitTest +{ +public: + InterpolatorTests() + : UnitTest ("InterpolatorTests", UnitTestCategories::audio) + { + } + +private: + template + void runInterplatorTests (const String& interpolatorName) + { + auto createGaussian = [](std::vector& destination, float scale, float centreInSamples, float width) + { + for (size_t i = 0; i < destination.size(); ++i) + { + auto x = (((float) i) - centreInSamples) * width; + destination[i] = std::exp (-(x * x)); + } + + FloatVectorOperations::multiply (destination.data(), scale, (int) destination.size()); + }; + + auto findGaussianPeak = [](const std::vector& input) -> float + { + auto max = std::max_element (std::begin (input), std::end (input)); + auto maxPrev = max - 1; + jassert (maxPrev >= std::begin (input)); + auto maxNext = max + 1; + jassert (maxNext < std::end (input)); + auto quadraticMaxLoc = (*maxPrev - *maxNext) / (2.0f * ((*maxNext + *maxPrev) - (2.0f * *max))); + return quadraticMaxLoc + (float) std::distance (std::begin (input), max); + }; + + auto expectAllElementsWithin = [this](const std::vector& v1, const std::vector& v2, float tolerance) + { + expectEquals ((int) v1.size(), (int) v2.size()); + + for (size_t i = 0; i < v1.size(); ++i) + expectWithinAbsoluteError (v1[i], v2[i], tolerance); + }; + + InterpolatorType interpolator; + + constexpr size_t inputSize = 1001; + static_assert (inputSize > 800 + InterpolatorType::getBaseLatency(), + "The test InterpolatorTests input buffer is too small"); + + std::vector input (inputSize); + constexpr auto inputGaussianMidpoint = (float) (inputSize - 1) / 2.0f; + constexpr auto inputGaussianValueAtEnds = 0.000001f; + const auto inputGaussianWidth = std::sqrt (-std::log (inputGaussianValueAtEnds)) / inputGaussianMidpoint; + + createGaussian (input, 1.0f, inputGaussianMidpoint, inputGaussianWidth); + + for (auto speedRatio : { 0.4, 0.8263, 1.0, 1.05, 1.2384, 1.6 }) + { + const auto expectedGaussianMidpoint = (inputGaussianMidpoint + InterpolatorType::getBaseLatency()) / (float) speedRatio; + const auto expectedGaussianWidth = inputGaussianWidth * (float) speedRatio; + + const auto outputBufferSize = (size_t) std::floor ((float) input.size() / speedRatio); + + for (int numBlocks : { 1, 5 }) + { + const auto inputBlockSize = (float) input.size() / (float) numBlocks; + const auto outputBlockSize = (int) std::floor (inputBlockSize / speedRatio); + + std::vector output (outputBufferSize, std::numeric_limits::min()); + + beginTest (interpolatorName + " process " + String (numBlocks) + " blocks ratio " + String (speedRatio)); + + interpolator.reset(); + + { + auto* inputPtr = input.data(); + auto* outputPtr = output.data(); + + for (int i = 0; i < numBlocks; ++i) + { + auto numInputSamplesRead = interpolator.process (speedRatio, inputPtr, outputPtr, outputBlockSize); + inputPtr += numInputSamplesRead; + outputPtr += outputBlockSize; + } + } + + expectWithinAbsoluteError (findGaussianPeak (output), expectedGaussianMidpoint, 0.1f); + + std::vector expectedOutput (output.size()); + createGaussian (expectedOutput, 1.0f, expectedGaussianMidpoint, expectedGaussianWidth); + + expectAllElementsWithin (output, expectedOutput, 0.02f); + + beginTest (interpolatorName + " process adding " + String (numBlocks) + " blocks ratio " + String (speedRatio)); + + interpolator.reset(); + + constexpr float addingGain = 0.7384f; + + { + auto* inputPtr = input.data(); + auto* outputPtr = output.data(); + + for (int i = 0; i < numBlocks; ++i) + { + auto numInputSamplesRead = interpolator.processAdding (speedRatio, inputPtr, outputPtr, outputBlockSize, addingGain); + inputPtr += numInputSamplesRead; + outputPtr += outputBlockSize; + } + } + + expectWithinAbsoluteError (findGaussianPeak (output), expectedGaussianMidpoint, 0.1f); + + std::vector additionalOutput (output.size()); + createGaussian (additionalOutput, addingGain, expectedGaussianMidpoint, expectedGaussianWidth); + FloatVectorOperations::add (expectedOutput.data(), additionalOutput.data(), (int) additionalOutput.size()); + + expectAllElementsWithin (output, expectedOutput, 0.02f); + } + + beginTest (interpolatorName + " process wrap 0 ratio " + String (speedRatio)); + + std::vector doubleLengthOutput (2 * outputBufferSize, std::numeric_limits::min()); + + interpolator.reset(); + interpolator.process (speedRatio, input.data(), doubleLengthOutput.data(), (int) doubleLengthOutput.size(), + (int) input.size(), 0); + + std::vector expectedDoubleLengthOutput (doubleLengthOutput.size()); + createGaussian (expectedDoubleLengthOutput, 1.0f, expectedGaussianMidpoint, expectedGaussianWidth); + + expectAllElementsWithin (doubleLengthOutput, expectedDoubleLengthOutput, 0.02f); + + beginTest (interpolatorName + " process wrap double ratio " + String (speedRatio)); + + interpolator.reset(); + interpolator.process (speedRatio, input.data(), doubleLengthOutput.data(), (int) doubleLengthOutput.size(), + (int) input.size(), (int) input.size()); + + std::vector secondGaussian (doubleLengthOutput.size()); + createGaussian (secondGaussian, 1.0f, expectedGaussianMidpoint + outputBufferSize, expectedGaussianWidth); + FloatVectorOperations::add (expectedDoubleLengthOutput.data(), secondGaussian.data(), (int) expectedDoubleLengthOutput.size()); + + expectAllElementsWithin (doubleLengthOutput, expectedDoubleLengthOutput, 0.02f); + } + } + +public: + void runTest() override + { + runInterplatorTests ("WindowedSincInterpolator"); + runInterplatorTests ("LagrangeInterpolator"); + runInterplatorTests ("CatmullRomInterpolator"); + runInterplatorTests ("LinearInterpolator"); + } +}; + +static InterpolatorTests interpolatorTests; + +#endif + +} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_Interpolators.h b/modules/juce_audio_basics/utilities/juce_Interpolators.h new file mode 100644 index 0000000000..c30d92b7cb --- /dev/null +++ b/modules/juce_audio_basics/utilities/juce_Interpolators.h @@ -0,0 +1,228 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +class Interpolators +{ +private: + struct WindowedSincTraits + { + static constexpr float algorithmicLatency = 100.0f; + + static forcedinline float windowedSinc (float firstFrac, int index) noexcept + { + auto index2 = index + 1; + auto frac = firstFrac; + + auto value1 = lookupTable[index]; + auto value2 = lookupTable[index2]; + + return value1 + (frac * (value2 - value1)); + } + + static forcedinline float valueAtOffset (const float* const inputs, const float offset, int indexBuffer) noexcept + { + int numCrossings = 100; + float result = 0.0f; + + auto samplePosition = indexBuffer; + float firstFrac = 0.0f; + float lastSincPosition = -1.0f; + int index = 0, sign = -1; + + for (int i = -numCrossings; i <= numCrossings; ++i) + { + auto sincPosition = (1.0f - offset) + (float) i; + + if (i == -numCrossings || (sincPosition >= 0 && lastSincPosition < 0)) + { + auto indexFloat = (sincPosition >= 0.f ? sincPosition : -sincPosition) * 100.0f; + index = (int) std::floor (indexFloat); + firstFrac = indexFloat - index; + sign = (sincPosition < 0 ? -1 : 1); + } + + if (sincPosition == 0.0f) + result += inputs[samplePosition]; + else if (sincPosition < numCrossings && sincPosition > -numCrossings) + result += inputs[samplePosition] * windowedSinc (firstFrac, index); + + if (++samplePosition == numCrossings * 2) + samplePosition = 0; + + lastSincPosition = sincPosition; + index += 100 * sign; + } + + return result; + } + + static const float lookupTable[10001]; + }; + + struct LagrangeTraits + { + static constexpr float algorithmicLatency = 2.0f; + + static float valueAtOffset (const float*, float, int) noexcept; + }; + + struct CatmullRomTraits + { + //============================================================================== + static constexpr float algorithmicLatency = 2.0f; + + static forcedinline float valueAtOffset (const float* const inputs, const float offset, int index) noexcept + { + auto y0 = inputs[index]; if (++index == 4) index = 0; + auto y1 = inputs[index]; if (++index == 4) index = 0; + auto y2 = inputs[index]; if (++index == 4) index = 0; + auto y3 = inputs[index]; + + auto halfY0 = 0.5f * y0; + auto halfY3 = 0.5f * y3; + + return y1 + offset * ((0.5f * y2 - halfY0) + + (offset * (((y0 + 2.0f * y2) - (halfY3 + 2.5f * y1)) + + (offset * ((halfY3 + 1.5f * y1) - (halfY0 + 1.5f * y2)))))); + } + }; + + struct LinearTraits + { + static constexpr float algorithmicLatency = 1.0f; + + static forcedinline float valueAtOffset (const float* const inputs, const float offset, int index) noexcept + { + auto y0 = inputs[index]; + auto y1 = inputs[index == 0 ? 1 : 0]; + + return y1 * offset + y0 * (1.0f - offset); + } + }; + + struct ZeroOrderHoldTraits + { + static constexpr float algorithmicLatency = 0.0f; + + static forcedinline float valueAtOffset (const float* const inputs, const float, int) noexcept + { + return inputs[0]; + } + }; + +public: + using WindowedSinc = GenericInterpolator; + using Lagrange = GenericInterpolator; + using CatmullRom = GenericInterpolator; + using Linear = GenericInterpolator; + using ZeroOrderHold = GenericInterpolator; +}; + +//============================================================================== +/** + An interpolator for resampling a stream of floats using high order windowed + (hann) sinc interpolation, recommended for high quality resampling. + + Note that the resampler is stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own LinearInterpolator object. + + @see GenericInterpolator + + @see LagrangeInterpolator, CatmullRomInterpolator, LinearInterpolator, + ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +using WindowedSincInterpolator = Interpolators::WindowedSinc; + +/** + An interpolator for resampling a stream of floats using 4-point lagrange interpolation. + + Note that the resampler is stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own LagrangeInterpolator object. + + @see GenericInterpolator + + @see CatmullRomInterpolator, WindowedSincInterpolator, LinearInterpolator, + ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +using LagrangeInterpolator = Interpolators::Lagrange; + +/** + An interpolator for resampling a stream of floats using Catmull-Rom interpolation. + + Note that the resampler is stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own CatmullRomInterpolator object. + + @see GenericInterpolator + + @see LagrangeInterpolator, WindowedSincInterpolator, LinearInterpolator, + ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +using CatmullRomInterpolator = Interpolators::CatmullRom; + +/** + An interpolator for resampling a stream of floats using linear interpolation. + + Note that the resampler is stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own LinearInterpolator object. + + @see GenericInterpolator + + @see LagrangeInterpolator, CatmullRomInterpolator, WindowedSincInterpolator, + ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +using LinearInterpolator = Interpolators::Linear; + +/** + An interpolator for resampling a stream of floats using zero order hold + interpolation. + + Note that the resampler is stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own ZeroOrderHoldInterpolator + object. + + @see GenericInterpolator + + @see LagrangeInterpolator, CatmullRomInterpolator, WindowedSincInterpolator, + LinearInterpolator + + @tags{Audio} +*/ +using ZeroOrderHoldInterpolator = Interpolators::ZeroOrderHold; + +} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp b/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp index d0026d15bd..0fd5ce840e 100644 --- a/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp +++ b/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp @@ -23,381 +23,6 @@ namespace juce { -namespace -{ - static forcedinline void pushInterpolationSample (float* lastInputSamples, float newValue) noexcept - { - lastInputSamples[4] = lastInputSamples[3]; - lastInputSamples[3] = lastInputSamples[2]; - lastInputSamples[2] = lastInputSamples[1]; - lastInputSamples[1] = lastInputSamples[0]; - lastInputSamples[0] = newValue; - } - - static forcedinline void pushInterpolationSamples (float* lastInputSamples, const float* input, int numOut) noexcept - { - if (numOut >= 5) - { - for (int i = 0; i < 5; ++i) - lastInputSamples[i] = input[--numOut]; - } - else - { - for (int i = 0; i < numOut; ++i) - pushInterpolationSample (lastInputSamples, input[i]); - } - } - - static forcedinline void pushInterpolationSamples (float* lastInputSamples, const float* input, - int numOut, int available, int wrapAround) noexcept - { - if (numOut >= 5) - { - if (available >= 5) - { - for (int i = 0; i < 5; ++i) - lastInputSamples[i] = input[--numOut]; - } - else - { - for (int i = 0; i < available; ++i) - lastInputSamples[i] = input[--numOut]; - - if (wrapAround > 0) - { - numOut -= wrapAround; - - for (int i = available; i < 5; ++i) - lastInputSamples[i] = input[--numOut]; - } - else - { - for (int i = available; i < 5; ++i) - lastInputSamples[i] = 0.0f; - } - } - } - else - { - if (numOut > available) - { - for (int i = 0; i < available; ++i) - pushInterpolationSample (lastInputSamples, input[i]); - - if (wrapAround > 0) - { - for (int i = 0; i < numOut - available; ++i) - pushInterpolationSample (lastInputSamples, input[i + available - wrapAround]); - } - else - { - for (int i = 0; i < numOut - available; ++i) - pushInterpolationSample (lastInputSamples, 0); - } - } - else - { - for (int i = 0; i < numOut; ++i) - pushInterpolationSample (lastInputSamples, input[i]); - } - } - } - - template - static int interpolate (float* lastInputSamples, double& subSamplePos, double actualRatio, - const float* in, float* out, int numOut) noexcept - { - auto pos = subSamplePos; - - if (actualRatio == 1.0 && pos == 1.0) - { - memcpy (out, in, (size_t) numOut * sizeof (float)); - pushInterpolationSamples (lastInputSamples, in, numOut); - return numOut; - } - - int numUsed = 0; - - while (numOut > 0) - { - while (pos >= 1.0) - { - pushInterpolationSample (lastInputSamples, in[numUsed++]); - pos -= 1.0; - } - - *out++ = InterpolatorType::valueAtOffset (lastInputSamples, (float) pos); - pos += actualRatio; - --numOut; - } - - subSamplePos = pos; - return numUsed; - } - - template - static int interpolate (float* lastInputSamples, double& subSamplePos, double actualRatio, - const float* in, float* out, int numOut, int available, int wrap) noexcept - { - if (actualRatio == 1.0) - { - if (available >= numOut) - { - memcpy (out, in, (size_t) numOut * sizeof (float)); - pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap); - } - else - { - memcpy (out, in, (size_t) available * sizeof (float)); - pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap); - - if (wrap > 0) - { - memcpy (out + available, in + available - wrap, (size_t) (numOut - available) * sizeof (float)); - pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap); - } - else - { - for (int i = 0; i < numOut - available; ++i) - pushInterpolationSample (lastInputSamples, 0); - } - } - - return numOut; - } - - auto originalIn = in; - auto pos = subSamplePos; - bool exceeded = false; - - if (actualRatio < 1.0) - { - for (int i = numOut; --i >= 0;) - { - if (pos >= 1.0) - { - if (exceeded) - { - pushInterpolationSample (lastInputSamples, 0); - } - else - { - pushInterpolationSample (lastInputSamples, *in++); - - if (--available <= 0) - { - if (wrap > 0) - { - in -= wrap; - available += wrap; - } - else - { - exceeded = true; - } - } - } - - pos -= 1.0; - } - - *out++ = InterpolatorType::valueAtOffset (lastInputSamples, (float) pos); - pos += actualRatio; - } - } - else - { - for (int i = numOut; --i >= 0;) - { - while (pos < actualRatio) - { - if (exceeded) - { - pushInterpolationSample (lastInputSamples, 0); - } - else - { - pushInterpolationSample (lastInputSamples, *in++); - - if (--available <= 0) - { - if (wrap > 0) - { - in -= wrap; - available += wrap; - } - else - { - exceeded = true; - } - } - } - - pos += 1.0; - } - - pos -= actualRatio; - *out++ = InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos)); - } - } - - subSamplePos = pos; - - if (wrap == 0) - return (int) (in - originalIn); - - return ((int) (in - originalIn) + wrap) % wrap; - } - - template - static int interpolateAdding (float* lastInputSamples, double& subSamplePos, double actualRatio, - const float* in, float* out, int numOut, - int available, int wrap, float gain) noexcept - { - if (actualRatio == 1.0) - { - if (available >= numOut) - { - FloatVectorOperations::addWithMultiply (out, in, gain, numOut); - pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap); - } - else - { - FloatVectorOperations::addWithMultiply (out, in, gain, available); - pushInterpolationSamples (lastInputSamples, in, available, available, wrap); - - if (wrap > 0) - { - FloatVectorOperations::addWithMultiply (out, in - wrap, gain, numOut - available); - pushInterpolationSamples (lastInputSamples, in - wrap, numOut - available, available, wrap); - } - else - { - for (int i = 0; i < numOut-available; ++i) - pushInterpolationSample (lastInputSamples, 0.0); - } - } - - return numOut; - } - - auto originalIn = in; - auto pos = subSamplePos; - bool exceeded = false; - - if (actualRatio < 1.0) - { - for (int i = numOut; --i >= 0;) - { - if (pos >= 1.0) - { - if (exceeded) - { - pushInterpolationSample (lastInputSamples, 0.0); - } - else - { - pushInterpolationSample (lastInputSamples, *in++); - - if (--available <= 0) - { - if (wrap > 0) - { - in -= wrap; - available += wrap; - } - else - { - exceeded = true; - } - } - } - - pos -= 1.0; - } - - *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (float) pos); - pos += actualRatio; - } - } - else - { - for (int i = numOut; --i >= 0;) - { - while (pos < actualRatio) - { - if (exceeded) - { - pushInterpolationSample (lastInputSamples, 0.0); - } - else - { - pushInterpolationSample (lastInputSamples, *in++); - - if (--available <= 0) - { - if (wrap > 0) - { - in -= wrap; - available += wrap; - } - else - { - exceeded = true; - } - } - } - - pos += 1.0; - } - - pos -= actualRatio; - *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos)); - } - } - - subSamplePos = pos; - - if (wrap == 0) - return (int) (in - originalIn); - - return ((int) (in - originalIn) + wrap) % wrap; - } - - template - static int interpolateAdding (float* lastInputSamples, double& subSamplePos, double actualRatio, - const float* in, float* out, int numOut, float gain) noexcept - { - auto pos = subSamplePos; - - if (actualRatio == 1.0 && pos == 1.0) - { - FloatVectorOperations::addWithMultiply (out, in, gain, numOut); - pushInterpolationSamples (lastInputSamples, in, numOut); - return numOut; - } - - int numUsed = 0; - - while (numOut > 0) - { - while (pos >= 1.0) - { - pushInterpolationSample (lastInputSamples, in[numUsed++]); - pos -= 1.0; - } - - *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (float) pos); - pos += actualRatio; - --numOut; - } - - subSamplePos = pos; - return numUsed; - } -} - -//============================================================================== template struct LagrangeResampleHelper { @@ -410,58 +35,28 @@ struct LagrangeResampleHelper<0> static forcedinline void calc (float&, float) noexcept {} }; -struct LagrangeAlgorithm -{ - static forcedinline float valueAtOffset (const float* inputs, float offset) noexcept - { - return calcCoefficient<0> (inputs[4], offset) - + calcCoefficient<1> (inputs[3], offset) - + calcCoefficient<2> (inputs[2], offset) - + calcCoefficient<3> (inputs[1], offset) - + calcCoefficient<4> (inputs[0], offset); - } - - template - static forcedinline float calcCoefficient (float input, float offset) noexcept - { - LagrangeResampleHelper<0 - k>::calc (input, -2.0f - offset); - LagrangeResampleHelper<1 - k>::calc (input, -1.0f - offset); - LagrangeResampleHelper<2 - k>::calc (input, 0.0f - offset); - LagrangeResampleHelper<3 - k>::calc (input, 1.0f - offset); - LagrangeResampleHelper<4 - k>::calc (input, 2.0f - offset); - return input; - } -}; - -LagrangeInterpolator::LagrangeInterpolator() noexcept { reset(); } -LagrangeInterpolator::~LagrangeInterpolator() noexcept {} - -void LagrangeInterpolator::reset() noexcept -{ - subSamplePos = 1.0; - - for (auto& s : lastInputSamples) - s = 0; -} - -int LagrangeInterpolator::process (double actualRatio, const float* in, float* out, int numOut, int available, int wrap) noexcept -{ - return interpolate (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, available, wrap); +template +static float calcCoefficient (float input, float offset) noexcept +{ + LagrangeResampleHelper<0 - k>::calc (input, -2.0f - offset); + LagrangeResampleHelper<1 - k>::calc (input, -1.0f - offset); + LagrangeResampleHelper<2 - k>::calc (input, 0.0f - offset); + LagrangeResampleHelper<3 - k>::calc (input, 1.0f - offset); + LagrangeResampleHelper<4 - k>::calc (input, 2.0f - offset); + return input; } -int LagrangeInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept +float Interpolators::LagrangeTraits::valueAtOffset (const float* inputs, float offset, int index) noexcept { - return interpolate (lastInputSamples, subSamplePos, actualRatio, in, out, numOut); -} + float result = 0.0f; -int LagrangeInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, int available, int wrap, float gain) noexcept -{ - return interpolateAdding (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, available, wrap, gain); -} + result += calcCoefficient<0> (inputs[index], offset); if (++index == 5) index = 0; + result += calcCoefficient<1> (inputs[index], offset); if (++index == 5) index = 0; + result += calcCoefficient<2> (inputs[index], offset); if (++index == 5) index = 0; + result += calcCoefficient<3> (inputs[index], offset); if (++index == 5) index = 0; + result += calcCoefficient<4> (inputs[index], offset); -int LagrangeInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, float gain) noexcept -{ - return interpolateAdding (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain); + return result; } } // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h b/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h deleted file mode 100644 index 6bff03e0ef..0000000000 --- a/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2020 - Raw Material Software Limited - - JUCE is an open source library subject to commercial or open-source - licensing. - - The code included in this file is provided under the terms of the ISC license - http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or - without fee is hereby granted provided that the above copyright notice and - this permission notice appear in all copies. - - JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER - EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE - DISCLAIMED. - - ============================================================================== -*/ - -namespace juce -{ - -/** - Interpolator for resampling a stream of floats using 4-point lagrange interpolation. - - Note that the resampler is stateful, so when there's a break in the continuity - of the input stream you're feeding it, you should call reset() before feeding - it any new data. And like with any other stateful filter, if you're resampling - multiple channels, make sure each one uses its own LagrangeInterpolator - object. - - @see CatmullRomInterpolator - - @tags{Audio} -*/ -class JUCE_API LagrangeInterpolator -{ -public: - LagrangeInterpolator() noexcept; - ~LagrangeInterpolator() noexcept; - - LagrangeInterpolator (LagrangeInterpolator&&) noexcept = default; - LagrangeInterpolator& operator= (LagrangeInterpolator&&) noexcept = default; - - /** Resets the state of the interpolator. - Call this when there's a break in the continuity of the input data stream. - */ - void reset() noexcept; - - /** Resamples a stream of samples. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results into - @param numOutputSamplesToProduce the number of output samples that should be created - - @returns the actual number of input samples that were used - */ - int process (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce) noexcept; - - /** Resamples a stream of samples. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results into - @param numOutputSamplesToProduce the number of output samples that should be created - @param available the number of available input samples. If it needs more samples - than available, it either wraps back for wrapAround samples, or - it feeds zeroes - @param wrapAround if the stream exceeds available samples, it wraps back for - wrapAround samples. If wrapAround is set to 0, it will feed zeroes. - - @returns the actual number of input samples that were used - */ - int process (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - int available, - int wrapAround) noexcept; - - /** Resamples a stream of samples, adding the results to the output data - with a gain. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results to - the result values will be added - to any pre-existing data in this buffer after being multiplied by - the gain factor - @param numOutputSamplesToProduce the number of output samples that should be created - @param gain a gain factor to multiply the resulting samples by before - adding them to the destination buffer - - @returns the actual number of input samples that were used - */ - int processAdding (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - float gain) noexcept; - - /** Resamples a stream of samples, adding the results to the output data - with a gain. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results to - the result values will be added - to any pre-existing data in this buffer after being multiplied by - the gain factor - @param numOutputSamplesToProduce the number of output samples that should be created - @param available the number of available input samples. If it needs more samples - than available, it either wraps back for wrapAround samples, or - it feeds zeroes - @param wrapAround if the stream exceeds available samples, it wraps back for - wrapAround samples. If wrapAround is set to 0, it will feed zeroes. - @param gain a gain factor to multiply the resulting samples by before - adding them to the destination buffer - - @returns the actual number of input samples that were used - */ - int processAdding (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - int available, - int wrapAround, - float gain) noexcept; - -private: - float lastInputSamples[5]; - double subSamplePos; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LagrangeInterpolator) -}; - -} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp b/modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp new file mode 100644 index 0000000000..94950233b5 --- /dev/null +++ b/modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp @@ -0,0 +1,10026 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +const float Interpolators::WindowedSincTraits::lookupTable[] { + 1.000000000000000000e+00f, + 9.998321499902942389e-01f, + 9.993287014045605376e-01f, + 9.984899584999463729e-01f, + 9.973164281284172539e-01f, + 9.958088193720359138e-01f, + 9.939680430327538785e-01f, + 9.917952109771142055e-01f, + 9.892916353363806481e-01f, + 9.864588275627174108e-01f, + 9.832984973421626806e-01f, + 9.798125513652424790e-01f, + 9.760030919561943907e-01f, + 9.718724155618675420e-01f, + 9.674230111014888722e-01f, + 9.626575581785837832e-01f, + 9.575789251564525983e-01f, + 9.521901670987075184e-01f, + 9.464945235764864462e-01f, + 9.404954163440536474e-01f, + 9.341964468846075675e-01f, + 9.276013938282199334e-01f, + 9.207142102439148657e-01f, + 9.135390208080165220e-01f, + 9.060801188509671755e-01f, + 8.983419632849326542e-01f, + 8.903291754145852277e-01f, + 8.820465356335611684e-01f, + 8.734989800091675916e-01f, + 8.646915967580026674e-01f, + 8.556296226152392270e-01f, + 8.463184391004026086e-01f, + 8.367635686825474206e-01f, + 8.269706708478274937e-01f, + 8.169455380725142435e-01f, + 8.066940917045994919e-01f, + 7.962223777571848515e-01f, + 7.855365626169290572e-01f, + 7.746429286708844675e-01f, + 7.635478698551215748e-01f, + 7.522578871285925395e-01f, + 7.407795838757467166e-01f, + 7.291196612414603262e-01f, + 7.172849134018910444e-01f, + 7.052822227749226958e-01f, + 6.931185551739007522e-01f, + 6.808009549084045320e-01f, + 6.683365398358420695e-01f, + 6.557324963676841589e-01f, + 6.429960744341879364e-01f, + 6.301345824114912286e-01f, + 6.171553820149802139e-01f, + 6.040658831628585856e-01f, + 5.908735388138642852e-01f, + 5.775858397830959667e-01f, + 5.642103095399239043e-01f, + 5.507544989919713752e-01f, + 5.372259812591544392e-01f, + 5.236323464417774742e-01f, + 5.099811963866732745e-01f, + 4.962801394553849055e-01f, + 4.825367852983662442e-01f, + 4.687587396391774686e-01f, + 4.549535990726381041e-01f, + 4.411289458808779762e-01f, + 4.272923428712149252e-01f, + 4.134513282397586642e-01f, + 3.996134104646188456e-01f, + 3.857860632325655903e-01f, + 3.719767204029549301e-01f, + 3.581927710127054132e-01f, + 3.444415543260631041e-01f, + 3.307303549328605707e-01f, + 3.170663978989262666e-01f, + 3.034568439722529765e-01f, + 2.899087848484924179e-01f, + 2.764292384992768636e-01f, + 2.630251445668272403e-01f, + 2.497033598282397682e-01f, + 2.364706537327855851e-01f, + 2.233337040154965702e-01f, + 2.102990923902373910e-01f, + 1.973733003254070084e-01f, + 1.845627049053287227e-01f, + 1.718735747803255554e-01f, + 1.593120662083951089e-01f, + 1.468842191913231343e-01f, + 1.345959537079954305e-01f, + 1.224530660475812854e-01f, + 1.104612252451845633e-01f, + 9.862596962246501786e-02f, + 8.695270343564839854e-02f, + 7.544669363325365308e-02f, + 6.411306672577052335e-02f, + 5.295680576943356810e-02f, + 4.198274746613558234e-02f, + 3.119557938143482229e-02f, + 2.059983728250635790e-02f, + 1.019990259779169663e-02f, + 3.897210076277699062e-17f, + -9.995804885990083877e-03f, + -1.978360764887690526e-02f, + -2.935966712899029663e-02f, + -3.872040732740943125e-02f, + -4.786241918501666498e-02f, + -5.678246223045373131e-02f, + -6.547746609606562573e-02f, + -7.394453190101335505e-02f, + -8.218093350085642346e-02f, + -9.018411860300616645e-02f, + -9.795170974756001181e-02f, + -1.054815051531433207e-01f, + -1.127714794274846111e-01f, + -1.198197841425640842e-01f, + -1.266247482742862418e-01f, + -1.331848785067307750e-01f, + -1.394988594011491723e-01f, + -1.455655534299787057e-01f, + -1.513840008762573630e-01f, + -1.569534195989277237e-01f, + -1.622732046646232218e-01f, + -1.673429278466408709e-01f, + -1.721623369919041413e-01f, + -1.767313552568272883e-01f, + -1.810500802130950160e-01f, + -1.851187828244720002e-01f, + -1.889379062958614630e-01f, + -1.925080647959259983e-01f, + -1.958300420546892351e-01f, + -1.989047898376287982e-01f, + -2.017334262978687787e-01f, + -2.043172342081740200e-01f, + -2.066576590745419495e-01f, + -2.087563071332755593e-01f, + -2.106149432335147065e-01f, + -2.122354886072851110e-01f, + -2.136200185292154441e-01f, + -2.147707598681500851e-01f, + -2.156900885329726125e-01f, + -2.163805268150296168e-01f, + -2.168447406296239166e-01f, + -2.170855366591212532e-01f, + -2.171058594002854003e-01f, + -2.169087881185291500e-01f, + -2.164975337118347498e-01f, + -2.158754354871634251e-01f, + -2.150459578522372073e-01f, + -2.140126869256352149e-01f, + -2.127793270682061255e-01f, + -2.113496973388519218e-01f, + -2.097277278777923137e-01f, + -2.079174562204673671e-01f, + -2.059230235452841895e-01f, + -2.037486708584572426e-01f, + -2.013987351192330633e-01f, + -1.988776453088292318e-01f, + -1.961899184464536705e-01f, + -1.933401555558005303e-01f, + -1.903330375854543621e-01f, + -1.871733212866534823e-01f, + -1.838658350518955764e-01f, + -1.804154747178837448e-01f, + -1.768271993363320083e-01f, + -1.731060269161642517e-01f, + -1.692570301406509103e-01f, + -1.652853320630413847e-01f, + -1.611961017842489241e-01f, + -1.569945501161558454e-01f, + -1.526859252341015438e-01f, + -1.482755083221153625e-01f, + -1.437686092144501160e-01f, + -1.391705620369629026e-01f, + -1.344867208518796264e-01f, + -1.297224553094619426e-01f, + -1.248831463100814054e-01f, + -1.199741816801844635e-01f, + -1.150009518656041618e-01f, + -1.099688456456556773e-01f, + -1.048832458714182708e-01f, + -9.974952523157622208e-02f, + -9.457304204915860379e-02f, + -8.935913611247510435e-02f, + -8.411312454351556334e-02f, + -7.884029770702483120e-02f, + -7.354591516343182700e-02f, + -6.823520166875686466e-02f, + -6.291334322457314832e-02f, + -5.758548318104762115e-02f, + -5.225671839602590713e-02f, + -4.693209545307914371e-02f, + -4.161660694135679156e-02f, + -3.631518780004174690e-02f, + -3.103271173013015527e-02f, + -2.577398767619723877e-02f, + -2.054375638074063329e-02f, + -1.534668701362280202e-02f, + -1.018737387906320201e-02f, + -5.070333202553640312e-03f, + -3.894325756689964161e-17f, + 5.019274968688979509e-03f, + 9.983228159422152803e-03f, + 1.488768611509041877e-02f, + 1.972856824609843865e-02f, + 2.450188951836063458e-02f, + 2.920376304695326483e-02f, + 3.383040259369500535e-02f, + 3.837812496701634851e-02f, + 4.284335232256628045e-02f, + 4.722261436309905386e-02f, + 5.151255043626536828e-02f, + 5.570991152903332494e-02f, + 5.981156215754928479e-02f, + 6.381448215134405411e-02f, + 6.771576833088721603e-02f, + 7.151263607757946117e-02f, + 7.520242079537053925e-02f, + 7.878257926329076954e-02f, + 8.225069087826682168e-02f, + 8.560445878770081563e-02f, + 8.884171091137989251e-02f, + 9.196040085238070538e-02f, + 9.495860869672850813e-02f, + 9.783454170166935859e-02f, + 1.005865348725034220e-01f, + 1.032130514280261008e-01f, + 1.057126831547209184e-01f, + 1.080841506499338051e-01f, + 1.103263034543625065e-01f, + 1.124381200742803483e-01f, + 1.144187078940081537e-01f, + 1.162673029792436336e-01f, + 1.179832697719408463e-01f, + 1.195661006775294716e-01f, + 1.210154155453490032e-01f, + 1.223309610432607719e-01f, + 1.235126099274892336e-01f, + 1.245603602088281303e-01f, + 1.254743342164319486e-01f, + 1.262547775604956901e-01f, + 1.269020579952085670e-01f, + 1.274166641834456049e-01f, + 1.277992043647412090e-01f, + 1.280504049281650791e-01f, + 1.281711088917953933e-01f, + 1.281622742905593748e-01f, + 1.280249724742810735e-01f, + 1.277603863178479460e-01f, + 1.273698083454741226e-01f, + 1.268546387711058931e-01f, + 1.262163834570771692e-01f, + 1.254566517931865743e-01f, + 1.245771544984256851e-01f, + 1.235797013476476885e-01f, + 1.224661988255190126e-01f, + 1.212386477101517479e-01f, + 1.198991405888646528e-01f, + 1.184498593085685503e-01f, + 1.168930723633207630e-01f, + 1.152311322216329759e-01f, + 1.134664725961638115e-01f, + 1.116016056584608895e-01f, + 1.096391192014578575e-01f, + 1.075816737524645378e-01f, + 1.054319996394198350e-01f, + 1.031928940132054995e-01f, + 1.008672178288464866e-01f, + 9.845789278844846448e-02f, + 9.596789824874003838e-02f, + 9.340026809611248759e-02f, + 9.075808759205977738e-02f, + 8.804449019193870407e-02f, + 8.526265433997994025e-02f, + 8.241580024348756084e-02f, + 7.950718662917011237e-02f, + 7.654010748455197799e-02f, + 7.351788878741070954e-02f, + 7.044388522618756643e-02f, + 6.732147691431115966e-02f, + 6.415406610136678567e-02f, + 6.094507388403559711e-02f, + 5.769793691971696753e-02f, + 5.441610414572558424e-02f, + 5.110303350694805208e-02f, + 4.776218869481312773e-02f, + 4.439703590041457065e-02f, + 4.101104058459904139e-02f, + 3.760766426780321608e-02f, + 3.419036134239462205e-02f, + 3.076257591024030361e-02f, + 2.732773864819467574e-02f, + 2.388926370415486722e-02f, + 2.045054562630352346e-02f, + 1.701495632810792399e-02f, + 1.358584209160797196e-02f, + 1.016652061148060233e-02f, + 6.760278082314462311e-03f, + 3.370366331490179130e-03f, + 3.889521720231377172e-17f, + -3.347646226505052690e-03f, + -6.669440334209695946e-03f, + -9.962295642995425485e-03f, + -1.322317341155379231e-02f, + -1.644908538369398501e-02f, + -1.963709627384800302e-02f, + -2.278432618984587571e-02f, + -2.588795299108807499e-02f, + -2.894521458031795724e-02f, + -3.195341112725825355e-02f, + -3.490990722244410177e-02f, + -3.781213395966125795e-02f, + -4.065759094545921132e-02f, + -4.344384823429099651e-02f, + -4.616854818789777049e-02f, + -4.882940725763235124e-02f, + -5.142421768849166769e-02f, + -5.395084914370364831e-02f, + -5.640725024878998073e-02f, + -5.879145005410169045e-02f, + -6.110155941490798270e-02f, + -6.333577228818905447e-02f, + -6.549236694536995917e-02f, + -6.756970710030717198e-02f, + -6.956624295191975171e-02f, + -7.148051214093797956e-02f, + -7.331114062032219325e-02f, + -7.505684343898266775e-02f, + -7.671642543851386886e-02f, + -7.828878186273431627e-02f, + -7.977289887990460238e-02f, + -8.116785401757553586e-02f, + -8.247281651009769066e-02f, + -8.368704755890117586e-02f, + -8.480990050573701533e-02f, + -8.584082091914502222e-02f, + -8.677934659449468291e-02f, + -8.762510746802033845e-02f, + -8.837782544534880658e-02f, + -8.903731414509374886e-02f, + -8.960347855816586105e-02f, + -9.007631462352130858e-02f, + -9.045590872114415981e-02f, + -9.074243708313121937e-02f, + -9.093616512381758055e-02f, + -9.103744668995188138e-02f, + -9.104672323199845818e-02f, + -9.096452289771120303e-02f, + -9.079145954918992067e-02f, + -9.052823170469484482e-02f, + -9.017562140655861758e-02f, + -8.973449301659575106e-02f, + -8.920579194047170701e-02f, + -8.859054328255137889e-02f, + -8.788985043280389542e-02f, + -8.710489358739707810e-02f, + -8.623692820466778708e-02f, + -8.528728339820713933e-02f, + -8.425736026884980689e-02f, + -8.314863017740434237e-02f, + -8.196263296000964871e-02f, + -8.070097508804566222e-02f, + -7.936532777456997700e-02f, + -7.795742502929374484e-02f, + -7.647906166414730755e-02f, + -7.493209125152387740e-02f, + -7.331842403732392877e-02f, + -7.164002481095702035e-02f, + -6.989891073448464831e-02f, + -6.809714913312167606e-02f, + -6.623685524933471680e-02f, + -6.432018996280304546e-02f, + -6.234935747852995286e-02f, + -6.032660298541026728e-02f, + -5.825421028757805930e-02f, + -5.613449941087523404e-02f, + -5.396982418679260179e-02f, + -5.176256981624846598e-02f, + -4.951515041557684460e-02f, + -4.723000654710355489e-02f, + -4.490960273669408059e-02f, + -4.255642498066016660e-02f, + -4.017297824440700660e-02f, + -3.776178395520819048e-02f, + -3.532537749148359496e-02f, + -3.286630567095341626e-02f, + -3.038712424003185350e-02f, + -2.789039536681189174e-02f, + -2.537868513997948439e-02f, + -2.285456107598123413e-02f, + -2.032058963675330288e-02f, + -1.777933376029512333e-02f, + -1.523335040635749593e-02f, + -1.268518811948355154e-02f, + -1.013738461162063884e-02f, + -7.592464366493653291e-03f, + -5.052936267896138492e-03f, + -2.521291254032028643e-03f, + -3.882802707905923401e-17f, + 2.508489369517248428e-03f, + 5.001753535334178304e-03f, + 7.477396204630696805e-03f, + 9.933050295659225093e-03f, + 1.236638008438947431e-02f, + 1.477508331123026167e-02f, + 1.715689324600980226e-02f, + 1.950958070945080572e-02f, + 2.183095604941610521e-02f, + 2.411887107025306037e-02f, + 2.637122091361803269e-02f, + 2.858594588921111249e-02f, + 3.076103325390444967e-02f, + 3.289451893780558772e-02f, + 3.498448921585006754e-02f, + 3.702908232357217388e-02f, + 3.902649001576798810e-02f, + 4.097495906681519057e-02f, + 4.287279271148002058e-02f, + 4.471835202509810703e-02f, + 4.651005724208144565e-02f, + 4.824638901176293154e-02f, + 4.992588959065285409e-02f, + 5.154716397024793756e-02f, + 5.310888093959532930e-02f, + 5.460977408187722010e-02f, + 5.604864270435185730e-02f, + 5.742435270104698924e-02f, + 5.873583734766929521e-02f, + 5.998209802826119652e-02f, + 6.116220489320042114e-02f, + 6.227529744820328728e-02f, + 6.332058507406373993e-02f, + 6.429734747692100738e-02f, + 6.520493506891764102e-02f, + 6.604276927917780704e-02f, + 6.681034279509827367e-02f, + 6.750721973401248299e-02f, + 6.813303574535393980e-02f, + 6.868749804350914034e-02f, + 6.917038537161544764e-02f, + 6.958154789662478190e-02f, + 6.992090703601620827e-02f, + 7.018845521660418973e-02f, + 7.038425556595274968e-02f, + 7.050844153696640693e-02f, + 7.056121646629046062e-02f, + 7.054285306721332083e-02f, + 7.045369285782319968e-02f, + 7.029414552522963988e-02f, + 7.006468822671796381e-02f, + 6.976586482876150075e-02f, + 6.939828508487122516e-02f, + 6.896262375331772831e-02f, + 6.845961965581227882e-02f, + 6.789007467828668541e-02f, + 6.725485271496202400e-02f, + 6.655487855694536270e-02f, + 6.579113672664134438e-02f, + 6.496467025931394745e-02f, + 6.407657943317585092e-02f, + 6.312802044942868174e-02f, + 6.212020406372047165e-02f, + 6.105439417052395401e-02f, + 5.993190634198172773e-02f, + 5.875410632280082118e-02f, + 5.752240848281407054e-02f, + 5.623827422886059496e-02f, + 5.490321037767217222e-02f, + 5.351876749147910922e-02f, + 5.208653817808057279e-02f, + 5.060815535715459945e-02f, + 4.908529049460156474e-02f, + 4.751965180674513900e-02f, + 4.591298243623419262e-02f, + 4.426705860150847993e-02f, + 4.258368772170978422e-02f, + 4.086470651893956557e-02f, + 3.911197909977250781e-02f, + 3.732739501795391546e-02f, + 3.551286732021802228e-02f, + 3.367033057717121886e-02f, + 3.180173890119344232e-02f, + 2.990906395331716441e-02f, + 2.799429294104273033e-02f, + 2.605942660905504957e-02f, + 2.410647722480178945e-02f, + 2.213746656089659454e-02f, + 2.015442387629913859e-02f, + 1.815938389822458268e-02f, + 1.615438480672493765e-02f, + 1.414146622387316317e-02f, + 1.212266720947206833e-02f, + 1.010002426519698848e-02f, + 8.075569349063350597e-03f, + 6.051327902095616530e-03f, + 4.029316889058113388e-03f, + 2.011542855081033601e-03f, + 3.874175350567572650e-17f, + -2.003331727797961342e-03f, + -3.996488516257723500e-03f, + -5.977524551525892349e-03f, + -7.944513855095518967e-03f, + -9.895552094544582400e-03f, + -1.182875836621732034e-02f, + -1.374227694822771975e-02f, + -1.563427902220560287e-02f, + -1.750296436223446397e-02f, + -1.934656298946970526e-02f, + -2.116333679096629727e-02f, + -2.295158110128149576e-02f, + -2.470962624546017145e-02f, + -2.643583904205206586e-02f, + -2.812862426485629452e-02f, + -2.978642606212655863e-02f, + -3.140772933202141265e-02f, + -3.299106105312992615e-02f, + -3.453499156894547506e-02f, + -3.603813582521487452e-02f, + -3.749915455913428036e-02f, + -3.891675543941802012e-02f, + -4.028969415631109691e-02f, + -4.161677546067264061e-02f, + -4.289685415130901208e-02f, + -4.412883600978426135e-02f, + -4.531167868199265092e-02f, + -4.644439250583275169e-02f, + -4.752604128436910269e-02f, + -4.855574300393437209e-02f, + -4.953267049666788130e-02f, + -5.045605204704892155e-02f, + -5.132517194203765898e-02f, + -5.213937096448940933e-02f, + -5.289804682956641274e-02f, + -5.360065456392785338e-02f, + -5.424670682753111178e-02f, + -5.483577417793748798e-02f, + -5.536748527706834150e-02f, + -5.584152704041558252e-02f, + -5.625764472876377403e-02f, + -5.661564198253816321e-02f, + -5.691538079894768037e-02f, + -5.715678145214542205e-02f, + -5.733982235668498573e-02f, + -5.746453987460405782e-02f, + -5.753102806651958639e-02f, + -5.753943838717312520e-02f, + -5.748997932591520116e-02f, + -5.738291599267093812e-02f, + -5.721856964997878298e-02f, + -5.699731719174516015e-02f, + -5.671959056940642507e-02f, + -5.638587616623912807e-02f, + -5.599671412060634040e-02f, + -5.555269759897443066e-02f, + -5.505447201958245385e-02f, + -5.450273422768755344e-02f, + -5.389823162335748846e-02f, + -5.324176124282154615e-02f, + -5.253416879443297688e-02f, + -5.177634765033799907e-02f, + -5.096923779498445384e-02f, + -5.011382473164045781e-02f, + -4.921113834813311411e-02f, + -4.826225174304939192e-02f, + -4.726828001367859577e-02f, + -4.623037900700535663e-02f, + -4.514974403509764561e-02f, + -4.402760855626140085e-02f, + -4.286524282336175162e-02f, + -4.166395250074144546e-02f, + -4.042507725118998224e-02f, + -3.914998929443946202e-02f, + -3.784009193869437848e-02f, + -3.649681808671064592e-02f, + -3.512162871797221836e-02f, + -3.371601134852347803e-02f, + -3.228147847003334792e-02f, + -3.081956596968622730e-02f, + -2.933183153250423780e-02f, + -2.781985302771665045e-02f, + -2.628522688080791453e-02f, + -2.472956643287790510e-02f, + -2.315450028896036058e-02f, + -2.156167065694567300e-02f, + -1.995273167876449386e-02f, + -1.832934775548567333e-02f, + -1.669319186798288307e-02f, + -1.504594389482788452e-02f, + -1.338928892906133400e-02f, + -1.172491559548742221e-02f, + -1.005451437013836664e-02f, + -8.379775903540833196e-03f, + -6.702389349412756978e-03f, + -5.024040700403363362e-03f, + -3.346411132483765802e-03f, + -1.671175359577019423e-03f, + -3.863648162376423474e-17f, + 1.665458043716377392e-03f, + 3.323553190096430274e-03f, + 4.972652767551836474e-03f, + 6.611138585273553490e-03f, + 8.237408484711907647e-03f, + 9.849877870182622078e-03f, + 1.144698121717139215e-02f, + 1.302717355693413029e-02f, + 1.458893193601275978e-02f, + 1.613075684932130729e-02f, + 1.765117364548211831e-02f, + 1.914873390312786527e-02f, + 2.062201677691140322e-02f, + 2.206963031200360678e-02f, + 2.349021272589388309e-02f, + 2.488243365633890924e-02f, + 2.624499537434637694e-02f, + 2.757663396111778922e-02f, + 2.887612044790845850e-02f, + 3.014226191780771530e-02f, + 3.137390256847804454e-02f, + 3.256992473493734719e-02f, + 3.372924987150486414e-02f, + 3.485083949207803955e-02f, + 3.593369606795079885e-02f, + 3.697686388242336919e-02f, + 3.797942984150279311e-02f, + 3.894052424003760504e-02f, + 3.985932148267041369e-02f, + 4.073504075904751942e-02f, + 4.156694667276145810e-02f, + 4.235434982355489736e-02f, + 4.309660734236082924e-02f, + 4.379312337879810030e-02f, + 4.444334954079259131e-02f, + 4.504678528604074556e-02f, + 4.560297826507851010e-02f, + 4.611152461576945721e-02f, + 4.657206920907153852e-02f, + 4.698430584599172510e-02f, + 4.734797740568404828e-02f, + 4.766287594469555827e-02f, + 4.792884274741274209e-02f, + 4.814576832780684268e-02f, + 4.831359238262550315e-02f, + 4.843230369622460174e-02f, + 4.850193999728014821e-02f, + 4.852258776766780329e-02f, + 4.849438200384208891e-02f, + 4.841750593109390294e-02f, + 4.829219067110925023e-02f, + 4.811871486329679509e-02f, + 4.789740424039561073e-02f, + 4.762863115891774468e-02f, + 4.731281408502291397e-02f, + 4.695041703646362502e-02f, + 4.654194898128217323e-02f, + 4.608796319397825969e-02f, + 4.558905656990844268e-02f, + 4.504586889871579902e-02f, + 4.445908209762516189e-02f, + 4.382941940547854798e-02f, + 4.315764453841920700e-02f, + 4.244456080816757376e-02f, + 4.169101020386845047e-02f, + 4.089787243851888271e-02f, + 4.006606396102018602e-02f, + 3.919653693492577279e-02f, + 3.829027818498920155e-02f, + 3.734830811264253092e-02f, + 3.637167958156230230e-02f, + 3.536147677450902915e-02f, + 3.431881402264831682e-02f, + 3.324483460858414924e-02f, + 3.214070954436337030e-02f, + 3.100763632572139938e-02f, + 2.984683766386852025e-02f, + 2.865956019612891231e-02f, + 2.744707317676135447e-02f, + 2.621066714931024125e-02f, + 2.495165260184606035e-02f, + 2.367135860646735895e-02f, + 2.237113144445156826e-02f, + 2.105233321844750261e-02f, + 1.971634045311482925e-02f, + 1.836454268561935055e-02f, + 1.699834104740382407e-02f, + 1.561914683865467043e-02f, + 1.422838009688787327e-02f, + 1.282746816108333576e-02f, + 1.141784423279322037e-02f, + 1.000094593564865818e-02f, + 8.578213874691159244e-03f, + 7.151090196945879447e-03f, + 5.721017154652988448e-03f, + 4.289435672562395829e-03f, + 2.857783920694851112e-03f, + 1.427495893958731022e-03f, + 3.851231532396259107e-17f, + -1.423282343340041833e-03f, + -2.840938099612009063e-03f, + -4.251563993045895384e-03f, + -5.653767874212517128e-03f, + -7.046170070757393038e-03f, + -8.427404721911885624e-03f, + -9.796121095514335672e-03f, + -1.115098488629330704e-02f, + -1.249067949418276348e-02f, + -1.381390728146736184e-02f, + -1.511939080757592098e-02f, + -1.640587404037048558e-02f, + -1.767212354279941791e-02f, + -1.891692963381457968e-02f, + -2.013910752248064540e-02f, + -2.133749841423027843e-02f, + -2.251097058825281272e-02f, + -2.365842044503514013e-02f, + -2.477877352310193029e-02f, + -2.587098548403953327e-02f, + -2.693404306491827341e-02f, + -2.796696499726556220e-02f, + -2.896880289177323695e-02f, + -2.993864208796185450e-02f, + -3.087560246806111269e-02f, + -3.177883923439979441e-02f, + -3.264754364963919769e-02f, + -3.348094373922329975e-02f, + -3.427830495545182432e-02f, + -3.503893080263100618e-02f, + -3.576216342278743660e-02f, + -3.644738414147634387e-02f, + -3.709401397325490235e-02f, + -3.770151408643012542e-02f, + -3.826938622673421719e-02f, + -3.879717309962135707e-02f, + -3.928445871091951203e-02f, + -3.973086866561512109e-02f, + -4.013607042458825630e-02f, + -4.049977351915948903e-02f, + -4.082172972334963124e-02f, + -4.110173318379706925e-02f, + -4.133962050731876392e-02f, + -4.153527080614199951e-02f, + -4.168860570087641604e-02f, + -4.179958928133744450e-02f, + -4.186822802537215615e-02f, + -4.189457067588118339e-02f, + -4.187870807626980357e-02f, + -4.182077296460211258e-02f, + -4.172093972677210633e-02f, + -4.157942410904505448e-02f, + -4.139648289036141487e-02f, + -4.117241351483449247e-02f, + -4.090755368491114791e-02f, + -4.060228091570139419e-02f, + -4.025701205102193148e-02f, + -3.987220274173181034e-02f, + -3.944834688697711200e-02f, + -3.898597603899465330e-02f, + -3.848565877215900932e-02f, + -3.794800001699184799e-02f, + -3.737364035988401112e-02f, + -3.676325530931268126e-02f, + -3.611755452936806637e-02f, + -3.543728104143289981e-02f, + -3.472321039488834166e-02f, + -3.397614980774645715e-02f, + -3.319693727813939621e-02f, + -3.238644066761971890e-02f, + -3.154555675725123631e-02f, + -3.067521027749671447e-02f, + -2.977635291292965100e-02f, + -2.884996228281870578e-02f, + -2.789704089865994302e-02f, + -2.691861509974309216e-02f, + -2.591573396786606143e-02f, + -2.488946822232386211e-02f, + -2.384090909631557051e-02f, + -2.277116719593108921e-02f, + -2.168137134289090454e-02f, + -2.057266740222485346e-02f, + -1.944621709609118537e-02f, + -1.830319680494362292e-02f, + -1.714479635726702186e-02f, + -1.597221780910678887e-02f, + -1.478667421462878662e-02f, + -1.358938838894852355e-02f, + -1.238159166447296011e-02f, + -1.116452264200503558e-02f, + -9.939425937859529617e-03f, + -8.707550928239674026e-03f, + -7.470150492127149849e-03f, + -6.228479753931915469e-03f, + -4.983794827149027815e-03f, + -3.737351560261789520e-03f, + -2.490404286130025371e-03f, + -1.244204576092051940e-03f, + -3.836937714341790683e-17f, + 1.240967106592762116e-03f, + 2.477460866896080867e-03f, + 3.708253077802783210e-03f, + 4.932124414085086068e-03f, + 6.147865620704987162e-03f, + 7.354278692082365058e-03f, + 8.550178037189383809e-03f, + 9.734391629351839964e-03f, + 1.090576213965407243e-02f, + 1.206314805286936957e-02f, + 1.320542476485127813e-02f, + 1.433148566034425815e-02f, + 1.544024317019840505e-02f, + 1.653062980698680531e-02f, + 1.760159917805776894e-02f, + 1.865212697506991868e-02f, + 1.968121193909236344e-02f, + 2.068787680036934112e-02f, + 2.167116919188432494e-02f, + 2.263016253588231996e-02f, + 2.356395690253657721e-02f, + 2.447167983997980412e-02f, + 2.535248717494724760e-02f, + 2.620556378330855113e-02f, + 2.703012432980111263e-02f, + 2.782541397630681687e-02f, + 2.859070905804561927e-02f, + 2.932531772709678214e-02f, + 3.002858056268817993e-02f, + 3.069987114772966194e-02f, + 3.133859661110379585e-02f, + 3.194419813525677804e-02f, + 3.251615142867379793e-02f, + 3.305396716285353975e-02f, + 3.355719137343705916e-02f, + 3.402540582517922518e-02f, + 3.445822834048845734e-02f, + 3.485531309129908523e-02f, + 3.521635085407364557e-02f, + 3.554106922777330868e-02f, + 3.582923281466892512e-02f, + 3.608064336390364585e-02f, + 3.629513987775428302e-02f, + 3.647259868057688842e-02f, + 3.661293345045708858e-02f, + 3.671609521362455969e-02f, + 3.678207230172601816e-02f, + 3.681089027208912096e-02f, + 3.680261179114461406e-02f, + 3.675733648121128072e-02f, + 3.667520073088332416e-02f, + 3.655637746929544379e-02f, + 3.640107590457612730e-02f, + 3.620954122683402165e-02f, + 3.598205427605740553e-02f, + 3.571893117533903733e-02f, + 3.542052292987402790e-02f, + 3.508721499220928547e-02f, + 3.471942679425710915e-02f, + 3.431761124661530937e-02f, + 3.388225420576965186e-02f, + 3.341387390978267646e-02f, + 3.291302038310394557e-02f, + 3.238027481116542705e-02f, + 3.181624888545521446e-02f, + 3.122158411978745787e-02f, + 3.059695113851780904e-02f, + 2.994304893747514948e-02f, + 2.926060411840791450e-02f, + 2.855037009776879506e-02f, + 2.781312629068145512e-02f, + 2.704967727096032129e-02f, + 2.626085190807075573e-02f, + 2.544750248194389483e-02f, + 2.461050377657450841e-02f, + 2.375075215335195958e-02f, + 2.286916460509363230e-02f, + 2.196667779176278423e-02f, + 2.104424705887289471e-02f, + 2.010284543959429265e-02f, + 1.914346264158977087e-02f, + 1.816710401962278246e-02f, + 1.717478953499241082e-02f, + 1.616755270285690979e-02f, + 1.514643952852146903e-02f, + 1.411250743377312315e-02f, + 1.306682417434898782e-02f, + 1.201046674963833320e-02f, + 1.094452030571538628e-02f, + 9.870077032812075643e-03f, + 8.788235058334580366e-03f, + 7.700097336538626325e-03f, + 6.606770535970839416e-03f, + 5.509363925787424780e-03f, + 4.408988262061687424e-03f, + 3.306754675183733866e-03f, + 2.203773559457802150e-03f, + 1.101153465996373331e-03f, + 3.820780814485725242e-17f, + -1.098585276486098786e-03f, + -2.193505935265162299e-03f, + -3.283671765059895803e-03f, + -4.367999845902193791e-03f, + -5.445415613796268477e-03f, + -6.514853914614496255e-03f, + -7.575260046206469533e-03f, + -8.625590787711353430e-03f, + -9.664815415077104843e-03f, + -1.069191670181151264e-02f, + -1.170589190400125879e-02f, + -1.270575372865473569e-02f, + -1.369053128444692319e-02f, + -1.465927101395613288e-02f, + -1.561103760651160084e-02f, + -1.654491489078413133e-02f, + -1.746000670628177626e-02f, + -1.835543775292705626e-02f, + -1.923035441792335376e-02f, + -2.008392557913836474e-02f, + -2.091534338425668146e-02f, + -2.172382400498286056e-02f, + -2.250860836560024739e-02f, + -2.326896284521650510e-02f, + -2.400417995305826127e-02f, + -2.471357897620288582e-02f, + -2.539650659916279848e-02f, + -2.605233749477112518e-02f, + -2.668047488584292248e-02f, + -2.728035107711810139e-02f, + -2.785142795702474916e-02f, + -2.839319746882786391e-02f, + -2.890518205076497357e-02f, + -2.938693504479734583e-02f, + -2.983804107364120342e-02f, + -3.025811638577266885e-02f, + -3.064680916813381298e-02f, + -3.100379982630099840e-02f, + -3.132880123190676103e-02f, + -3.162155893714221899e-02f, + -3.188185135619839294e-02f, + -3.210948991353843734e-02f, + -3.230431915892578026e-02f, + -3.246621684916723566e-02f, + -3.259509399656147777e-02f, + -3.269089488407847521e-02f, + -3.275359704732655475e-02f, + -3.278321122339819538e-02f, + -3.277978126671703824e-02f, + -3.274338403204220954e-02f, + -3.267412922481752885e-02f, + -3.257215921908560019e-02f, + -3.243764884321845982e-02f, + -3.227080513374773474e-02f, + -3.207186705760879664e-02f, + -3.184110520314317044e-02f, + -3.157882144023508447e-02f, + -3.128534854998637343e-02f, + -3.096104982436503894e-02f, + -3.060631863628960475e-02f, + -3.022157798064227172e-02f, + -2.980727998672943677e-02f, + -2.936390540273656549e-02f, + -2.889196305275088666e-02f, + -2.839198926695188710e-02f, + -2.786454728559313240e-02f, + -2.731022663742679185e-02f, + -2.672964249324305541e-02f, + -2.612343499522145479e-02f, + -2.549226856281475509e-02f, + -2.483683117590470071e-02f, + -2.415783363599420183e-02f, + -2.345600880621569531e-02f, + -2.273211083096061610e-02f, + -2.198691433594817182e-02f, + -2.122121360957183317e-02f, + -2.043582176638020914e-02f, + -1.963156989356096283e-02f, + -1.880930618131524887e-02f, + -1.796989503802343471e-02f, + -1.711421619111335238e-02f, + -1.624316377455840843e-02f, + -1.535764540394315113e-02f, + -1.445858124004167390e-02f, + -1.354690304186740787e-02f, + -1.262355321016035703e-02f, + -1.168948382228147259e-02f, + -1.074565565949768715e-02f, + -9.793037227638747358e-03f, + -8.832603772118776536e-03f, + -7.865336288311713595e-03f, + -6.892220528280442078e-03f, + -5.914246004853488010e-03f, + -4.932404994047567826e-03f, + -3.947691536835270382e-03f, + -2.961100441250685226e-03f, + -1.973626285828549223e-03f, + -9.862624253675238758e-04f, + -3.802776777737574016e-17f, + 9.841730514465974952e-04f, + 1.965272972826986615e-03f, + 2.942321165824257449e-03f, + 3.914345157906578068e-03f, + 4.880379562147291184e-03f, + 5.839467027964861424e-03f, + 6.790659181857343525e-03f, + 7.733017557214086520e-03f, + 8.665614512298646516e-03f, + 9.587534135515569239e-03f, + 1.049787313708307364e-02f, + 1.139574172625059875e-02f, + 1.228026447321984953e-02f, + 1.315058115493771343e-02f, + 1.400584758395503719e-02f, + 1.484523641955660424e-02f, + 1.566793796039387537e-02f, + 1.647316091786455577e-02f, + 1.726013316951060736e-02f, + 1.802810249172396087e-02f, + 1.877633727107054853e-02f, + 1.950412719356916028e-02f, + 2.021078391128274671e-02f, + 2.089564168560189075e-02f, + 2.155805800663082583e-02f, + 2.219741418810250791e-02f, + 2.281311593728354431e-02f, + 2.340459389934918671e-02f, + 2.397130417573897082e-02f, + 2.451272881602797882e-02f, + 2.502837628287757701e-02f, + 2.551778188965732330e-02f, + 2.598050821035589528e-02f, + 2.641614546142960138e-02f, + 2.682431185526281195e-02f, + 2.720465392494783932e-02f, + 2.755684682011533618e-02f, + 2.788059457358115292e-02f, + 2.817563033860144908e-02f, + 2.844171659655807607e-02f, + 2.867864533492812257e-02f, + 2.888623819541892568e-02f, + 2.906434659218049346e-02f, + 2.921285180003846058e-02f, + 2.933166501271905480e-02f, + 2.942072737106802074e-02f, + 2.948000996129596790e-02f, + 2.950951378331144459e-02f, + 2.950926968923310578e-02f, + 2.947933829220211049e-02f, + 2.941980984564465662e-02f, + 2.933080409316416587e-02f, + 2.921247008927130642e-02f, + 2.906498599118855983e-02f, + 2.888855882199470315e-02f, + 2.868342420540245102e-02f, + 2.844984607248968178e-02f, + 2.818811634073307634e-02f, + 2.789855456571845721e-02f, + 2.758150756593012731e-02f, + 2.723734902104646763e-02f, + 2.686647904419447314e-02f, + 2.646932372864202465e-02f, + 2.604633466943028636e-02f, + 2.559798846047255452e-02f, + 2.512478616767030437e-02f, + 2.462725277861903608e-02f, + 2.410593662949834029e-02f, + 2.356140880976381052e-02f, + 2.299426254527723104e-02f, + 2.240511256053460618e-02f, + 2.179459442066713701e-02f, + 2.116336385391225788e-02f, + 2.051209605527045191e-02f, + 1.984148497207598519e-02f, + 1.915224257223392679e-02f, + 1.844509809588383564e-02f, + 1.772079729127159706e-02f, + 1.698010163562099079e-02f, + 1.622378754181329208e-02f, + 1.545264555169341587e-02f, + 1.466747951683269359e-02f, + 1.386910576759178837e-02f, + 1.305835227133488388e-02f, + 1.223605778065572393e-02f, + 1.140307097248631669e-02f, + 1.056024957896441879e-02f, + 9.708459510942056905e-03f, + 8.848573975026030602e-03f, + 7.981472585042176035e-03f, + 7.108040468822868913e-03f, + 6.229167371217365738e-03f, + 5.345746754226499142e-03f, + 4.458674895167382204e-03f, + 3.568849983769900418e-03f, + 2.677171219111589007e-03f, + 1.784537907287459457e-03f, + 8.918485607199820456e-04f, + 1.375963414501481870e-16f, + -8.901135408467832598e-04f, + -1.777601304782279023e-03f, + -2.661576896985846409e-03f, + -3.541159164019371322e-03f, + -4.415473066061055551e-03f, + -5.283650541348036689e-03f, + -6.144831361984745034e-03f, + -6.998163980273221924e-03f, + -7.842806364743631908e-03f, + -8.677926825066678909e-03f, + -9.502704825047591716e-03f, + -1.031633178291084009e-02f, + -1.111801185810167188e-02f, + -1.190696272384546804e-02f, + -1.268241632471873645e-02f, + -1.344361961850560477e-02f, + -1.418983530162710137e-02f, + -1.492034251745096018e-02f, + -1.563443754680784656e-02f, + -1.633143448005669809e-02f, + -1.701066587006366121e-02f, + -1.767148336547917642e-02f, + -1.831325832371670168e-02f, + -1.893538240305999570e-02f, + -1.953726813334768359e-02f, + -2.011834946470413346e-02f, + -2.067808229381145821e-02f, + -2.121594496723701664e-02f, + -2.173143876136030342e-02f, + -2.222408833845995052e-02f, + -2.269344217855321158e-02f, + -2.313907298660076647e-02f, + -2.356057807471537494e-02f, + -2.395757971904149269e-02f, + -2.432972549099499809e-02f, + -2.467668856258116092e-02f, + -2.499816798553347250e-02f, + -2.529388894404376378e-02f, + -2.556360298088074245e-02f, + -2.580708819671996904e-02f, + -2.602414942253634608e-02f, + -2.621461836493719708e-02f, + -2.637835372434049752e-02f, + -2.651524128593106544e-02f, + -2.662519398335435120e-02f, + -2.670815193513444846e-02f, + -2.676408245383069331e-02f, + -2.679298002797401990e-02f, + -2.679486627685148323e-02f, + -2.676978987823442138e-02f, + -2.671782646917223933e-02f, + -2.663907852000062249e-02f, + -2.653367518173962297e-02f, + -2.640177210708273547e-02f, + -2.624355124520492619e-02f, + -2.605922061064226344e-02f, + -2.584901402652179520e-02f, + -2.561319084244592648e-02f, + -2.535203562735873287e-02f, + -2.506585783774740658e-02f, + -2.475499146155598143e-02f, + -2.441979463821075669e-02f, + -2.406064925518100819e-02f, + -2.367796052152183056e-02f, + -2.327215651886596973e-02f, + -2.284368773035500011e-02f, + -2.239302654802176329e-02f, + -2.192066675915328375e-02f, + -2.142712301218852727e-02f, + -2.091293026271947089e-02f, + -2.037864320018679606e-02f, + -1.982483565587724039e-02f, + -1.925209999284902343e-02f, + -1.866104647842747183e-02f, + -1.805230263992868914e-02f, + -1.742651260428690341e-02f, + -1.678433642227292188e-02f, + -1.612644937800953443e-02f, + -1.545354128449657159e-02f, + -1.476631576587938456e-02f, + -1.406548952719811375e-02f, + -1.335179161237267514e-02f, + -1.262596265118436090e-02f, + -1.188875409602925537e-02f, + -1.114092744922038150e-02f, + -1.038325348163284326e-02f, + -9.616511443484248786e-03f, + -8.841488268055055361e-03f, + -8.058977769158835736e-03f, + -7.269779833172840267e-03f, + -6.474699606447542784e-03f, + -5.674546678917565326e-03f, + -4.870134264732259473e-03f, + -4.062278380735639960e-03f, + -3.251797023616004832e-03f, + -2.439509346553158861e-03f, + -1.626234836185142018e-03f, + -8.127924907184056955e-04f, + -3.761300170173902632e-17f, + 8.113270716327609542e-04f, + 1.620376098912416430e-03f, + 2.426338204803805097e-03f, + 3.228409064469819033e-03f, + 4.025789703243586731e-03f, + 4.817687287821219300e-03f, + 5.603315909897037261e-03f, + 6.381897361469502858e-03f, + 7.152661901059502447e-03f, + 7.914849010088072581e-03f, + 8.667708138679361060e-03f, + 9.410499440156691597e-03f, + 1.014249449352174620e-02f, + 1.086297701321397788e-02f, + 1.157124354546169333e-02f, + 1.226660415055517636e-02f, + 1.294838307038302834e-02f, + 1.361591938058873304e-02f, + 1.426856762672633859e-02f, + 1.490569844380274823e-02f, + 1.552669915862028849e-02f, + 1.613097437434502304e-02f, + 1.671794653674912173e-02f, + 1.728705648159101563e-02f, + 1.783776396262254024e-02f, + 1.836954815972504512e-02f, + 1.888190816670458697e-02f, + 1.937436345829177120e-02f, + 1.984645433591701591e-02f, + 2.029774235185137846e-02f, + 2.072781071132718048e-02f, + 2.113626465227521484e-02f, + 2.152273180233675934e-02f, + 2.188686251283411544e-02f, + 2.222833016940416184e-02f, + 2.254683147902725865e-02f, + 2.284208673320283281e-02f, + 2.311384004705211576e-02f, + 2.336185957414964667e-02f, + 2.358593769691042299e-02f, + 2.378589119238579130e-02f, + 2.396156137334416389e-02f, + 2.411281420453805294e-02f, + 2.423954039408468888e-02f, + 2.434165545991162638e-02f, + 2.441909977124352010e-02f, + 2.447183856513244701e-02f, + 2.449986193805772303e-02f, + 2.450318481264677009e-02f, + 2.448184687959331640e-02f, + 2.443591251487354371e-02f, + 2.436547067238563694e-02f, + 2.427063475216228658e-02f, + 2.415154244432998407e-02f, + 2.400835554901284072e-02f, + 2.384125977240247538e-02f, + 2.365046449923850422e-02f, + 2.343620254196809860e-02f, + 2.319872986687494115e-02f, + 2.293832529749150265e-02f, + 2.265529019562997209e-02f, + 2.234994812038883921e-02f, + 2.202264446551434676e-02f, + 2.167374607551639937e-02f, + 2.130364084095871455e-02f, + 2.091273727336449839e-02f, + 2.050146406019705617e-02f, + 2.007026960039413541e-02f, + 1.961962152095459225e-02f, + 1.915000617509209774e-02f, + 1.866192812249098040e-02f, + 1.815590959221258585e-02f, + 1.763248992881976882e-02f, + 1.709222502230338045e-02f, + 1.653568672240555287e-02f, + 1.596346223795577085e-02f, + 1.537615352184286931e-02f, + 1.477437664226473150e-02f, + 1.415876114090650062e-02f, + 1.352994937871285740e-02f, + 1.288859586992923897e-02f, + 1.223536660509748700e-02f, + 1.157093836370297682e-02f, + 1.089599801717802338e-02f, + 1.021124182297453685e-02f, + 9.517374710428586071e-03f, + 8.815109559144568979e-03f, + 8.105166470632777995e-03f, + 7.388272033942047505e-03f, + 6.665158586030823715e-03f, + 5.936563467627156351e-03f, + 5.203228275329005968e-03f, + 4.465898110698729960e-03f, + 3.725320827109799334e-03f, + 2.982246275101344511e-03f, + 2.237425547001025122e-03f, + 1.491610221569002930e-03f, + 7.455516094238633746e-04f, + -4.603360121389620097e-17f, + -7.442960892099980894e-04f, + -1.486590660381493286e-03f, + -2.226140979308201089e-03f, + -2.962208314840183033e-03f, + -3.694058673076393295e-03f, + -4.420963525583790008e-03f, + -5.142200530928310413e-03f, + -5.857054248801788626e-03f, + -6.564816846046666980e-03f, + -7.264788793882578921e-03f, + -7.956279555653332503e-03f, + -8.638608264420137572e-03f, + -9.311104389740483545e-03f, + -9.973108392984011278e-03f, + -1.062397237054689761e-02f, + -1.126306068434249248e-02f, + -1.188975057895664926e-02f, + -1.250343278487292369e-02f, + -1.310351210718740250e-02f, + -1.368940799924666003e-02f, + -1.426055512066000397e-02f, + -1.481640387915378679e-02f, + -1.535642095575079358e-02f, + -1.588008981277712686e-02f, + -1.638691118421688533e-02f, + -1.687640354795164402e-02f, + -1.734810357944292433e-02f, + -1.780156658643218884e-02f, + -1.823636692425711220e-02f, + -1.865209839139694153e-02f, + -1.904837460488604042e-02f, + -1.942482935525157578e-02f, + -1.978111694065281395e-02f, + -2.011691247992323031e-02f, + -2.043191220423512186e-02f, + -2.072583372713042438e-02f, + -2.099841629268202337e-02f, + -2.124942100157323904e-02f, + -2.147863101490525214e-02f, + -2.168585173556427867e-02f, + -2.187091096700358173e-02f, + -2.203365904931835206e-02f, + -2.217396897251361007e-02f, + -2.229173646688911367e-02f, + -2.238688007048804385e-02f, + -2.245934117357874585e-02f, + -2.250908404016256636e-02f, + -2.253609580652320837e-02f, + -2.254038645685636430e-02f, + -2.252198877604117550e-02f, + -2.248095827963758273e-02f, + -2.241737312121652378e-02f, + -2.233133397715249616e-02f, + -2.222296390902992261e-02f, + -2.209240820383755882e-02f, + -2.193983419214646027e-02f, + -2.176543104448896288e-02f, + -2.156940954617817680e-02f, + -2.135200185082751848e-02f, + -2.111346121285143443e-02f, + -2.085406169924960626e-02f, + -2.057409788099558851e-02f, + -2.027388450437186615e-02f, + -1.995375614261341718e-02f, + -1.961406682823892828e-02f, + -1.925518966646928148e-02f, + -1.887751643015150166e-02f, + -1.848145713662151246e-02f, + -1.806743960696060095e-02f, + -1.763590900811298073e-02f, + -1.718732737835180352e-02f, + -1.672217313659431215e-02f, + -1.624094057608432493e-02f, + -1.574413934297350451e-02f, + -1.523229390034704089e-02f, + -1.470594297825480838e-02f, + -1.416563901031964515e-02f, + -1.361194755751050575e-02f, + -1.304544671967466062e-02f, + -1.246672653544142993e-02f, + -1.187638837111369521e-02f, + -1.127504429917872836e-02f, + -1.066331646707572613e-02f, + -1.004183645686986676e-02f, + -9.411244636485087758e-03f, + -8.772189503162801036e-03f, + -8.125327019812878665e-03f, + -7.471319944934195698e-03f, + -6.810837156787309839e-03f, + -6.144552972502608131e-03f, + -5.473146462815121210e-03f, + -4.797300763120759294e-03f, + -4.117702381546011793e-03f, + -3.435040504733359156e-03f, + -2.750006302037344939e-03f, + -2.063292228833295185e-03f, + -1.375591329636196821e-03f, + -6.875965417295367256e-04f, + -3.712671580871972529e-17f, + 6.865076563281155998e-04f, + 1.371237974366756743e-03f, + 2.053505374957837522e-03f, + 2.732627836105371629e-03f, + 3.407927571765508035e-03f, + 4.078731705322887272e-03f, + 4.744372937087731369e-03f, + 5.404190205152949872e-03f, + 6.057529338961288590e-03f, + 6.703743704936756392e-03f, + 7.342194843549852169e-03f, + 7.972253097187404283e-03f, + 8.593298228216065052e-03f, + 9.204720026634211766e-03f, + 9.805918906718476616e-03f, + 1.039630649208695898e-02f, + 1.097530618860973091e-02f, + 1.154235374461037682e-02f, + 1.209689779782041619e-02f, + 1.263840040855540407e-02f, + 1.316633757860326444e-02f, + 1.368019975532520915e-02f, + 1.417949232048846230e-02f, + 1.466373606336292788e-02f, + 1.513246763763515662e-02f, + 1.558524000170355243e-02f, + 1.602162284194235189e-02f, + 1.644120297853483154e-02f, + 1.684358475349722120e-02f, + 1.722839040053121898e-02f, + 1.759526039636302719e-02f, + 1.794385379324603749e-02f, + 1.827384853232209144e-02f, + 1.858494173755794940e-02f, + 1.887684998999094102e-02f, + 1.914930958204142525e-02f, + 1.940207675166573387e-02f, + 1.963492789614775663e-02f, + 1.984765976534554055e-02f, + 2.004008963423044992e-02f, + 2.021205545457873884e-02f, + 2.036341598569508388e-02f, + 2.049405090406888896e-02f, + 2.060386089188653500e-02f, + 2.069276770434292853e-02f, + 2.076071421571710346e-02f, + 2.080766444419874725e-02f, + 2.083360355547297926e-02f, + 2.083853784509219140e-02f, + 2.082249469968529276e-02f, + 2.078552253707531203e-02f, + 2.072769072539770024e-02f, + 2.064908948133232364e-02f, + 2.054982974758300454e-02f, + 2.043004304975895233e-02f, + 2.028988133283307627e-02f, + 2.012951677737172956e-02f, + 1.994914159575129214e-02f, + 1.974896780859568615e-02f, + 1.952922700168944689e-02f, + 1.929017006363938427e-02f, + 1.903206690457660832e-02f, + 1.875520615621007955e-02f, + 1.845989485356032758e-02f, + 1.814645809871968940e-02f, + 1.781523870700396292e-02f, + 1.746659683587628575e-02f, + 1.710090959704086561e-02f, + 1.671857065212146304e-02f, + 1.631998979235366534e-02f, + 1.590559250273780936e-02f, + 1.547581951111101986e-02f, + 1.503112632261381296e-02f, + 1.457198274004087128e-02f, + 1.409887237057541251e-02f, + 1.361229211942506165e-02f, + 1.311275167088374154e-02f, + 1.260077295736035038e-02f, + 1.207688961692321428e-02f, + 1.154164643992243444e-02f, + 1.099559880526047861e-02f, + 1.043931210689104556e-02f, + 9.873361171136581238e-03f, + 9.298329665421793330e-03f, + 8.714809499028142170e-03f, + 8.123400216482846645e-03f, + 7.524708384200954649e-03f, + 6.919346971004516206e-03f, + 6.307934723150263913e-03f, + 5.691095534499056308e-03f, + 5.069457812466930842e-03f, + 4.443653840398907248e-03f, + 3.814319137009273761e-03f, + 3.182091813536080255e-03f, + 2.547611929256090018e-03f, + 1.911520846010968415e-03f, + 1.274460582389453983e-03f, + 6.370731682176064472e-04f, + 1.081397080984820549e-16f, + -6.361188020413131080e-04f, + -1.270645034688974500e-03f, + -1.902943049573664223e-03f, + -2.532380387505061333e-03f, + -3.158328408659244208e-03f, + -3.780162917995376869e-03f, + -4.397264785285395425e-03f, + -5.009020559139008844e-03f, + -5.614823074421015914e-03f, + -6.214072052459541223e-03f, + -6.806174693455702487e-03f, + -7.390546260511059347e-03f, + -7.966610654700514993e-03f, + -8.533800980628097194e-03f, + -9.091560101911401459e-03f, + -9.639341186054086255e-03f, + -1.017660823817454450e-02f, + -1.070283662307290606e-02f, + -1.121751357513068974e-02f, + -1.172013869554890987e-02f, + -1.221022443644520679e-02f, + -1.268729657134461120e-02f, + -1.315089465161116758e-02f, + -1.360057244838422906e-02f, + -1.403589837959812528e-02f, + -1.445645592167801516e-02f, + -1.486184400552278267e-02f, + -1.525167739639943926e-02f, + -1.562558705739423154e-02f, + -1.598322049607744932e-02f, + -1.632424209406116086e-02f, + -1.664833341914373141e-02f, + -1.695519351975287997e-02f, + -1.724453920141957169e-02f, + -1.751610528503054487e-02f, + -1.776964484662796329e-02f, + -1.800492943854209438e-02f, + -1.822174929166297391e-02f, + -1.841991349867593691e-02f, + -1.859925017810457049e-02f, + -1.875960661902498217e-02f, + -1.890084940633438015e-02f, + -1.902286452647648438e-02f, + -1.912555745354639625e-02f, + -1.920885321571724064e-02f, + -1.927269644195031550e-02f, + -1.931705138897083646e-02f, + -1.934190194851057379e-02f, + -1.934725163483910423e-02f, + -1.933312355262460300e-02f, + -1.929956034518492611e-02f, + -1.924662412320928689e-02f, + -1.917439637405042932e-02f, + -1.908297785170610245e-02f, + -1.897248844762847511e-02f, + -1.884306704251837231e-02f, + -1.869487133928060194e-02f, + -1.852807767733529593e-02f, + -1.834288082849799481e-02f, + -1.813949377465985668e-02f, + -1.791814746751756518e-02f, + -1.767909057061923042e-02f, + -1.742258918401042023e-02f, + -1.714892655178226061e-02f, + -1.685840275283847015e-02f, + -1.655133437521590783e-02f, + -1.622805417430966263e-02f, + -1.588891071536682048e-02f, + -1.553426800063207637e-02f, + -1.516450508153929268e-02f, + -1.478001565636058098e-02f, + -1.438120765373634632e-02f, + -1.396850280252506793e-02f, + -1.354233618842332412e-02f, + -1.310315579781915797e-02f, + -1.265142204935544926e-02f, + -1.218760731368947504e-02f, + -1.171219542194896698e-02f, + -1.122568116339099642e-02f, + -1.072856977278602644e-02f, + -1.022137640805312678e-02f, + -9.704625618685933791e-03f, + -9.178850805514197561e-03f, + -8.644593672357078762e-03f, + -8.102403670126549079e-03f, + -7.552837433952721592e-03f, + -6.996458213902527305e-03f, + -6.433835299872929167e-03f, + -5.865543441244903435e-03f, + -5.292162261885334160e-03f, + -4.714275671091273240e-03f, + -4.132471271074346537e-03f, + -3.547339761581234756e-03f, + -2.959474342255256820e-03f, + -2.369470113338262643e-03f, + -1.777923475318417051e-03f, + -1.185431528126037071e-03f, + -5.925914704819672469e-04f, + -3.657082924657467151e-17f, + 5.917472853565048079e-04f, + 1.182056483865000056e-03f, + 1.770335984084810870e-03f, + 2.355997055758636289e-03f, + 2.938454436983550105e-03f, + 3.517126917070770645e-03f, + 4.091437914513436185e-03f, + 4.660816049491952121e-03f, + 5.224695710346304901e-03f, + 5.782517613461616614e-03f, + 6.333729356008878375e-03f, + 6.877785961000690458e-03f, + 7.414150414123792977e-03f, + 7.942294191823096386e-03f, + 8.461697780117830373e-03f, + 8.971851183644980604e-03f, + 9.472254424431190978e-03f, + 9.962418029908697709e-03f, + 1.044186350969892804e-02f, + 1.091012382070481734e-02f, + 1.136674382005683007e-02f, + 1.181128070548041059e-02f, + 1.224330444265740725e-02f, + 1.266239817917228644e-02f, + 1.306815864464697975e-02f, + 1.346019653668105442e-02f, + 1.383813689223166964e-02f, + 1.420161944407984794e-02f, + 1.455029896204724192e-02f, + 1.488384557864121625e-02f, + 1.520194509882482302e-02f, + 1.550429929362267742e-02f, + 1.579062617728919579e-02f, + 1.606066026778677283e-02f, + 1.631415283033408117e-02f, + 1.655087210380375498e-02f, + 1.677060350976731021e-02f, + 1.697314984400075458e-02f, + 1.715833145028389933e-02f, + 1.732598637634284386e-02f, + 1.747597051180499114e-02f, + 1.760815770805244929e-02f, + 1.772243987987905459e-02f, + 1.781872708887428242e-02f, + 1.789694760847562044e-02f, + 1.795704797064969285e-02f, + 1.799899299418070836e-02f, + 1.802276579456344244e-02f, + 1.802836777551610967e-02f, + 1.801581860214731406e-02f, + 1.798515615582916075e-02f, + 1.793643647084725012e-02f, + 1.786973365291627536e-02f, + 1.778513977966790505e-02f, + 1.768276478323590681e-02f, + 1.756273631508084576e-02f, + 1.742519959321422313e-02f, + 1.727031723200050592e-02f, + 1.709826905473061168e-02f, + 1.690925188917933447e-02f, + 1.670347934637539389e-02f, + 1.648118158282851561e-02f, + 1.624260504647542444e-02f, + 1.598801220662182665e-02f, + 1.571768126817298800e-02f, + 1.543190587046214431e-02f, + 1.513099477099881518e-02f, + 1.481527151447596842e-02f, + 1.448507408738769486e-02f, + 1.414075455862428936e-02f, + 1.378267870642391028e-02f, + 1.341122563207439514e-02f, + 1.302678736077021032e-02f, + 1.262976843004335811e-02f, + 1.222058546619729687e-02f, + 1.179966674918666268e-02f, + 1.136745176639336087e-02f, + 1.092439075576322714e-02f, + 1.047094423877575897e-02f, + 1.000758254372885632e-02f, + 9.534785319831791742e-03f, + 9.053041042603243369e-03f, + 8.562846511087114296e-03f, + 8.064706337396969349e-03f, + 7.559132429115091208e-03f, + 7.046643465073196971e-03f, + 6.527764365051815301e-03f, + 6.003025753936333010e-03f, + 5.472963420876755282e-03f, + 4.938117773999208156e-03f, + 4.399033291224269636e-03f, + 3.856257967746062627e-03f, + 3.310342760733056815e-03f, + 2.761841031809351716e-03f, + 2.211307987882755663e-03f, + 1.659300120877342261e-03f, + 1.106374646939666147e-03f, + 5.530889456780919066e-04f, + -2.562212629853384453e-17f, + -5.523361628926795478e-04f, + -1.103365028790336249e-03f, + -1.652534151487132074e-03f, + -2.199293704964780296e-03f, + -2.743097032196961139e-03f, + -3.283401190029548548e-03f, + -3.819667489593037233e-03f, + -4.351362031714790628e-03f, + -4.877956236795205104e-03f, + -5.398927368629055645e-03f, + -5.913759051650750720e-03f, + -6.421941781095417100e-03f, + -6.922973425571511859e-03f, + -7.416359721553146198e-03f, + -7.901614759304937882e-03f, + -8.378261459764673943e-03f, + -8.845832041915659832e-03f, + -9.303868480194682489e-03f, + -9.751922951488184790e-03f, + -1.018955827128389773e-02f, + -1.061634831855159944e-02f, + -1.103187844894640973e-02f, + -1.143574589593108516e-02f, + -1.182756015943418025e-02f, + -1.220694338166910739e-02f, + -1.257353070975459307e-02f, + -1.292697064479079137e-02f, + -1.326692537705756285e-02f, + -1.359307110701880525e-02f, + -1.390509835182837141e-02f, + -1.420271223705014962e-02f, + -1.448563277331862270e-02f, + -1.475359511768305730e-02f, + -1.500634981939290638e-02f, + -1.524366304989917265e-02f, + -1.546531681686134224e-02f, + -1.567110916196697012e-02f, + -1.586085434238630049e-02f, + -1.603438299570249595e-02f, + -1.619154228817324542e-02f, + -1.633219604619749049e-02f, + -1.645622487087768787e-02f, + -1.656352623558475859e-02f, + -1.665401456645098158e-02f, + -1.672762130573241662e-02f, + -1.678429495799975413e-02f, + -1.682400111913467597e-02f, + -1.684672248812496553e-02f, + -1.685245886166945525e-02f, + -1.684122711162113276e-02f, + -1.681306114531371312e-02f, + -1.676801184883415854e-02f, + -1.670614701332074833e-02f, + -1.662755124438308404e-02f, + -1.653232585475732791e-02f, + -1.642058874032645624e-02f, + -1.629247423965218475e-02f, + -1.614813297718115451e-02f, + -1.598773169030448180e-02f, + -1.581145304046532168e-02f, + -1.561949540852535824e-02f, + -1.541207267461631135e-02f, + -1.518941398271757108e-02f, + -1.495176349021716013e-02f, + -1.469938010272622657e-02f, + -1.443253719443338481e-02f, + -1.415152231429803349e-02f, + -1.385663687839711923e-02f, + -1.354819584875125403e-02f, + -1.322652739897053030e-02f, + -1.289197256707447573e-02f, + -1.254488489584905733e-02f, + -1.218563006111956712e-02f, + -1.181458548832869243e-02f, + -1.143213995781868463e-02f, + -1.103869319922974775e-02f, + -1.063465547543513724e-02f, + -1.022044715644565907e-02f, + -9.796498283722697084e-03f, + -9.363248125350869672e-03f, + -8.921144722528617441e-03f, + -8.470644427841999072e-03f, + -8.012211435799141551e-03f, + -7.546317306102053729e-03f, + -7.073440480148323294e-03f, + -6.594065791253660332e-03f, + -6.108683969096916598e-03f, + -5.617791138891340720e-03f, + -5.121888315793346122e-03f, + -4.621480895060380706e-03f, + -4.117078138476948368e-03f, + -3.609192657567809014e-03f, + -3.098339894123382839e-03f, + -2.585037598558611194e-03f, + -2.069805306636893476e-03f, + -1.553163815081216479e-03f, + -1.035634656603983328e-03f, + -5.177395748811913952e-04f, + -3.594753584560424697e-17f, + 5.170634750964393008e-04f, + 1.032931616641648070e-03f, + 1.547087070033249757e-03f, + 2.059014877257667187e-03f, + 2.568202991233530484e-03f, + 3.074142786564025911e-03f, + 3.576329566188138527e-03f, + 4.074263063429547048e-03f, + 4.567447938941549164e-03f, + 5.055394272060948803e-03f, + 5.537618046079833753e-03f, + 6.013641626959552108e-03f, + 6.482994235012814500e-03f, + 6.945212409090805589e-03f, + 7.399840462817311795e-03f, + 7.846430932424257321e-03f, + 8.284545015748243785e-03f, + 8.713753001960018382e-03f, + 9.133634691605685765e-03f, + 9.543779806553546671e-03f, + 9.943788389443802139e-03f, + 1.033327119225793331e-02f, + 1.071185005362884461e-02f, + 1.107915826452845684e-02f, + 1.143484092198099322e-02f, + 1.177855527046098826e-02f, + 1.210997103065078462e-02f, + 1.242877071524243864e-02f, + 1.273464993148456723e-02f, + 1.302731767018629021e-02f, + 1.330649658090683578e-02f, + 1.357192323307192076e-02f, + 1.382334836277147004e-02f, + 1.406053710501154602e-02f, + 1.428326921120452730e-02f, + 1.449133925169799296e-02f, + 1.468455680315914995e-02f, + 1.486274662064523792e-02f, + 1.502574879420732167e-02f, + 1.517341888988939583e-02f, + 1.530562807500203924e-02f, + 1.542226322756440338e-02f, + 1.552322702982500066e-02f, + 1.560843804578798157e-02f, + 1.567783078268716879e-02f, + 1.573135573636695247e-02f, + 1.576897942054480972e-02f, + 1.579068437994683369e-02f, + 1.579646918732351482e-02f, + 1.578634842436942021e-02f, + 1.576035264658639731e-02f, + 1.571852833214611861e-02f, + 1.566093781482364236e-02f, + 1.558765920108961048e-02f, + 1.549878627146459784e-02f, + 1.539442836625458041e-02f, + 1.527471025580193729e-02f, + 1.513977199540266459e-02f, + 1.498976876505400853e-02f, + 1.482487069421324286e-02f, + 1.464526267176276438e-02f, + 1.445114414139052512e-02f, + 1.424272888261022586e-02f, + 1.402024477765924718e-02f, + 1.378393356452596412e-02f, + 1.353405057637283200e-02f, + 1.327086446763305755e-02f, + 1.299465692707358656e-02f, + 1.270572237812851030e-02f, + 1.240436766682034841e-02f, + 1.209091173759783630e-02f, + 1.176568529743146629e-02f, + 1.142903046851825692e-02f, + 1.108130042995956500e-02f, + 1.072285904878491486e-02f, + 1.035408050070699311e-02f, + 9.975348881000042217e-03f, + 9.587057805905971689e-03f, + 9.189610004980062336e-03f, + 8.783416904796481281e-03f, + 8.368898204444107092e-03f, + 7.946481443246316417e-03f, + 7.516601561152745289e-03f, + 7.079700452249429281e-03f, + 6.636226511847269707e-03f, + 6.186634177609999508e-03f, + 5.731383465191587125e-03f, + 5.270939498854294337e-03f, + 4.805772037546594995e-03f, + 4.336354996921345552e-03f, + 3.863165967780911834e-03f, + 3.386685731435247395e-03f, + 2.907397772465186801e-03f, + 2.425787789381585267e-03f, + 1.942343203677738541e-03f, + 1.457552667765169528e-03f, + 9.719055722931030025e-04f, + 4.858915533437137995e-04f, + 8.998451329969168033e-17f, + -4.852804372203572384e-04f, + -9.694623365727714258e-04f, + -1.452059993443630213e-03f, + -1.932589906371710072e-03f, + -2.410571260246647390e-03f, + -2.885526406203937043e-03f, + -3.356981337736776681e-03f, + -3.824466162554774652e-03f, + -4.287515569716226875e-03f, + -4.745669291575628328e-03f, + -5.198472560085647988e-03f, + -5.645476557004205746e-03f, + -6.086238857560498199e-03f, + -6.520323867144547751e-03f, + -6.947303250588880534e-03f, + -7.366756353621596760e-03f, + -7.778270616075868595e-03f, + -8.181441976453041054e-03f, + -8.575875267442242128e-03f, + -8.961184602012178466e-03f, + -9.336993749696280778e-03f, + -9.702936502709572433e-03f, + -1.005865703153830532e-02f, + -1.040381022966105004e-02f, + -1.073806204706719697e-02f, + -1.106108981225218876e-02f, + -1.137258254238081648e-02f, + -1.167224124132068379e-02f, + -1.195977918526302392e-02f, + -1.223492219565827481e-02f, + -1.249740889920878534e-02f, + -1.274699097467286470e-02f, + -1.298343338624937185e-02f, + -1.320651460332445369e-02f, + -1.341602680637729757e-02f, + -1.361177607885452785e-02f, + -1.379358258483857035e-02f, + -1.396128073234834122e-02f, + -1.411471932212687332e-02f, + -1.425376168178382232e-02f, + -1.437828578517633127e-02f, + -1.448818435692682781e-02f, + -1.458336496199062575e-02f, + -1.466375008020243120e-02f, + -1.472927716574510063e-02f, + -1.477989869149929497e-02f, + -1.481558217824864229e-02f, + -1.483631020872940888e-02f, + -1.484208042652921528e-02f, + -1.483290551985472217e-02f, + -1.480881319020316278e-02f, + -1.476984610598764888e-02f, + -1.471606184118155226e-02f, + -1.464753279906179893e-02f, + -1.456434612114611976e-02f, + -1.446660358143379496e-02f, + -1.435442146607433973e-02f, + -1.422793043860267476e-02f, + -1.408727539089408773e-02f, + -1.393261528000593226e-02f, + -1.376412295108748671e-02f, + -1.358198494655285873e-02f, + -1.338640130172517699e-02f, + -1.317758532717458811e-02f, + -1.295576337798411137e-02f, + -1.272117461019173744e-02f, + -1.247407072466863269e-02f, + -1.221471569870679480e-02f, + -1.194338550559997762e-02f, + -1.166036782251413627e-02f, + -1.136596172695676817e-02f, + -1.106047738216157407e-02f, + -1.074423571171940345e-02f, + -1.041756806379570341e-02f, + -1.008081586528326509e-02f, + -9.734330266250949479e-03f, + -9.378471775056540852e-03f, + -9.013609884502808353e-03f, + -8.640122689421677812e-03f, + -8.258396496082181723e-03f, + -7.868825423824252902e-03f, + -7.471810999326916093e-03f, + -7.067761743930141109e-03f, + -6.657092754429278468e-03f, + -6.240225277775035030e-03f, + -5.817586280110769240e-03f, + -5.389608010588473400e-03f, + -4.956727560406810548e-03f, + -4.519386417521461217e-03f, + -4.078030017478383173e-03f, + -3.633107290827413370e-03f, + -3.185070207573783597e-03f, + -2.734373319130519765e-03f, + -2.281473298231648152e-03f, + -1.826828477275332062e-03f, + -1.370898385557953137e-03f, + -9.141432858685172996e-04f, + -4.570237109078288933e-04f, + -3.525929546010641032e-17f, + 4.564681634404971059e-04f, + 9.119222132217494076e-04f, + 1.365905160004667876e-03f, + 1.817962048792683442e-03f, + 2.267640413821652746e-03f, + 2.714490730398470830e-03f, + 3.158066863236440400e-03f, + 3.597926510843086571e-03f, + 4.033631645515631595e-03f, + 4.464748948511986122e-03f, + 4.890850239961540627e-03f, + 5.311512903093372658e-03f, + 5.726320302360849920e-03f, + 6.134862195051104215e-03f, + 6.536735135972274353e-03f, + 6.931542874822234357e-03f, + 7.318896745846920765e-03f, + 7.698416049407258259e-03f, + 8.069728425079554859e-03f, + 8.432470215927469551e-03f, + 8.786286823586514014e-03f, + 9.130833053819266409e-03f, + 9.465773452203021798e-03f, + 9.790782629625502387e-03f, + 1.010554557727417341e-02f, + 1.040975797081422800e-02f, + 1.070312646346415798e-02f, + 1.098536896768670043e-02f, + 1.125621492522658335e-02f, + 1.151540556523688447e-02f, + 1.176269415025001618e-02f, + 1.199784620976064760e-02f, + 1.222063976119941615e-02f, + 1.243086551809268608e-02f, + 1.262832708521319930e-02f, + 1.281284114054117608e-02f, + 1.298423760386959412e-02f, + 1.314235979189961462e-02f, + 1.328706455968696638e-02f, + 1.341822242831278503e-02f, + 1.353571769866840878e-02f, + 1.363944855125505048e-02f, + 1.372932713191544682e-02f, + 1.380527962342858322e-02f, + 1.386724630291150812e-02f, + 1.391518158498825965e-02f, + 1.394905405069915734e-02f, + 1.396884646213872837e-02f, + 1.397455576282423569e-02f, + 1.396619306381172501e-02f, + 1.394378361559041324e-02f, + 1.390736676580064946e-02f, + 1.385699590283483162e-02f, + 1.379273838539456926e-02f, + 1.371467545809203735e-02f, + 1.362290215319624312e-02f, + 1.351752717864009370e-02f, + 1.339867279241668298e-02f, + 1.326647466350721130e-02f, + 1.312108171949675703e-02f, + 1.296265598104565965e-02f, + 1.279137238340016282e-02f, + 1.260741858513507452e-02f, + 1.241099476433735194e-02f, + 1.220231340244982976e-02f, + 1.198159905600587605e-02f, + 1.174908811650030374e-02f, + 1.150502855865119002e-02f, + 1.124967967731822956e-02f, + 1.098331181335730246e-02f, + 1.070620606869824784e-02f, + 1.041865401094608894e-02f, + 1.012095736781302990e-02f, + 9.813427711702541953e-03f, + 9.496386134773091015e-03f, + 9.170162914817906255e-03f, + 8.835097172309763769e-03f, + 8.491536518964717603e-03f, + 8.139836698186228570e-03f, + 7.780361217764370299e-03f, + 7.413480975203700848e-03f, + 7.039573876068914819e-03f, + 6.659024445737531453e-03f, + 6.272223434958205251e-03f, + 5.879567419619150664e-03f, + 5.481458395132861143e-03f, + 5.078303365855517913e-03f, + 4.670513929954199853e-03f, + 4.258505860148748337e-03f, + 3.842698680752674144e-03f, + 3.423515241440691897e-03f, + 3.001381288178317595e-03f, + 2.576725031746534850e-03f, + 2.149976714294795244e-03f, + 1.721568174367767547e-03f, + 1.291932410834989269e-03f, + 8.615031461717679489e-04f, + 4.307143895238358311e-04f, + -1.330885637378024658e-17f, + -4.302067493707025154e-04f, + -8.594736065816692546e-04f, + -1.287369774051150230e-03f, + -1.713466340056074740e-03f, + -2.137336707761578608e-03f, + -2.558557021419832853e-03f, + -2.976706589314977430e-03f, + -3.391368303029395053e-03f, + -3.802129052617245642e-03f, + -4.208580137271933364e-03f, + -4.610317671079266870e-03f, + -5.006942983457264747e-03f, + -5.398063013881818258e-03f, + -5.783290700513624497e-03f, + -6.162245362338608992e-03f, + -6.534553074447273235e-03f, + -6.899847036085403514e-03f, + -7.257767931111701668e-03f, + -7.607964280510494219e-03f, + -7.950092786617034279e-03f, + -8.283818668712937539e-03f, + -8.608815989672613522e-03f, + -8.924767973335575449e-03f, + -9.231367312302321895e-03f, + -9.528316465851647404e-03f, + -9.815327947693202118e-03f, + -1.009212460327926254e-02f, + -1.035843987640591192e-02f, + -1.061401806485215774e-02f, + -1.085861456480968767e-02f, + -1.109199610387191955e-02f, + -1.131394096236322706e-02f, + -1.152423918279525498e-02f, + -1.172269276725893851e-02f, + -1.190911586256368677e-02f, + -1.208333493295382470e-02f, + -1.224518892024368394e-02f, + -1.239452939122312469e-02f, + -1.253122067220243524e-02f, + -1.265513997057455924e-02f, + -1.276617748328832784e-02f, + -1.286423649213934428e-02f, + -1.294923344579684485e-02f, + -1.302109802850088746e-02f, + -1.307977321537517543e-02f, + -1.312521531431613646e-02f, + -1.315739399443144331e-02f, + -1.317629230101505927e-02f, + -1.318190665705944176e-02f, + -1.317424685131877472e-02f, + -1.315333601295100296e-02f, + -1.311921057277957818e-02f, + -1.307192021122943054e-02f, + -1.301152779300470720e-02f, + -1.293810928858945414e-02f, + -1.285175368266549059e-02f, + -1.275256286955382679e-02f, + -1.264065153580123772e-02f, + -1.251614703004294733e-02f, + -1.237918922028838700e-02f, + -1.222993033878752925e-02f, + -1.206853481464722870e-02f, + -1.189517909438159854e-02f, + -1.171005145058865056e-02f, + -1.151335177896088170e-02f, + -1.130529138384659196e-02f, + -1.108609275258971849e-02f, + -1.085598931889009827e-02f, + -1.061522521543183453e-02f, + -1.036405501604320198e-02f, + -1.010274346765773629e-02f, + -9.831565212357994479e-03f, + -9.550804499793438818e-03f, + -9.260754890270634504e-03f, + -8.961718948827171807e-03f, + -8.654007930606116492e-03f, + -8.337941457855730515e-03f, + -8.013847188892069678e-03f, + -7.682060479362260927e-03f, + -7.342924036161159809e-03f, + -6.996787564356483392e-03f, + -6.644007407482657376e-03f, + -6.284946181578719530e-03f, + -5.919972403337297497e-03f, + -5.549460112752437578e-03f, + -5.173788490645978184e-03f, + -4.793341471466837367e-03f, + -4.408507351756223852e-03f, + -4.019678394675591307e-03f, + -3.627250431002364273e-03f, + -3.231622456996959773e-03f, + -2.833196229547020346e-03f, + -2.432375859003425757e-03f, + -2.029567400113351655e-03f, + -1.625178441472032017e-03f, + -1.219617693898372018e-03f, + -8.132945781564861155e-04f, + -4.066188124353766527e-04f, + -1.255183464083940188e-16f, + 4.061527825679167288e-04f, + 8.114313961304521613e-04f, + 1.215429048341218040e-03f, + 1.617740701170319395e-03f, + 2.017963476201877198e-03f, + 2.415697057295686061e-03f, + 2.810544090212879591e-03f, + 3.202110578810242990e-03f, + 3.590006277401872493e-03f, + 3.973845078907196904e-03f, + 4.353245398391843331e-03f, + 4.727830551627599208e-03f, + 5.097229128292139061e-03f, + 5.461075359441391712e-03f, + 5.819009478893136939e-03f, + 6.170678078162634105e-03f, + 6.515734454602445554e-03f, + 6.853838952405788033e-03f, + 7.184659296134813210e-03f, + 7.507870916452765928e-03f, + 7.823157267734456854e-03f, + 8.130210137252638636e-03f, + 8.428729945633239504e-03f, + 8.718426038289772001e-03f, + 8.999016967555456201e-03f, + 9.270230765236708165e-03f, + 9.531805205328850242e-03f, + 9.783488056638036182e-03f, + 1.002503732506817256e-02f, + 1.025622148534208536e-02f, + 1.047681970193385138e-02f, + 1.068662203900417294e-02f, + 1.088542965913968583e-02f, + 1.107305501070874297e-02f, + 1.124932200365959603e-02f, + 1.141406617359526365e-02f, + 1.156713483397583953e-02f, + 1.170838721630671625e-02f, + 1.183769459818636779e-02f, + 1.195494041909911376e-02f, + 1.206002038384902317e-02f, + 1.215284255354657367e-02f, + 1.223332742406933564e-02f, + 1.230140799193264051e-02f, + 1.235702980751857485e-02f, + 1.240015101562292471e-02f, + 1.243074238329506739e-02f, + 1.244878731495606579e-02f, + 1.245428185479465800e-02f, + 1.244723467645303394e-02f, + 1.242766706002694684e-02f, + 1.239561285641773217e-02f, + 1.235111843908625294e-02f, + 1.229424264327155618e-02f, + 1.222505669274922754e-02f, + 1.214364411421739454e-02f, + 1.205010063941019949e-02f, + 1.194453409505086793e-02f, + 1.182706428076905555e-02f, + 1.169782283511792108e-02f, + 1.155695308984023249e-02f, + 1.140460991254168763e-02f, + 1.124095953794393248e-02f, + 1.106617938789930186e-02f, + 1.088045788035994950e-02f, + 1.068399422750770586e-02f, + 1.047699822325738259e-02f, + 1.025969002036108101e-02f, + 1.003229989734856151e-02f, + 9.795068015547647028e-03f, + 9.548244166444083345e-03f, + 9.292087509640511306e-03f, + 9.026866301692599431e-03f, + 8.752857616103554630e-03f, + 8.470347054767179973e-03f, + 8.179628451162134981e-03f, + 7.881003565601285565e-03f, + 7.574781772854489656e-03f, + 7.261279742466121394e-03f, + 6.940821112095421283e-03f, + 6.613736154219424825e-03f, + 6.280361436535699012e-03f, + 5.941039476420039225e-03f, + 5.596118389785657496e-03f, + 5.245951534708952028e-03f, + 4.890897150183600751e-03f, + 4.531317990370226784e-03f, + 4.167580954717115850e-03f, + 3.800056714327025055e-03f, + 3.429119334948160357e-03f, + 3.055145896976142229e-03f, + 2.678516112847336220e-03f, + 2.299611942215314033e-03f, + 1.918817205297107184e-03f, + 1.536517194780740196e-03f, + 1.153098286686640977e-03f, + 7.689475505726472288e-04f, + 3.844523594784173275e-04f, + 7.713589460388476895e-17f, + -3.840227171148354263e-04f, + -7.672298454569775623e-04f, + -1.149236690145042554e-03f, + -1.529660193323781423e-03f, + -1.908119317586332020e-03f, + -2.284235426939436406e-03f, + -2.657632664926935610e-03f, + -3.027938329540865066e-03f, + -3.394783244538977351e-03f, + -3.757802126807970565e-03f, + -4.116633949400874508e-03f, + -4.470922299891161820e-03f, + -4.820315733689854894e-03f, + -5.164468121973136636e-03f, + -5.503038993878216732e-03f, + -5.835693872631364174e-03f, + -6.162104605273097113e-03f, + -6.481949685660806648e-03f, + -6.794914570427616589e-03f, + -7.100691987590134792e-03f, + -7.398982237502254970e-03f, + -7.689493485860325432e-03f, + -7.971942048476048787e-03f, + -8.246052667536663341e-03f, + -8.511558779087890353e-03f, + -8.768202771477389898e-03f, + -9.015736234510263528e-03f, + -9.253920199077345435e-03f, + -9.482525367023937612e-03f, + -9.701332331039827506e-03f, + -9.910131784361380508e-03f, + -1.010872472008433366e-02f, + -1.029692261989997165e-02f, + -1.047454763207558877e-02f, + -1.064143273851355688e-02f, + -1.079742191073151426e-02f, + -1.094237025462001418e-02f, + -1.107614414384500319e-02f, + -1.119862134177232113e-02f, + -1.130969111180511570e-02f, + -1.140925431603640253e-02f, + -1.149722350212928346e-02f, + -1.157352297835191959e-02f, + -1.163808887670370745e-02f, + -1.169086920408306425e-02f, + -1.173182388145829064e-02f, + -1.176092477101533564e-02f, + -1.177815569126870569e-02f, + -1.178351242013314648e-02f, + -1.177700268596670700e-02f, + -1.175864614660714416e-02f, + -1.172847435643616099e-02f, + -1.168653072151761875e-02f, + -1.163287044286803393e-02f, + -1.156756044792955386e-02f, + -1.149067931032693446e-02f, + -1.140231715800252288e-02f, + -1.130257556983401725e-02f, + -1.119156746085197413e-02f, + -1.106941695618434904e-02f, + -1.093625925386791653e-02f, + -1.079224047667651058e-02f, + -1.063751751312634955e-02f, + -1.047225784783175143e-02f, + -1.029663938139156396e-02f, + -1.011085024000046503e-02f, + -9.915088574987292874e-03f, + -9.709562352492116799e-03f, + -9.494489133505876546e-03f, + -9.270095844503068935e-03f, + -9.036618538908790590e-03f, + -8.794302149650478143e-03f, + -8.543400233051267126e-03f, + -8.284174704334627132e-03f, + -8.016895565012135613e-03f, + -7.741840622440153072e-03f, + -7.459295201834709003e-03f, + -7.169551851041272746e-03f, + -6.872910038367072844e-03f, + -6.569675843783693604e-03f, + -6.260161643820879619e-03f, + -5.944685790473217164e-03f, + -5.623572284449645554e-03f, + -5.297150443101252340e-03f, + -4.965754563364804634e-03f, + -4.629723580069068818e-03f, + -4.289400719951269245e-03f, + -3.945133151734599684e-03f, + -3.597271632626723118e-03f, + -3.246170151593960954e-03f, + -2.892185569777141942e-03f, + -2.535677258412258675e-03f, + -2.177006734621175950e-03f, + -1.816537295443911102e-03f, + -1.454633650479946480e-03f, + -1.091661553510198676e-03f, + -7.279874334719225624e-04f, + -3.639780251556599890e-04f, + -3.369908401361916715e-17f, + 3.635804026494091068e-04f, + 7.263977434430309238e-04f, + 1.088087749724279355e-03f, + 1.448287680655482423e-03f, + 1.806636690402828576e-03f, + 2.162776189022377980e-03f, + 2.516350200682577424e-03f, + 2.867005718868611067e-03f, + 3.214393058213963015e-03f, + 3.558166202608354332e-03f, + 3.897983149238446517e-03f, + 4.233506248216929377e-03f, + 4.564402537464701606e-03f, + 4.890344072516150664e-03f, + 5.211008250917694221e-03f, + 5.526078130903779376e-03f, + 5.835242744032488431e-03f, + 6.138197401474478412e-03f, + 6.434643993655418670e-03f, + 6.724291282955277560e-03f, + 7.006855189179749324e-03f, + 7.282059067523997259e-03f, + 7.549633978756757104e-03f, + 7.809318951363577316e-03f, + 8.060861235391183002e-03f, + 8.304016547750365032e-03f, + 8.538549308736993748e-03f, + 8.764232869544244173e-03f, + 8.980849730547869544e-03f, + 9.188191750152601561e-03f, + 9.386060344002900707e-03f, + 9.574266674365642868e-03f, + 9.752631829506541034e-03f, + 9.920986992890266226e-03f, + 1.007917360204479626e-02f, + 1.022704349694264145e-02f, + 1.036445905775955530e-02f, + 1.049129333188454291e-02f, + 1.060743015006561894e-02f, + 1.071276423158474926e-02f, + 1.080720127836987295e-02f, + 1.089065805795989307e-02f, + 1.096306247525190812e-02f, + 1.102435363297093844e-02f, + 1.107448188081278095e-02f, + 1.111340885322339295e-02f, + 1.114110749578882571e-02f, + 1.115756208022166719e-02f, + 1.116276820794095091e-02f, + 1.115673280225443556e-02f, + 1.113947408916339532e-02f, + 1.111102156682138194e-02f, + 1.107141596369005596e-02f, + 1.102070918544608043e-02f, + 1.095896425070500523e-02f, + 1.088625521563825124e-02f, + 1.080266708757151098e-02f, + 1.070829572766292780e-02f, + 1.060324774277076644e-02f, + 1.048764036663119362e-02f, + 1.036160133047638564e-02f, + 1.022526872323565802e-02f, + 1.007879084146987361e-02f, + 9.922326029202397854e-03f, + 9.756042507818011092e-03f, + 9.580118196210777107e-03f, + 9.394740521373458678e-03f, + 9.200106219628658571e-03f, + 8.996421128710744425e-03f, + 8.783899970919039138e-03f, + 8.562766127568535030e-03f, + 8.333251404975441923e-03f, + 8.095595792220260448e-03f, + 7.850047210942715306e-03f, + 7.596861257427847160e-03f, + 7.336300937249773911e-03f, + 7.068636392749921664e-03f, + 6.794144623630500764e-03f, + 6.513109200950242123e-03f, + 6.225819974820153910e-03f, + 5.932572776096196529e-03f, + 5.633669112378537902e-03f, + 5.329415858627153425e-03f, + 5.020124942711203311e-03f, + 4.706113026214525825e-03f, + 4.387701180821052503e-03f, + 4.065214560613866247e-03f, + 3.738982070617613389e-03f, + 3.409336031925057006e-03f, + 3.076611843746769430e-03f, + 2.741147642725723539e-03f, + 2.403283959864889810e-03f, + 2.063363375414229133e-03f, + 1.721730172063813159e-03f, + 1.378729986799676023e-03f, + 1.034709461766141576e-03f, + 6.900158944939007019e-04f, + 3.449968878405673157e-04f, + 0.000000000000000000e+00f, + -3.446276050693368302e-04f, + -6.885395064473497171e-04f, + -1.031390373933058213e-03f, + -1.372836314259132063e-03f, + -1.712535215489931510e-03f, + -2.050147089260192981e-03f, + -2.385334410513898287e-03f, + -2.717762454401503706e-03f, + -3.047099630002055894e-03f, + -3.373017810537275608e-03f, + -3.695192659748559091e-03f, + -4.013303954115152519e-03f, + -4.327035900590155311e-03f, + -4.636077449543945204e-03f, + -4.940122602601876300e-03f, + -5.238870715073626685e-03f, + -5.532026792676994140e-03f, + -5.819301782261442936e-03f, + -6.100412856246560135e-03f, + -6.375083690498107615e-03f, + -6.643044735364164385e-03f, + -6.904033479612515893e-03f, + -7.157794707005572452e-03f, + -7.404080745267220716e-03f, + -7.642651707196129220e-03f, + -7.873275723692764461e-03f, + -8.095729168475295640e-03f, + -8.309796874264679251e-03f, + -8.515272340233715279e-03f, + -8.711957930518144516e-03f, + -8.899665063600716020e-03f, + -9.078214392388751081e-03f, + -9.247435974810619408e-03f, + -9.407169434773821060e-03f, + -9.557264113329744237e-03f, + -9.697579209904895123e-03f, + -9.827983913467562213e-03f, + -9.948357523507136632e-03f, + -1.005858956071708186e-02f, + -1.015857986727966046e-02f, + -1.024823869666328068e-02f, + -1.032748679285360252e-02f, + -1.039625545894891021e-02f, + -1.045448661506321979e-02f, + -1.050213284548926623e-02f, + -1.053915743508587223e-02f, + -1.056553439486431802e-02f, + -1.058124847675941289e-02f, + -1.058629517758200196e-02f, + -1.058068073216014530e-02f, + -1.056442209568751386e-02f, + -1.053754691530808460e-02f, + -1.050009349097712034e-02f, + -1.045211072564902234e-02f, + -1.039365806485362080e-02f, + -1.032480542573286329e-02f, + -1.024563311561991173e-02f, + -1.015623174025468214e-02f, + -1.005670210173764852e-02f, + -9.947155086336527396e-03f, + -9.827711542269031153e-03f, + -9.698502147594538492e-03f, + -9.559667268359363368e-03f, + -9.411356807146858960e-03f, + -9.253730042196249908e-03f, + -9.086955457261344099e-03f, + -8.911210562389308004e-03f, + -8.726681705811039844e-03f, + -8.533563877139486997e-03f, + -8.332060502084964390e-03f, + -8.122383228901621996e-03f, + -7.904751706788885890e-03f, + -7.679393356479695225e-03f, + -7.446543133253041326e-03f, + -7.206443282618896044e-03f, + -6.959343088928202255e-03f, + -6.705498617166942392e-03f, + -6.445172448203926978e-03f, + -6.178633407762102944e-03f, + -5.906156289395311614e-03f, + -5.628021571754467968e-03f, + -5.344515130431467045e-03f, + -5.055927944681215189e-03f, + -4.762555799315829584e-03f, + -4.464698982081711544e-03f, + -4.162661976823887194e-03f, + -3.856753152753953674e-03f, + -3.547284450136960633e-03f, + -3.234571062715784710e-03f, + -2.918931117198290178e-03f, + -2.600685350131433544e-03f, + -2.280156782488628776e-03f, + -1.957670392303650399e-03f, + -1.633552785677109664e-03f, + -1.308131866494795974e-03f, + -9.817365051840280538e-04f, + -6.546962068479288350e-04f, + -3.273407791097072712e-04f, + 4.043570989833329463e-17f, + 3.269967137754016561e-04f, + 6.533206378577746144e-04f, + 9.786440702132328823e-04f, + 1.302640659735354979e-03f, + 1.624985733145793004e-03f, + 1.945356619862989578e-03f, + 2.263432974515657958e-03f, + 2.578897096781404205e-03f, + 2.891434248225943724e-03f, + 3.200732965834694743e-03f, + 3.506485371918194750e-03f, + 3.808387480088745985e-03f, + 4.106139497000982005e-03f, + 4.399446119558816405e-03f, + 4.688016827295758519e-03f, + 4.971566169637211575e-03f, + 5.249814047762459135e-03f, + 5.522485990789751178e-03f, + 5.789313426009380474e-03f, + 6.050033942903848549e-03f, + 6.304391550690290578e-03f, + 6.552136929139138963e-03f, + 6.793027672418951342e-03f, + 7.026828525731477169e-03f, + 7.253311614507366133e-03f, + 7.472256665937161355e-03f, + 7.683451222625906421e-03f, + 7.886690848162170725e-03f, + 8.081779324404252465e-03f, + 8.268528840294541229e-03f, + 8.446760172019297450e-03f, + 8.616302854343038317e-03f, + 8.776995342953978693e-03f, + 8.928685167666237238e-03f, + 9.071229076335495314e-03f, + 9.204493169351136636e-03f, + 9.328353024581554839e-03f, + 9.442693812655188201e-03f, + 9.547410402472212773e-03f, + 9.642407456851329745e-03f, + 9.727599518224548311e-03f, + 9.802911084305539202e-03f, + 9.868276673664756402e-03f, + 9.923640881156430005e-03f, + 9.968958423152556383e-03f, + 1.000419417254796474e-02f, + 1.002932318351319220e-02f, + 1.004433070597993659e-02f, + 1.004921218985568680e-02f, + 1.004397327897390071e-02f, + 1.002862979479642036e-02f, + 1.000320770989520693e-02f, + 9.967743111250705959e-03f, + 9.922282153414410666e-03f, + 9.866881001593018341e-03f, + 9.801605764722259168e-03f, + 9.726532418607795535e-03f, + 9.641746719220965420e-03f, + 9.547344106246909851e-03f, + 9.443429596991709252e-03f, + 9.330117670766156779e-03f, + 9.207532143871193647e-03f, + 9.075806035321471940e-03f, + 8.935081423451458893e-03f, + 8.785509293556969038e-03f, + 8.627249376736262007e-03f, + 8.460469980100025419e-03f, + 8.285347808531550937e-03f, + 8.102067778184653124e-03f, + 7.910822821914111069e-03f, + 7.711813686845882775e-03f, + 7.505248724294873164e-03f, + 7.291343672252590877e-03f, + 7.070321430670069122e-03f, + 6.842411829768484458e-03f, + 6.607851391620159567e-03f, + 6.366883085243799263e-03f, + 6.119756075469458441e-03f, + 5.866725465831302069e-03f, + 5.608052035751829104e-03f, + 5.344001972290637024e-03f, + 5.074846596729006530e-03f, + 4.800862086276046561e-03f, + 4.522329191175403912e-03f, + 4.239532947506496723e-03f, + 3.952762385971762653e-03f, + 3.662310236965878128e-03f, + 3.368472632229732935e-03f, + 3.071548803391624394e-03f, + 2.771840777700751261e-03f, + 2.469653071265261093e-03f, + 2.165292380101938724e-03f, + 1.859067269314046813e-03f, + 1.551287860709699411e-03f, + 1.242265519177247843e-03f, + 9.323125381350914204e-04f, + 6.217418243711637623e-04f, + 3.108665825923342669e-04f, + 6.717146213127583512e-17f, + -3.105450687918437651e-04f, + -6.204564161774286978e-04f, + -9.294227950051989944e-04f, + -1.237134230733572199e-03f, + -1.543282331983834290e-03f, + -1.847560599181306829e-03f, + -2.149664730972687243e-03f, + -2.449292928118728188e-03f, + -2.746146194552807982e-03f, + -3.039928635312416725e-03f, + -3.330347751041712323e-03f, + -3.617114728774667616e-03f, + -3.899944728711154593e-03f, + -4.178557166699342108e-03f, + -4.452675992145861683e-03f, + -4.722029961080219732e-03f, + -4.986352904100606331e-03f, + -5.245383988940638745e-03f, + -5.498867977395256908e-03f, + -5.746555476355140642e-03f, + -5.988203182702574526e-03f, + -6.223574121828233212e-03f, + -6.452437879537288590e-03f, + -6.674570827115577747e-03f, + -6.889756339339682574e-03f, + -7.097785005216259401e-03f, + -7.298454831247235333e-03f, + -7.491571437024912607e-03f, + -7.676948242966399882e-03f, + -7.854406650007556001e-03f, + -8.023776211084653054e-03f, + -8.184894794238147323e-03f, + -8.337608737184420971e-03f, + -8.481772993207853037e-03f, + -8.617251268236572961e-03f, + -8.743916148971660543e-03f, + -8.861649221950897853e-03f, + -8.970341183436947655e-03f, + -9.069891940027947907e-03f, + -9.160210699899310610e-03f, + -9.241216054595012552e-03f, + -9.312836051294730300e-03f, + -9.375008255495077131e-03f, + -9.427679804050792534e-03f, + -9.470807448532998427e-03f, + -9.504357588870533669e-03f, + -9.528306297250627166e-03f, + -9.542639332264922503e-03f, + -9.547352143296350749e-03f, + -9.542449865152758184e-03f, + -9.527947302962450418e-03f, + -9.503868907356978132e-03f, + -9.470248739975935248e-03f, + -9.427130429338478543e-03f, + -9.374567117135889846e-03f, + -9.312621395008722006e-03f, + -9.241365231882207529e-03f, + -9.160879891942457637e-03f, + -9.071255843345765041e-03f, + -8.972592657761846446e-03f, + -8.864998900862054027e-03f, + -8.748592013871738307e-03f, + -8.623498186314530051e-03f, + -8.489852220086737886e-03f, + -8.347797385005961690e-03f, + -8.197485265989208972e-03f, + -8.039075602022388231e-03f, + -7.872736117090798832e-03f, + -7.698642343250202899e-03f, + -7.516977436023509172e-03f, + -7.327931982316876480e-03f, + -7.131703801056546270e-03f, + -6.928497736752988953e-03f, + -6.718525446209536699e-03f, + -6.502005178594330234e-03f, + -6.279161549105892817e-03f, + -6.050225306465603983e-03f, + -5.815433094476260209e-03f, + -5.575027207895101936e-03f, + -5.329255342869666442e-03f, + -5.078370342195653343e-03f, + -4.822629935656748412e-03f, + -4.562296475713070905e-03f, + -4.297636668809446704e-03f, + -4.028921302576533685e-03f, + -3.756424969205551280e-03f, + -3.480425785277831575e-03f, + -3.201205108333276313e-03f, + -2.919047250469300383e-03f, + -2.634239189257616548e-03f, + -2.347070276275515198e-03f, + -2.057831943546030353e-03f, + -1.766817408183218516e-03f, + -1.474321375543928428e-03f, + -1.180639741184265909e-03f, + -8.860692919223937727e-04f, + -5.909074063099545391e-04f, + -2.954517548118973532e-04f, + -3.191480037364917763e-17f, + 2.951505029420960018e-04f, + 5.897030050987488040e-04f, + 8.833616617872707506e-04f, + 1.175831829311610932e-03f, + 1.466820360203527135e-03f, + 1.756035896659971941e-03f, + 2.043189161879899619e-03f, + 2.327993249011680189e-03f, + 2.610163907422230218e-03f, + 2.889419826001986703e-03f, + 3.165482913225662470e-03f, + 3.438078573687941564e-03f, + 3.706935980840707877e-03f, + 3.971788345662486015e-03f, + 4.232373180990945533e-03f, + 4.488432561260610569e-03f, + 4.739713377386114979e-03f, + 4.985967586540838471e-03f, + 5.226952456585757904e-03f, + 5.462430804905994176e-03f, + 5.692171231422111718e-03f, + 5.915948345547154125e-03f, + 6.133542986866762428e-03f, + 6.344742439328332831e-03f, + 6.549340638727800534e-03f, + 6.747138373295004030e-03f, + 6.937943477180526231e-03f, + 7.121571016657480234e-03f, + 7.297843468859207573e-03f, + 7.466590892878511958e-03f, + 7.627651093066531961e-03f, + 7.780869774372829901e-03f, + 7.926100689579733752e-03f, + 8.063205778290625028e-03f, + 8.192055297540449046e-03f, + 8.312527943906498212e-03f, + 8.424510967003927958e-03f, + 8.527900274261378949e-03f, + 8.622600526880391109e-03f, + 8.708525226889919993e-03f, + 8.785596795218742969e-03f, + 8.853746640715155422e-03f, + 8.912915220054325877e-03f, + 8.963052088482293539e-03f, + 9.004115941354405919e-03f, + 9.036074646436131896e-03f, + 9.058905266942841872e-03f, + 9.072594075305043249e-03f, + 9.077136557654227889e-03f, + 9.072537409034447248e-03f, + 9.058810519353838187e-03f, + 9.035978950099398527e-03f, + 9.004074901847999857e-03f, + 8.963139672615380235e-03f, + 8.913223607094592979e-03f, + 8.854386036843783780e-03f, + 8.786695211493011221e-03f, + 8.710228221048086500e-03f, + 8.625070909378744488e-03f, + 8.531317778987176914e-03f, + 8.429071887160986820e-03f, + 8.318444733624745513e-03f, + 8.199556139810507127e-03f, + 8.072534119878281914e-03f, + 7.937514743624142846e-03f, + 7.794641991421518389e-03f, + 7.644067601350621258e-03f, + 7.485950908677277416e-03f, + 7.320458677849650715e-03f, + 7.147764927190735675e-03f, + 6.968050746469218841e-03f, + 6.781504107540342781e-03f, + 6.588319668252944766e-03f, + 6.388698569828255708e-03f, + 6.182848227920212554e-03f, + 5.970982117573007432e-03f, + 5.753319552299874899e-03f, + 5.530085457510665325e-03f, + 5.301510138520690307e-03f, + 5.067829043382217347e-03f, + 4.829282520779390811e-03f, + 4.586115573237751521e-03f, + 4.338577605899722467e-03f, + 4.086922171123733884e-03f, + 3.831406709168724920e-03f, + 3.572292285227009461e-03f, + 3.309843323076701056e-03f, + 3.044327335621568181e-03f, + 2.776014652595465773e-03f, + 2.505178145706950243e-03f, + 2.232092951502079141e-03f, + 1.957036192228632423e-03f, + 1.680286694983667639e-03f, + 1.402124709426648972e-03f, + 1.122831624348555194e-03f, + 8.426896833769130903e-04f, + 5.619817001094690135e-04f, + 2.809907729590478470e-04f, + 0.000000000000000000e+00f, + -2.807078058981391780e-04f, + -5.608504013647517628e-04f, + -8.401463959614267896e-04f, + -1.118315534473937048e-03f, + -1.395078977776910336e-03f, + -1.670159581991349264e-03f, + -1.943282175656975462e-03f, + -2.214173834640201406e-03f, + -2.482564154505302687e-03f, + -2.748185520076693727e-03f, + -3.010773371923358872e-03f, + -3.270066469502342678e-03f, + -3.525807150696843618e-03f, + -3.777741587494939240e-03f, + -4.025620037552721069e-03f, + -4.269197091394013634e-03f, + -4.508231915003397400e-03f, + -4.742488487571064684e-03f, + -4.971735834156138824e-03f, + -5.195748253041122811e-03f, + -5.414305537549929381e-03f, + -5.627193192117104295e-03f, + -5.834202642391930586e-03f, + -6.035131439175642903e-03f, + -6.229783455990234309e-03f, + -6.417969080087524217e-03f, + -6.599505396713676100e-03f, + -6.774216366448439740e-03f, + -6.941932995450164623e-03f, + -7.102493498440299972e-03f, + -7.255743454271620582e-03f, + -7.401535953931983637e-03f, + -7.539731740839664825e-03f, + -7.670199343300234535e-03f, + -7.792815198996800620e-03f, + -7.907463771397596833e-03f, + -8.014037657972214804e-03f, + -8.112437690114479572e-03f, + -8.202573024681410890e-03f, + -8.284361227063144831e-03f, + -8.357728345709419457e-03f, + -8.422608978046395439e-03f, + -8.478946327725278564e-03f, + -8.526692253154843221e-03f, + -8.565807307276868815e-03f, + -8.596260768553768902e-03f, + -8.618030663145858153e-03f, + -8.631103778264705498e-03f, + -8.635475666698075314e-03f, + -8.631150642510639071e-03f, + -8.618141767933615305e-03f, + -8.596470831465410564e-03f, + -8.566168317214016212e-03f, + -8.527273365520683310e-03f, + -8.479833724913378445e-03f, + -8.423905695446994024e-03f, + -8.359554063495495263e-03f, + -8.286852028071115678e-03f, + -8.205881118751968267e-03f, + -8.116731105309984984e-03f, + -8.019499899138108831e-03f, + -7.914293446583613167e-03f, + -7.801225614304001070e-03f, + -7.680418066767507809e-03f, + -7.552000136030336853e-03f, + -7.416108683929066407e-03f, + -7.272887956833709935e-03f, + -7.122489433116511483e-03f, + -6.965071663495360846e-03f, + -6.800800104421189651e-03f, + -6.629846944682925639e-03f, + -6.452390925411476304e-03f, + -6.268617153670886545e-03f, + -6.078716909829352984e-03f, + -5.882887448911673298e-03f, + -5.681331796138239937e-03f, + -5.474258536861224822e-03f, + -5.261881601117059278e-03f, + -5.044420043014674268e-03f, + -4.822097815188827914e-03f, + -4.595143538549655710e-03f, + -4.363790267563028361e-03f, + -4.128275251306491068e-03f, + -3.888839690540101934e-03f, + -3.645728491045435640e-03f, + -3.399190013480753690e-03f, + -3.149475820010231263e-03f, + -2.896840417964342308e-03f, + -2.641541000791211135e-03f, + -2.383837186564273774e-03f, + -2.123990754310813977e-03f, + -1.862265378427587111e-03f, + -1.598926361455722204e-03f, + -1.334240365481033667e-03f, + -1.068475142436885140e-03f, + -8.018992635760308074e-04f, + -5.347818483891565765e-04f, + -2.673922932415280962e-04f, + -9.079959879021497232e-17f, + 2.671258950737993680e-04f, + 5.337167918945780664e-04f, + 7.995048963151187319e-04f, + 1.064223488808225876e-03f, + 1.327607191801307438e-03f, + 1.589392235393608270e-03f, + 1.849316721191365896e-03f, + 2.107120883999156515e-03f, + 2.362547351101621299e-03f, + 2.615341398882998439e-03f, + 2.865251206523531432e-03f, + 3.112028106524595324e-03f, + 3.355426831810707448e-03f, + 3.595205759164358736e-03f, + 3.831127148753331844e-03f, + 4.062957379511429948e-03f, + 4.290467180140932618e-03f, + 4.513431855509694376e-03f, + 4.731631508217054409e-03f, + 4.944851255114078407e-03f, + 5.152881438560737853e-03f, + 5.355517832217622683e-03f, + 5.552561841166678107e-03f, + 5.743820696166867384e-03f, + 5.929107641855835276e-03f, + 6.108242118712046975e-03f, + 6.281049938603144346e-03f, + 6.447363453748070593e-03f, + 6.607021718930415448e-03f, + 6.759870646807101223e-03f, + 6.905763156161545159e-03f, + 7.044559312960290212e-03f, + 7.176126464077911202e-03f, + 7.300339363562619553e-03f, + 7.417080291323936703e-03f, + 7.526239164128890706e-03f, + 7.627713638804527879e-03f, + 7.721409207549118775e-03f, + 7.807239285264657921e-03f, + 7.885125288831035251e-03f, + 7.954996708249086751e-03f, + 8.016791169590116797e-03f, + 8.070454489695856257e-03f, + 8.115940722582272102e-03f, + 8.153212197509116660e-03f, + 8.182239548684301991e-03f, + 8.203001736582492612e-03f, + 8.215486060864016227e-03f, + 8.219688164889776480e-03f, + 8.215612031835866150e-03f, + 8.203269972420074163e-03f, + 8.182682604260985149e-03f, + 8.153878822898639675e-03f, + 8.116895764514334491e-03f, + 8.071778760395010785e-03f, + 8.018581283196542925e-03f, + 7.957364885067841689e-03f, + 7.888199127706180952e-03f, + 7.811161504422274408e-03f, + 7.726337354300897436e-03f, + 7.633819768552089179e-03f, + 7.533709489153867997e-03f, + 7.426114799896956116e-03f, + 7.311151409948320190e-03f, + 7.188942330057568331e-03f, + 7.059617741539236935e-03f, + 6.923314858168461497e-03f, + 6.780177781137243509e-03f, + 6.630357347223709771e-03f, + 6.474010970332770391e-03f, + 6.311302476576784518e-03f, + 6.142401933065200215e-03f, + 5.967485470584375090e-03f, + 5.786735100350979578e-03f, + 5.600338525028452849e-03f, + 5.408488944204285429e-03f, + 5.211384854526987694e-03f, + 5.009229844711029882e-03f, + 4.802232385620449663e-03f, + 4.590605615646119360e-03f, + 4.374567121599736569e-03f, + 4.154338715345936607e-03f, + 3.930146206405986734e-03f, + 3.702219170760879478e-03f, + 3.470790716094145426e-03f, + 3.236097243712496643e-03f, + 2.998378207386371425e-03f, + 2.757875869357837798e-03f, + 2.514835053763304993e-03f, + 2.269502897720573724e-03f, + 2.022128600335697159e-03f, + 1.772963169880989280e-03f, + 1.522259169403208240e-03f, + 1.270270461017685608e-03f, + 1.017251949147536440e-03f, + 7.634593229678904650e-04f, + 5.091487983134088255e-04f, + 2.545768593114422170e-04f, + 5.893834195817279027e-17f, + -2.543255338102004309e-04f, + -5.081440021684953965e-04f, + -7.612004278544677463e-04f, + -1.013240852227075906e-03f, + -1.264012589796192692e-03f, + -1.513264481263194719e-03f, + -1.760747144774524840e-03f, + -2.006213225141300748e-03f, + -2.249417640770990170e-03f, + -2.490117828070589987e-03f, + -2.728073983073443527e-03f, + -2.963049300051106942e-03f, + -3.194810206873958253e-03f, + -3.423126596884991813e-03f, + -3.647772057057938316e-03f, + -3.868524092214752682e-03f, + -4.085164345078219975e-03f, + -4.297478811945374191e-03f, + -4.505258053766428641e-03f, + -4.708297402422947572e-03f, + -4.906397162001897849e-03f, + -5.099362804867554194e-03f, + -5.287005162340526442e-03f, + -5.469140609795000892e-03f, + -5.645591245996113387e-03f, + -5.816185066500464615e-03f, + -5.980756130952048950e-03f, + -6.139144724111944909e-03f, + -6.291197510464445995e-03f, + -6.436767682251153498e-03f, + -6.575715100791147336e-03f, + -6.707906430950256842e-03f, + -6.833215268632009988e-03f, + -6.951522261168058443e-03f, + -7.062715220494850468e-03f, + -7.166689229008634497e-03f, + -7.263346738000107591e-03f, + -7.352597658577248937e-03f, + -7.434359444991439289e-03f, + -7.508557170290937506e-03f, + -7.575123594233416392e-03f, + -7.633999223396016783e-03f, + -7.685132363431001340e-03f, + -7.728479163421451623e-03f, + -7.764003652300489888e-03f, + -7.791677767305085246e-03f, + -7.811481374443590177e-03f, + -7.823402280964399449e-03f, + -7.827436239820800487e-03f, + -7.823586946135632075e-03f, + -7.811866025676963803e-03f, + -7.792293015364394268e-03f, + -7.764895335833248320e-03f, + -7.729708256092200462e-03f, + -7.686774850317674296e-03f, + -7.636145946835978977e-03f, + -7.577880069352489409e-03f, + -7.512043370494353445e-03f, + -7.438709557741495296e-03f, + -7.357959811827293611e-03f, + -7.269882697699128586e-03f, + -7.174574068135403972e-03f, + -7.072136960122816021e-03f, + -6.962681484106240416e-03f, + -6.846324706228426420e-03f, + -6.723190523685911024e-03f, + -6.593409533333032847e-03f, + -6.457118893672204353e-03f, + -6.314462180376954545e-03f, + -6.165589235498591079e-03f, + -6.010656010514694655e-03f, + -5.849824403383760418e-03f, + -5.683262089774722935e-03f, + -5.511142348648704649e-03f, + -5.333643882371955774e-03f, + -5.150950631548067808e-03f, + -4.963251584760376527e-03f, + -4.770740583420043056e-03f, + -4.573616121923121738e-03f, + -4.372081143319735304e-03f, + -4.166342830707624179e-03f, + -3.956612394562757443e-03f, + -3.743104856225459159e-03f, + -3.526038827764110296e-03f, + -3.305636288440114059e-03f, + -3.082122358004176291e-03f, + -2.855725067054290869e-03f, + -2.626675124688376134e-03f, + -2.395205683690529615e-03f, + -2.161552103486554573e-03f, + -1.925951711112042913e-03f, + -1.688643560434465851e-03f, + -1.449868189872311657e-03f, + -1.209867378858563115e-03f, + -9.688839032931976462e-04f, + -7.271612902323416720e-04f, + -4.849435720621983882e-04f, + -2.424750404039046129e-04f, + -2.993458375907816894e-17f, + 2.422374771728505677e-04f, + 4.839937973155881718e-04f, + 7.250260894964933667e-04f, + 9.650924493755287268e-04f, + 1.203952181715645022e-03f, + 1.441366041441651457e-03f, + 1.677096473002762708e-03f, + 1.910907847800708860e-03f, + 2.142566699447316300e-03f, + 2.371841956615023273e-03f, + 2.598505173249376302e-03f, + 2.822330755915376365e-03f, + 3.043096188049002060e-03f, + 3.260582250895563590e-03f, + 3.474573240909645862e-03f, + 3.684857183408437892e-03f, + 3.891226042261025642e-03f, + 4.093475925410680442e-03f, + 4.291407286024813764e-03f, + 4.484825119075430515e-03f, + 4.673539153157502297e-03f, + 4.857364037355267616e-03f, + 5.036119522974105353e-03f, + 5.209630639960896592e-03f, + 5.377727867838498661e-03f, + 5.540247300990066084e-03f, + 5.697030808130492709e-03f, + 5.847926185810888196e-03f, + 5.992787305808217578e-03f, + 6.131474256255946623e-03f, + 6.263853476381850416e-03f, + 6.389797884721984053e-03f, + 6.509187000688825345e-03f, + 6.621907059378241700e-03f, + 6.727851119505293652e-03f, + 6.826919164367567169e-03f, + 6.919018195741605953e-03f, + 7.004062320623680518e-03f, + 7.081972830736373535e-03f, + 7.152678274725585150e-03f, + 7.216114522985169963e-03f, + 7.272224825048948307e-03f, + 7.320959859500953196e-03f, + 7.362277776360223042e-03f, + 7.396144231905143855e-03f, + 7.422532415909789162e-03f, + 7.441423071271871179e-03f, + 7.452804506020377015e-03f, + 7.456672597697913858e-03f, + 7.453030790120977571e-03f, + 7.441890082528809791e-03f, + 7.423269011139091954e-03f, + 7.397193623136587293e-03f, + 7.363697443128093892e-03f, + 7.322821432105069799e-03f, + 7.274613938962194541e-03f, + 7.219130644628227352e-03f, + 7.156434498872478629e-03f, + 7.086595649857397282e-03f, + 7.009691366515777115e-03f, + 6.925805953836947082e-03f, + 6.835030661154887534e-03f, + 6.737463583536625229e-03f, + 6.633209556377676723e-03f, + 6.522380043316587661e-03f, + 6.405093017587785986e-03f, + 6.281472836939533053e-03f, + 6.151650112247645033e-03f, + 6.015761569964638532e-03f, + 5.873949908548246022e-03f, + 5.726363649019010349e-03f, + 5.573156979804561387e-03f, + 5.414489596030440909e-03f, + 5.250526533426200064e-03f, + 5.081437997018541791e-03f, + 4.907399184788277351e-03f, + 4.728590106474792054e-03f, + 4.545195397714440512e-03f, + 4.357404129703668430e-03f, + 4.165409614584718312e-03f, + 3.969409206751546570e-03f, + 3.769604100281869798e-03f, + 3.566199122702250202e-03f, + 3.359402525296319511e-03f, + 3.149425770172853845e-03f, + 2.936483314308355533e-03f, + 2.720792390786955402e-03f, + 2.502572787458282825e-03f, + 2.282046623241240982e-03f, + 2.059438122297536054e-03f, + 1.834973386307630792e-03f, + 1.608880165078690333e-03f, + 1.381387625716168745e-03f, + 1.152726120594538663e-03f, + 9.231269543609431621e-04f, + 6.928221502061572470e-04f, + 4.620442156413446209e-04f, + 2.310259080137343159e-04f, + 0.000000000000000000e+00f, + -2.308009546876257196e-04f, + -4.611448551480424674e-04f, + -6.908002864531671621e-04f, + -9.195367518942560445e-04f, + -1.147124904077175120e-03f, + -1.373336774636224914e-03f, + -1.597946002337608667e-03f, + -1.820728059342699347e-03f, + -2.041460475406135615e-03f, + -2.259923059786094965e-03f, + -2.475898120643176686e-03f, + -2.689170681712491420e-03f, + -2.899528696030911467e-03f, + -3.106763256509465377e-03f, + -3.310668803139505106e-03f, + -3.511043326630707874e-03f, + -3.707688568276315544e-03f, + -3.900410215849520103e-03f, + -4.089018095338427944e-03f, + -4.273326358329034881e-03f, + -4.453153664852741063e-03f, + -4.628323361519555770e-03f, + -4.798663654760284072e-03f, + -4.964007779010489244e-03f, + -5.124194159669920833e-03f, + -5.279066570679284004e-03f, + -5.428474286561691883e-03f, + -5.572272228779376162e-03f, + -5.710321106265994241e-03f, + -5.842487549997011850e-03f, + -5.968644241469281582e-03f, + -6.088670034966893116e-03f, + -6.202450073495178670e-03f, + -6.309875898273007572e-03f, + -6.410845551679807824e-03f, + -6.505263673558881257e-03f, + -6.593041590787944613e-03f, + -6.674097400032071199e-03f, + -6.748356043603334110e-03f, + -6.815749378356467103e-03f, + -6.876216237559267495e-03f, + -6.929702485681070272e-03f, + -6.976161066051603243e-03f, + -7.015552041349363589e-03f, + -7.047842626885069371e-03f, + -7.073007216654443596e-03f, + -7.091027402140489926e-03f, + -7.101891983853740598e-03f, + -7.105596975605809294e-03f, + -7.102145601518914352e-03f, + -7.091548285781580294e-03f, + -7.073822635167690588e-03f, + -7.048993414343677349e-03f, + -7.017092513995498021e-03f, + -6.978158911814610725e-03f, + -6.932238626389115345e-03f, + -6.879384664053103844e-03f, + -6.819656958754997597e-03f, + -6.753122305011623888e-03f, + -6.679854284022603873e-03f, + -6.599933183026034100e-03f, + -6.513445907982721647e-03f, + -6.420485889683830161e-03f, + -6.321152983382738975e-03f, + -6.215553362058191117e-03f, + -6.103799403422135138e-03f, + -5.986009570792679216e-03f, + -5.862308287957658688e-03f, + -5.732825808160025433e-03f, + -5.597698077343937588e-03f, + -5.457066591803097846e-03f, + -5.311078250381432928e-03f, + -5.159885201379617314e-03f, + -5.003644684325990639e-03f, + -4.842518866777322309e-03f, + -4.676674676317842463e-03f, + -4.506283627929590085e-03f, + -4.331521646914106120e-03f, + -4.152568887545756218e-03f, + -3.969609547645198966e-03f, + -3.782831679262896318e-03f, + -3.592426995666025014e-03f, + -3.398590674828782209e-03f, + -3.201521159624679935e-03f, + -3.001419954927217991e-03f, + -2.798491421825367344e-03f, + -2.592942569162944196e-03f, + -2.384982842615481630e-03f, + -2.174823911519171114e-03f, + -1.962679453667881199e-03f, + -1.748764938296653790e-03f, + -1.533297407473102874e-03f, + -1.316495256117520629e-03f, + -1.098578010873439530e-03f, + -8.797661080547270916e-04f, + -6.602806708906880156e-04f, + -4.403432862964624440e-04f, + -2.201757813928862664e-04f, + 2.040351603294562245e-17f, + 2.199624206685035094e-04f, + 4.394902728878673139e-04f, + 6.583630006562409291e-04f, + 8.763609210572648189e-04f, + 1.093265444530637075e-03f, + 1.308859293828115375e-03f, + 1.522926721436776171e-03f, + 1.735253725253141800e-03f, + 1.945628262290407520e-03f, + 2.153840460208438813e-03f, + 2.359682826453400172e-03f, + 2.562950454799774267e-03f, + 2.763441229090153693e-03f, + 2.960956023969243955e-03f, + 3.155298902413077380e-03f, + 3.346277309858471712e-03f, + 3.533702264740658325e-03f, + 3.717388545249705484e-03f, + 3.897154872122122679e-03f, + 4.072824087288320731e-03f, + 4.244223328198080784e-03f, + 4.411184197655197183e-03f, + 4.573542928992711636e-03f, + 4.731140546427802310e-03f, + 4.883823020440311580e-03f, + 5.031441418021543807e-03f, + 5.173852047649186298e-03f, + 5.310916598845810341e-03f, + 5.442502276186440141e-03f, + 5.568481927626215550e-03f, + 5.688734167023349123e-03f, + 5.803143490740288873e-03f, + 5.911600388211953397e-03f, + 6.014001446374228968e-03f, + 6.110249447855176444e-03f, + 6.200253462834825341e-03f, + 6.283928934487773878e-03f, + 6.361197757929115161e-03f, + 6.431988352589909121e-03f, + 6.496235727955871307e-03f, + 6.553881542609762793e-03f, + 6.604874156524493181e-03f, + 6.649168676560485158e-03f, + 6.686726995128343919e-03f, + 6.717517821984657529e-03f, + 6.741516709135119897e-03f, + 6.758706068827057510e-03f, + 6.769075184619558622e-03f, + 6.772620215526905380e-03f, + 6.769344193237896226e-03f, + 6.759257012420358431e-03f, + 6.742375414127462462e-03f, + 6.718722962329050537e-03f, + 6.688330013598418541e-03f, + 6.651233679991463629e-03f, + 6.607477785162285504e-03f, + 6.557112813765961223e-03f, + 6.500195854205608435e-03f, + 6.436790534788347680e-03f, + 6.366966953360074857e-03f, + 6.290801600496780284e-03f, + 6.208377276335759996e-03f, + 6.119783001136048020e-03f, + 6.025113919665214118e-03f, + 5.924471199513612826e-03f, + 5.817961923445152776e-03f, + 5.705698975897815182e-03f, + 5.587800923754974829e-03f, + 5.464391891511682919e-03f, + 5.335601430968130686e-03f, + 5.201564385586319485e-03f, + 5.062420749651009438e-03f, + 4.918315522382780622e-03f, + 4.769398557154420036e-03f, + 4.615824405966431621e-03f, + 4.457752159344428866e-03f, + 4.295345281821967565e-03f, + 4.128771443180331673e-03f, + 3.958202345618636216e-03f, + 3.783813547031247577e-03f, + 3.605784280576109987e-03f, + 3.424297270716869252e-03f, + 3.239538545929211699e-03f, + 3.051697248262471695e-03f, + 2.860965439950404268e-03f, + 2.667537907270099533e-03f, + 2.471611961848510855e-03f, + 2.273387239617670301e-03f, + 2.073065497626217380e-03f, + 1.870850408910636978e-03f, + 1.666947355636944159e-03f, + 1.461563220720618573e-03f, + 1.254906178138427263e-03f, + 1.047185482141736864e-03f, + 8.386112555867926812e-04f, + 6.293942775949764364e-04f, + 4.197457707565461658e-04f, + 2.098771880941680316e-04f, + 5.182902902306673378e-17f, + -2.096745186397723764e-04f, + -4.189355009176130525e-04f, + -6.275726997620592390e-04f, + -8.353766989667140222e-04f, + -1.042139123179063390e-03f, + -1.247652846640042714e-03f, + -1.451712200463105501e-03f, + -1.654113178248326063e-03f, + -1.854653639823899535e-03f, + -2.053133512912701415e-03f, + -2.249354992523720179e-03f, + -2.443122737868256775e-03f, + -2.634244066605816777e-03f, + -2.822529146228016077e-03f, + -3.007791182387730897e-03f, + -3.189846603989948855e-03f, + -3.368515244858865266e-03f, + -3.543620521803565997e-03f, + -3.714989608904360665e-03f, + -3.882453607850389066e-03f, + -4.045847714158852700e-03f, + -4.205011379113398479e-03f, + -4.359788467263430063e-03f, + -4.510027409328340973e-03f, + -4.655581350359307320e-03f, + -4.796308293012311458e-03f, + -4.932071235793691541e-03f, + -5.062738306144363987e-03f, + -5.188182888232652744e-03f, + -5.308283745332808071e-03f, + -5.422925136671735008e-03f, + -5.531996928630324509e-03f, + -5.635394700194489362e-03f, + -5.733019842553966489e-03f, + -5.824779652754896557e-03f, + -5.910587421317968493e-03f, + -5.990362513738736391e-03f, + -6.064030445795148827e-03f, + -6.131522952591644815e-03f, + -6.192778051276466925e-03f, + -6.247740097375581447e-03f, + -6.296359834692139695e-03f, + -6.338594438727926730e-03f, + -6.374407553588771515e-03f, + -6.403769322343668378e-03f, + -6.426656410812841419e-03f, + -6.443052024767408938e-03f, + -6.452945920529682723e-03f, + -6.456334408969627466e-03f, + -6.453220352899971361e-03f, + -6.443613157878890461e-03f, + -6.427528756435856722e-03f, + -6.404989585742853347e-03f, + -6.376024558759821499e-03f, + -6.340669028889607886e-03f, + -6.298964748184136819e-03f, + -6.250959819150409338e-03f, + -6.196708640210494418e-03f, + -6.136271844877025546e-03f, + -6.069716234711278365e-03f, + -5.997114706136989597e-03f, + -5.918546171190292200e-03f, + -5.834095472290020540e-03f, + -5.743853291122007730e-03f, + -5.647916051732237638e-03f, + -5.546385817934258548e-03f, + -5.439370185137868373e-03f, + -5.326982166714451343e-03f, + -5.209340075018284791e-03f, + -5.086567397188134117e-03f, + -4.958792665860112768e-03f, + -4.826149324926455597e-03f, + -4.688775590479438843e-03f, + -4.546814307086526931e-03f, + -4.400412799544136007e-03f, + -4.249722720265064653e-03f, + -4.094899892456855747e-03f, + -3.936104149252287777e-03f, + -3.773499168959473186e-03f, + -3.607252306599120252e-03f, + -3.437534421903807366e-03f, + -3.264519703955130747e-03f, + -3.088385492637782913e-03f, + -2.909312097094693232e-03f, + -2.727482611368168587e-03f, + -2.543082727414555134e-03f, + -2.356300545685272984e-03f, + -2.167326383463741464e-03f, + -1.976352581158412423e-03f, + -1.783573306742843468e-03f, + -1.589184358546649181e-03f, + -1.393382966593760411e-03f, + -1.196367592691694598e-03f, + -9.983377294733853085e-04f, + -7.994936985940647280e-04f, + -6.000364482887320626e-04f, + -4.001673504937983648e-04f, + -2.000879977366511349e-04f, + -2.778966336884198701e-17f, + 1.998952182369787911e-04f, + 3.993966205749271080e-04f, + 5.983037606844037121e-04f, + 7.964169835089038611e-04f, + 9.935376254762236150e-04f, + 1.189468213520454305e-03f, + 1.384012662713176006e-03f, + 1.576976472307146200e-03f, + 1.768166919997466715e-03f, + 1.957393254204812128e-03f, + 2.144466884189903406e-03f, + 2.329201567810756240e-03f, + 2.511413596733711156e-03f, + 2.690921978917853227e-03f, + 2.867548618186650019e-03f, + 3.041118490714745520e-03f, + 3.211459818250186199e-03f, + 3.378404237904315821e-03f, + 3.541786968339587227e-03f, + 3.701446972192292979e-03f, + 3.857227114570970297e-03f, + 4.008974317473392411e-03f, + 4.156539709971333353e-03f, + 4.299778774016645676e-03f, + 4.438551485724410994e-03f, + 4.572722451997321066e-03f, + 4.702161042356552134e-03f, + 4.826741515851794284e-03f, + 4.946343142927884552e-03f, + 5.060850322128870871e-03f, + 5.170152691528663233e-03f, + 5.274145234779758183e-03f, + 5.372728381679093071e-03f, + 5.465808103155446809e-03f, + 5.553296000587267314e-03f, + 5.635109389366979755e-03f, + 5.711171376633489283e-03f, + 5.781410933099281717e-03f, + 5.845762958906964256e-03f, + 5.904168343452670387e-03f, + 5.956574019124233517e-03f, + 6.002933008903923832e-03f, + 6.043204467795012733e-03f, + 6.077353718035662794e-03f, + 6.105352278070978224e-03f, + 6.127177885260168266e-03f, + 6.142814512301600360e-03f, + 6.152252377365692929e-03f, + 6.155487947931146189e-03f, + 6.152523938326903176e-03f, + 6.143369300988309016e-03f, + 6.128039211442289080e-03f, + 6.106555047042762537e-03f, + 6.078944359483547284e-03f, + 6.045240841122706543e-03f, + 6.005484285157759554e-03f, + 5.959720539698134222e-03f, + 5.908001455786886062e-03f, + 5.850384829429483569e-03f, + 5.786934337694401610e-03f, + 5.717719468954846757e-03f, + 5.642815447348050774e-03f, + 5.562303151533275723e-03f, + 5.476269027836244349e-03f, + 5.384804997872509429e-03f, + 5.288008360747798245e-03f, + 5.185981689939928203e-03f, + 5.078832724969969611e-03f, + 4.966674257977718963e-03f, + 4.849624015320279195e-03f, + 4.727804534317043249e-03f, + 4.601343035271158316e-03f, + 4.470371288899312352e-03f, + 4.335025479308940791e-03f, + 4.195446062664641082e-03f, + 4.051777621689569946e-03f, + 3.904168716153416478e-03f, + 3.752771729500774690e-03f, + 3.597742711777335116e-03f, + 3.439241219017221893e-03f, + 3.277430149254536695e-03f, + 3.112475575329156242e-03f, + 2.944546574657440699e-03f, + 2.773815056141443278e-03f, + 2.600455584395403811e-03f, + 2.424645201466829776e-03f, + 2.246563246236072363e-03f, + 2.066391171676635035e-03f, + 1.884312360164382659e-03f, + 1.700511937020543225e-03f, + 1.515176582480621701e-03f, + 1.328494342278832389e-03f, + 1.140654437039362876e-03f, + 9.518470706689883707e-04f, + 7.622632379441338004e-04f, + 5.720945314859912732e-04f, + 3.815329483207086005e-04f, + 1.907706962172203138e-04f, + 0.000000000000000000e+00f, + -1.905870919690720166e-04f, + -3.807989009460705778e-04f, + -5.704443104011880719e-04f, + -7.593329578651235225e-04f, + -9.472754258310465579e-04f, + -1.134083431521770496e-03f, + -1.319570015332951216e-03f, + -1.503549727762363468e-03f, + -1.685838814639319377e-03f, + -1.866255400470208034e-03f, + -2.044619669715354044e-03f, + -2.220754045819160229e-03f, + -2.394483367813274831e-03f, + -2.565635064319175124e-03f, + -2.734039324775422008e-03f, + -2.899529267722648820e-03f, + -3.061941105977069883e-03f, + -3.221114308530460043e-03f, + -3.376891759017279938e-03f, + -3.529119910591425012e-03f, + -3.677648937060845960e-03f, + -3.822332880132129837e-03f, + -3.963029792618880109e-03f, + -4.099601877475613464e-03f, + -4.231915622519577709e-03f, + -4.359841930709697395e-03f, + -4.483256245856345398e-03f, + -4.602038673638307598e-03f, + -4.716074097811356024e-03f, + -4.825252291494681184e-03f, + -4.929468023428436492e-03f, + -5.028621159100716588e-03f, + -5.122616756646161500e-03f, + -5.211365157425208207e-03f, + -5.294782071198274320e-03f, + -5.372788655813301971e-03f, + -5.445311591332913613e-03f, + -5.512283148530877468e-03f, + -5.573641251695150671e-03f, + -5.629329535678900300e-03f, + -5.679297397148663600e-03f, + -5.723500039982650292e-03f, + -5.761898514779588421e-03f, + -5.794459752444061987e-03f, + -5.821156591819873563e-03f, + -5.841967801349767786e-03f, + -5.856878094745045400e-03f, + -5.865878140655318707e-03f, + -5.868964566334378651e-03f, + -5.866139955304165016e-03f, + -5.857412839025080524e-03f, + -5.842797682586693166e-03f, + -5.822314864439076185e-03f, + -5.795990650190794430e-03f, + -5.763857160505719661e-03f, + -5.725952333136686070e-03f, + -5.682319879139611715e-03f, + -5.633009233318153446e-03f, + -5.578075498953882598e-03f, + -5.517579386883428826e-03f, + -5.451587148989341623e-03f, + -5.380170506176684860e-03f, + -5.303406570913458962e-03f, + -5.221377764418140034e-03f, + -5.134171728582574354e-03f, + -5.041881232723846064e-03f, + -4.944604075264455272e-03f, + -4.842442980444399032e-03f, + -4.735505490173459210e-03f, + -4.623903851138305189e-03f, + -4.507754897281265882e-03f, + -4.387179927774727435e-03f, + -4.262304580617813123e-03f, + -4.133258701986374309e-03f, + -4.000176211472765767e-03f, + -3.863194963354634262e-03f, + -3.722456604035540191e-03f, + -3.578106425806113627e-03f, + -3.430293217074662122e-03f, + -3.279169109222944672e-03f, + -3.124889420243918709e-03f, + -2.967612495321265455e-03f, + -2.807499544515807202e-03f, + -2.644714477722959114e-03f, + -2.479423737071674658e-03f, + -2.311796126935456146e-03f, + -2.142002641728153745e-03f, + -1.970216291661061950e-03f, + -1.796611926638601179e-03f, + -1.621366058471044799e-03f, + -1.444656681584796090e-03f, + -1.266663092413158409e-03f, + -1.087565707650077398e-03f, + -9.075458815500990310e-04f, + -7.267857224613794324e-04f, + -5.454679087747773278e-04f, + -3.637755044768799673e-04f, + -1.818917744922234167e-04f, + -6.738072953108251659e-17f, + 1.817167060868667974e-04f, + 3.630755832968266678e-04f, + 5.438944072423667351e-04f, + 7.239916725462016735e-04f, + 9.031867748685456793e-04f, + 1.081300191851528036e-03f, + 1.258153662800393048e-03f, + 1.433570366922595502e-03f, + 1.607375099944760447e-03f, + 1.779394448933648617e-03f, + 1.949456965144877449e-03f, + 2.117393334728095468e-03f, + 2.283036547119419220e-03f, + 2.446222060952827054e-03f, + 2.606787967325983370e-03f, + 2.764575150259260348e-03f, + 2.919427444189183745e-03f, + 3.071191788339645758e-03f, + 3.219718377819110952e-03f, + 3.364860811295488155e-03f, + 3.506476235101599771e-03f, + 3.644425483631654871e-03f, + 3.778573215889237825e-03f, + 3.908788048053789092e-03f, + 4.034942681936477468e-03f, + 4.156914029198645506e-03f, + 4.274583331213595815e-03f, + 4.387836274453780008e-03f, + 4.496563101292173729e-03f, + 4.600658716111065936e-03f, + 4.700022786615127950e-03f, + 4.794559840251754780e-03f, + 4.884179355646818196e-03f, + 4.968795848967465581e-03f, + 5.048328955131142076e-03f, + 5.122703503783020661e-03f, + 5.191849589970850935e-03f, + 5.255702639451336616e-03f, + 5.314203468567116513e-03f, + 5.367298338639234223e-03f, + 5.414939004826021217e-03f, + 5.457082759404304449e-03f, + 5.493692469434578556e-03f, + 5.524736608777790041e-03f, + 5.550189284437050813e-03f, + 5.570030257202884111e-03f, + 5.584244956587067731e-03f, + 5.592824490035200498e-03f, + 5.595765646414466166e-03f, + 5.593070893778484716e-03f, + 5.584748371416978392e-03f, + 5.570811876203813663e-03f, + 5.551280843262597353e-03f, + 5.526180320974835580e-03f, + 5.495540940361090358e-03f, + 5.459398878871563054e-03f, + 5.417795818627875980e-03f, + 5.370778899163226178e-03f, + 5.318400664714218601e-03f, + 5.260719006122124147e-03f, + 5.197797097407722174e-03f, + 5.129703327088560444e-03f, + 5.056511224312396427e-03f, + 4.978299379887104678e-03f, + 4.895151362290443668e-03f, + 4.807155628749874669e-03f, + 4.714405431485941232e-03f, + 4.616998719219183103e-03f, + 4.515038034043206486e-03f, + 4.408630403773131437e-03f, + 4.297887229881802197e-03f, + 4.182924171140340805e-03f, + 4.063861023085189352e-03f, + 3.940821593436607748e-03f, + 3.813933573597338717e-03f, + 3.683328406365983000e-03f, + 3.549141150000212786e-03f, + 3.411510338771623577e-03f, + 3.270577840155389476e-03f, + 3.126488708801145999e-03f, + 2.979391037436725231e-03f, + 2.829435804855929236e-03f, + 2.676776721147767438e-03f, + 2.521570070325003087e-03f, + 2.363974550512310240e-03f, + 2.204151111858506946e-03f, + 2.042262792337711051e-03f, + 1.878474551605653284e-03f, + 1.712953103082745163e-03f, + 1.545866744432049548e-03f, + 1.377385186606322909e-03f, + 1.207679381635921347e-03f, + 1.036921349334177364e-03f, + 8.652840030934819777e-04f, + 6.929409749502218625e-04f, + 5.200664400946462904e-04f, + 3.468349410021595147e-04f, + 1.734212113648546741e-04f, + 4.550251594910668594e-17f, + -1.732541050876819561e-04f, + -3.461668523119788257e-04f, + -5.185645016036600878e-04f, + -6.902739988253162214e-04f, + -8.611231493274518678e-04f, + -1.030940790473021396e-03f, + -1.199556962955737344e-03f, + -1.366803080743145661e-03f, + -1.532512099472770496e-03f, + -1.696518683134078977e-03f, + -1.858659368870755474e-03f, + -2.018772729737835104e-03f, + -2.176699535252429873e-03f, + -2.332282909579588056e-03f, + -2.485368487193882845e-03f, + -2.635804565865009202e-03f, + -2.783442256814043243e-03f, + -2.928135631893509418e-03f, + -3.069741867644090218e-03f, + -3.208121386087987512e-03f, + -3.343137992118676207e-03f, + -3.474659007352662483e-03f, + -3.602555400312496166e-03f, + -3.726701912812024550e-03f, + -3.846977182422010779e-03f, + -3.963263860895238633e-03f, + -4.075448728436278055e-03f, + -4.183422803705368759e-03f, + -4.287081449448809645e-03f, + -4.386324473654241302e-03f, + -4.481056226133709602e-03f, + -4.571185690440540857e-03f, + -4.656626571033325307e-03f, + -4.737297375602708346e-03f, + -4.813121492483313744e-03f, + -4.884027263077780033e-03f, + -4.949948049224051072e-03f, + -5.010822295443905297e-03f, + -5.066593586014279949e-03f, + -5.117210696809050205e-03f, + -5.162627641864468188e-03f, + -5.202803714625973616e-03f, + -5.237703523840436977e-03f, + -5.267297024062328296e-03f, + -5.291559540748885272e-03f, + -5.310471789923680921e-03f, + -5.324019892394351271e-03f, + -5.332195382515387931e-03f, + -5.334995211492236412e-03f, + -5.332421745228884194e-03f, + -5.324482756726165410e-03f, + -5.311191413043757879e-03f, + -5.292566256844271830e-03f, + -5.268631182543137906e-03f, + -5.239415407093645990e-03f, + -5.204953435441478891e-03f, + -5.165285020688987344e-03f, + -5.120455119014034190e-03f, + -5.070513839394155328e-03f, + -5.015516388191593698e-03f, + -4.955523008659636248e-03f, + -4.890598915436772734e-03f, + -4.820814224098224007e-03f, + -4.746243875842361994e-03f, + -4.666967557390416105e-03f, + -4.583069616186550947e-03f, + -4.494638970986890303e-03f, + -4.401769017932832123e-03f, + -4.304557532207274433e-03f, + -4.203106565376605631e-03f, + -4.097522338526705075e-03f, + -3.987915131304275475e-03f, + -3.874399166978647214e-03f, + -3.757092493644813031e-03f, + -3.636116861689554780e-03f, + -3.511597597648849663e-03f, + -3.383663474586599915e-03f, + -3.252446579127917913e-03f, + -3.118082175285466148e-03f, + -2.980708565217376257e-03f, + -2.840466947061273412e-03f, + -2.697501269989864385e-03f, + -2.551958086636046431e-03f, + -2.403986403039817116e-03f, + -2.253737526269895732e-03f, + -2.101364909875016573e-03f, + -1.947023997324411840e-03f, + -1.790872063594110223e-03f, + -1.633068055064607060e-03f, + -1.473772427887728434e-03f, + -1.313146984991218642e-03f, + -1.151354711883460216e-03f, + -9.885596114266794344e-04f, + -8.249265377453095672e-04f, + -6.606210294368872974e-04f, + -4.958091422553860149e-04f, + -3.306572814353150912e-04f, + -1.653320338249910076e-04f, + -2.551386587880797004e-17f, + 1.651723734761380335e-04f, + 3.300189614740527827e-04f, + 4.943741272349469777e-04f, + 6.580728886553833265e-04f, + 8.209510837512715370e-04f, + 9.828455351376394825e-04f, + 1.143594213357676742e-03f, + 1.303036398898462693e-03f, + 1.461012842732159695e-03f, + 1.617365925221177182e-03f, + 1.771939813229538550e-03f, + 1.924580615284706168e-03f, + 2.075136534633631631e-03f, + 2.223458020043932865e-03f, + 2.369397914196333301e-03f, + 2.512811599526118631e-03f, + 2.653557141365132238e-03f, + 2.791495428245575894e-03f, + 2.926490309225380886e-03f, + 3.058408728100418372e-03f, + 3.187120854371934629e-03f, + 3.312500210839413109e-03f, + 3.434423797694213451e-03f, + 3.552772212992939740e-03f, + 3.667429769391414990e-03f, + 3.778284607026904680e-03f, + 3.885228802437357565e-03f, + 3.988158473412363458e-03f, + 4.086973879674651519e-03f, + 4.181579519293593741e-03f, + 4.271884220739164024e-03f, + 4.357801230486726615e-03f, + 4.439248296089245809e-03f, + 4.516147744637950996e-03f, + 4.588426556536215166e-03f, + 4.656016434517300413e-03f, + 4.718853867841324261e-03f, + 4.776880191610652533e-03f, + 4.830041641149988331e-03f, + 4.878289401399377341e-03f, + 4.921579651277259264e-03f, + 4.959873602972050821e-03f, + 4.993137536128673497e-03f, + 5.021342826899958915e-03f, + 5.044465971838839151e-03f, + 5.062488606612373584e-03f, + 5.075397519523472574e-03f, + 5.083184659832008616e-03f, + 5.085847140871759681e-03f, + 5.083387237965185726e-03f, + 5.075812381143095242e-03f, + 5.063135142681596430e-03f, + 5.045373219473861526e-03f, + 5.022549410259432613e-03f, + 4.994691587739028341e-03f, + 4.961832665607723673e-03f, + 4.924010560544767219e-03f, + 4.881268149203150074e-03f, + 4.833653220246830577e-03f, + 4.781218421489157218e-03f, + 4.724021202189871739e-03f, + 4.662123750573998575e-03f, + 4.595592926639679825e-03f, + 4.524500190327651952e-03f, + 4.448921525128770975e-03f, + 4.368937357210857936e-03f, + 4.284632470151218328e-03f, + 4.196095915364042757e-03f, + 4.103420918317851433e-03f, + 4.006704780641143562e-03f, + 3.906048778218370893e-03f, + 3.801558055383750991e-03f, + 3.693341515321936323e-03f, + 3.581511706790642402e-03f, + 3.466184707282398206e-03f, + 3.347480002746349489e-03f, + 3.225520363994377124e-03f, + 3.100431719920501098e-03f, + 2.972343027662367743e-03f, + 2.841386139839377056e-03f, + 2.707695669005051858e-03f, + 2.571408849450755249e-03f, + 2.432665396503416125e-03f, + 2.291607363462537170e-03f, + 2.148378996320580991e-03f, + 2.003126586416237656e-03f, + 1.855998321172221827e-03f, + 1.707144133066539190e-03f, + 1.556715546994994403e-03f, + 1.404865526175997237e-03f, + 1.251748316758327694e-03f, + 1.097519291286103453e-03f, + 9.423347911819565052e-04f, + 7.863519684062989651e-04f, + 6.297286264551491203e-04f, + 4.726230608546003620e-04f, + 3.151938993142525320e-04f, + 1.575999417021628837e-04f, + 7.784442283331923853e-17f, + -1.574472615986340432e-04f, + -3.145834862862096032e-04f, + -4.712507837750268031e-04f, + -6.272918888083930770e-04f, + -7.825503188873347447e-04f, + -9.368705310580024981e-04f, + -1.090098077600495973e-03f, + -1.242079760465078378e-03f, + -1.392663784299297746e-03f, + -1.541699907915918119e-03f, + -1.689039594049394563e-03f, + -1.834536157250591781e-03f, + -1.978044909775040876e-03f, + -2.119423305318431615e-03f, + -2.258531080456323715e-03f, + -2.395230393648445800e-03f, + -2.529385961670430668e-03f, + -2.660865193337756500e-03f, + -2.789538320388635587e-03f, + -2.915278525399034055e-03f, + -3.037962066602765791e-03f, + -3.157468399492973938e-03f, + -3.273680295087870538e-03f, + -3.386483954743054609e-03f, + -3.495769121399434042e-03f, + -3.601429187156589447e-03f, + -3.703361297068739032e-03f, + -3.801466449061457163e-03f, + -3.895649589871598342e-03f, + -3.985819706919274674e-03f, + -4.071889916022448409e-03f, + -4.153777544869190555e-03f, + -4.231404212169127994e-03f, + -4.304695902407762974e-03f, + -4.373583036132095911e-03f, + -4.438000535702448651e-03f, + -4.497887886447530723e-03f, + -4.553189193166368338e-03f, + -4.603853231924096880e-03f, + -4.649833497094323954e-03f, + -4.691088243605770480e-03f, + -4.727580524354188865e-03f, + -4.759278222747725245e-03f, + -4.786154080356886005e-03f, + -4.808185719646517267e-03f, + -4.825355661771149086e-03f, + -4.837651339421160553e-03f, + -4.845065104711230967e-03f, + -4.847594232107986685e-03f, + -4.845240916398877579e-03f, + -4.838012265708960952e-03f, + -4.825920289577491362e-03f, + -4.808981882111157055e-03f, + -4.787218800235539494e-03f, + -4.760657637071705889e-03f, + -4.729329790469200510e-03f, + -4.693271426731996689e-03f, + -4.652523439578401879e-03f, + -4.607131404381258066e-03f, + -4.557145527738585764e-03f, + -4.502620592430119431e-03f, + -4.443615897820203317e-03f, + -4.380195195770275780e-03f, + -4.312426622131352791e-03f, + -4.240382623888087031e-03f, + -4.164139882033739311e-03f, + -4.083779230256361775e-03f, + -3.999385569522737396e-03f, + -3.911047778650672546e-03f, + -3.818858620962382270e-03f, + -3.722914647117278510e-03f, + -3.623316094226521674e-03f, + -3.520166781352995246e-03f, + -3.413574001506695325e-03f, + -3.303648410246657133e-03f, + -3.190503911006380925e-03f, + -3.074257537259608274e-03f, + -2.955029331648956637e-03f, + -2.832942222203055620e-03f, + -2.708121895767779796e-03f, + -2.580696668782614736e-03f, + -2.450797355535883071e-03f, + -2.318557134031954108e-03f, + -2.184111409608732648e-03f, + -2.047597676446088772e-03f, + -1.909155377104432803e-03f, + -1.768925760238825853e-03f, + -1.627051736631422978e-03f, + -1.483677733692766133e-03f, + -1.338949548574867041e-03f, + -1.193014200049233526e-03f, + -1.046019779297893606e-03f, + -8.981152997709223890e-04f, + -7.494505462600843963e-04f, + -6.001759233424719181e-04f, + -4.504423033485727233e-04f, + -3.004008740059210055e-04f, + -1.502029859132318287e-04f, + 0.000000000000000000e+00f, + 1.500568648773128620e-04f, + 2.998166840477804458e-04f, + 4.491289786934320964e-04f, + 5.978438669215414185e-04f, + 7.458122140882831198e-04f, + 8.928857822246706166e-04f, + 1.038917378413064868e-03f, + 1.183761001968396554e-03f, + 1.327271990275858586e-03f, + 1.469307163138363920e-03f, + 1.609724965492229879e-03f, + 1.748385608347759190e-03f, + 1.885151207813307852e-03f, + 2.019885922067833454e-03f, + 2.152456086142171161e-03f, + 2.282730344379329916e-03f, + 2.410579780439001552e-03f, + 2.535878044720715069e-03f, + 2.658501479078634582e-03f, + 2.778329238704075124e-03f, + 2.895243411057801981e-03f, + 3.009129131734148907e-03f, + 3.119874697142386698e-03f, + 3.227371673896960082e-03f, + 3.331515004807996620e-03f, + 3.432203111369802693e-03f, + 3.529337992646119828e-03f, + 3.622825320457822695e-03f, + 3.712574530779899368e-03f, + 3.798498911258710829e-03f, + 3.880515684766671931e-03f, + 3.958546088913222558e-03f, + 4.032515451435444119e-03f, + 4.102353261397662619e-03f, + 4.167993236131739207e-03f, + 4.229373383854271966e-03f, + 4.286436061903056705e-03f, + 4.339128030537392315e-03f, + 4.387400502253299348e-03f, + 4.431209186566910548e-03f, + 4.470514330227219786e-03f, + 4.505280752820716751e-03f, + 4.535477877737257441e-03f, + 4.561079758469966522e-03f, + 4.582065100227887371e-03f, + 4.598417276843720300e-03f, + 4.610124342964186731e-03f, + 4.617179041515659735e-03f, + 4.619578806441900290e-03f, + 4.617325760715732842e-03f, + 4.610426709631436880e-03f, + 4.598893129389029603e-03f, + 4.582741150986642878e-03f, + 4.561991539441702728e-03f, + 4.536669668366456049e-03f, + 4.506805489927790190e-03f, + 4.472433500226501331e-03f, + 4.433592700134834745e-03f, + 4.390326551636334652e-03f, + 4.342682929716723365e-03f, + 4.290714069857965926e-03f, + 4.234476511192970805e-03f, + 4.174031035382547508e-03f, + 4.109442601280248290e-03f, + 4.040780275454714486e-03f, + 3.968117158643618379e-03f, + 3.891530308217908476e-03f, + 3.811100656737222755e-03f, + 3.726912926682747658e-03f, + 3.639055541457847723e-03f, + 3.547620532748325950e-03f, + 3.452703444340344142e-03f, + 3.354403232495308754e-03f, + 3.252822162986789261e-03f, + 3.148065704904799266e-03f, + 3.040242421338187288e-03f, + 2.929463857049219994e-03f, + 2.815844423254667064e-03f, + 2.699501279633036762e-03f, + 2.580554213680439322e-03f, + 2.459125517537331940e-03f, + 2.335339862413496597e-03f, + 2.209324170741059669e-03f, + 2.081207486184459728e-03f, + 1.951120841642063749e-03f, + 1.819197125372980488e-03f, + 1.685570945387657215e-03f, + 1.550378492237483022e-03f, + 1.413757400346775340e-03f, + 1.275846608024381462e-03f, + 1.136786216300893085e-03f, + 9.967173467317232399e-04f, + 8.557819983114523963e-04f, + 7.141229036455263310e-04f, + 5.718833845226121287e-04f, + 4.292072070347436501e-04f, + 2.862384363927389136e-04f, + 1.431212915810999909e-04f, + 3.976073045763746639e-17f, + -1.429813477578194541e-04f, + -2.856789428524072441e-04f, + -4.279494027150967353e-04f, + -5.696499149979476154e-04f, + -7.106383808068707187e-04f, + -8.507735570776003928e-04f, + -9.899151979507884221e-04f, + -1.127924195003721704e-03f, + -1.264662716200822120e-03f, + -1.399994343423132705e-03f, + -1.533784208438585678e-03f, + -1.665899127179875554e-03f, + -1.796207732195136955e-03f, + -1.924580603139482322e-03f, + -2.050890395178425665e-03f, + -2.175011965176371249e-03f, + -2.296822495544894628e-03f, + -2.416201615627299338e-03f, + -2.533031520501645515e-03f, + -2.647197087084067826e-03f, + -2.758585987417253894e-03f, + -2.867088799034697190e-03f, + -2.972599112290812313e-03f, + -3.075013634552971071e-03f, + -3.174232291152105818e-03f, + -3.270158322995199603e-03f, + -3.362698380743715538e-03f, + -3.451762615465765304e-03f, + -3.537264765675776721e-03f, + -3.619122240676629892e-03f, + -3.697256200123399950e-03f, + -3.771591629733630612e-03f, + -3.842057413070905456e-03f, + -3.908586399332766859e-03f, + -3.971115467079878135e-03f, + -4.029585583845121145e-03f, + -4.083941861567453452e-03f, + -4.134133607797787699e-03f, + -4.180114372630844115e-03f, + -4.221841991318395042e-03f, + -4.259278622526630094e-03f, + -4.292390782202119143e-03f, + -4.321149373017542893e-03f, + -4.345529709371441680e-03f, + -4.365511537920943770e-03f, + -4.381079053631709713e-03f, + -4.392220911332943636e-03f, + -4.398930232770211640e-03f, + -4.401204609153669053e-03f, + -4.399046099203249988e-03f, + -4.392461222697331344e-03f, + -4.381460949535757529e-03f, + -4.366060684332634563e-03f, + -4.346280246558699781e-03f, + -4.322143846257833419e-03f, + -4.293680055366262162e-03f, + -4.260921774667682412e-03f, + -4.223906196422148006e-03f, + -4.182674762710170135e-03f, + -4.137273119538274584e-03f, + -4.087751066756856698e-03f, + -4.034162503844153022e-03f, + -3.976565371615301513e-03f, + -3.915021589919383607e-03f, + -3.849596991390978259e-03f, + -3.780361251326535416e-03f, + -3.707387813760094821e-03f, + -3.630753813817203315e-03f, + -3.550539996427677474e-03f, + -3.466830631483622076e-03f, + -3.379713425530830959e-03f, + -3.289279430087042790e-03f, + -3.195622946681347856e-03f, + -3.098841428714084380e-03f, + -2.999035380240086535e-03f, + -2.896308251778681887e-03f, + -2.790766333258949596e-03f, + -2.682518644211763417e-03f, + -2.571676821320250696e-03f, + -2.458355003445216510e-03f, + -2.342669714244821622e-03f, + -2.224739742507099091e-03f, + -2.104686020319705697e-03f, + -1.982631499200445194e-03f, + -1.858701024317035294e-03f, + -1.733021206922603788e-03f, + -1.605720295138181623e-03f, + -1.476928043214278908e-03f, + -1.346775579404299638e-03f, + -1.215395272583683463e-03f, + -1.082920597750686208e-03f, + -9.494860005465256434e-04f, + -8.152267609301555324e-04f, + -6.802788561468293017e-04f, + -5.447788231302409367e-04f, + -4.088636204751821168e-04f, + -2.726704901212254279e-04f, + -1.363368188880890964e-04f, + -8.417792963206818356e-17f, + 1.362027052598085422e-04f, + 2.721343056259442508e-04f, + 4.076582175196397572e-04f, + 5.426384021722333592e-04f, + 6.769395020654857481e-04f, + 8.104269765506644935e-04f, + 9.429672365128469180e-04f, + 1.074427777944659190e-03f, + 1.204677314294974296e-03f, + 1.333585907462621518e-03f, + 1.461025097303440606e-03f, + 1.586868029520704633e-03f, + 1.710989581813802214e-03f, + 1.833266488158666763e-03f, + 1.953577461096326229e-03f, + 2.071803311908859517e-03f, + 2.187827068564226606e-03f, + 2.301534091313028798e-03f, + 2.412812185822113195e-03f, + 2.521551713735463440e-03f, + 2.627645700551932938e-03f, + 2.730989940714999460e-03f, + 2.831483099809944254e-03f, + 2.929026813770171413e-03f, + 3.023525784994855574e-03f, + 3.114887875283365529e-03f, + 3.203024195497624661e-03f, + 3.287849191864475069e-03f, + 3.369280728833792034e-03f, + 3.447240168413722491e-03f, + 3.521652445905853156e-03f, + 3.592446141966990254e-03f, + 3.659553550929970766e-03f, + 3.722910745317228355e-03f, + 3.782457636486660606e-03f, + 3.838138031351646592e-03f, + 3.889899685123011756e-03f, + 3.937694350023167832e-03f, + 3.981477819927187536e-03f, + 4.021209970890143003e-03f, + 4.056854797524065380e-03f, + 4.088380445191790516e-03f, + 4.115759237989136295e-03f, + 4.138967702491964246e-03f, + 4.157986587248014773e-03f, + 4.172800877997954669e-03f, + 4.183399808614909378e-03f, + 4.189776867755429235e-03f, + 4.191929801219356974e-03f, + 4.189860610020690324e-03f, + 4.183575544175400195e-03f, + 4.173085092216739442e-03f, + 4.158403966452908773e-03f, + 4.139551083985980491e-03f, + 4.116549543515387807e-03f, + 4.089426597953691074e-03f, + 4.058213622886065394e-03f, + 4.022946080909405378e-03f, + 3.983663481891361151e-03f, + 3.940409339192868857e-03f, + 3.893231121902388826e-03f, + 3.842180203134375367e-03f, + 3.787311804446883475e-03f, + 3.728684936439468408e-03f, + 3.666362335593461707e-03f, + 3.600410397423470070e-03f, + 3.530899106009756632e-03f, + 3.457901959986858006e-03f, + 3.381495895065876871e-03f, + 3.301761203172812187e-03f, + 3.218781448286551963e-03f, + 3.132643379065020751e-03f, + 3.043436838351391838e-03f, + 2.951254669653231681e-03f, + 2.856192620692367314e-03f, + 2.758349244126263259e-03f, + 2.657825795542260918e-03f, + 2.554726128830706305e-03f, + 2.449156589045835622e-03f, + 2.341225902863081770e-03f, + 2.231045066746887174e-03f, + 2.118727232942822086e-03f, + 2.004387593412520346e-03f, + 1.888143261828470910e-03f, + 1.770113153750305698e-03f, + 1.650417865105977249e-03f, + 1.529179549100039177e-03f, + 1.406521791675539998e-03f, + 1.282569485656734343e-03f, + 1.157448703700234525e-03f, + 1.031286570183274475e-03f, + 9.042111321594720934e-04f, + 7.763512295141050895e-04f, + 6.478363644484194097e-04f, + 5.187965704260827501e-04f, + 3.893622807153351221e-04f, + 2.596641966575497277e-04f, + 1.298331557961695734e-04f, + 0.000000000000000000e+00f, + -1.297045562884773494e-04f, + -2.591500575455231805e-04f, + -3.882064382682380425e-04f, + -5.167441535531211438e-04f, + -6.446343090221472215e-04f, + -7.717487899651593111e-04f, + -8.979603895682745050e-04f, + -1.023142936102136233e-03f, + -1.147171418941898315e-03f, + -1.269922113292209966e-03f, + -1.391272703494883479e-03f, + -1.511102404795431394e-03f, + -1.629292083446334978e-03f, + -1.745724375030405316e-03f, + -1.860283800883534306e-03f, + -1.972856882504857214e-03f, + -2.083332253837852453e-03f, + -2.191600771314119924e-03f, + -2.297555621549458339e-03f, + -2.401092426587344512e-03f, + -2.502109346584675646e-03f, + -2.600507179840733183e-03f, + -2.696189460070382710e-03f, + -2.789062550825482587e-03f, + -2.879035736973885838e-03f, + -2.966021313145917292e-03f, + -3.049934669061640530e-03f, + -3.130694371657468528e-03f, + -3.208222243931873989e-03f, + -3.282443440433375874e-03f, + -3.353286519319528813e-03f, + -3.420683510916569352e-03f, + -3.484569982714951809e-03f, + -3.544885100737864888e-03f, + -3.601571687225699116e-03f, + -3.654576274581390269e-03f, + -3.703849155525655665e-03f, + -3.749344429416276783e-03f, + -3.791020044687998507e-03f, + -3.828837837374106986e-03f, + -3.862763565674989016e-03f, + -3.892766940542859502e-03f, + -3.918821652255656887e-03f, + -3.940905392957132734e-03f, + -3.958999875144887486e-03f, + -3.973090846091481033e-03f, + -3.983168098188016350e-03f, + -3.989225475204148490e-03f, + -3.991260874462022705e-03f, + -3.989276244926093229e-03f, + -3.983277581214771101e-03f, + -3.973274913544052635e-03f, + -3.959282293617159831e-03f, + -3.941317776478633732e-03f, + -3.919403398354929027e-03f, + -3.893565150507910695e-03f, + -3.863832949131735649e-03f, + -3.830240601327010268e-03f, + -3.792825767190527789e-03f, + -3.751629918062933215e-03f, + -3.706698290979619330e-03f, + -3.658079839375025927e-03f, + -3.605827180092993720e-03f, + -3.549996536761576733e-03f, + -3.490647679591208329e-03f, + -3.427843861661717968e-03f, + -3.361651751765054510e-03f, + -3.292141363875685824e-03f, + -3.219385983321982822e-03f, + -3.143462089736679104e-03f, + -3.064449276867864478e-03f, + -2.982430169333176711e-03f, + -2.897490336404670141e-03f, + -2.809718202914781877e-03f, + -2.719204957374711431e-03f, + -2.626044457401114501e-03f, + -2.530333132549811032e-03f, + -2.432169884655409342e-03f, + -2.331655985780983504e-03f, + -2.228894973881932924e-03f, + -2.123992546292832913e-03f, + -2.017056451144963979e-03f, + -1.908196376826750383e-03f, + -1.797523839601251243e-03f, + -1.685152069494012198e-03f, + -1.571195894568736418e-03f, + -1.455771623709985587e-03f, + -1.338996928029888246e-03f, + -1.220990721022854842e-03f, + -1.101873037586910105e-03f, + -9.817649120378681756e-04f, + -8.607882552375694957e-04f, + -7.390657309618451016e-04f, + -6.167206316344765651e-04f, + -4.938767535509734369e-04f, + -3.706582717193119820e-04f, + -2.471896144450557429e-04f, + -1.235953377853419590e-04f, + -4.959890100963354769e-17f, + 1.234719638747178042e-04f, + 2.466963672028767455e-04f, + 3.695493965506171539e-04f, + 4.919077359883478268e-04f, + 6.136486907666624611e-04f, + 7.346503102443730469e-04f, + 8.547915099445561275e-04f, + 9.739521926155840070e-04f, + 1.092013368178181270e-03f, + 1.208857272437798046e-03f, + 1.324367484443061309e-03f, + 1.438429042375458577e-03f, + 1.550928557853214172e-03f, + 1.661754328537675893e-03f, + 1.770796448927353453e-03f, + 1.877946919233882935e-03f, + 1.983099752229050636e-03f, + 2.086151077959072422e-03f, + 2.186999246221175627e-03f, + 2.285544926703325219e-03f, + 2.381691206687666998e-03f, + 2.475343686220975951e-03f, + 2.566410570660377331e-03f, + 2.654802760502929671e-03f, + 2.740433938410591005e-03f, + 2.823220653347242176e-03f, + 2.903082401745072944e-03f, + 2.979941705620986828e-03f, + 3.053724187568778933e-03f, + 3.124358642553495477e-03f, + 3.191777106439702780e-03f, + 3.255914921186875855e-03f, + 3.316710796650810048e-03f, + 3.374106868931566437e-03f, + 3.428048755212193075e-03f, + 3.478485605037506118e-03f, + 3.525370147984284441e-03f, + 3.568658737678078504e-03f, + 3.608311392117048363e-03f, + 3.644291830264629207e-03f, + 3.676567504879116322e-03f, + 3.705109631549780621e-03f, + 3.729893213914910709e-03f, + 3.750897065039809040e-03f, + 3.768103824936940016e-03f, + 3.781499974214817122e-03f, + 3.791075843845443261e-03f, + 3.796825621044523733e-03f, + 3.798747351262270894e-03f, + 3.796842936286857866e-03f, + 3.791118128466208596e-03f, + 3.781582521057830042e-03f, + 3.768249534720393822e-03f, + 3.751136400164309208e-03f, + 3.730264136982911188e-03f, + 3.705657528689156911e-03f, + 3.677345093986788237e-03f, + 3.645359054308939216e-03f, + 3.609735297660244310e-03f, + 3.570513338802807409e-03f, + 3.527736275829614857e-03f, + 3.481450743173182798e-03f, + 3.431706861099539409e-03f, + 3.378558181742752180e-03f, + 3.322061631737472948e-03f, + 3.262277451510458420e-03f, + 3.199269131295992552e-03f, + 3.133103343942434792e-03f, + 3.063849874581625003e-03f, + 2.991581547234064588e-03f, + 2.916374148427355699e-03f, + 2.838306347908428270e-03f, + 2.757459616531154987e-03f, + 2.673918141405439829e-03f, + 2.587768738396670036e-03f, + 2.499100762065002874e-03f, + 2.408006013138405590e-03f, + 2.314578643615823259e-03f, + 2.218915059596944257e-03f, + 2.121113821939972673e-03f, + 2.021275544848643961e-03f, + 1.919502792494091415e-03f, + 1.815899973775997930e-03f, + 1.710573235331645401e-03f, + 1.603630352903246976e-03f, + 1.495180621172954036e-03f, + 1.385334742178912079e-03f, + 1.274204712426525677e-03f, + 1.161903708809525985e-03f, + 1.048545973456544876e-03f, + 9.342466976205273310e-04f, + 8.191219047299183901e-04f, + 7.032883327184241478e-04f, + 5.868633157534830069e-04f, + 4.699646654841184022e-04f, + 3.527105519262883665e-04f, + 2.352193841077147634e-04f, + 1.176096905914035935e-04f, + -1.816279043680416122e-17f, + -1.174912783408097822e-04f, + -2.347459735184355596e-04f, + -3.516462717890174536e-04f, + -4.680748348545702049e-04f, + -5.839149175424285850e-04f, + -6.990504847680064412e-04f, + -8.133663276656900908e-04f, + -9.267481787707859599e-04f, + -1.039082826136560620e-03f, + -1.150258226274457644e-03f, + -1.260163615803283491e-03f, + -1.368689621697415744e-03f, + -1.475728370022750873e-03f, + -1.581173593054908304e-03f, + -1.684920734670451118e-03f, + -1.786867053909769803e-03f, + -1.886911726606242201e-03f, + -1.984955944983589262e-03f, + -2.080903015122214511e-03f, + -2.174658452197730102e-03f, + -2.266130073399595744e-03f, + -2.355228088437774474e-03f, + -2.441865187547984182e-03f, + -2.525956626910913581e-03f, + -2.607420311401180066e-03f, + -2.686176874584755934e-03f, + -2.762149755888469640e-03f, + -2.835265274865544395e-03f, + -2.905452702486107687e-03f, + -2.972644329382842596e-03f, + -3.036775530987343309e-03f, + -3.097784829494083791e-03f, + -3.155613952592319516e-03f, + -3.210207888911055518e-03f, + -3.261514940123977010e-03f, + -3.309486769664863031e-03f, + -3.354078448008697769e-03f, + -3.395248494475826620e-03f, + -3.432958915520433179e-03f, + -3.467175239468593684e-03f, + -3.497866547674528641e-03f, + -3.525005502067194568e-03f, + -3.548568369062852102e-03f, + -3.568535039823742677e-03f, + -3.584889046845683540e-03f, + -3.597617576861870340e-03f, + -3.606711480053335483e-03f, + -3.612165275560820770e-03f, + -3.613977153296067668e-03f, + -3.612148972054406073e-03f, + -3.606686253934421674e-03f, + -3.597598175073908090e-03f, + -3.584897552715274240e-03f, + -3.568600828617066786e-03f, + -3.548728048831968108e-03f, + -3.525302839875490025e-03f, + -3.498352381312806562e-03f, + -3.467907374795066184e-03f, + -3.434002009579821546e-03f, + -3.396673924574244215e-03f, + -3.355964166942346574e-03f, + -3.311917147321609932e-03f, + -3.264580591697720767e-03f, + -3.214005489989122874e-03f, + -3.160246041396339717e-03f, + -3.103359596574423087e-03f, + -3.043406596690569153e-03f, + -2.980450509430481246e-03f, + -2.914557762021494861e-03f, + -2.845797671343432839e-03f, + -2.774242371199536934e-03f, + -2.699966736824086378e-03f, + -2.623048306706114718e-03f, + -2.543567201809550458e-03f, + -2.461606042274317591e-03f, + -2.377249861685521663e-03f, + -2.290586018998170062e-03f, + -2.201704108209648781e-03f, + -2.110695865872344850e-03f, + -2.017655076542951807e-03f, + -1.922677476264368895e-03f, + -1.825860654179994359e-03f, + -1.727303952382239390e-03f, + -1.627108364096408778e-03f, + -1.525376430304876962e-03f, + -1.422212134918130876e-03f, + -1.317720798598115244e-03f, + -1.212008971343053179e-03f, + -1.105184323943502606e-03f, + -9.973555384197396820e-04f, + -8.886321975514789584e-04f, + -7.791246736123785127e-04f, + -6.689440164231939519e-04f, + -5.582018408351800513e-04f, + -4.470102137591960715e-04f, + -3.354815408535864675e-04f, + -2.237284529868988829e-04f, + -1.118636925881364959e-04f, + -2.071470033548900873e-17f, + 1.117500000493719706e-04f, + 2.232739117441697070e-04f, + 3.344596811326808606e-04f, + 4.451957086194700233e-04f, + 5.553709608865004844e-04f, + 6.648750821302810846e-04f, + 7.735985045027994698e-04f, + 8.814325576476730742e-04f, + 9.882695772205538597e-04f, + 1.094003012286658312e-03f, + 1.198527531486872971e-03f, + 1.301739127868568706e-03f, + 1.403535222275920568e-03f, + 1.503814765196793968e-03f, + 1.602478336965568358e-03f, + 1.699428246223005749e-03f, + 1.794568626535442959e-03f, + 1.887805531077050170e-03f, + 1.979047025283286153e-03f, + 2.068203277383505716e-03f, + 2.155186646722974993e-03f, + 2.239911769789048289e-03f, + 2.322295643856428504e-03f, + 2.402257708169032186e-03f, + 2.479719922580636039e-03f, + 2.554606843576476966e-03f, + 2.626845697602746450e-03f, + 2.696366451631782273e-03f, + 2.763101880895990278e-03f, + 2.826987633724481735e-03f, + 2.887962293419586799e-03f, + 2.945967437115027624e-03f, + 3.000947691558917239e-03f, + 3.052850785768143008e-03f, + 3.101627600505197247e-03f, + 3.147232214530348154e-03f, + 3.189621947585512783e-03f, + 3.228757400070635542e-03f, + 3.264602489375515067e-03f, + 3.297124482833800954e-03f, + 3.326294027269616291e-03f, + 3.352085175110586929e-03f, + 3.374475407044334914e-03f, + 3.393445651198981165e-03f, + 3.408980298832289899e-03f, + 3.421067216516832533e-03f, + 3.429697754812713849e-03f, + 3.434866753422505335e-03f, + 3.436572542826982733e-03f, + 3.434816942403465419e-03f, + 3.429605255032289191e-03f, + 3.420946258200424379e-03f, + 3.408852191614762661e-03f, + 3.393338741341164321e-03f, + 3.374425020488695717e-03f, + 3.352133546462037709e-03f, + 3.326490214808674843e-03f, + 3.297524269690380733e-03f, + 3.265268271012441645e-03f, + 3.229758058246862303e-03f, + 3.191032710989869740e-03f, + 3.149134506296154788e-03f, + 3.104108872836428955e-03f, + 3.056004341927853838e-03f, + 3.004872495489709604e-03f, + 2.950767910979716115e-03f, + 2.893748103369611722e-03f, + 2.833873464221980509e-03f, + 2.771207197931811923e-03f, + 2.705815255200260967e-03f, + 2.637766263811031336e-03f, + 2.567131456780837821e-03f, + 2.493984597959450489e-03f, + 2.418401905157508119e-03f, + 2.340461970880830869e-03f, + 2.260245680754550089e-03f, + 2.177836129720765214e-03f, + 2.093318536097558535e-03f, + 2.006780153586758438e-03f, + 1.918310181321814228e-03f, + 1.827999672049080305e-03f, + 1.735941438535555485e-03f, + 1.642229958299797413e-03f, + 1.546961276764474095e-03f, + 1.450232908928234844e-03f, + 1.352143739658173346e-03f, + 1.252793922705604940e-03f, + 1.152284778546037915e-03f, + 1.050718691150112800e-03f, + 9.481990037877905493e-04f, + 8.448299139744811252e-04f, + 7.407163676634808108e-04f, + 6.359639527935932865e-04f, + 5.306787922987215612e-04f, + 4.249674366892458523e-04f, + 3.189367563120465432e-04f, + 2.126938333988559937e-04f, + 1.063458540127559251e-04f, + 5.580875061456703527e-17f, + -1.062366589427715403e-04f, + -2.122572729776368709e-04f, + -3.179553195023174803e-04f, + -4.232247100881988380e-04f, + -5.279598968701624921e-04f, + -6.320559782838149239e-04f, + -7.354088040427114292e-04f, + -8.379150792517338136e-04f, + -9.394724675511614224e-04f, + -1.039979693190289578e-03f, + -1.139336641928036893e-03f, + -1.237444460659308312e-03f, + -1.334205655669700157e-03f, + -1.429524189420069849e-03f, + -1.523305575764726449e-03f, + -1.615456973509339471e-03f, + -1.705887278216311432e-03f, + -1.794507212166710506e-03f, + -1.881229412389207739e-03f, + -1.965968516670845660e-03f, + -2.048641247464260805e-03f, + -2.129166493608392920e-03f, + -2.207465389784019332e-03f, + -2.283461393625221911e-03f, + -2.357080360412389282e-03f, + -2.428250615272878506e-03f, + -2.496903022820505004e-03f, + -2.562971054165676978e-03f, + -2.626390851230865024e-03f, + -2.687101288310514684e-03f, + -2.745044030815619023e-03f, + -2.800163591146226632e-03f, + -2.852407381639556275e-03f, + -2.901725764542836122e-03f, + -2.948072098963223399e-03f, + -2.991402784751522655e-03f, + -3.031677303277889764e-03f, + -3.068858255062130534e-03f, + -3.102911394223503531e-03f, + -3.133805659718869735e-03f, + -3.161513203341241758e-03f, + -3.186009414453190580e-03f, + -3.207272941434331694e-03f, + -3.225285709824096680e-03f, + -3.240032937145292686e-03f, + -3.251503144396590377e-03f, + -3.259688164206146245e-03f, + -3.264583145641404907e-03f, + -3.266186555673606436e-03f, + -3.264500177299172780e-03f, + -3.259529104323136660e-03f, + -3.251281732813429259e-03f, + -3.239769749237986739e-03f, + -3.225008115300036140e-03f, + -3.207015049490388476e-03f, + -3.185812005378460370e-03f, + -3.161423646667512952e-03f, + -3.133877819042292512e-03f, + -3.103205518841122348e-03f, + -3.069440858586877912e-03f, + -3.032621029414926759e-03f, + -2.992786260439455476e-03f, + -2.949979775101472298e-03f, + -2.904247744546611422e-03f, + -2.855639238081619617e-03f, + -2.804206170763586491e-03f, + -2.750003248176786843e-03f, + -2.693087908455917955e-03f, + -2.633520261617509212e-03f, + -2.571363026262532200e-03f, + -2.506681463717044551e-03f, + -2.439543309680427315e-03f, + -2.370018703451564571e-03f, + -2.298180114807654630e-03f, + -2.224102268611033526e-03f, + -2.147862067223294154e-03f, + -2.069538510805925442e-03f, + -1.989212615590480685e-03f, + -1.906967330203344566e-03f, + -1.822887450130181207e-03f, + -1.737059530408692877e-03f, + -1.649571796640214366e-03f, + -1.560514054410137245e-03f, + -1.469977597210741713e-03f, + -1.378055112961429048e-03f, + -1.284840589220490525e-03f, + -1.190429217186597059e-03f, + -1.094917294586464536e-03f, + -9.984021275502952091e-04f, + -9.009819315715012801e-04f, + -8.027557316540494606e-04f, + -7.038232617473004970e-04f, + -6.042848635718732616e-04f, + -5.042413849374186366e-04f, + -4.037940776560225800e-04f, + -3.030444951553179869e-04f, + -2.020943898931319878e-04f, + -1.010456106780149166e-04f, + 0.000000000000000000e+00f, + 1.009407085266458343e-04f, + 2.016749925046095251e-04f, + 3.021016427750876994e-04f, + 4.021198650188813296e-04f, + 5.016293808337416761e-04f, + 6.005305281877486908e-04f, + 6.987243611467527623e-04f, + 7.961127487778794053e-04f, + 8.925984731294979088e-04f, + 9.880853261891541211e-04f, + 1.082478205724416668e-03f, + 1.175683209910467547e-03f, + 1.267607730649530483e-03f, + 1.358160545491613001e-03f, + 1.447251908062810368e-03f, + 1.534793636914284342e-03f, + 1.620699202701525671e-03f, + 1.704883813609845864e-03f, + 1.787264498941020874e-03f, + 1.867760190778164960e-03f, + 1.946291803649916963e-03f, + 2.022782312115050697e-03f, + 2.097156826190940942e-03f, + 2.169342664553446445e-03f, + 2.239269425435684406e-03f, + 2.306869055157482768e-03f, + 2.372075914217887990e-03f, + 2.434826840887931946e-03f, + 2.495061212241576985e-03f, + 2.552721002565519828e-03f, + 2.607750839092839740e-03f, + 2.660098055006482071e-03f, + 2.709712739661699482e-03f, + 2.756547785980618080e-03f, + 2.800558934973623130e-03f, + 2.841704817345394509e-03f, + 2.879946992147500422e-03f, + 2.915249982440988770e-03f, + 2.947581307936787947e-03f, + 2.976911514583215936e-03f, + 3.003214201075224757e-03f, + 3.026466042260897698e-03f, + 3.046646809425394842e-03f, + 3.063739387434716906e-03f, + 3.077729788725812928e-03f, + 3.088607164131847160e-03f, + 3.096363810535085210e-03f, + 3.100995175343106407e-03f, + 3.102499857787075627e-03f, + 3.100879607044029155e-03f, + 3.096139317188489372e-03f, + 3.088287018981677665e-03f, + 3.077333868510032794e-03f, + 3.063294132687598148e-03f, + 3.046185171640329852e-03f, + 3.026027417993118994e-03f, + 3.002844353083898229e-03f, + 2.976662480131725321e-03f, + 2.947511294389127540e-03f, + 2.915423250312139825e-03f, + 2.880433725783904282e-03f, + 2.842580983431017543e-03f, + 2.801906129074849608e-03f, + 2.758453067362536676e-03f, + 2.712268454625132129e-03f, + 2.663401649013388741e-03f, + 2.611904657964648872e-03f, + 2.557832083055883686e-03f, + 2.501241062301404455e-03f, + 2.442191209956580140e-03f, + 2.380744553889864272e-03f, + 2.316965470589540683e-03f, + 2.250920617872494492e-03f, + 2.182678865366110329e-03f, + 2.112311222834577142e-03f, + 2.039890766424525773e-03f, + 1.965492562907071757e-03f, + 1.889193591993552652e-03f, + 1.811072666805763759e-03f, + 1.731210352583364151e-03f, + 1.649688883710983146e-03f, + 1.566592079150942642e-03f, + 1.482005256369143794e-03f, + 1.396015143841002710e-03f, + 1.308709792228250146e-03f, + 1.220178484316535592e-03f, + 1.130511643807194247e-03f, + 1.039800743054220596e-03f, + 9.481382098429354081e-04f, + 8.556173333027085976e-04f, + 7.623321690519257836e-04f, + 6.683774436695268453e-04f, + 5.738484585908526416e-04f, + 4.788409935259931006e-04f, + 3.834512094969080875e-04f, + 2.877755515921519335e-04f, + 1.919106515382334099e-04f, + 9.595323018441329955e-05f, + 2.961728936009675573e-17f, + -9.585243231666533902e-05f, + -1.915076630217971002e-04f, + -2.868695882022341873e-04f, + -3.818425002487855048e-04f, + -4.763311838281015891e-04f, + -5.702410112587507447e-04f, + -6.634780371952385403e-04f, + -7.559490925245654922e-04f, + -8.475618773830773632e-04f, + -9.382250532000561190e-04f, + -1.027848333675624067e-03f, + -1.116342574603918251e-03f, + -1.203619862451413194e-03f, + -1.289593601602254461e-03f, + -1.374178600184431222e-03f, + -1.457291154392131340e-03f, + -1.538849131220664879e-03f, + -1.618772049531532397e-03f, + -1.696981159369096662e-03f, + -1.773399519450076641e-03f, + -1.847952072749128047e-03f, + -1.920565720107696725e-03f, + -1.991169391792951045e-03f, + -2.059694116937665648e-03f, + -2.126073090792308593e-03f, + -2.190241739725098773e-03f, + -2.252137783906322643e-03f, + -2.311701297615694015e-03f, + -2.368874767115570264e-03f, + -2.423603146033716672e-03f, + -2.475833908202009024e-03f, + -2.525517097901476115e-03f, + -2.572605377465290739e-03f, + -2.617054072194128448e-03f, + -2.658821212542411203e-03f, + -2.697867573534989526e-03f, + -2.734156711378059063e-03f, + -2.767654997229715939e-03f, + -2.798331648100023990e-03f, + -2.826158754851514684e-03f, + -2.851111307275881745e-03f, + -2.873167216223860253e-03f, + -2.892307332769767248e-03f, + -2.908515464394205354e-03f, + -2.921778388171670463e-03f, + -2.932085860953250172e-03f, + -2.939430626537135362e-03f, + -2.943808419822793298e-03f, + -2.945217967948095782e-03f, + -2.943660988411156160e-03f, + -2.939142184182125771e-03f, + -2.931669235812944720e-03f, + -2.921252790556253757e-03f, + -2.907906448507473381e-03f, + -2.891646745787318507e-03f, + -2.872493134784635110e-03f, + -2.850467961482642393e-03f, + -2.825596439894601745e-03f, + -2.797906623637558873e-03f, + -2.767429374675792631e-03f, + -2.734198329268788634e-03f, + -2.698249861160541534e-03f, + -2.659623042050382122e-03f, + -2.618359599388156086e-03f, + -2.574503871538993439e-03f, + -2.528102760365492311e-03f, + -2.479205681277817097e-03f, + -2.427864510805224571e-03f, + -2.374133531743618380e-03f, + -2.318069375937653262e-03f, + -2.259730964756961977e-03f, + -2.199179447329721766e-03f, + -2.136478136597202548e-03f, + -2.071692443256429803e-03f, + -2.004889807660292528e-03f, + -1.936139629744864461e-03f, + -1.865513197057068430e-03f, + -1.793083610957797377e-03f, + -1.718925711075672356e-03f, + -1.643115998089900122e-03f, + -1.565732554922428339e-03f, + -1.486854966419205639e-03f, + -1.406564237604140694e-03f, + -1.324942710588779184e-03f, + -1.242073980223971008e-03f, + -1.158042808578502083e-03f, + -1.072935038332762650e-03f, + -9.868375051760999109e-04f, + -8.998379492968846009e-04f, + -8.120249260550908496e-04f, + -7.234877159284703501e-04f, + -6.343162338246114773e-04f, + -5.446009378495034713e-04f, + -4.544327376257831556e-04f, + -3.639029022542405989e-04f, + -2.731029680102384292e-04f, + -1.821246458690281339e-04f, + -9.105972895404852794e-05f, + 2.249668800172135414e-17f, + 9.096286107495146821e-05f, + 1.817373693953476012e-04f, + 2.722323270597744641e-04f, + 3.623569146858229449e-04f, + 4.520207824765948832e-04f, + 5.411341407166387263e-04f, + 6.296078496082298161e-04f, + 7.173535083574583433e-04f, + 8.042835434204669747e-04f, + 8.903112958232611450e-04f, + 9.753511074673767468e-04f, + 1.059318406334858621e-03f, + 1.142129790509272816e-03f, + 1.223703110928572564e-03f, + 1.303957552787602704e-03f, + 1.382813715509965393e-03f, + 1.460193691210495345e-03f, + 1.536021141570667560e-03f, + 1.610221373050487641e-03f, + 1.682721410364203859e-03f, + 1.753450068146556471e-03f, + 1.822338020740059362e-03f, + 1.889317870034044975e-03f, + 1.954324211290346669e-03f, + 2.017293696890905524e-03f, + 2.078165097944757213e-03f, + 2.136879363695696771e-03f, + 2.193379678672519300e-03f, + 2.247611517526280130e-03f, + 2.299522697502668928e-03f, + 2.349063428498731048e-03f, + 2.396186360655621055e-03f, + 2.440846629443004217e-03f, + 2.483001898191590853e-03f, + 2.522612398034211525e-03f, + 2.559640965217286051e-03f, + 2.594053075748732184e-03f, + 2.625816877349718484e-03f, + 2.654903218680989673e-03f, + 2.681285675817290850e-03f, + 2.704940575946320012e-03f, + 2.725847018271134597e-03f, + 2.743986892097757119e-03f, + 2.759344892093201339e-03f, + 2.771908530701254220e-03f, + 2.781668147706524256e-03f, + 2.788616916940388039e-03f, + 2.792750850124972248e-03f, + 2.794068797854331460e-03f, + 2.792572447715026187e-03f, + 2.788266319550961395e-03f, + 2.781157757880268772e-03f, + 2.771256921475067844e-03f, + 2.758576770117475430e-03f, + 2.743133048548284346e-03f, + 2.724944267627588904e-03f, + 2.704031682729127542e-03f, + 2.680419269393146536e-03f, + 2.654133696265428919e-03f, + 2.625204295352332774e-03f, + 2.593663029624824687e-03f, + 2.559544458007235838e-03f, + 2.522885697788194298e-03f, + 2.483726384495194266e-03f, + 2.442108629274998555e-03f, + 2.398076973826478078e-03f, + 2.351678342933034675e-03f, + 2.302961994645597293e-03f, + 2.251979468168421438e-03f, + 2.198784529503366135e-03f, + 2.143433114908959661e-03f, + 2.085983272233949380e-03f, + 2.026495100187157301e-03f, + 1.965030685606198105e-03f, + 1.901654038790769660e-03f, + 1.836431026968307709e-03f, + 1.769429305960019570e-03f, + 1.700718250118553624e-03f, + 1.630368880610306992e-03f, + 1.558453792115264015e-03f, + 1.485047078020867951e-03f, + 1.410224254186159386e-03f, + 1.334062181355563604e-03f, + 1.256638986300702377e-03f, + 1.178033981771610395e-03f, + 1.098327585339919834e-03f, + 1.017601237215742414e-03f, + 9.359373171227939204e-04f, + 8.534190603167809844e-04f, + 7.701304728322726310e-04f, + 6.861562460439943638e-04f, + 6.015816706295592760e-04f, + 5.164925500217144947e-04f, + 4.309751134365081789e-04f, + 3.451159285661133287e-04f, + 2.590018140253294793e-04f, + 1.727197516388577871e-04f, + 8.635679865857319275e-05f, + 0.000000000000000000e+00f, + -8.626369941502123060e-05f, + -1.723475421202091517e-04f, + -2.581650452840001070e-04f, + -3.436300875175078229e-04f, + -4.286569952255241947e-04f, + -5.131606284134141056e-04f, + -5.970564658633488713e-04f, + -6.802606895961190543e-04f, + -7.626902685335093437e-04f, + -8.442630412771376771e-04f, + -9.248977979226647274e-04f, + -1.004514360827295531e-03f, + -1.083033664249621842e-03f, + -1.160377832784585195e-03f, + -1.236470258513610188e-03f, + -1.311235676795854824e-03f, + -1.384600240623468786e-03f, + -1.456491593469362491e-03f, + -1.526838940554491693e-03f, + -1.595573118465392530e-03f, + -1.662626663052574382e-03f, + -1.727933875544430866e-03f, + -1.791430886811391570e-03f, + -1.853055719717038941e-03f, + -1.912748349496546643e-03f, + -1.970450762103117051e-03f, + -2.026107010465434590e-03f, + -2.079663268602624775e-03f, + -2.131067883544039959e-03f, + -2.180271425003505598e-03f, + -2.227226732761336536e-03f, + -2.271888961708070937e-03f, + -2.314215624507658369e-03f, + -2.354166631838931854e-03f, + -2.391704330178351379e-03f, + -2.426793537088085383e-03f, + -2.459401573976375491e-03f, + -2.489498296300512482e-03f, + -2.517056121184375189e-03f, + -2.542050052425464269e-03f, + -2.564457702869174776e-03f, + -2.584259314130737690e-03f, + -2.601437773647668344e-03f, + -2.615978629048301869e-03f, + -2.627870099825200655e-03f, + -2.637103086304351703e-03f, + -2.643671175903983435e-03f, + -2.647570646679886421e-03f, + -2.648800468156370640e-03f, + -2.647362299445082338e-03f, + -2.643260484656465709e-03f, + -2.636502045611470533e-03f, + -2.627096671863705067e-03f, + -2.615056708045107071e-03f, + -2.600397138550693873e-03f, + -2.583135569580662441e-03f, + -2.563292208561044304e-03f, + -2.540889840966167532e-03f, + -2.515953804569251093e-03f, + -2.488511961150026430e-03f, + -2.458594665690286458e-03f, + -2.426234733091499601e-03f, + -2.391467402450208560e-03f, + -2.354330298930778966e-03f, + -2.314863393275341449e-03f, + -2.273108958995205108e-03f, + -2.229111527288808303e-03f, + -2.182917839734724828e-03f, + -2.134576798809103074e-03f, + -2.084139416280047803e-03f, + -2.031658759533671622e-03f, + -1.977189895887380630e-03f, + -1.920789834949013144e-03f, + -1.862517469082529712e-03f, + -1.802433512041404706e-03f, + -1.740600435833956081e-03f, + -1.677082405886637763e-03f, + -1.611945214571482154e-03f, + -1.545256213167279678e-03f, + -1.477084242324090734e-03f, + -1.407499561103702770e-03f, + -1.336573774667974704e-03f, + -1.264379760689891439e-03f, + -1.190991594563459415e-03f, + -1.116484473487968287e-03f, + -1.040934639504879694e-03f, + -9.644193015667102938e-04f, + -8.870165567158059617e-04f, + -8.088053104554945427e-04f, + -7.298651963925226931e-04f, + -6.502764952346872223e-04f, + -5.701200532242376492e-04f, + -4.894772000905328905e-04f, + -4.084296666057908869e-04f, + -3.270595018261514210e-04f, + -2.454489901024086416e-04f, + -1.636805679449392656e-04f, + -8.183674082536929162e-05f, + -3.536521155687695770e-17f, + 8.174726056185484973e-05f, + 1.633228270606075061e-04f, + 2.446447484770642063e-04f, + 3.256314188286605011e-04f, + 4.062016589873803664e-04f, + 4.862747979789591962e-04f, + 5.657707536813316989e-04f, + 6.446101128410288350e-04f, + 7.227142103289445341e-04f, + 8.000052075557968854e-04f, + 8.764061699685609655e-04f, + 9.518411435521427575e-04f, + 1.026235230259113333e-03f, + 1.099514662293880982e-03f, + 1.171606875175669731e-03f, + 1.242440579510656730e-03f, + 1.311945831400333469e-03f, + 1.380054101417801157e-03f, + 1.446698342082995128e-03f, + 1.511813053771716119e-03f, + 1.575334348993146514e-03f, + 1.637200014972404940e-03f, + 1.697349574477985271e-03f, + 1.755724344834148822e-03f, + 1.812267495060354474e-03f, + 1.866924101083174007e-03f, + 1.919641198966668804e-03f, + 1.970367836109312640e-03f, + 2.019055120359112502e-03f, + 2.065656266998848294e-03f, + 2.110126643557067375e-03f, + 2.152423812401290867e-03f, + 2.192507571073842951e-03f, + 2.230339990331663483e-03f, + 2.265885449854030363e-03f, + 2.299110671585404518e-03f, + 2.329984750682085725e-03f, + 2.358479184033766222e-03f, + 2.384567896334751410e-03f, + 2.408227263680306953e-03f, + 2.429436134667956135e-03f, + 2.448175848984440826e-03f, + 2.464430253462965986e-03f, + 2.478185715597053772e-03f, + 2.489431134500083229e-03f, + 2.498157949302601787e-03f, + 2.504360144981462345e-03f, + 2.508034255617927130e-03f, + 2.509179365084111650e-03f, + 2.507797105160097621e-03f, + 2.503891651086268943e-03f, + 2.497469714558282327e-03f, + 2.488540534174480279e-03f, + 2.477115863348166615e-03f, + 2.463209955699809280e-03f, + 2.446839547946541571e-03f, + 2.428023840308957040e-03f, + 2.406784474457862241e-03f, + 2.383145509025629081e-03f, + 2.357133392709743602e-03f, + 2.328776934998069703e-03f, + 2.298107274548326535e-03f, + 2.265157845255661752e-03f, + 2.229964340045592890e-03f, + 2.192564672431069738e-03f, + 2.152998935874733330e-03f, + 2.111309361000000308e-03f, + 2.067540270696137036e-03f, + 2.021738033165410009e-03f, + 1.973951012961244755e-03f, + 1.924229520069206407e-03f, + 1.872625757084688284e-03f, + 1.819193764541884861e-03f, + 1.763989364451496421e-03f, + 1.707070102106509864e-03f, + 1.648495186215746637e-03f, + 1.588325427427724965e-03f, + 1.526623175309085347e-03f, + 1.463452253841756060e-03f, + 1.398877895506348739e-03f, + 1.332966674019096277e-03f, + 1.265786435792502209e-03f, + 1.197406230189095033e-03f, + 1.127896238640391496e-03f, + 1.057327702704293892e-03f, + 9.857728511335100193e-04f, + 9.133048260301522472e-04f, + 8.399976081621432457e-04f, + 7.659259415173617783e-04f, + 6.911652571721143201e-04f, + 6.157915965516007339e-04f, + 5.398815341610210556e-04f, + 4.635120998645952885e-04f, + 3.867607007918734689e-04f, + 3.097050429510698013e-04f, + 2.324230526274301040e-04f, + 1.549927976471593514e-04f, + 7.749240858556649941e-05f, + 0.000000000000000000e+00f, + -7.740640823447261787e-05f, + -1.546489694066701043e-04f, + -2.316500881890203695e-04f, + -3.083324985177912040e-04f, + -3.846193410553054690e-04f, + -4.604342401558712806e-04f, + -5.357013802596746321e-04f, + -6.103455816376617384e-04f, + -6.842923754112235652e-04f, + -7.574680777731551771e-04f, + -8.297998633349399841e-04f, + -9.012158375281924391e-04f, + -9.716451079872685803e-04f, + -1.041017854843918943e-03f, + -1.109265399862380090e-03f, + -1.176320274348555822e-03f, + -1.242116285764278049e-03f, + -1.306588582982534663e-03f, + -1.369673720118763302e-03f, + -1.431309718874978175e-03f, + -1.491436129336623072e-03f, + -1.549994089162047605e-03f, + -1.606926381106289162e-03f, + -1.662177488824047355e-03f, + -1.715693650896988340e-03f, + -1.767422913032514007e-03f, + -1.817315178384378135e-03f, + -1.865322255945725321e-03f, + -1.911397906968511154e-03f, + -1.955497889364013041e-03f, + -1.997580000042790960e-03f, + -2.037604115153256439e-03f, + -2.075532228180405718e-03f, + -2.111328485869323496e-03f, + -2.144959221939368461e-03f, + -2.176392988557203194e-03f, + -2.205600585540104519e-03f, + -2.232555087262260568e-03f, + -2.257231867239448825e-03f, + -2.279608620370068926e-03f, + -2.299665382812773017e-03f, + -2.317384549483214162e-03f, + -2.332750889154779940e-03f, + -2.345751557151114393e-03f, + -2.356376105620029086e-03f, + -2.364616491381328796e-03f, + -2.370467081343168980e-03f, + -2.373924655484415357e-03f, + -2.374988407402560224e-03f, + -2.373659942429402498e-03f, + -2.369943273319134042e-03f, + -2.363844813515844894e-03f, + -2.355373368009962363e-03f, + -2.344540121795531118e-03f, + -2.331358625942570734e-03f, + -2.315844781301389533e-03f, + -2.298016819857692100e-03f, + -2.277895283760072130e-03f, + -2.255503002043453362e-03f, + -2.230865065074793489e-03f, + -2.204008796749007838e-03f, + -2.174963724465795757e-03f, + -2.143761546920198904e-03f, + -2.110436099741713409e-03f, + -2.075023319018890790e-03f, + -2.037561202748555591e-03f, + -1.998089770251173809e-03f, + -1.956651019594995121e-03f, + -1.913288883074297899e-03f, + -1.868049180789196646e-03f, + -1.820979572375211594e-03f, + -1.772129506933642308e-03f, + -1.721550171215585189e-03f, + -1.669294436113043234e-03f, + -1.615416801513268677e-03f, + -1.559973339574200445e-03f, + -1.503021636479029855e-03f, + -1.444620732731039447e-03f, + -1.384831062049924873e-03f, + -1.323714388933566266e-03f, + -1.261333744948669490e-03f, + -1.197753363816366759e-03f, + -1.133038615360030133e-03f, + -1.067255938382161932e-03f, + -1.000472772539666867e-03f, + -9.327574892878164135e-04f, + -8.641793219624978621e-04f, + -7.948082950727303935e-04f, + -7.247151528757850725e-04f, + -6.539712873074342899e-04f, + -5.826486653404457788e-04f, + -5.108197558453200652e-04f, + -4.385574560281823480e-04f, + -3.659350175192179139e-04f, + -2.930259721875476224e-04f, + -2.199040577568145362e-04f, + -1.466431432977234172e-04f, + -7.331715467149604577e-05f, + -1.583863635030426600e-17f, + 7.323450476167464791e-05f, + 1.463127100768226222e-04f, + 2.191612068271459025e-04f, + 2.917068999868720029e-04f, + 3.638770818979462419e-04f, + 4.355995050724186771e-04f, + 5.068024544486168575e-04f, + 5.774148190301226381e-04f, + 6.473661628350382271e-04f, + 7.165867950855838104e-04f, + 7.850078395671508278e-04f, + 8.525613030890458839e-04f, + 9.191801429783286312e-04f, + 9.847983335396156852e-04f, + 1.049350931415344917e-03f, + 1.112774139782065014e-03f, + 1.175005371319211289e-03f, + 1.235983309887723515e-03f, + 1.295647970858855580e-03f, + 1.353940760033357088e-03f, + 1.410804531092786597e-03f, + 1.466183641527706851e-03f, + 1.520024006987588487e-03f, + 1.572273153999021768e-03f, + 1.622880271001914641e-03f, + 1.671796257653338251e-03f, + 1.718973772351856891e-03f, + 1.764367277935770294e-03f, + 1.807933085512109829e-03f, + 1.849629396373906774e-03f, + 1.889416341965344378e-03f, + 1.927256021857423661e-03f, + 1.963112539697747360e-03f, + 1.996952037100198536e-03f, + 2.028742725443338692e-03f, + 2.058454915547453749e-03f, + 2.086061045202587064e-03f, + 2.111535704522703519e-03f, + 2.134855659102633321e-03f, + 2.155999870956868715e-03f, + 2.174949517221738769e-03f, + 2.191688006604752131e-03f, + 2.206200993566935931e-03f, + 2.218476390226378162e-03f, + 2.228504375973802080e-03f, + 2.236277404792865950e-03f, + 2.241790210280533453e-03f, + 2.245039808364943448e-03f, + 2.246025497720799922e-03f, + 2.244748857884364644e-03f, + 2.241213745072582770e-03f, + 2.235426285713204824e-03f, + 2.227394867694926922e-03f, + 2.217130129349095119e-03f, + 2.204644946176507331e-03f, + 2.189954415335300473e-03f, + 2.173075837908174709e-03f, + 2.154028698969212043e-03f, + 2.132834645472967295e-03f, + 2.109517461990493593e-03f, + 2.084103044319416103e-03f, + 2.056619370996764975e-03f, + 2.027096472745798170e-03f, + 1.995566399890039318e-03f, + 1.962063187769620600e-03f, + 1.926622820196907150e-03f, + 1.889283190990552431e-03f, + 1.850084063629192947e-03f, + 1.809067029067121680e-03f, + 1.766275461756697642e-03f, + 1.721754473924256863e-03f, + 1.675550868146924400e-03f, + 1.627713088280349860e-03f, + 1.578291168789072458e-03f, + 1.527336682531643414e-03f, + 1.474902687055531115e-03f, + 1.421043669457084475e-03f, + 1.365815489864515746e-03f, + 1.309275323601538730e-03f, + 1.251481602091836709e-03f, + 1.192493952565831317e-03f, + 1.132373136630967277e-03f, + 1.071180987769143524e-03f, + 1.008980347826006095e-03f, + 9.458350025562797456e-04f, + 8.818096162916508503e-04f, + 8.169696657985963404e-04f, + 7.513813733923349223e-04f, + 6.851116393769219248e-04f, + 6.182279738784716289e-04f, + 5.507984281427341774e-04f, + 4.828915253653128263e-04f, + 4.145761911257870138e-04f, + 3.459216834955630552e-04f, + 2.769975228912344525e-04f, + 2.078734217432808354e-04f, + 1.386192140517258974e-04f, + 6.930478490043769405e-05f, + 3.850678557016620008e-17f, + -6.922536466905694359e-05f, + -1.383016930421246003e-04f, + -2.071595989147220697e-04f, + -2.757299955756169576e-04f, + -3.439441650576845872e-04f, + -4.117338269385969812e-04f, + -4.790312066215028815e-04f, + -5.457691030282071530e-04f, + -6.118809556363564821e-04f, + -6.773009107949520824e-04f, + -7.419638872516609194e-04f, + -8.058056408262444324e-04f, + -8.687628281669950792e-04f, + -9.307730695263674928e-04f, + -9.917750104935054486e-04f, + -1.051708382622899233e-03f, + -1.110514062899539038e-03f, + -1.168134131981801499e-03f, + -1.224511931164258289e-03f, + -1.279592118005431134e-03f, + -1.333320720565457380e-03f, + -1.385645190200188951e-03f, + -1.436514452861111955e-03f, + -1.485878958850318310e-03f, + -1.533690730982715860e-03f, + -1.579903411108077825e-03f, + -1.624472304948763358e-03f, + -1.667354425209425627e-03f, + -1.708508532916933748e-03f, + -1.747895176951601770e-03f, + -1.785476731731549735e-03f, + -1.821217433014094391e-03f, + -1.855083411780856367e-03f, + -1.887042726174312105e-03f, + -1.917065391455589646e-03f, + -1.945123407956183582e-03f, + -1.971190786997232842e-03f, + -1.995243574752887921e-03f, + -2.017259874035835007e-03f, + -2.037219863985523585e-03f, + -2.055105817641905350e-03f, + -2.070902117388888439e-03f, + -2.084595268254915961e-03f, + -2.096173909059424311e-03f, + -2.105628821396557989e-03f, + -2.112952936449467856e-03f, + -2.118141339630974854e-03f, + -2.121191273048350125e-03f, + -2.122102135792170319e-03f, + -2.120875482051600824e-03f, + -2.117515017060413347e-03f, + -2.112026590880362788e-03f, + -2.104418190030685459e-03f, + -2.094699926974599290e-03f, + -2.082884027475962168e-03f, + -2.068984815841183947e-03f, + -2.053018698063778860e-03f, + -2.035004142890892240e-03f, + -2.014961660833440929e-03f, + -1.992913781143200273e-03f, + -1.968885026782406667e-03f, + -1.942901887413728572e-03f, + -1.914992790439534482e-03f, + -1.885188070122604002e-03f, + -1.853519934820884200e-03f, + -1.820022432372197857e-03f, + -1.784731413665374862e-03f, + -1.747684494436782749e-03f, + -1.708921015333154415e-03f, + -1.668482000282380450e-03f, + -1.626410113216474832e-03f, + -1.582749613192508320e-03f, + -1.537546307957996655e-03f, + -1.490847506009852948e-03f, + -1.442701967196525136e-03f, + -1.393159851915445457e-03f, + -1.342272668957837298e-03f, + -1.290093222055339146e-03f, + -1.236675555184266412e-03f, + -1.182074896683267323e-03f, + -1.126347602242422363e-03f, + -1.069551096823031762e-03f, + -1.011743815566986619e-03f, + -9.529851437568570560e-04f, + -8.933353558887932458e-04f, + -8.328555539196910067e-04f, + -7.716076047526932357e-04f, + -7.096540770239413622e-04f, + -6.470581772568036877e-04f, + -5.838836854464510024e-04f, + -5.201948901420694023e-04f, + -4.560565230917139183e-04f, + -3.915336935171430800e-04f, + -3.266918220842130881e-04f, + -2.615965746362512961e-04f, + -1.963137957579778382e-04f, + -1.309094422360982627e-04f, + -6.544951648425400908e-05f, + 0.000000000000000000e+00f, + 6.537321308021720669e-05f, + 1.306043822607082607e-04f, + 1.956279867336831537e-04f, + 2.603787911287086792e-04f, + 3.247919108976276181e-04f, + 3.888028772701663366e-04f, + 4.523477017143444248e-04f, + 5.153629398383980818e-04f, + 5.777857546699370411e-04f, + 6.395539792487880222e-04f, + 7.006061784722651719e-04f, + 7.608817101308743870e-04f, + 8.203207850733748325e-04f, + 8.788645264429036270e-04f, + 9.364550279239102458e-04f, + 9.930354109440190161e-04f, + 1.048549880772794290e-03f, + 1.102943781463442676e-03f, + 1.156163649582898304e-03f, + 1.208157266677142242e-03f, + 1.258873710421226384e-03f, + 1.308263404403530459e-03f, + 1.356278166495282879e-03f, + 1.402871255759119157e-03f, + 1.447997417850374223e-03f, + 1.491612928867637770e-03f, + 1.533675637609531331e-03f, + 1.574145006197766577e-03f, + 1.612982149027046997e-03f, + 1.650149870004234296e-03f, + 1.685612698041884239e-03f, + 1.719336920772085442e-03f, + 1.751290616448417667e-03f, + 1.781443684006613678e-03f, + 1.809767871255424246e-03f, + 1.836236801171283600e-03f, + 1.860825996272981193e-03f, + 1.883512901053582605e-03f, + 1.904276902449677372e-03f, + 1.923099348328973467e-03f, + 1.939963563980765578e-03f, + 1.954854866594344254e-03f, + 1.967760577713456756e-03f, + 1.978670033656380715e-03f, + 1.987574593893788513e-03f, + 1.994467647378149553e-03f, + 1.999344616820692734e-03f, + 2.002202960914168783e-03f, + 2.003042174501439791e-03f, + 2.001863786692200525e-03f, + 1.998671356932133197e-03f, + 1.993470469030853877e-03f, + 1.986268723157068750e-03f, + 1.977075725811386266e-03f, + 1.965903077789286045e-03f, + 1.952764360148673750e-03f, + 1.937675118198656623e-03f, + 1.920652843527819766e-03f, + 1.901716954092479844e-03f, + 1.880888772387422731e-03f, + 1.858191501723117835e-03f, + 1.833650200635677813e-03f, + 1.807291755457605693e-03f, + 1.779144851079101806e-03f, + 1.749239939931425750e-03f, + 1.717609209225661468e-03f, + 1.684286546482327823e-03f, + 1.649307503388023569e-03f, + 1.612709258017795862e-03f, + 1.574530575463451180e-03f, + 1.534811766908859409e-03f, + 1.493594647195765511e-03f, + 1.450922490924287005e-03f, + 1.406839987134609086e-03f, + 1.361393192616601943e-03f, + 1.314629483896238502e-03f, + 1.266597507949261160e-03f, + 1.217347131692460890e-03f, + 1.166929390305300809e-03f, + 1.115396434435750447e-03f, + 1.062801476344078485e-03f, + 1.009198735040490926e-03f, + 9.546433804735578524e-04f, + 8.991914768259076738e-04f, + 8.428999249761178706e-04f, + 7.858264041852376820e-04f, + 7.280293130684387321e-04f, + 6.695677099108536621e-04f, + 6.105012523900892442e-04f, + 5.508901367652243143e-04f, + 4.907950365958332764e-04f, + 4.302770410520321762e-04f, + 3.693975928787344835e-04f, + 3.082184260775406768e-04f, + 2.468015033684312445e-04f, + 1.852089534950353614e-04f, + 1.235030084373483811e-04f, + 6.174594059430125743e-05f, + 2.096293806310516030e-17f, + -6.167264836248043244e-05f, + -1.232099870881719884e-04f, + -1.845502086537135426e-04f, + -2.456317774361367959e-04f, + -3.063934913834511463e-04f, + -3.667745432764744212e-04f, + -4.267145815201261821e-04f, + -4.861537704029955404e-04f, + -5.450328497660459227e-04f, + -6.032931940205293235e-04f, + -6.608768704559289274e-04f, + -7.177266967809564115e-04f, + -7.737862978399837359e-04f, + -8.290001614485750878e-04f, + -8.833136932931055871e-04f, + -9.366732708404333684e-04f, + -9.890262962043143858e-04f, + -1.040321247916032189e-03f, + -1.090507731549242732e-03f, + -1.139536529148920665e-03f, + -1.187359647415603143e-03f, + -1.233930364598734937e-03f, + -1.279203276052626528e-03f, + -1.323134338411260068e-03f, + -1.365680912338360217e-03f, + -1.406801803812153832e-03f, + -1.446457303904537337e-03f, + -1.484609227016050938e-03f, + -1.521220947530623618e-03f, + -1.556257434854668676e-03f, + -1.589685286806867721e-03f, + -1.621472761327541912e-03f, + -1.651589806477331930e-03f, + -1.680008088696766707e-03f, + -1.706701019300830170e-03f, + -1.731643779183499347e-03f, + -1.754813341709760346e-03f, + -1.776188493773842719e-03f, + -1.795749855005169008e-03f, + -1.813479895104255042e-03f, + -1.829362949293911016e-03f, + -1.843385231871876419e-03f, + -1.855534847853930556e-03f, + -1.865801802697809961e-03f, + -1.874178010100366288e-03f, + -1.880657297862605663e-03f, + -1.885235411818870100e-03f, + -1.887910017828480034e-03f, + -1.888680701830295272e-03f, + -1.887548967962307056e-03f, + -1.884518234750538193e-03f, + -1.879593829373407774e-03f, + -1.872782980009604853e-03f, + -1.864094806279484534e-03f, + -1.853540307791953041e-03f, + -1.841132350810590528e-03f, + -1.826885653054665781e-03f, + -1.810816766652771246e-03f, + -1.792944059268252940e-03f, + -1.773287693417722457e-03f, + -1.751869604005822220e-03f, + -1.728713474100759947e-03f, + -1.703844708977252705e-03f, + -1.677290408455194264e-03f, + -1.649079337563943938e-03f, + -1.619241895563655999e-03f, + -1.587810083356924057e-03f, + -1.554817469325785705e-03f, + -1.520299153629931172e-03f, + -1.484291731004316970e-03f, + -1.446833252095214512e-03f, + -1.407963183375834622e-03f, + -1.367722365683123140e-03f, + -1.326152971419345067e-03f, + -1.283298460463622734e-03f, + -1.239203534838731165e-03f, + -1.193914092180647360e-03f, + -1.147477178059556511e-03f, + -1.099940937201084957e-03f, + -1.051354563658511796e-03f, + -1.001768249987922176e-03f, + -9.512331354778615728e-04f, + -8.998012534875231673e-04f, + -8.475254779470752691e-04f, + -7.944594690758058310e-04f, + -7.406576183728511139e-04f, + -6.861749929372944591e-04f, + -6.310672791747117981e-04f, + -5.753907259474574801e-04f, + -5.192020872264638655e-04f, + -4.625585643030877768e-04f, + -4.055177476203069577e-04f, + -3.481375582814421167e-04f, + -2.904761892961940780e-04f, + -2.325920466240080111e-04f, + -1.745436900735062170e-04f, + -1.163897741181921285e-04f, + -5.818898868865390200e-05f, + -3.951477669352645278e-17f, + 5.811860852513058267e-05f, + 1.161083951789106388e-04f, + 1.739111186764226750e-04f, + 2.314687965911455317e-04f, + 2.887237634590489712e-04f, + 3.456187284925843007e-04f, + 4.020968328478077619e-04f, + 4.581017063869804681e-04f, + 5.135775238795969085e-04f, + 5.684690605867797827e-04f, + 6.227217471732920040e-04f, + 6.762817238922043568e-04f, + 7.290958939893588033e-04f, + 7.811119762742447376e-04f, + 8.322785568051721625e-04f, + 8.825451396379117895e-04f, + 9.318621965879654058e-04f, + 9.801812159573458638e-04f, + 1.027454750177579689e-03f, + 1.073636462323048543e-03f, + 1.118681171448473750e-03f, + 1.162544896706745696e-03f, + 1.205184900203477068e-03f, + 1.246559728547386213e-03f, + 1.286629253055807933e-03f, + 1.325354708576141497e-03f, + 1.362698730886437387e-03f, + 1.398625392638811350e-03f, + 1.433100237810905602e-03f, + 1.466090314633128333e-03f, + 1.497564206959974605e-03f, + 1.527492064055464794e-03f, + 1.555845628765160742e-03f, + 1.582598264047852974e-03f, + 1.607724977842486065e-03f, + 1.631202446246891868e-03f, + 1.653009034987472543e-03f, + 1.673124819160033650e-03f, + 1.691531601223876481e-03f, + 1.708212927233296189e-03f, + 1.723154101292263601e-03f, + 1.736342198219845579e-03f, + 1.747766074415657220e-03f, + 1.757416376916791541e-03f, + 1.765285550639219018e-03f, + 1.771367843798416159e-03f, + 1.775659311506234831e-03f, + 1.778157817542435270e-03f, + 1.778863034301330324e-03f, + 1.777776440915891046e-03f, + 1.774901319563383737e-03f, + 1.770242749958432374e-03f, + 1.763807602041371232e-03f, + 1.755604526871366649e-03f, + 1.745643945735682106e-03f, + 1.733938037488337493e-03f, + 1.720500724132964119e-03f, + 1.705347654666533944e-03f, + 1.688496187202536726e-03f, + 1.669965369393517111e-03f, + 1.649775917174820059e-03f, + 1.627950191853253523e-03f, + 1.604512175565338738e-03f, + 1.579487445132431861e-03f, + 1.552903144340421785e-03f, + 1.524787954674487571e-03f, + 1.495172064539795074e-03f, + 1.464087137001309370e-03f, + 1.431566276076835656e-03f, + 1.397643991619413597e-03f, + 1.362356162825694014e-03f, + 1.325740000408985944e-03f, + 1.287834007477042493e-03f, + 1.248677939155022100e-03f, + 1.208312760996174511e-03f, + 1.166780606223920529e-03f, + 1.124124731849302948e-03f, + 1.080389473709662384e-03f, + 1.035620200475557496e-03f, + 9.898632666728486313e-04f, + 9.431659647690965754e-04f, + 8.955764763732448116e-04f, + 8.471438225995464935e-04f, + 7.979178136459807611e-04f, + 7.479489976393288025e-04f, + 6.972886087997711303e-04f, + 6.459885149773112378e-04f, + 5.941011646141058575e-04f, + 5.416795331870154695e-04f, + 4.887770691848273815e-04f, + 4.354476396749826271e-04f, + 3.817454755153243395e-04f, + 3.277251162670002699e-04f, + 2.734413548635745875e-04f, + 2.189491820928326409e-04f, + 1.643037309479273775e-04f, + 1.095602209032437102e-04f, + 5.477390217168007973e-05f, + 0.000000000000000000e+00f, + -5.470634094252695156e-05f, + -1.092901120256077629e-04f, + -1.636964959141602542e-04f, + -2.178709215633056469e-04f, + -2.717591188977905368e-04f, + -3.253071731207118249e-04f, + -3.784615785968173970e-04f, + -4.311692922574608179e-04f, + -4.833777864735189634e-04f, + -5.350351013432206020e-04f, + -5.860898963437366797e-04f, + -6.364915012948296367e-04f, + -6.861899665835708047e-04f, + -7.351361126015605119e-04f, + -7.832815783443825139e-04f, + -8.305788691267564604e-04f, + -8.769814033650232248e-04f, + -9.224435583820854738e-04f, + -9.669207151891035966e-04f, + -1.010369302200565247e-03f, + -1.052746837839338510e-03f, + -1.094011971990893574e-03f, + -1.134124526265950332e-03f, + -1.173045533032109934e-03f, + -1.210737273177340265e-03f, + -1.247163312568430474e-03f, + -1.282288537169006893e-03f, + -1.316079186783988613e-03f, + -1.348502887397804448e-03f, + -1.379528682075299327e-03f, + -1.409127060396503806e-03f, + -1.437269986396952099e-03f, + -1.463930924987541645e-03f, + -1.489084866828790932e-03f, + -1.512708351636820334e-03f, + -1.534779489899245307e-03f, + -1.555277982980894256e-03f, + -1.574185141601471948e-03f, + -1.591483902668316052e-03f, + -1.607158844449279840e-03f, + -1.621196200072613954e-03f, + -1.633583869342330195e-03f, + -1.644311428859175465e-03f, + -1.653370140439019498e-03f, + -1.660752957822507871e-03f, + -1.666454531671149753e-03f, + -1.670471212846983723e-03f, + -1.672801053974688886e-03f, + -1.673443809286669515e-03f, + -1.672400932753375074e-03f, + -1.669675574502914881e-03f, + -1.665272575535695033e-03f, + -1.659198460741494619e-03f, + -1.651461430228174168e-03f, + -1.642071348972851856e-03f, + -1.631039734807969606e-03f, + -1.618379744756649665e-03f, + -1.604106159732930550e-03f, + -1.588235367624443381e-03f, + -1.570785344776701219e-03f, + -1.551775635899458553e-03f, + -1.531227332417528422e-03f, + -1.509163049289567434e-03f, + -1.485606900320671090e-03f, + -1.460584471994783983e-03f, + -1.434122795855729757e-03f, + -1.406250319466170913e-03f, + -1.376996875975918010e-03f, + -1.346393652331567652e-03f, + -1.314473156161391357e-03f, + -1.281269181370805988e-03f, + -1.246816772484174701e-03f, + -1.211152187770746713e-03f, + -1.174312861193657241e-03f, + -1.136337363221307049e-03f, + -1.097265360542288778e-03f, + -1.057137574726171045e-03f, + -1.015995739872469503e-03f, + -9.738825592923504131e-04f, + -9.308416612674603454e-04f, + -8.869175539322839185e-04f, + -8.421555793258690996e-04f, + -7.966018666606091347e-04f, + -7.503032848565528582e-04f, + -7.033073943892899100e-04f, + -6.556623985011526476e-04f, + -6.074170938261656567e-04f, + -5.586208204781806371e-04f, + -5.093234116545103949e-04f, + -4.595751428051017724e-04f, + -4.094266804203762987e-04f, + -3.589290304887579673e-04f, + -3.081334866766899275e-04f, + -2.570915782841462450e-04f, + -2.058550180275716367e-04f, + -1.544756497035134832e-04f, + -1.030053957862678347e-04f, + -5.149620501158499536e-05f, + -2.384103929205831118e-17f, + 5.143137502784089743e-05f, + 1.027462063910287337e-04f, + 1.538929628910742572e-04f, + 2.048203475057252935e-04f, + 2.554773487812054080e-04f, + 3.058132918724349066e-04f, + 3.557778891797814462e-04f, + 4.053212905313948854e-04f, + 4.543941328619231237e-04f, + 5.029475893377426772e-04f, + 5.509334178794880440e-04f, + 5.983040090345575221e-04f, + 6.450124331513995514e-04f, + 6.910124868096819382e-04f, + 7.362587384591508678e-04f, + 7.807065732238670707e-04f, + 8.243122368263766566e-04f, + 8.670328785894033810e-04f, + 9.088265934721979824e-04f, + 9.496524631011158801e-04f, + 9.894705957539746879e-04f, + 1.028242165258874252e-03f, + 1.065929448770301484e-03f, + 1.102495863385499807e-03f, + 1.137906001565360849e-03f, + 1.172125665326259570e-03f, + 1.205121899169577957e-03f, + 1.236863021717049538e-03f, + 1.267318656022278301e-03f, + 1.296459758529015880e-03f, + 1.324258646649080235e-03f, + 1.350689024933432675e-03f, + 1.375726009812287777e-03f, + 1.399346152880900310e-03f, + 1.421527462709165374e-03f, + 1.442249425155372978e-03f, + 1.461493022165247842e-03f, + 1.479240749039111274e-03f, + 1.495476630152138510e-03f, + 1.510186233113277763e-03f, + 1.523356681351052851e-03f, + 1.534976665115079944e-03f, + 1.545036450884612481e-03f, + 1.553527889176402723e-03f, + 1.560444420746071904e-03f, + 1.565781081178877019e-03f, + 1.569534503867175447e-03f, + 1.571702921373700117e-03f, + 1.572286165181262111e-03f, + 1.571285663831225405e-03f, + 1.568704439454675749e-03f, + 1.564547102701767346e-03f, + 1.558819846076479193e-03f, + 1.551530435685405255e-03f, + 1.542688201411057929e-03f, + 1.532304025521471613e-03f, + 1.520390329729599246e-03f, + 1.506961060717611732e-03f, + 1.492031674142519585e-03f, + 1.475619117141234709e-03f, + 1.457741809354577093e-03f, + 1.438419622491405236e-03f, + 1.417673858455001249e-03f, + 1.395527226055938864e-03f, + 1.372003816336560527e-03f, + 1.347129076533619364e-03f, + 1.320929782707246439e-03f, + 1.293434011065339607e-03f, + 1.264671108014265698e-03f, + 1.234671658967309224e-03f, + 1.203467455944029225e-03f, + 1.171091463995042447e-03f, + 1.137577786487074328e-03f, + 1.102961629284945943e-03f, + 1.067279263868331236e-03f, + 1.030567989421257843e-03f, + 9.928660939341588630e-04f, + 9.542128143592528474e-04f, + 9.146482958600143324e-04f, + 8.742135501974977914e-04f, + 8.329504132961628631e-04f, + 7.909015020336008844e-04f, + 7.481101702980445106e-04f, + 7.046204643591989737e-04f, + 6.604770775986386951e-04f, + 6.157253046455315841e-04f, + 5.704109949650640419e-04f, + 5.245805059471973005e-04f, + 4.782806555435268323e-04f, + 4.315586745004174507e-04f, + 3.844621582371941467e-04f, + 3.370390184187921768e-04f, + 2.893374342713311603e-04f, + 2.414058036903930554e-04f, + 1.932926941919554573e-04f, + 1.450467937548224429e-04f, + 9.671686160493662174e-05f, + 4.835167899075133784e-05f, + 0.000000000000000000e+00f, + -4.828949753345398863e-05f, + -9.646826098282474608e-05f, + -1.444879116922577944e-04f, + -1.923002935030318679e-04f, + -2.398575209931877504e-04f, + -2.871120273819045897e-04f, + -3.340166120515270496e-04f, + -3.805244876394365660e-04f, + -4.265893266524579085e-04f, + -4.721653075582231689e-04f, + -5.172071603070152717e-04f, + -5.616702112394265662e-04f, + -6.055104273346537417e-04f, + -6.486844597567101994e-04f, + -6.911496866543188596e-04f, + -7.328642551735467438e-04f, + -7.737871226406448826e-04f, + -8.138780968755867382e-04f, + -8.530978755963916508e-04f, + -8.914080848753665014e-04f, + -9.287713166103488344e-04f, + -9.651511649741133930e-04f, + -1.000512261806224762e-03f, + -1.034820310913592929e-03f, + -1.068042121246285314e-03f, + -1.100145638916268705e-03f, + -1.131099978028938862e-03f, + -1.160875450297352155e-03f, + -1.189443593411230841e-03f, + -1.216777198133303000e-03f, + -1.242850334097847032e-03f, + -1.267638374286776453e-03f, + -1.291118018160179043e-03f, + -1.313267313420094689e-03f, + -1.334065676387146760e-03f, + -1.353493910971104207e-03f, + -1.371534226218442407e-03f, + -1.388170252420803863e-03f, + -1.403387055769956442e-03f, + -1.417171151546464019e-03f, + -1.429510515830663278e-03f, + -1.440394595726007159e-03f, + -1.449814318086319878e-03f, + -1.457762096740287039e-03f, + -1.464231838207676094e-03f, + -1.469218945903567495e-03f, + -1.472720322828254208e-03f, + -1.474734372742105958e-03f, + -1.475260999826186192e-03f, + -1.474301606830856525e-03f, + -1.471859091716282196e-03f, + -1.467937842790105170e-03f, + -1.462543732349215952e-03f, + -1.455684108833884020e-03f, + -1.447367787504157772e-03f, + -1.437605039649846777e-03f, + -1.426407580346835237e-03f, + -1.413788554773978299e-03f, + -1.399762523106214953e-03f, + -1.384345444001102527e-03f, + -1.367554656697077568e-03f, + -1.349408861743359471e-03f, + -1.329928100382799265e-03f, + -1.309133732610135619e-03f, + -1.287048413929449148e-03f, + -1.263696070835965916e-03f, + -1.239101875048799527e-03f, + -1.213292216521904285e-03f, + -1.186294675262172631e-03f, + -1.158137991984896625e-03f, + -1.128852037637259912e-03f, + -1.098467781822281067e-03f, + -1.067017260156693896e-03f, + -1.034533540596639092e-03f, + -1.001050688766642752e-03f, + -9.666037323284525605e-04f, + -9.312286244263419952e-04f, + -8.949622062474039356e-04f, + -8.578421687353971186e-04f, + -8.199070134983350812e-04f, + -7.811960129497022435e-04f, + -7.417491697247534464e-04f, + -7.016071754140860680e-04f, + -6.608113686563731959e-04f, + -6.194036926336412294e-04f, + -5.774266520130750657e-04f, + -5.349232693788336665e-04f, + -4.919370411988257261e-04f, + -4.485118933715837031e-04f, + -4.046921363984502134e-04f, + -3.605224202266125153e-04f, + -3.160476888090664981e-04f, + -2.713131344280844096e-04f, + -2.263641518278198237e-04f, + -1.812462922031631745e-04f, + -1.360052170909635560e-04f, + -9.068665221087721649e-05f, + -4.533634130168751519e-05f, + -1.119205495635177410e-17f, + 4.527673019179228291e-05f, + 9.044832780293992876e-05f, + 1.354694371103048339e-04f, + 1.802949136270320799e-04f, + 2.248798693188531084e-04f, + 2.691797175024917524e-04f, + 3.131502173809525350e-04f, + 3.567475181720213820e-04f, + 3.999282027853717433e-04f, + 4.426493310053094079e-04f, + 4.848684821356317727e-04f, + 5.265437970650557525e-04f, + 5.676340197111919006e-04f, + 6.080985378017700815e-04f, + 6.478974229535403896e-04f, + 6.869914700090091119e-04f, + 7.253422355920121755e-04f, + 7.629120758449196762e-04f, + 7.996641833101642005e-04f, + 8.355626229197331365e-04f, + 8.705723670581514643e-04f, + 9.046593296642918905e-04f, + 9.377903993392572779e-04f, + 9.699334714277904395e-04f, + 1.001057479042750638e-03f, + 1.031132423002631329e-03f, + 1.060129400652862165e-03f, + 1.088020633543997301e-03f, + 1.114779493940055944e-03f, + 1.140380530131902001e-03f, + 1.164799490531472428e-03f, + 1.188013346524613607e-03f, + 1.210000314060736106e-03f, + 1.230739873959466437e-03f, + 1.250212790915166154e-03f, + 1.268401131182280697e-03f, + 1.285288278925214404e-03f, + 1.300858951217885064e-03f, + 1.315099211679921550e-03f, + 1.327996482737379275e-03f, + 1.339539556497333726e-03f, + 1.349718604227470977e-03f, + 1.358525184432789320e-03f, + 1.365952249523105658e-03f, + 1.371994151066654273e-03f, + 1.376646643626202498e-03f, + 1.379906887175804363e-03f, + 1.381773448097536276e-03f, + 1.382246298759191167e-03f, + 1.381326815675158054e-03f, + 1.379017776254279782e-03f, + 1.375323354139781646e-03f, + 1.370249113147892998e-03f, + 1.363801999813117269e-03f, + 1.355990334549495588e-03f, + 1.346823801438608650e-03f, + 1.336313436656531026e-03f, + 1.324471615553049963e-03f, + 1.311312038398147750e-03f, + 1.296849714811698206e-03f, + 1.281100946894079716e-03f, + 1.264083311076190895e-03f, + 1.245815638708950906e-03f, + 1.226317995413717370e-03f, + 1.205611659215808989e-03f, + 1.183719097484903357e-03f, + 1.160663942707366959e-03f, + 1.136470967116147033e-03f, + 1.111166056205482996e-03f, + 1.084776181158849176e-03f, + 1.057329370218964941e-03f, + 1.028854679030497465e-03f, + 9.993821599864546878e-04f, + 9.689428306109160735e-04f, + 9.375686410107936589e-04f, + 9.052924404308006949e-04f, + 8.721479429470286020e-04f, + 8.381696923342349089e-04f, + 8.033930261436254697e-04f, + 7.678540390285455838e-04f, + 7.315895453557641741e-04f, + 6.946370411414883386e-04f, + 6.570346653508382520e-04f, + 6.188211606008807691e-04f, + 5.800358333080047517e-04f, + 5.407185133199405181e-04f, + 5.009095130741225872e-04f, + 4.606495863245328032e-04f, + 4.199798864786004988e-04f, + 3.789419245869958758e-04f, + 3.375775270294791236e-04f, + 2.959287929392034368e-04f, + 2.540380514093228668e-04f, + 2.119478185249197815e-04f, + 1.697007542644115945e-04f, + 1.273396193133593797e-04f, + 8.490723183468631443e-05f, + 4.244642423929934338e-05f, + 2.489132717092975244e-17f, + -4.238930944730621606e-05f, + -8.467888767193799395e-05f, + -1.268262760429604032e-04f, + -1.687892163075062216e-04f, + -2.105256929093874817e-04f, + -2.519939750065616508e-04f, + -2.931526581448565673e-04f, + -3.339607055468352646e-04f, + -3.743774889740940815e-04f, + -4.143628291230573081e-04f, + -4.538770355138195783e-04f, + -4.928809458321817922e-04f, + -5.313359646865749471e-04f, + -5.692041017412580173e-04f, + -6.064480091878560880e-04f, + -6.430310185189792816e-04f, + -6.789171765674388570e-04f, + -7.140712807754315923e-04f, + -7.484589136597800171e-04f, + -7.820464764390349256e-04f, + -8.148012217900297898e-04f, + -8.466912857015470575e-04f, + -8.776857183947638259e-04f, + -9.077545142802680937e-04f, + -9.368686409224388084e-04f, + -9.650000669841776822e-04f, + -9.921217891239340544e-04f, + -1.018207857820698729e-03f, + -1.043233402101169816e-03f, + -1.067174653146455267e-03f, + -1.090008966755562705e-03f, + -1.111714844644859455e-03f, + -1.132271954563242268e-03f, + -1.151661149204728438e-03f, + -1.169864483900832875e-03f, + -1.186865233076385287e-03f, + -1.202647905454177829e-03f, + -1.217198257994649147e-03f, + -1.230503308558112416e-03f, + -1.242551347278776424e-03f, + -1.253331946640669171e-03f, + -1.262835970246984230e-03f, + -1.271055580275981447e-03f, + -1.277984243617538056e-03f, + -1.283616736686040089e-03f, + -1.287949148906458816e-03f, + -1.290978884872014988e-03f, + -1.292704665172990245e-03f, + -1.293126525897621585e-03f, + -1.292245816807471729e-03f, + -1.290065198190826342e-03f, + -1.286588636399150143e-03f, + -1.281821398072865732e-03f, + -1.275770043064026376e-03f, + -1.268442416064888972e-03f, + -1.259847636952461181e-03f, + -1.249996089860607850e-03f, + -1.238899410992382174e-03f, + -1.226570475186708736e-03f, + -1.213023381254520064e-03f, + -1.198273436100851744e-03f, + -1.182337137650689993e-03f, + -1.165232156597218035e-03f, + -1.146977316992536366e-03f, + -1.127592575702190524e-03f, + -1.107099000745486849e-03f, + -1.085518748545065719e-03f, + -1.062875040110370555e-03f, + -1.039192136180123365e-03f, + -1.014495311350580541e-03f, + -9.888108272168318318e-04f, + -9.621659045558878355e-04f, + -9.345886945805340160e-04f, + -9.061082492943768954e-04f, + -8.767544909794978232e-04f, + -8.465581808478967385e-04f, + -8.155508868906216624e-04f, + -7.837649509569552704e-04f, + -7.512334550985514227e-04f, + -7.179901872135618750e-04f, + -6.840696060258972568e-04f, + -6.495068054360894584e-04f, + -6.143374782808354653e-04f, + -5.785978795380620956e-04f, + -5.423247890156327302e-04f, + -5.055554735623122827e-04f, + -4.683276488392193763e-04f, + -4.306794406911591301e-04f, + -3.926493461576842912e-04f, + -3.542761941630523837e-04f, + -3.155991059257000266e-04f, + -2.766574551271435236e-04f, + -2.374908278813562743e-04f, + -1.981389825446179249e-04f, + -1.586418094068897395e-04f, + -1.190392903058594805e-04f, + -7.937145820385292140e-05f, + -3.967835676875259741e-05f, + 0.000000000000000000e+00f, + 3.962366806029014220e-05f, + 7.915281349029238485e-05f, + 1.185477524848153186e-04f, + 1.577689911456342596e-04f, + 1.967772650253714708e-04f, + 2.355335783858113143e-04f, + 2.739992431308870902e-04f, + 3.121359173761859267e-04f, + 3.499056436162521094e-04f, + 3.872708864514444720e-04f, + 4.241945698375216493e-04f, + 4.606401138207244462e-04f, + 4.965714707217308132e-04f, + 5.319531607333346764e-04f, + 5.667503068964558190e-04f, + 6.009286694197791883e-04f, + 6.344546793099163770e-04f, + 6.672954712786205531e-04f, + 6.994189158952225562e-04f, + 7.307936509524349481e-04f, + 7.613891120155314102e-04f, + 7.911755621249407519e-04f, + 8.201241206232327396e-04f, + 8.482067910791271214e-04f, + 8.753964882812977381e-04f, + 9.016670642761047145e-04f, + 9.269933334240764138e-04f, + 9.513510964518079316e-04f, + 9.747171634758099818e-04f, + 9.970693759769062425e-04f, + 1.018386627704094679e-03f, + 1.038648884488686591e-03f, + 1.057837202950029669e-03f, + 1.075933748075338925e-03f, + 1.092921809657792587e-03f, + 1.108785817577722472e-03f, + 1.123511355912956439e-03f, + 1.137085175865973829e-03f, + 1.149495207496349907e-03f, + 1.160730570248186353e-03f, + 1.170781582263828594e-03f, + 1.179639768475975034e-03f, + 1.187297867471814568e-03f, + 1.193749837123847697e-03f, + 1.198990858983596747e-03f, + 1.203017341435374133e-03f, + 1.205826921608644554e-03f, + 1.207418466048858175e-03f, + 1.207792070147742499e-03f, + 1.206949056335355347e-03f, + 1.204891971037466616e-03f, + 1.201624580403049501e-03f, + 1.197151864807891562e-03f, + 1.191480012141583498e-03f, + 1.184616409886339811e-03f, + 1.176569635997314197e-03f, + 1.167349448595342331e-03f, + 1.156966774484061893e-03f, + 1.145433696504678973e-03f, + 1.132763439742820021e-03f, + 1.118970356602857433e-03f, + 1.104069910766385543e-03f, + 1.088078660052710107e-03f, + 1.071014238199964868e-03f, + 1.052895335586819490e-03f, + 1.033741678915853354e-03f, + 1.013574009880266035e-03f, + 9.924140628370767443e-04f, + 9.702845415105564161e-04f, + 9.472090947510056159e-04f, + 9.232122913743140771e-04f, + 8.983195941091211278e-04f, + 8.725573326793036348e-04f, + 8.459526760497619287e-04f, + 8.185336038648948062e-04f, + 7.903288771097757327e-04f, + 7.613680080244982808e-04f, + 7.316812293033188221e-04f, + 7.012994626104158578e-04f, + 6.702542864450650520e-04f, + 6.385779033898540073e-04f, + 6.063031067753177393e-04f, + 5.734632467957093789e-04f, + 5.400921961110872679e-04f, + 5.062243149706446149e-04f, + 4.718944158933642270e-04f, + 4.371377279425392405e-04f, + 4.019898606301749847e-04f, + 3.664867674887073131e-04f, + 3.306647093468514844e-04f, + 2.945602173475719322e-04f, + 2.582100557452125193e-04f, + 2.216511845199241977e-04f, + 1.849207218476427064e-04f, + 1.480559064630949787e-04f, + 1.110940599542368509e-04f, + 7.407254902655125068e-05f, + 3.702874777472067589e-05f, + 1.371254292486084993e-17f, + -3.697641838836769948e-05f, + -7.386333685080383616e-05f, + -1.106237275354719183e-04f, + -1.472207424002393370e-04f, + -1.836177501005376326e-04f, + -2.197783726069668013e-04f, + -2.556665215157765151e-04f, + -2.912464340157351313e-04f, + -3.264827084761888032e-04f, + -3.613403396206332991e-04f, + -3.957847532506383946e-04f, + -4.297818404862966193e-04f, + -4.632979914890506846e-04f, + -4.963001286333401738e-04f, + -5.287557390949833508e-04f, + -5.606329068237270391e-04f, + -5.919003438689767176e-04f, + -6.225274210275311962e-04f, + -6.524841977839308848e-04f, + -6.817414515139428016e-04f, + -7.102707059225399746e-04f, + -7.380442586892487162e-04f, + -7.650352082938549928e-04f, + -7.912174799963587243e-04f, + -8.165658509465838124e-04f, + -8.410559743992581695e-04f, + -8.646644030108421603e-04f, + -8.873686111969257854e-04f, + -9.091470165279773525e-04f, + -9.299790001438900484e-04f, + -9.498449261678874270e-04f, + -9.687261601014614341e-04f, + -9.866050861835819630e-04f, + -1.003465123697943424e-03f, + -1.019290742213164363e-03f, + -1.034067475742384131e-03f, + -1.047781935809330650e-03f, + -1.060421823409143580e-03f, + -1.071975939853697006e-03f, + -1.082434196491879799e-03f, + -1.091787623296736802e-03f, + -1.100028376312290647e-03f, + -1.107149743954318269e-03f, + -1.113146152160276754e-03f, + -1.118013168384754657e-03f, + -1.121747504438212967e-03f, + -1.124347018167691677e-03f, + -1.125810713979439898e-03f, + -1.126138742204658245e-03f, + -1.125332397310586279e-03f, + -1.123394114960401657e-03f, + -1.120327467926549893e-03f, + -1.116137160863255560e-03f, + -1.110829023945101137e-03f, + -1.104410005379749494e-03f, + -1.096888162803940974e-03f, + -1.088272653573009452e-03f, + -1.078573723955405161e-03f, + -1.067802697244547546e-03f, + -1.055971960801616169e-03f, + -1.043094952043956310e-03f, + -1.029186143394582309e-03f, + -1.014261026209532400e-03f, + -9.983360937008427163e-04f, + -9.814288228736027086e-04f, + -9.635576554969104172e-04f, + -9.447419781291415113e-04f, + -9.250021012192831361e-04f, + -9.043592373064512696e-04f, + -8.828354783409939847e-04f, + -8.604537721515002468e-04f, + -8.372378980823497055e-04f, + -8.132124418277322840e-04f, + -7.884027694888517653e-04f, + -7.628350008812852896e-04f, + -7.365359821204960078e-04f, + -7.095332575148247155e-04f, + -6.818550407942288718e-04f, + -6.535301857058335630e-04f, + -6.245881560060952261e-04f, + -5.950589948810114296e-04f, + -5.649732938262623386e-04f, + -5.343621610190059943e-04f, + -5.032571892141756960e-04f, + -4.716904231986256981e-04f, + -4.396943268360438742e-04f, + -4.073017497369382724e-04f, + -3.745458935874993508e-04f, + -3.414602781722681792e-04f, + -3.080787071247825435e-04f, + -2.744352334413967037e-04f, + -2.405641247936734649e-04f, + -2.064998286741144789e-04f, + -1.722769374108738480e-04f, + -1.379301530872341895e-04f, + -1.034942524008109811e-04f, + -6.900405149830530008e-05f, + -3.449437082158992495e-05f, + 0.000000000000000000e+00f, + 3.444433717537312282e-05f, + 6.880401766040344078e-05f, + 1.030445539143494854e-04f, + 1.371316284694892038e-04f, + 1.710311282792226217e-04f, + 2.047091788099896501e-04f, + 2.381321778435391604e-04f, + 2.712668289555900309e-04f, + 3.040801746373052975e-04f, + 3.365396290272290244e-04f, + 3.686130102209533182e-04f, + 4.002685721262641268e-04f, + 4.314750358328316138e-04f, + 4.622016204652085376e-04f, + 4.924180734885345943e-04f, + 5.220947004376862242e-04f, + 5.512023940402758712e-04f, + 5.797126627053133911e-04f, + 6.075976583493116747e-04f, + 6.348302035331886400e-04f, + 6.613838178833868642e-04f, + 6.872327437713459134e-04f, + 7.123519712269649109e-04f, + 7.367172620617903596e-04f, + 7.603051731785161974e-04f, + 7.830930790451201724e-04f, + 8.050591933112499331e-04f, + 8.261825895472138482e-04f, + 8.464432210854224304e-04f, + 8.658219399455064280e-04f, + 8.843005148257124162e-04f, + 9.018616481435636715e-04f, + 9.184889921098693746e-04f, + 9.341671638215605540e-04f, + 9.488817593593959444e-04f, + 9.626193668776509334e-04f, + 9.753675786743276274e-04f, + 9.871150022309649764e-04f, + 9.978512702125698873e-04f, + 1.007567049418917103e-03f, + 1.016254048679934505e-03f, + 1.023905025688631211e-03f, + 1.030513792766163958e-03f, + 1.036075221554958858e-03f, + 1.040585246636590612e-03f, + 1.044040868072351400e-03f, + 1.046440152865581131e-03f, + 1.047782235345830204e-03f, + 1.048067316476006608e-03f, + 1.047296662084868128e-03f, + 1.045472600028134798e-03f, + 1.042598516282698499e-03f, + 1.038678849979428548e-03f, + 1.033719087381135097e-03f, + 1.027725754813292765e-03f, + 1.020706410556256006e-03f, + 1.012669635708591783e-03f, + 1.003625024032280683e-03f, + 9.935831707915917296e-04f, + 9.825556605982765750e-04f, + 9.705550542768091827e-04f, + 9.575948747645024592e-04f, + 9.436895920619294822e-04f, + 9.288546072504160834e-04f, + 9.131062355939434513e-04f, + 8.964616887440624146e-04f, + 8.789390560668727381e-04f, + 8.605572851122642768e-04f, + 8.413361612465680012e-04f, + 8.212962864701133696e-04f, + 8.004590574423870028e-04f, + 7.788466427383010891e-04f, + 7.564819593593443900e-04f, + 7.333886485245473975e-04f, + 7.095910507669888961e-04f, + 6.851141803613563976e-04f, + 6.599836991102931479e-04f, + 6.342258895159663982e-04f, + 6.078676273653686388e-04f, + 5.809363537579391706e-04f, + 5.534600466042048465e-04f, + 5.254671916251264134e-04f, + 4.969867528824211626e-04f, + 4.680481428698100464e-04f, + 4.386811921962611408e-04f, + 4.089161188926386807e-04f, + 3.787834973728029320e-04f, + 3.483142270813974271e-04f, + 3.175395008601156806e-04f, + 2.864907730651890965e-04f, + 2.551997274681527816e-04f, + 2.236982449728073510e-04f, + 1.920183711814943037e-04f, + 1.601922838431261954e-04f, + 1.282522602162407851e-04f, + 9.623064438038904595e-05f, + 6.415981452841493812e-05f, + 3.207215027289962711e-05f, + 0.000000000000000000e+00f, + -3.202435169696419165e-05f, + -6.396871647107672993e-05f, + -9.580103453013783627e-05f, + -1.274894067670554485e-04f, + -1.590021266806003833e-04f, + -1.903077120544014096e-04f, + -2.213749363623242509e-04f, + -2.521728598694509757e-04f, + -2.826708603974881218e-04f, + -3.128386637238008165e-04f, + -3.426463735844534645e-04f, + -3.720645012513128301e-04f, + -4.010639946537739552e-04f, + -4.296162670168992745e-04f, + -4.576932249873889727e-04f, + -4.852672962200506594e-04f, + -5.123114563973639067e-04f, + -5.387992556561681809e-04f, + -5.647048443954880668e-04f, + -5.900029984401524482e-04f, + -6.146691435362195647e-04f, + -6.386793791542513593e-04f, + -6.620105015772862009e-04f, + -6.846400262516423845e-04f, + -7.065462093789202968e-04f, + -7.277080687284316705e-04f, + -7.481054036504530087e-04f, + -7.677188142710961042e-04f, + -7.865297198508461448e-04f, + -8.045203762893993540e-04f, + -8.216738927602709611e-04f, + -8.379742474599812278e-04f, + -8.534063024570928127e-04f, + -8.679558176273523317e-04f, + -8.816094636625075804e-04f, + -8.943548341408386320e-04f, + -9.061804566487988806e-04f, + -9.170758029437478922e-04f, + -9.270312981492120604e-04f, + -9.360383289747114437e-04f, + -9.440892509532578013e-04f, + -9.511773946908641834e-04f, + -9.572970711231403289e-04f, + -9.624435757751192066e-04f, + -9.666131920216366113e-04f, + -9.698031933463969285e-04f, + -9.720118445989208052e-04f, + -9.732384022497203710e-04f, + -9.734831136448424821e-04f, + -9.727472152621121065e-04f, + -9.710329299722829204e-04f, + -9.683434633094111085e-04f, + -9.646829987556522013e-04f, + -9.600566920467877531e-04f, + -9.544706645056394391e-04f, + -9.479319954115860043e-04f, + -9.404487134153821952e-04f, + -9.320297870093062660e-04f, + -9.226851140636999115e-04f, + -9.124255104419481694e-04f, + -9.012626977066420320e-04f, + -8.892092899308199835e-04f, + -8.762787796288336881e-04f, + -8.624855228225505183e-04f, + -8.478447232590492723e-04f, + -8.323724157971091513e-04f, + -8.160854489806475048e-04f, + -7.990014668176755822e-04f, + -7.811388897844821115e-04f, + -7.625168950755145496e-04f, + -7.431553961197853112e-04f, + -7.230750213856750215e-04f, + -7.022970924967909898e-04f, + -6.808436016816696431e-04f, + -6.587371885813887371e-04f, + -6.360011164391399848e-04f, + -6.126592476972289288e-04f, + -5.887360190265250072e-04f, + -5.642564158146420091e-04f, + -5.392459461393457349e-04f, + -5.137306142544784474e-04f, + -4.877368936155090711e-04f, + -4.612916994728182745e-04f, + -4.344223610612315406e-04f, + -4.071565934140700962e-04f, + -3.795224688310699706e-04f, + -3.515483880292340994e-04f, + -3.232630510065746267e-04f, + -2.946954276481456654e-04f, + -2.658747281046207941e-04f, + -2.368303729738942764e-04f, + -2.075919633156370829e-04f, + -1.781892505295539549e-04f, + -1.486521061281701210e-04f, + -1.190104914343625921e-04f, + -8.929442723454692366e-05f, + -5.953396341846094902e-05f, + -2.975914863569874771e-05f, + -1.469383061752921166e-17f, + 2.971352712842046073e-05f, + 5.935156925200977569e-05f, + 8.888438470625297655e-05f, + 1.182823834615285115e-04f, + 1.475161567260801273e-04f, + 1.765565063211114430e-04f, + 2.053744737984555227e-04f, + 2.339413692715925134e-04f, + 2.622287999318306112e-04f, + 2.902086982211098056e-04f, + 3.178533496333097114e-04f, + 3.451354201170366942e-04f, + 3.720279830524620595e-04f, + 3.985045457759202716e-04f, + 4.245390756258103919e-04f, + 4.501060254847104552e-04f, + 4.751803587924769172e-04f, + 4.997375740056823846e-04f, + 5.237537284800026236e-04f, + 5.472054617520811680e-04f, + 5.700700181981503386e-04f, + 5.923252690478518056e-04f, + 6.139497337318547063e-04f, + 6.349226005425641405e-04f, + 6.552237465884745531e-04f, + 6.748337570230266303e-04f, + 6.937339435292449487e-04f, + 7.119063620434466517e-04f, + 7.293338297005069531e-04f, + 7.459999409853247188e-04f, + 7.618890830752056463e-04f, + 7.769864503587980151e-04f, + 7.912780581184908910e-04f, + 8.047507553635035353e-04f, + 8.173922368022044829e-04f, + 8.291910539426864280e-04f, + 8.401366253119868770e-04f, + 8.502192457848813112e-04f, + 8.594300950141066115e-04f, + 8.677612449551008961e-04f, + 8.752056664789573028e-04f, + 8.817572350682475763e-04f, + 8.874107355915474612e-04f, + 8.921618661531745048e-04f, + 8.960072410156486164e-04f, + 8.989443925934634261e-04f, + 9.009717725175072972e-04f, + 9.020887517705425190e-04f, + 9.022956198950072941e-04f, + 9.015935832754222229e-04f, + 8.999847624985231375e-04f, + 8.974721887952514209e-04f, + 8.940597995695863213e-04f, + 8.897524330201562462e-04f, + 8.845558218614805405e-04f, + 8.784765861525543331e-04f, + 8.715222252413793759e-04f, + 8.637011088350353069e-04f, + 8.550224672055297846e-04f, + 8.454963805427627172e-04f, + 8.351337674665857812e-04f, + 8.239463727109863026e-04f, + 8.119467539939648334e-04f, + 7.991482680876762579e-04f, + 7.855650561042518912e-04f, + 7.712120280131833138e-04f, + 7.561048464071653402e-04f, + 7.402599095340949053e-04f, + 7.236943336132475825e-04f, + 7.064259344547092496e-04f, + 6.884732084018442772e-04f, + 6.698553126167958562e-04f, + 6.505920447301977031e-04f, + 6.307038218764186291e-04f, + 6.102116591367832835e-04f, + 5.891371474128742191e-04f, + 5.675024307539662440e-04f, + 5.453301831613886286e-04f, + 5.226435848948802945e-04f, + 4.994662983050689653e-04f, + 4.758224432173879066e-04f, + 4.517365718931811943e-04f, + 4.272336435935402852e-04f, + 4.023389987724907877e-04f, + 3.770783329259057943e-04f, + 3.514776701234272852e-04f, + 3.255633362501970246e-04f, + 2.993619319860350001e-04f, + 2.729003055499868075e-04f, + 2.462055252376792419e-04f, + 2.193048517797492180e-04f, + 1.922257105497324930e-04f, + 1.649956636492767566e-04f, + 1.376423818992599316e-04f, + 1.101936167654500256e-04f, + 8.267717224668583544e-05f, + 5.512087675440251894e-05f, + 2.755255501160192006e-05f, + 0.000000000000000000e+00f, + -2.750905501689023422e-05f, + -5.494696436636345655e-05f, + -8.228619770668268139e-05f, + -1.094993676073878112e-04f, + -1.365592569419782647e-04f, + -1.634388460653853027e-04f, + -1.901113397495802181e-04f, + -2.165501938502928923e-04f, + -2.427291416781312899e-04f, + -2.686222200484022333e-04f, + -2.942037949834695591e-04f, + -3.194485870425304262e-04f, + -3.443316962534629451e-04f, + -3.688286266226424733e-04f, + -3.929153101984506676e-04f, + -4.165681306646761548e-04f, + -4.397639464411628790e-04f, + -4.624801132689337598e-04f, + -4.846945062576402791e-04f, + -5.063855413743057745e-04f, + -5.275321963523644251e-04f, + -5.481140310006175909e-04f, + -5.681112068929672181e-04f, + -5.875045064196726674e-04f, + -6.062753511821435647e-04f, + -6.244058197136283239e-04f, + -6.418786645088341578e-04f, + -6.586773283467862658e-04f, + -6.747859598912580702e-04f, + -6.901894285541135439e-04f, + -7.048733386080151741e-04f, + -7.188240425351924510e-04f, + -7.320286536001779053e-04f, + -7.444750576348447895e-04f, + -7.561519240253451084e-04f, + -7.670487158910010940e-04f, + -7.771556994460668971e-04f, + -7.864639525364079805e-04f, + -7.949653723436894259e-04f, + -8.026526822505372595e-04f, + -8.095194378612496173e-04f, + -8.155600321732297967e-04f, + -8.207696998952141061e-04f, + -8.251445209094316778e-04f, + -8.286814228754654961e-04f, + -8.313781829745840735e-04f, + -8.332334287941438105e-04f, + -8.342466383525489566e-04f, + -8.344181392661235552e-04f, + -8.337491070600727781e-04f, + -8.322415626266423810e-04f, + -8.298983688343719274e-04f, + -8.267232262932451212e-04f, + -8.227206682813439833e-04f, + -8.178960548394521293e-04f, + -8.122555660409656268e-04f, + -8.058061944451279162e-04f, + -7.985557367425892995e-04f, + -7.905127846029615362e-04f, + -7.816867147349541335e-04f, + -7.720876781703026525e-04f, + -7.617265887835813565e-04f, + -7.506151110607858345e-04f, + -7.387656471301075898e-04f, + -7.261913230692261566e-04f, + -7.129059745042091046e-04f, + -6.989241315155087344e-04f, + -6.842610028674840552e-04f, + -6.689324595785751861e-04f, + -6.529550178495424672e-04f, + -6.363458213682250285e-04f, + -6.191226230095402778e-04f, + -6.013037659503773147e-04f, + -5.829081642191303019e-04f, + -5.639552827005720349e-04f, + -5.444651166170623056e-04f, + -5.244581705078699748e-04f, + -5.039554367282136470e-04f, + -4.829783734907900630e-04f, + -4.615488824727865158e-04f, + -4.396892860113637874e-04f, + -4.174223039115742672e-04f, + -3.947710298905243330e-04f, + -3.717589076824774933e-04f, + -3.484097068291740662e-04f, + -3.247474981805008798e-04f, + -3.007966291308984577e-04f, + -2.765816986165605708e-04f, + -2.521275318992345573e-04f, + -2.274591551626225019e-04f, + -2.026017699469456171e-04f, + -1.775807274479320418e-04f, + -1.524215027065971577e-04f, + -1.271496687156270196e-04f, + -1.017908704690000349e-04f, + -7.637079898086366356e-05f, + -5.091516530030798363e-05f, + -2.544967454785041741e-05f, + 0.000000000000000000e+00f, + 2.540824275175630965e-05f, + 5.074952154213560791e-05f, + 7.599841324713188062e-05f, + 1.011296292473662763e-04f, + 1.261180407145145923e-04f, + 1.509387036954135824e-04f, + 1.755668839686425260e-04f, + 1.999780816492812915e-04f, + 2.241480555170535154e-04f, + 2.480528470440098191e-04f, + 2.716688040976286797e-04f, + 2.949726042963528197e-04f, + 3.179412779943405166e-04f, + 3.405522308726428231e-04f, + 3.627832661150276234e-04f, + 3.846126061465318354e-04f, + 4.060189139133383055e-04f, + 4.269813136835948837e-04f, + 4.474794113487838955e-04f, + 4.674933142057642490e-04f, + 4.870036502007597822e-04f, + 5.059915866164069404e-04f, + 5.244388481841380598e-04f, + 5.423277346042669565e-04f, + 5.596411374573758216e-04f, + 5.763625564908231172e-04f, + 5.924761152646927393e-04f, + 6.079665761428002836e-04f, + 6.228193546145188893e-04f, + 6.370205329341033923e-04f, + 6.505568730647005556e-04f, + 6.634158289153857567e-04f, + 6.755855578598123036e-04f, + 6.870549315261518814e-04f, + 6.978135458484613016e-04f, + 7.078517303707442540e-04f, + 7.171605567954273622e-04f, + 7.257318467687813622e-04f, + 7.335581788968564615e-04f, + 7.406328949860011826e-04f, + 7.469501055028914937e-04f, + 7.525046942499604482e-04f, + 7.572923222527377452e-04f, + 7.613094308564032336e-04f, + 7.645532440298472834e-04f, + 7.670217698761347402e-04f, + 7.687138013491711264e-04f, + 7.696289161771383436e-04f, + 7.697674759941319994e-04f, + 7.691306246821071795e-04f, + 7.677202859261749368e-04f, + 7.655391599869575776e-04f, + 7.625907196945825228e-04f, + 7.588792056696464167e-04f, + 7.544096207772237267e-04f, + 7.491877238207874951e-04f, + 7.432200224837051672e-04f, + 7.365137655266115572e-04f, + 7.290769342498153649e-04f, + 7.209182332305319723e-04f, + 7.120470803455674876e-04f, + 7.024735960906073294e-04f, + 6.922085922080986782e-04f, + 6.812635596364262705e-04f, + 6.696506557935362697e-04f, + 6.573826912090139371e-04f, + 6.444731155192746008e-04f, + 6.309360028408991924e-04f, + 6.167860365379857716e-04f, + 6.020384934000156665e-04f, + 5.867092272469688922e-04f, + 5.708146519793728339e-04f, + 5.543717240911742901e-04f, + 5.373979246641968867e-04f, + 5.199112408629773122e-04f, + 5.019301469495465393e-04f, + 4.834735848383831772e-04f, + 4.645609442115968056e-04f, + 4.452120422152791297e-04f, + 4.254471027583006421e-04f, + 4.052867354349356968e-04f, + 3.847519140935204570e-04f, + 3.638639550730222647e-04f, + 3.426444951302156034e-04f, + 3.211154690804265380e-04f, + 2.992990871745817845e-04f, + 2.772178122359930490e-04f, + 2.548943365805551777e-04f, + 2.323515587436648325e-04f, + 2.096125600378590220e-04f, + 1.867005809653108641e-04f, + 1.636389975088607706e-04f, + 1.404512973260482907e-04f, + 1.171610558701005774e-04f, + 9.379191246244331451e-05f, + 7.036754634058427660e-05f, + 4.691165270578145734e-05f, + 2.344791879487271815e-05f, + 1.447139493247874122e-17f, + -2.340850393945113271e-05f, + -4.675407264888852574e-05f, + -7.001328871061514335e-05f, + -9.316286111268942802e-05f, + -1.161796485306134486e-04f, + -1.390406824191185795e-04f, + -1.617231898906969537e-04f, + -1.842046163583829115e-04f, + -2.064626479199869254e-04f, + -2.284752334619991466e-04f, + -2.502206064611250252e-04f, + -2.716773064617690556e-04f, + -2.928242002086798895e-04f, + -3.136405024138114671e-04f, + -3.341057961368736713e-04f, + -3.542000527599929792e-04f, + -3.739036515368039746e-04f, + -3.931973986967992316e-04f, + -4.120625460867281776e-04f, + -4.304808093307158469e-04f, + -4.484343854917819923e-04f, + -4.659059702174845512e-04f, + -4.828787743535818602e-04f, + -4.993365400096493739e-04f, + -5.152635560612082175e-04f, + -5.306446730741198057e-04f, + -5.454653176364612647e-04f, + -5.597115060851909612e-04f, + -5.733698576140564907e-04f, + -5.864276067510603525e-04f, + -5.988726151936528234e-04f, + -6.106933829909588687e-04f, + -6.218790590626611069e-04f, + -6.324194510452570833e-04f, + -6.423050344567614702e-04f, + -6.515269611716821042e-04f, + -6.600770671990646883e-04f, + -6.679478797567967160e-04f, + -6.751326236362062069e-04f, + -6.816252268518211213e-04f, + -6.874203255717539112e-04f, + -6.925132683248836490e-04f, + -6.969001194819386376e-04f, + -7.005776620080852567e-04f, + -7.035433994855702167e-04f, + -7.057955574054943209e-04f, + -7.073330837287954750e-04f, + -7.081556487170125340e-04f, + -7.082636440342657963e-04f, + -7.076581811226278617e-04f, + -7.063410888537339193e-04f, + -7.043149104602236445e-04f, + -7.015828997513892445e-04f, + -6.981490166179902005e-04f, + -6.940179218320851728e-04f, + -6.891949711482260339e-04f, + -6.836862087132502142e-04f, + -6.774983597924347884e-04f, + -6.706388228206039545e-04f, + -6.631156607872861451e-04f, + -6.549375919657807231e-04f, + -6.461139799966924375e-04f, + -6.366548233369270175e-04f, + -6.265707440859499865e-04f, + -6.158729762017194510e-04f, + -6.045733531191070480e-04f, + -5.926842947843961179e-04f, + -5.802187941200323941e-04f, + -5.671904029341022849e-04f, + -5.536132172898791236e-04f, + -5.395018623509823539e-04f, + -5.248714767185811651e-04f, + -5.097376962770673765e-04f, + -4.941166375654838707e-04f, + -4.780248806924582670e-04f, + -4.614794518122551344e-04f, + -4.444978051810356389e-04f, + -4.270978048115207926e-04f, + -4.092977057456325968e-04f, + -3.911161349647420196e-04f, + -3.725720719571632062e-04f, + -3.536848289632427730e-04f, + -3.344740309187047944e-04f, + -3.149595951167335258e-04f, + -2.951617106099559715e-04f, + -2.751008173737486736e-04f, + -2.547975852520000407e-04f, + -2.342728927071314657e-04f, + -2.135478053963316245e-04f, + -1.926435545956132946e-04f, + -1.715815154940239279e-04f, + -1.503831853799458774e-04f, + -1.290701617419976258e-04f, + -1.076641203064520068e-04f, + -8.618679303362720165e-05f, + -6.465994609572296963e-05f, + -4.310535785803166131e-05f, + -2.154479688593094298e-05f, + 0.000000000000000000e+00f, + 2.150734959899484319e-05f, + 4.295564411312584395e-05f, + 6.432337281627700971e-05f, + 8.558914358778801847e-05f, + 1.067317042889163222e-04f, + 1.277299639610350547e-04f, + 1.485630138241603702e-04f, + 1.692101480553038985e-04f, + 1.896508843258684759e-04f, + 2.098649840776009373e-04f, + 2.298324725174021228e-04f, + 2.495336583111203762e-04f, + 2.689491529567958729e-04f, + 2.880598898186698250e-04f, + 3.068471428031533201e-04f, + 3.252925446583616268e-04f, + 3.433781048797137779e-04f, + 3.610862272039176181e-04f, + 3.783997266745809350e-04f, + 3.953018462627122791e-04f, + 4.117762730263829513e-04f, + 4.278071537938969346e-04f, + 4.433791103553099983e-04f, + 4.584772541480976356e-04f, + 4.730872004228363326e-04f, + 4.871950818755382503e-04f, + 5.007875617336743747e-04f, + 5.138518462839280912e-04f, + 5.263756968296791783e-04f, + 5.383474410673522387e-04f, + 5.497559838709404180e-04f, + 5.605908174750933934e-04f, + 5.708420310473718206e-04f, + 5.805003196410431958e-04f, + 5.895569925205944436e-04f, + 5.980039808525682747e-04f, + 6.058338447549957298e-04f, + 6.130397796995799755e-04f, + 6.196156222612016684e-04f, + 6.255558552100400158e-04f, + 6.308556119424503159e-04f, + 6.355106802471486953e-04f, + 6.395175054041730848e-04f, + 6.428731926145374613e-04f, + 6.455755087594301040e-04f, + 6.476228834882815982e-04f, + 6.490144096357687228e-04f, + 6.497498429685649897e-04f, + 6.498296012632502226e-04f, + 6.492547627174425229e-04f, + 6.480270636970132886e-04f, + 6.461488958227519508e-04f, + 6.436233024006336820e-04f, + 6.404539742004272803e-04f, + 6.366452445880759490e-04f, + 6.322020840178591873e-04f, + 6.271300938911197539e-04f, + 6.214354997887679231e-04f, + 6.151251440855713855e-04f, + 6.082064779547860164e-04f, + 6.006875527722377360e-04f, + 5.925770109296073186e-04f, + 5.838840760673158665e-04f, + 5.746185427377923640e-04f, + 5.647907655106131422e-04f, + 5.544116475315949552e-04f, + 5.434926285482021132e-04f, + 5.320456724144572097e-04f, + 5.200832540887690824e-04f, + 5.076183461388823585e-04f, + 4.946644047682729551e-04f, + 4.812353553790131599e-04f, + 4.673455776866451889e-04f, + 4.530098904026903664e-04f, + 4.382435355011193574e-04f, + 4.230621620855109567e-04f, + 4.074818098737383954e-04f, + 3.915188923177147684e-04f, + 3.751901793757405701e-04f, + 3.585127799555410831e-04f, + 3.415041240464490179e-04f, + 3.241819445590930424e-04f, + 3.065642588915733278e-04f, + 2.886693502413833915e-04f, + 2.705157486821331970e-04f, + 2.521222120247453859e-04f, + 2.335077064829918579e-04f, + 2.146913871629504706e-04f, + 1.956925783966609658e-04f, + 1.765307539399361904e-04f, + 1.572255170548387095e-04f, + 1.377965804968402466e-04f, + 1.182637464271945108e-04f, + 9.864688627111849629e-05f, + 7.896592054191218808e-05f, + 5.924079865161975436e-05f, + 3.949147872881094546e-05f, + 1.973790746354780164e-05f, + 0.000000000000000000e+00f, + -1.970238010284559686e-05f, + -3.934944082275756825e-05f, + -5.892148151755434546e-05f, + -7.839891264075306743e-05f, + -9.776227530943462282e-05f, + -1.169922607052078226e-04f, + -1.360697292888009540e-04f, + -1.549757298090502554e-04f, + -1.736915180877542444e-04f, + -1.921985755616629511e-04f, + -2.104786275631484471e-04f, + -2.285136613218662050e-04f, + -2.462859436695555878e-04f, + -2.637780384304916933e-04f, + -2.809728234808804288e-04f, + -2.978535074603023448e-04f, + -3.144036461191332854e-04f, + -3.306071582858338361e-04f, + -3.464483414389500442e-04f, + -3.619118868686585066e-04f, + -3.769828944131547489e-04f, + -3.916468867560180043e-04f, + -4.058898232707585751e-04f, + -4.196981133992728607e-04f, + -4.330586295517413042e-04f, + -4.459587195157615211e-04f, + -4.583862183627433859e-04f, + -4.703294598410216135e-04f, + -4.817772872445234334e-04f, + -4.927190637473565383e-04f, + -5.031446821946852560e-04f, + -5.130445743409007284e-04f, + -5.224097195269496782e-04f, + -5.312316527889542495e-04f, + -5.395024723908887479e-04f, + -5.472148467749195742e-04f, + -5.543620209233284749e-04f, + -5.609378221266176105e-04f, + -5.669366651531786106e-04f, + -5.723535568162687118e-04f, + -5.771840999348496837e-04f, + -5.814244966853034362e-04f, + -5.850715513418501545e-04f, + -5.881226724039281687e-04f, + -5.905758741095224786e-04f, + -5.924297773340420807e-04f, + -5.936836098749646720e-04f, + -5.943372061230182968e-04f, + -5.943910061214307226e-04f, + -5.938460540152537288e-04f, + -5.927039958934639209e-04f, + -5.909670770271131714e-04f, + -5.886381385074528462e-04f, + -5.857206132884568801e-04f, + -5.822185216389217429e-04f, + -5.781364660097343096e-04f, + -5.734796253225910197e-04f, + -5.682537486870293739e-04f, + -5.624651485531170217e-04f, + -5.561206933077393524e-04f, + -5.492277993230843978e-04f, + -5.417944224662266713e-04f, + -5.338290490794490428e-04f, + -5.253406864414295312e-04f, + -5.163388527197619636e-04f, + -5.068335664260176796e-04f, + -4.968353353848055896e-04f, + -4.863551452290165310e-04f, + -4.754044474335747460e-04f, + -4.639951469007321709e-04f, + -4.521395891103186892e-04f, + -4.398505468486206245e-04f, + -4.271412065301010948e-04f, + -4.140251541266666644e-04f, + -4.005163607192301599e-04f, + -3.866291676868795061e-04f, + -3.723782715496072680e-04f, + -3.577787084799967311e-04f, + -3.428458385006848889e-04f, + -3.275953293837695238e-04f, + -3.120431402691025606e-04f, + -2.962055050186841124e-04f, + -2.800989153242122590e-04f, + -2.637401035854408898e-04f, + -2.471460255771968360e-04f, + -2.303338429226980228e-04f, + -2.133209053914711568e-04f, + -1.961247330399053007e-04f, + -1.787629982130247515e-04f, + -1.612535074256399813e-04f, + -1.436141831415453836e-04f, + -1.258630454695097874e-04f, + -1.080181937944321024e-04f, + -9.009778836248835666e-05f, + -7.212003183910606612e-05f, + -5.410315085817400264e-05f, + -3.606537758129155149e-05f, + -1.802493128582126862e-05f, + -1.334841303324302416e-17f, + 1.799127779618168215e-05f, + 3.593083138609340919e-05f, + 5.380067592915723640e-05f, + 7.158293045321104055e-05f, + 8.925983570849392351e-05f, + 1.068137718653035880e-04f, + 1.242272760380188604e-04f, + 1.414830596179534239e-04f, + 1.585640253977377951e-04f, + 1.754532844705931341e-04f, + 1.921341728876877549e-04f, + 2.085902680570638303e-04f, + 2.248054048683053446e-04f, + 2.407636915270301768e-04f, + 2.564495250836037240e-04f, + 2.718476066412367303e-04f, + 2.869429562284523142e-04f, + 3.017209273216939929e-04f, + 3.161672210038205064e-04f, + 3.302678997451251666e-04f, + 3.440094007935225488e-04f, + 3.573785491609914131e-04f, + 3.703625701941320385e-04f, + 3.829491017167877117e-04f, + 3.951262057331397641e-04f, + 4.068823796806154101e-04f, + 4.182065672215850910e-04f, + 4.290881685642916978e-04f, + 4.395170503031860959e-04f, + 4.494835547696116843e-04f, + 4.589785088844519070e-04f, + 4.679932325046681232e-04f, + 4.765195462561217800e-04f, + 4.845497788459313506e-04f, + 4.920767738478327470e-04f, + 4.990938959546221661e-04f, + 5.055950366925160639e-04f, + 5.115746195925331957e-04f, + 5.170276048147706216e-04f, + 5.219494932218531839e-04f, + 5.263363298985630810e-04f, + 5.301847071150910407e-04f, + 5.334917667319233727e-04f, + 5.362552020450717756e-04f, + 5.384732590707796192e-04f, + 5.401447372694501321e-04f, + 5.412689897091851800e-04f, + 5.418459226697609071e-04f, + 5.418759946885404492e-04f, + 5.413602150503207117e-04f, + 5.403001417237128035e-04f, + 5.386978787471504403e-04f, + 5.365560730682539118e-04f, + 5.338779108407521986e-04f, + 5.306671131837313420e-04f, + 5.269279314085348852e-04f, + 5.226651417191434303e-04f, + 5.178840393923420668e-04f, + 5.125904324446496933e-04f, + 5.067906347932736285e-04f, + 5.004914589190106924e-04f, + 4.937002080395005770e-04f, + 4.864246678015905052e-04f, + 4.786730975021753222e-04f, + 4.704542208472601629e-04f, + 4.617772162595178012e-04f, + 4.526517067449197353e-04f, + 4.430877493295452938e-04f, + 4.330958240781504313e-04f, + 4.226868227062654973e-04f, + 4.118720367981569454e-04f, + 4.006631456434114435e-04f, + 3.890722037049972786e-04f, + 3.771116277322665187e-04f, + 3.647941835326885492e-04f, + 3.521329724160614195e-04f, + 3.391414173259668587e-04f, + 3.258332486726308631e-04f, + 3.122224898823369732e-04f, + 2.983234426785867904e-04f, + 2.841506721102148633e-04f, + 2.697189913421606591e-04f, + 2.550434462248571854e-04f, + 2.401392996580377489e-04f, + 2.250220157652570890e-04f, + 2.097072438956290921e-04f, + 1.942108024690222747e-04f, + 1.785486626815674697e-04f, + 1.627369320880489372e-04f, + 1.467918380782401184e-04f, + 1.307297112638300613e-04f, + 1.145669687930290083e-04f, + 9.832009760999397456e-05f, + 8.200563767584910741e-05f, + 6.564016516846416676e-05f, + 4.924027567815219766e-05f, + 3.282256741602081771e-05f, + 1.640362445206236378e-05f, + 0.000000000000000000e+00f, + -1.637180023455527615e-05f, + -3.269533462575305538e-05f, + -4.895424210242561722e-05f, + -6.513225850968472699e-05f, + -8.121323284108457146e-05f, + -9.718114332507469882e-05f, + -1.130201133496294995e-04f, + -1.287144272095247152e-04f, + -1.442485456605490041e-04f, + -1.596071212651732553e-04f, + -1.747750135148174182e-04f, + -1.897373037137282015e-04f, + -2.044793096097578128e-04f, + -2.189865997580020041e-04f, + -2.332450076030689249e-04f, + -2.472406452664517324e-04f, + -2.609599170254186065e-04f, + -2.743895324706472098e-04f, + -2.875165193297870496e-04f, + -3.003282359445427004e-04f, + -3.128123833895385809e-04f, + -3.249570172213065876e-04f, + -3.367505588461240803e-04f, + -3.481818064961628547e-04f, + -3.592399458034899098e-04f, + -3.699145599619731075e-04f, + -3.801956394677196631e-04f, + -3.900735914289291096e-04f, + -3.995392484366653077e-04f, + -4.085838769884034077e-04f, + -4.171991854566158182e-04f, + -4.253773315953880327e-04f, + -4.331109295782838197e-04f, + -4.403930565612024142e-04f, + -4.472172587646578920e-04f, + -4.535775570701503011e-04f, + -4.594684521259947778e-04f, + -4.648849289583206301e-04f, + -4.698224610836477188e-04f, + -4.742770141197898636e-04f, + -4.782450488924013302e-04f, + -4.817235240350806647e-04f, + -4.847098980813407910e-04f, + -4.872021310473242527e-04f, + -4.891986855046963432e-04f, + -4.906985271436078684e-04f, + -4.917011248261453924e-04f, + -4.922064501312485964e-04f, + -4.922149763925275263e-04f, + -4.917276772309548717e-04f, + -4.907460245849183233e-04f, + -4.892719862405896280e-04f, + -4.873080228661261920e-04f, + -4.848570845536456569e-04f, + -4.819226068734645927e-04f, + -4.785085064455284654e-04f, + -4.746191760334893435e-04f, + -4.702594791673116756e-04f, + -4.654347443007680212e-04f, + -4.601507585106936983e-04f, + -4.544137607452196142e-04f, + -4.482304346287416166e-04f, + -4.416079008317367900e-04f, + -4.345537090140839465e-04f, + -4.270758293507777911e-04f, + -4.191826436494728442e-04f, + -4.108829360697150140e-04f, + -4.021858834539161960e-04f, + -3.931010452806725248e-04f, + -3.836383532514024155e-04f, + -3.738081005214428367e-04f, + -3.636209305872444616e-04f, + -3.530878258416693307e-04f, + -3.422200958094793414e-04f, + -3.310293650756770912e-04f, + -3.195275609193634256e-04f, + -3.077269006664550737e-04f, + -2.956398787743567697e-04f, + -2.832792536622980853e-04f, + -2.706580343011211979e-04f, + -2.577894665766888188e-04f, + -2.446870194409517208e-04f, + -2.313643708652139079e-04f, + -2.178353936102799936e-04f, + -2.041141408280510209e-04f, + -1.902148315096290467e-04f, + -1.761518357948250199e-04f, + -1.619396601583952301e-04f, + -1.475929324880076194e-04f, + -1.331263870693465308e-04f, + -1.185548494938537772e-04f, + -1.038932215042936427e-04f, + -8.915646579370446799e-05f, + -7.435959077332714683e-05f, + -5.951763532474445284e-05f, + -4.464565355180115499e-05f, + -2.975869954784884257e-05f, + -1.487181219344128483e-05f, + 0.000000000000000000e+00f, + 1.484177398541613872e-05f, + 2.963860719904158576e-05f, + 4.437567248797690006e-05f, + 5.903823293163951847e-05f, + 7.361165654203178363e-05f, + 8.808143082849284827e-05f, + 1.024331772123446792e-04f, + 1.166526652770380289e-04f, + 1.307258268399512900e-04f, + 1.446387698318426075e-04f, + 1.583777919701953075e-04f, + 1.719293942132778794e-04f, + 1.852802939815504897e-04f, + 1.984174381336592573e-04f, + 2.113280156841942253e-04f, + 2.239994702510968052e-04f, + 2.364195122205586396e-04f, + 2.485761306175752138e-04f, + 2.604576046709465229e-04f, + 2.720525150615433867e-04f, + 2.833497548429932469e-04f, + 2.943385400246083098e-04f, + 3.050084198064263339e-04f, + 3.153492864566233744e-04f, + 3.253513848222112969e-04f, + 3.350053214640939868e-04f, + 3.443020734077864120e-04f, + 3.532329965021145852e-04f, + 3.617898333778522433e-04f, + 3.699647209993159932e-04f, + 3.777501978020017677e-04f, + 3.851392104098344126e-04f, + 3.921251199262121398e-04f, + 3.987017077932429100e-04f, + 4.048631812141973915e-04f, + 4.106041781344828734e-04f, + 4.159197717771173663e-04f, + 4.208054747289555891e-04f, + 4.252572425744124453e-04f, + 4.292714770740190195e-04f, + 4.328450288854669421e-04f, + 4.359751998253025848e-04f, + 4.386597446699808871e-04f, + 4.408968724953503567e-04f, + 4.426852475541531284e-04f, + 4.440239896916363025e-04f, + 4.449126742997511793e-04f, + 4.453513318109698395e-04f, + 4.453404467331309718e-04f, + 4.448809562272690614e-04f, + 4.439742482307769997e-04f, + 4.426221591287388775e-04f, + 4.408269709767168466e-04f, + 4.385914082787080990e-04f, + 4.359186343244749818e-04f, + 4.328122470908071003e-04f, + 4.292762747118040057e-04f, + 4.253151705236267433e-04f, + 4.209338076896006566e-04f, + 4.161374734119831350e-04f, + 4.109318627370653408e-04f, + 4.053230719607911351e-04f, + 3.993175916422970020e-04f, + 3.929222992332770761e-04f, + 3.861444513314888326e-04f, + 3.789916755669021876e-04f, + 3.714719621295073122e-04f, + 3.635936549481525153e-04f, + 3.553654425299459119e-04f, + 3.467963484702393361e-04f, + 3.378957216435445662e-04f, + 3.286732260858342197e-04f, + 3.191388305792130522e-04f, + 3.093027979500185209e-04f, + 2.991756740919330917e-04f, + 2.887682767254974537e-04f, + 2.780916839063471402e-04f, + 2.671572222938670333e-04f, + 2.559764551930417240e-04f, + 2.445611703817801011e-04f, + 2.329233677365916448e-04f, + 2.210752466696249048e-04f, + 2.090291933900031019e-04f, + 1.967977680028590282e-04f, + 1.843936914593410459e-04f, + 1.718298323712722203e-04f, + 1.591191937038941441e-04f, + 1.462748993604876967e-04f, + 1.333101806727993762e-04f, + 1.202383628109180238e-04f, + 1.070728511266315022e-04f, + 9.382711744432409014e-05f, + 8.051468631319089826e-05f, + 6.714912123485984206e-05f, + 5.374401088052293570e-05f, + 4.031295531131948081e-05f, + 2.686955221609669864e-05f, + 1.342738318029786585e-05f, + 0.000000000000000000e+00f, + -1.339908894537428966e-05f, + -2.675643224788563980e-05f, + -4.005864893978847017e-05f, + -5.329244186287420863e-05f, + -6.644461092502548262e-05f, + -7.950206623069222111e-05f, + -9.245184107248077213e-05f, + -1.052811047708897691e-04f, + -1.179771753494133872e-04f, + -1.305275320327536741e-04f, + -1.429198275556728382e-04f, + -1.551419002705676728e-04f, + -1.671817860417565296e-04f, + -1.790277299150954120e-04f, + -1.906681975514930251e-04f, + -2.020918864131418622e-04f, + -2.132877366918702598e-04f, + -2.242449419689906455e-04f, + -2.349529595963345725e-04f, + -2.454015207887385404e-04f, + -2.555806404182784557e-04f, + -2.654806265008874768e-04f, + -2.750920893665808145e-04f, + -2.844059505045345624e-04f, + -2.934134510748270851e-04f, + -3.021061600789069551e-04f, + -3.104759821811575835e-04f, + -3.185151651745712952e-04f, + -3.262163070835866359e-04f, + -3.335723628976332462e-04f, + -3.405766509294967594e-04f, + -3.472228587927296962e-04f, + -3.535050489929618660e-04f, + -3.594176641281607277e-04f, + -3.649555316935231171e-04f, + -3.701138684869255359e-04f, + -3.748882846112615666e-04f, + -3.792747870705806133e-04f, + -3.832697829571900684e-04f, + -3.868700822273337075e-04f, + -3.900729000635904330e-04f, + -3.928758588224299966e-04f, + -3.952769895658223660e-04f, + -3.972747331762911953e-04f, + -3.988679410551167681e-04f, + -4.000558754039121919e-04f, + -4.008382090901287695e-04f, + -4.012150250975650445e-04f, + -4.011868155632819922e-04f, + -4.007544804028019764e-04f, + -3.999193255258539845e-04f, + -3.986830606453539640e-04f, + -3.970477966826979296e-04f, + -3.950160427728647184e-04f, + -3.925907028732052292e-04f, + -3.897750719802241096e-04f, + -3.865728319589897214e-04f, + -3.829880469902513843e-04f, + -3.790251586406653394e-04f, + -3.746889805619719256e-04f, + -3.699846928252342087e-04f, + -3.649178358966703251e-04f, + -3.594943042620016315e-04f, + -3.537203397064425225e-04f, + -3.476025242579046902e-04f, + -3.411477728013451389e-04f, + -3.343633253723441497e-04f, + -3.272567391384403391e-04f, + -3.198358800770878963e-04f, + -3.121089143591786099e-04f, + -3.040842994476012479e-04f, + -2.957707749203746634e-04f, + -2.871773530283563362e-04f, + -2.783133089975229658e-04f, + -2.691881710862687534e-04f, + -2.598117104082893068e-04f, + -2.501939305319653465e-04f, + -2.403450568670490101e-04f, + -2.302755258500093155e-04f, + -2.199959739394581452e-04f, + -2.095172264330585757e-04f, + -1.988502861177488868e-04f, + -1.880063217650495839e-04f, + -1.769966564835590396e-04f, + -1.658327559405899988e-04f, + -1.545262164652106557e-04f, + -1.430887530451063164e-04f, + -1.315321872294559114e-04f, + -1.198684349503653277e-04f, + -1.081094942754574683e-04f, + -9.626743310399233169e-05f, + -8.435437681917366869e-05f, + -7.238249590935302358e-05f, + -6.036399357051934749e-05f, + -4.831109330284252872e-05f, + -3.623602651371357099e-05f, + -2.415102013999141309e-05f, + -1.206828430174254195e-05f, + 0.000000000000000000e+00f, + 1.204169312897504154e-05f, + 2.404470899092571738e-05f, + 3.599702712991723069e-05f, + 4.788670473170228393e-05f, + 5.970188852229866780e-05f, + 7.143082654988841410e-05f, + 8.306187983826528306e-05f, + 9.458353390051201588e-05f, + 1.059844101013897441e-04f, + 1.172532768573817302e-04f, + 1.283790606632529297e-04f, + 1.393508569345262404e-04f, + 1.501579406552106444e-04f, + 1.607897768203369465e-04f, + 1.712360306633601821e-04f, + 1.814865776584426626e-04f, + 1.915315132879176962e-04f, + 2.013611625657108102e-04f, + 2.109660893075433882e-04f, + 2.203371051389893943e-04f, + 2.294652782330296192e-04f, + 2.383419417686963803e-04f, + 2.469587021029656941e-04f, + 2.553074466481195588e-04f, + 2.633803514474035304e-04f, + 2.711698884419244454e-04f, + 2.786688324219942182e-04f, + 2.858702676567446673e-04f, + 2.927675941959327296e-04f, + 2.993545338382966954e-04f, + 3.056251357610912951e-04f, + 3.115737818059637109e-04f, + 3.171951914164931581e-04f, + 3.224844262232151398e-04f, + 3.274368942722000880e-04f, + 3.320483538937818360e-04f, + 3.363149172082760107e-04f, + 3.402330532659012994e-04f, + 3.437995908186134266e-04f, + 3.470117207218301322e-04f, + 3.498669979643943373e-04f, + 3.523633433256204432e-04f, + 3.544990446585373207e-04f, + 3.562727577988377661e-04f, + 3.576835070995022250e-04f, + 3.587306855913434921e-04f, + 3.594140547701693143e-04f, + 3.597337440115922912e-04f, + 3.596902496149280318e-04f, + 3.592844334779736470e-04f, + 3.585175214048202355e-04f, + 3.573911010492562368e-04f, + 3.559071194966300722e-04f, + 3.540678804874658795e-04f, + 3.518760412864115083e-04f, + 3.493346092005057690e-04f, + 3.464469377510762094e-04f, + 3.432167225039049318e-04f, + 3.396479965626749342e-04f, + 3.357451257309863640e-04f, + 3.315128033486363182e-04f, + 3.269560448080700604e-04f, + 3.220801817572939820e-04f, + 3.168908559958683816e-04f, + 3.113940130707873932e-04f, + 3.055958955794286277e-04f, + 2.995030361870785703e-04f, + 2.931222503666503615e-04f, + 2.864606288686135879e-04f, + 2.795255299294358681e-04f, + 2.723245712269062205e-04f, + 2.648656215911465348e-04f, + 2.571567924801972712e-04f, + 2.492064292294373924e-04f, + 2.410231020841035532e-04f, + 2.326155970245017573e-04f, + 2.239929063938051238e-04f, + 2.151642193382072939e-04f, + 2.061389120696203742e-04f, + 1.969265379611917521e-04f, + 1.875368174860041030e-04f, + 1.779796280096115294e-04f, + 1.682649934469443648e-04f, + 1.584030737944329339e-04f, + 1.484041545483235042e-04f, + 1.382786360200012393e-04f, + 1.280370225594695995e-04f, + 1.176899116981768777e-04f, + 1.072479832222307631e-04f, + 9.672198818729011848e-05f, + 8.612273788649634355e-05f, + 7.546109278254378857e-05f, + 6.474795141533576512e-05f, + 5.399423929640585659e-05f, + 4.321089780154245503e-05f, + 3.240887307268698056e-05f, + 2.159910494042194029e-05f, + 1.079251587830625557e-05f, + 0.000000000000000000e+00f, + -1.076758788963704548e-05f, + -2.149944317856241301e-05f, + -3.218482225573323713e-05f, + -4.281305323283309065e-05f, + -5.337354656864646082e-05f, + -6.385580558576757243e-05f, + -7.424943686907754835e-05f, + -8.454416053583386234e-05f, + -9.472982036711456591e-05f, + -1.047963937908457071e-04f, + -1.147340017065515562e-04f, + -1.245329181421548671e-04f, + -1.341835797335974307e-04f, + -1.436765950179864047e-04f, + -1.530027535312186607e-04f, + -1.621530347014577759e-04f, + -1.711186165298485740e-04f, + -1.798908840500873269e-04f, + -1.884614375589472831e-04f, + -1.968221006098050266e-04f, + -2.049649277617257863e-04f, + -2.128822120766777921e-04f, + -2.205664923580282378e-04f, + -2.280105601234851175e-04f, + -2.352074663059836263e-04f, + -2.421505276765508960e-04f, + -2.488333329829885750e-04f, + -2.552497487991398626e-04f, + -2.613939250791943547e-04f, + -2.672603004122885910e-04f, + -2.728436069726557201e-04f, + -2.781388751610882780e-04f, + -2.831414379336380212e-04f, + -2.878469348139965243e-04f, + -2.922513155861687336e-04f, + -2.963508436644055012e-04f, + -3.001420991378207152e-04f, + -3.036219814873026852e-04f, + -3.067877119727112443e-04f, + -3.096368356887807777e-04f, + -3.121672232883608046e-04f, + -3.143770723720249469e-04f, + -3.162649085434524054e-04f, + -3.178295861302663341e-04f, + -3.190702885703869526e-04f, + -3.199865284642772981e-04f, + -3.205781472938346467e-04f, + -3.208453148089736979e-04f, + -3.207885280832979214e-04f, + -3.204086102406083158e-04f, + -3.197067088542942777e-04f, + -3.186842940220061915e-04f, + -3.173431561183079385e-04f, + -3.156854032283730655e-04f, + -3.137134582660339763e-04f, + -3.114300557798812749e-04f, + -3.088382384513568856e-04f, + -3.059413532891418143e-04f, + -3.027430475243637962e-04f, + -2.992472642115744834e-04f, + -2.954582375405406932e-04f, + -2.913804878643640249e-04f, + -2.870188164496020400e-04f, + -2.823782999543770502e-04f, + -2.774642846407175700e-04f, + -2.722823803275761204e-04f, + -2.668384540913915862e-04f, + -2.611386237210131574e-04f, + -2.551892509343225957e-04f, + -2.489969343639438274e-04f, + -2.425685023197270455e-04f, + -2.359110053357878537e-04f, + -2.290317085103517163e-04f, + -2.219380836464229334e-04f, + -2.146378012019111564e-04f, + -2.071387220576676933e-04f, + -1.994488891124380440e-04f, + -1.915765187133722193e-04f, + -1.835299919314087671e-04f, + -1.753178456905652674e-04f, + -1.669487637607092330e-04f, + -1.584315676229787050e-04f, + -1.497752072176369788e-04f, + -1.409887515839194623e-04f, + -1.320813794016571026e-04f, + -1.230623694444957564e-04f, + -1.139410909545171644e-04f, + -1.047269939484425535e-04f, + -9.542959946509581922e-05f, + -8.605848976438549571e-05f, + -7.662329848777562182e-05f, + -6.713370079033298594e-05f, + -5.759940345433426073e-05f, + -4.803013499474702882e-05f, + -3.843563576630159076e-05f, + -2.882564808243503731e-05f, + -1.920990635599448016e-05f, + -9.598127271662273025e-06f, + 0.000000000000000000e+00f, + 9.574823537103811872e-06f, + 1.911673833977519833e-05f, + 2.861619593263633836e-05f, + 3.806371388693437398e-05f, + 4.744988525275912425e-05f, + 5.676538789203427777e-05f, + 6.600099370314859348e-05f, + 7.514757772787978142e-05f, + 8.419612713200058348e-05f, + 9.313775005050625494e-05f, + 1.019636842889295287e-04f, + 1.106653058722401322e-04f, + 1.192341374330203445e-04f, + 1.276618564308877656e-04f, + 1.359403031950059157e-04f, + 1.440614887822626452e-04f, + 1.520176026433699178e-04f, + 1.598010200896498841e-04f, + 1.674043095534119953e-04f, + 1.748202396351221399e-04f, + 1.820417859305353066e-04f, + 1.890621376316773902e-04f, + 1.958747038953250451e-04f, + 2.024731199731614757e-04f, + 2.088512530979652713e-04f, + 2.150032081205004760e-04f, + 2.209233328918379412e-04f, + 2.266062233865404583e-04f, + 2.320467285618302712e-04f, + 2.372399549487279324e-04f, + 2.421812709709947786e-04f, + 2.468663109882154221e-04f, + 2.512909790595921756e-04f, + 2.554514524253027516e-04f, + 2.593441847026279235e-04f, + 2.629659087941870811e-04f, + 2.663136395061924231e-04f, + 2.693846758746589278e-04f, + 2.721766031979693879e-04f, + 2.746872947744395253e-04f, + 2.769149133438811154e-04f, + 2.788579122323372257e-04f, + 2.805150361996677278e-04f, + 2.818853219897804355e-04f, + 2.829680985836939208e-04f, + 2.837629871559238016e-04f, + 2.842699007349416287e-04f, + 2.844890435688079782e-04f, + 2.844209101973068656e-04f, + 2.840662842322885578e-04f, + 2.834262368481505552e-04f, + 2.825021249847073845e-04f, + 2.812955892649861810e-04f, + 2.798085516307519159e-04f, + 2.780432126988811935e-04f, + 2.760020488419260187e-04f, + 2.736878089965273718e-04f, + 2.711035112035945611e-04f, + 2.682524388844043702e-04f, + 2.651381368570786159e-04f, + 2.617644070980710701e-04f, + 2.581353042536924927e-04f, + 2.542551309067299522e-04f, + 2.501284326036580432e-04f, + 2.457599926480392495e-04f, + 2.411548266659954384e-04f, + 2.363181769497842621e-04f, + 2.312555065858830860e-04f, + 2.259724933739240289e-04f, + 2.204750235432793924e-04f, + 2.147691852741365984e-04f, + 2.088612620301268357e-04f, + 2.027577257097531386e-04f, + 1.964652296239523634e-04f, + 1.899906013075300696e-04f, + 1.833408351718813763e-04f, + 1.765230850071902420e-04f, + 1.695446563417966825e-04f, + 1.624129986670188350e-04f, + 1.551356975356094168e-04f, + 1.477204665421056229e-04f, + 1.401751391936988090e-04f, + 1.325076606798998916e-04f, + 1.247260795497873826e-04f, + 1.168385393054425164e-04f, + 1.088532699203247078e-04f, + 1.007785792914005370e-04f, + 9.262284463377021455e-05f, + 8.439450382689701034e-05f, + 7.610204672104689636e-05f, + 6.775400641307872908e-05f, + 5.935895050042970316e-05f, + 5.092547232225660091e-05f, + 4.246218219656006581e-05f, + 3.397769866242637815e-05f, + 2.548063973595517562e-05f, + 1.697961418894217532e-05f, + 8.483212859017624744e-06f, + 0.000000000000000000e+00f, + -8.461495318869855788e-06f, + -1.689278775621859074e-05f, + -2.528544417573815790e-05f, + -3.363109204902172219e-05f, + -4.192142777555209638e-05f, + -5.014822491167240422e-05f, + -5.830334230039153014e-05f, + -6.637873209411312210e-05f, + -7.436644766219583183e-05f, + -8.225865137590645756e-05f, + -9.004762226295531552e-05f, + -9.772576352426085543e-05f, + -1.052856099056577086e-04f, + -1.127198349174101543e-04f, + -1.200212578946849995e-04f, + -1.271828508920051467e-04f, + -1.341977454053923206e-04f, + -1.410592389156038187e-04f, + -1.477608012463634826e-04f, + -1.542960807315748824e-04f, + -1.606589101858277410e-04f, + -1.668433126724388452e-04f, + -1.728435070639570102e-04f, + -1.786539133898150888e-04f, + -1.842691579663201804e-04f, + -1.896840783043778154e-04f, + -1.948937277903842115e-04f, + -1.998933801363103201e-04f, + -2.046785335949608540e-04f, + -2.092449149366440572e-04f, + -2.135884831840112908e-04f, + -2.177054331017576675e-04f, + -2.215921984383175921e-04f, + -2.252454549169022465e-04f, + -2.286621229734833933e-04f, + -2.318393702396226929e-04f, + -2.347746137681952429e-04f, + -2.374655220005397348e-04f, + -2.399100164736049493e-04f, + -2.421062732660711372e-04f, + -2.440527241826416158e-04f, + -2.457480576760017301e-04f, + -2.471912195061305153e-04f, + -2.483814131370483272e-04f, + -2.493180998712305895e-04f, + -2.500009987222372404e-04f, + -2.504300860263741746e-04f, + -2.506055947944560284e-04f, + -2.505280138049976969e-04f, + -2.501980864404289577e-04f, + -2.496168092681825537e-04f, + -2.487854303687649961e-04f, + -2.477054474131509354e-04f, + -2.463786054921205315e-04f, + -2.448068947003734946e-04f, + -2.429925474785403472e-04f, + -2.409380357163841445e-04f, + -2.386460676207832049e-04f, + -2.361195843522810752e-04f, + -2.333617564342224063e-04f, + -2.303759799387175490e-04f, + -2.271658724538751066e-04f, + -2.237352688370258271e-04f, + -2.200882167587254817e-04f, + -2.162289720426820811e-04f, + -2.121619938068343967e-04f, + -2.078919394110624542e-04f, + -2.034236592171233195e-04f, + -1.987621911667231361e-04f, + -1.939127551835801355e-04f, + -1.888807474057235954e-04f, + -1.836717342542969276e-04f, + -1.782914463453192841e-04f, + -1.727457722510192901e-04f, + -1.670407521174195056e-04f, + -1.611825711451174772e-04f, + -1.551775529402107034e-04f, + -1.490321527423956686e-04f, + -1.427529505375406372e-04f, + -1.363466440619829170e-04f, + -1.298200417059508136e-04f, + -1.231800553235984548e-04f, + -1.164336929571301011e-04f, + -1.095880514828144936e-04f, + -1.026503091863229081e-04f, + -9.562771827530503561e-05f, + -8.852759733689483329e-05f, + -8.135732374798783709e-05f, + -7.412432604604385269e-05f, + -6.683607626845965535e-05f, + -5.950008226812831386e-05f, + -5.212388001323979862e-05f, + -4.471502587911416735e-05f, + -3.728108893993130443e-05f, + -2.982964326820167396e-05f, + -2.236826024970074687e-05f, + -1.490450092183243395e-05f, + -7.445908342878064974e-06f, + 0.000000000000000000e+00f, + 7.425739736475704763e-06f, + 1.482386710490919136e-05f, + 2.218698638297385948e-05f, + 2.950775724944274754e-05f, + 3.677890207012403487e-05f, + 4.399321310054077095e-05f, + 5.114355959833892794e-05f, + 5.822289483842819512e-05f, + 6.522426302397340788e-05f, + 7.214080608657170231e-05f, + 7.896577036881257869e-05f, + 8.569251318300049464e-05f, + 9.231450923951847092e-05f, + 9.882535693872643605e-05f, + 1.052187845203471448e-04f, + 1.114886560645364380e-04f, + 1.176289773387779070e-04f, + 1.236339014852947521e-04f, + 1.294977345434665896e-04f, + 1.352149408021485982e-04f, + 1.407801479768994418e-04f, + 1.461881522073272849e-04f, + 1.514339228700169496e-04f, + 1.565126072024935349e-04f, + 1.614195347342348315e-04f, + 1.661502215206463087e-04f, + 1.707003741761581588e-04f, + 1.750658937030649676e-04f, + 1.792428791126197800e-04f, + 1.832276308353748221e-04f, + 1.870166539177443887e-04f, + 1.906066610022775826e-04f, + 1.939945750890921376e-04f, + 1.971775320762906734e-04f, + 2.001528830773817175e-04f, + 2.029181965139526369e-04f, + 2.054712599821023459e-04f, + 2.078100818912826861e-04f, + 2.099328928746136498e-04f, + 2.118381469697695253e-04f, + 2.135245225699071707e-04f, + 2.149909231442836445e-04f, + 2.162364777284813886e-04f, + 2.172605411843266446e-04f, + 2.180626942299304465e-04f, + 2.186427432404015815e-04f, + 2.190007198200883928e-04f, + 2.191368801473969510e-04f, + 2.190517040934920065e-04f, + 2.187458941163810658e-04f, + 2.182203739321322280e-04f, + 2.174762869651921987e-04f, + 2.165149945799773028e-04f, + 2.153380740961488441e-04f, + 2.139473165901802359e-04f, + 2.123447244860358321e-04f, + 2.105325089380130263e-04f, + 2.085130870089506230e-04f, + 2.062890786472634959e-04f, + 2.038633034664208931e-04f, + 2.012387773306926119e-04f, + 1.984187087511740796e-04f, + 1.954064950962511793e-04f, + 1.922057186209438458e-04f, + 1.888201423195703249e-04f, + 1.852537056065179267e-04f, + 1.815105198299485519e-04f, + 1.775948636234848943e-04f, + 1.735111781010148112e-04f, + 1.692640619000253591e-04f, + 1.648582660788071937e-04f, + 1.602986888732223973e-04f, + 1.555903703187100698e-04f, + 1.507384867433899029e-04f, + 1.457483451382290192e-04f, + 1.406253774102959029e-04f, + 1.353751345253480795e-04f, + 1.300032805459848623e-04f, + 1.245155865716643785e-04f, + 1.189179245871088876e-04f, + 1.132162612255646118e-04f, + 1.074166514535061193e-04f, + 1.015252321834391158e-04f, + 9.554821582143662340e-05f, + 8.949188375630919609e-05f, + 8.336257979698908499e-05f, + 7.716670356510142823e-05f, + 7.091070384951115571e-05f, + 6.460107192972675580e-05f, + 5.824433487497955288e-05f, + 5.184704882602284872e-05f, + 4.541579226631734119e-05f, + 3.895715928963878430e-05f, + 3.247775287090116139e-05f, + 2.598417814704357540e-05f, + 1.948303571479631031e-05f, + 1.298091495202827620e-05f, + 6.484387369576324119e-06f, + 0.000000000000000000e+00f, + -6.465731169933958513e-06f, + -1.290632771657884088e-05f, + -1.931535523998722761e-05f, + -2.568642976144864805e-05f, + -3.201322405145375435e-05f, + -3.828947388208588727e-05f, + -4.450898419751903002e-05f, + -5.066563519664518423e-05f, + -5.675338832188378036e-05f, + -6.276629214833436183e-05f, + -6.869848816762920277e-05f, + -7.454421646074183764e-05f, + -8.029782125450870081e-05f, + -8.595375635638307819e-05f, + -9.150659046230223595e-05f, + -9.695101233261035672e-05f, + -1.022818358312054416e-04f, + -1.074940048230266600e-04f, + -1.125825979255044379e-04f, + -1.175428331093993729e-04f, + -1.223700721448543901e-04f, + -1.270598248885527321e-04f, + -1.316077534080812585e-04f, + -1.360096759398110458e-04f, + -1.402615706766127137e-04f, + -1.443595793822601773e-04f, + -1.483000108290968150e-04f, + -1.520793440561845624e-04f, + -1.556942314450015955e-04f, + -1.591415016101448729e-04f, + -1.624181621026041017e-04f, + -1.655214019234404826e-04f, + -1.684485938457612995e-04f, + -1.711972965433097588e-04f, + -1.737652565239656850e-04f, + -1.761504098667907340e-04f, + -1.783508837614152301e-04f, + -1.803649978487851233e-04f, + -1.821912653624264543e-04f, + -1.838283940697296227e-04f, + -1.852752870127996935e-04f, + -1.865310430487398998e-04f, + -1.875949571893940915e-04f, + -1.884665207407716647e-04f, + -1.891454212426279299e-04f, + -1.896315422087889631e-04f, + -1.899249626691283926e-04f, + -1.900259565141956190e-04f, + -1.899349916437565312e-04f, + -1.896527289206770522e-04f, + -1.891800209317994808e-04f, + -1.885179105576068514e-04f, + -1.876676293527271906e-04f, + -1.866305957394497354e-04f, + -1.854084130166551892e-04f, + -1.840028671867227714e-04f, + -1.824159246031662005e-04f, + -1.806497294418971144e-04f, + -1.787066009992514435e-04f, + -1.765890308199928246e-04f, + -1.742996796587417414e-04f, + -1.718413742784095856e-04f, + -1.692171040893801167e-04f, + -1.664300176333031469e-04f, + -1.634834189156041844e-04f, + -1.603807635908042269e-04f, + -1.571256550050320762e-04f, + -1.537218401001562711e-04f, + -1.501732051841159817e-04f, + -1.464837715721702366e-04f, + -1.426576911038343165e-04f, + -1.386992415405413062e-04f, + -1.346128218489411334e-04f, + -1.304029473750683709e-04f, + -1.260742449145932711e-04f, + -1.216314476844448554e-04f, + -1.170793902013302941e-04f, + -1.124230030725036544e-04f, + -1.076673077044100317e-04f, + -1.028174109349222682e-04f, + -9.787849959470351147e-05f, + -9.285583500357369501e-05f, + -8.775474740762446567e-05f, + -8.258063036294733172e-05f, + -7.733893507179906781e-05f, + -7.203516467725131118e-05f, + -6.667486852207986337e-05f, + -6.126363637798329517e-05f, + -5.580709265104459485e-05f, + -5.031089056941896167e-05f, + -4.478070635923045353e-05f, + -3.922223341459007002e-05f, + -3.364117646783503998e-05f, + -2.804324576573561864e-05f, + -2.243415125772841104e-05f, + -1.681959680200483478e-05f, + -1.120527439532200600e-05f, + -5.596858432283831980e-06f, + 0.000000000000000000e+00f, + 5.579678786350002526e-06f, + 1.113659040131433947e-05f, + 1.666518747469618845e-05f, + 2.215996829939644689e-05f, + 2.761548227605910744e-05f, + 3.302633528924318619e-05f, + 3.838719500969946610e-05f, + 4.369279611777013815e-05f, + 4.893794544267782349e-05f, + 5.411752701278543923e-05f, + 5.922650701192542296e-05f, + 6.425993863709400348e-05f, + 6.921296685271543028e-05f, + 7.408083303713561935e-05f, + 7.885887951679374148e-05f, + 8.354255398385457916e-05f, + 8.812741379313725198e-05f, + 9.260913013432653981e-05f, + 9.698349207564205016e-05f, + 1.012464104751122735e-04f, + 1.053939217560361348e-04f, + 1.094221915430763865e-04f, + 1.133275181557522266e-04f, + 1.171063359561930271e-04f, + 1.207552185482215309e-04f, + 1.242708818248938415e-04f, + 1.276501868619005589e-04f, + 1.308901426543747110e-04f, + 1.339879086947369589e-04f, + 1.369407973894841402e-04f, + 1.397462763129272100e-04f, + 1.424019702960989549e-04f, + 1.449056633492160203e-04f, + 1.472553004161910543e-04f, + 1.494489889600180950e-04f, + 1.514850003778564957e-04f, + 1.533617712449332308e-04f, + 1.550779043865114734e-04f, + 1.566321697773859439e-04f, + 1.580235052684658486e-04f, + 1.592510171403173336e-04f, + 1.603139804835744661e-04f, + 1.612118394063934590e-04f, + 1.619442070692711196e-04f, + 1.625108655477295867e-04f, + 1.629117655235336551e-04f, + 1.631470258052963916e-04f, + 1.632169326794885361e-04f, + 1.631219390930484540e-04f, + 1.628626636689312806e-04f, + 1.624398895561451970e-04f, + 1.618545631159456772e-04f, + 1.611077924460503359e-04f, + 1.602008457448726990e-04f, + 1.591351495179624102e-04f, + 1.579122866289444445e-04f, + 1.565339941974661477e-04f, + 1.550021613467485204e-04f, + 1.533188268035131036e-04f, + 1.514861763532199430e-04f, + 1.495065401536325306e-04f, + 1.473823899099098260e-04f, + 1.451163359145451060e-04f, + 1.427111239555983182e-04f, + 1.401696320967573881e-04f, + 1.374948673329850774e-04f, + 1.346899621254734052e-04f, + 1.317581708198773619e-04f, + 1.287028659518289764e-04f, + 1.255275344438603485e-04f, + 1.222357736979611648e-04f, + 1.188312875880578206e-04f, + 1.153178823568962413e-04f, + 1.116994624217160199e-04f, + 1.079800260933631265e-04f, + 1.041636612134171070e-04f, + 1.002545407141449194e-04f, + 9.625691810593006150e-05f, + 9.217512289710953982e-05f, + 8.801355595103532931e-05f, + 8.377668478539886923e-05f, + 7.946903881866790591e-05f, + 7.509520456875234419e-05f, + 7.065982080891584666e-05f, + 6.616757368602117870e-05f, + 6.162319180617105993e-05f, + 5.703144129297408308e-05f, + 5.239712082341619980e-05f, + 4.772505664658922863e-05f, + 4.302009759036991954e-05f, + 3.828711006119116657e-05f, + 3.353097304204050925e-05f, + 2.875657309374543029e-05f, + 2.396879936476407346e-05f, + 1.917253861437825900e-05f, + 1.437267025445376776e-05f, + 9.574061414716567378e-06f, + 4.781562036525325622e-06f, + 0.000000000000000000e+00f, + -4.765823710467572352e-06f, + -9.511139797770952161e-06f, + -1.423121539568319248e-05f, + -1.892135876000095219e-05f, + -2.357692390252032815e-05f, + -2.819331516332007593e-05f, + -3.276599171692918774e-05f, + -3.729047200786769084e-05f, + -4.176233811142703061e-05f, + -4.617724001535500485e-05f, + -5.053089981838045005e-05f, + -5.481911584154466779e-05f, + -5.903776664846981624e-05f, + -6.318281497064232792e-05f, + -6.725031153416303120e-05f, + -7.123639878426539594e-05f, + -7.513731450417200934e-05f, + -7.894939532493793865e-05f, + -8.266908012303817257e-05f, + -8.629291330264409008e-05f, + -8.981754795950380526e-05f, + -9.323974892372517958e-05f, + -9.655639567864357899e-05f, + -9.976448515324246556e-05f, + -1.028611343856743177e-04f, + -1.058435830556215613e-04f, + -1.087091958832444314e-04f, + -1.114554648928591494e-04f, + -1.140800115393030879e-04f, + -1.165805886954139077e-04f, + -1.189550824989598954e-04f, + -1.212015140576370412e-04f, + -1.233180410108325074e-04f, + -1.253029589470822374e-04f, + -1.271547026761611632e-04f, + -1.288718473550913872e-04f, + -1.304531094673266076e-04f, + -1.318973476546234471e-04f, + -1.332035634012388348e-04f, + -1.343709015702383085e-04f, + -1.353986507918701350e-04f, + -1.362862437040613826e-04f, + -1.370332570453443202e-04f, + -1.376394116005415203e-04f, + -1.381045719998066825e-04f, + -1.384287463716805618e-04f, + -1.386120858510235900e-04f, + -1.386548839427931658e-04f, + -1.385575757428196932e-04f, + -1.383207370168273054e-04f, + -1.379450831391416433e-04f, + -1.374314678926119766e-04f, + -1.367808821314652607e-04f, + -1.359944523088843157e-04f, + -1.350734388713058730e-04f, + -1.340192345214945692e-04f, + -1.328333623526271043e-04f, + -1.315174738557150504e-04f, + -1.300733468028466666e-04f, + -1.285028830087897415e-04f, + -1.268081059737171702e-04f, + -1.249911584097946639e-04f, + -1.230542996545981637e-04f, + -1.209999029743675174e-04f, + -1.188304527602330177e-04f, + -1.165485416206351921e-04f, + -1.141568673732511950e-04f, + -1.116582299398947146e-04f, + -1.090555281478102406e-04f, + -1.063517564410224357e-04f, + -1.035500015053626303e-04f, + -1.006534388109464010e-04f, + -9.766532907587492868e-05f, + -9.458901465512266783e-05f, + -9.142791585846299308e-05f, + -8.818552720148400341e-05f, + -8.486541359380171191e-05f, + -8.147120646848431092e-05f, + -7.800659985692548243e-05f, + -7.447534641334087790e-05f, + -7.088125339309563760e-05f, + -6.722817858922308187e-05f, + -6.352002623131395697e-05f, + -5.976074285119170978e-05f, + -5.595431311967590562e-05f, + -5.210475565880340852e-05f, + -4.821611883387434797e-05f, + -4.429247652966449879e-05f, + -4.033792391527355533e-05f, + -3.635657320185136960e-05f, + -3.235254939766243925e-05f, + -2.832998606480489144e-05f, + -2.429302108193049522e-05f, + -2.024579241723850257e-05f, + -1.619243391613931063e-05f, + -1.213707110770494373e-05f, + -8.083817034238642389e-06f, + -4.036768108108601457e-06f, + 0.000000000000000000e+00f, + 4.022436437324076239e-06f, + 8.026519205701394352e-06f, + 1.200825915466515436e-05f, + 1.596370392708562708e-05f, + 1.988894185342372352e-05f, + 2.378010579081847397e-05f, + 2.763337690325799793e-05f, + 3.144498837921355557e-05f, + 3.521122908304340009e-05f, + 3.892844713680019853e-05f, + 4.259305342891470467e-05f, + 4.620152504646010591e-05f, + 4.975040862773826440e-05f, + 5.323632363207353587e-05f, + 5.665596552365893460e-05f, + 6.000610886662674704e-05f, + 6.328361032838766603e-05f, + 6.648541158852724214e-05f, + 6.960854215060292317e-05f, + 7.265012205430279883e-05f, + 7.560736448556652138e-05f, + 7.847757828228031152e-05f, + 8.125817033344999527e-05f, + 8.394664786969736913e-05f, + 8.654062064313692193e-05f, + 8.903780299482053388e-05f, + 9.143601580795497152e-05f, + 9.373318834539185970e-05f, + 9.592735996986403448e-05f, + 9.801668174559524367e-05f, + 9.999941792013674572e-05f, + 1.018739472852775956e-04f, + 1.036387644160876654e-04f, + 1.052924807872517206e-04f, + 1.068338257660048085e-04f, + 1.082616474810422510e-04f, + 1.095749135670224514e-04f, + 1.107727117842931974e-04f, + 1.118542505136681491e-04f, + 1.128188591261970936e-04f, + 1.136659882279879026e-04f, + 1.143952097802875201e-04f, + 1.150062170951232128e-04f, + 1.154988247069874726e-04f, + 1.158729681211121310e-04f, + 1.161287034390441527e-04f, + 1.162662068623534605e-04f, + 1.162857740754014629e-04f, + 1.161878195082552873e-04f, + 1.159728754809229666e-04f, + 1.156415912302182657e-04f, + 1.151947318206731616e-04f, + 1.146331769410351999e-04f, + 1.139579195879890020e-04f, + 1.131700646388664324e-04f, + 1.122708273152050117e-04f, + 1.112615315391279159e-04f, + 1.101436081846065776e-04f, + 1.089185932257956109e-04f, + 1.075881257847022211e-04f, + 1.061539460805467204e-04f, + 1.046178932833044002e-04f, + 1.029819032739389583e-04f, + 1.012480063139884254e-04f, + 9.941832462721362205e-05f, + 9.749506989611064225e-05f, + 9.548054067616838824e-05f, + 9.337711973079915206e-05f, + 9.118727129001866780e-05f, + 8.891353823589849862e-05f, + 8.655853921798483167e-05f, + 8.412496570189726970e-05f, + 8.161557895436345137e-05f, + 7.903320696801201077e-05f, + 7.638074132934370719e-05f, + 7.366113403320848053e-05f, + 7.087739424737539320e-05f, + 6.803258503057929422e-05f, + 6.512982000765911157e-05f, + 6.217226000532499622e-05f, + 5.916310965216279986e-05f, + 5.610561394646146512e-05f, + 5.300305479558382887e-05f, + 4.985874753042966284e-05f, + 4.667603739873827257e-05f, + 4.345829604087496334e-05f, + 4.020891795178530215e-05f, + 3.693131693280893166e-05f, + 3.362892253699031918e-05f, + 3.030517651164982165e-05f, + 2.696352924175526110e-05f, + 2.360743619783213642e-05f, + 2.024035439200125525e-05f, + 1.686573884576587145e-05f, + 1.348703907309045250e-05f, + 1.010769558241483277e-05f, + 6.731136401002770680e-06f, + 3.360773625198592391e-06f, + 0.000000000000000000e+00f, + -3.347814468650473784e-06f, + -6.679325865479849946e-06f, + -9.991219678161110501e-06f, + -1.328021406688385974e-05f, + -1.654306308815880257e-05f, + -1.977655986962290348e-05f, + -2.297753973280750991e-05f, + -2.614288326084785529e-05f, + -2.926951930822502027e-05f, + -3.235442794958472064e-05f, + -3.539464336494777658e-05f, + -3.838725665850617859e-05f, + -4.132941860839394398e-05f, + -4.421834234486570842e-05f, + -4.705130595439784442e-05f, + -4.982565500735158521e-05f, + -5.253880500681173683e-05f, + -5.518824375649152762e-05f, + -5.777153364550003561e-05f, + -6.028631384797333815e-05f, + -6.273030243562301752e-05f, + -6.510129840139457593e-05f, + -6.739718359242333320e-05f, + -6.961592455074339493e-05f, + -7.175557426013427060e-05f, + -7.381427379772556206e-05f, + -7.579025388895909592e-05f, + -7.768183636476383978e-05f, + -7.948743551975573677e-05f, + -8.120555937048918389e-05f, + -8.283481081280139394e-05f, + -8.437388867751212612e-05f, + -8.582158868373181084e-05f, + -8.717680428922131703e-05f, + -8.843852743731167663e-05f, + -8.960584920002047696e-05f, + -9.067796031711479563e-05f, + -9.165415163093462887e-05f, + -9.253381441698060807e-05f, + -9.331644061029057509e-05f, + -9.400162292779464348e-05f, + -9.458905488691879318e-05f, + -9.507853072082816524e-05f, + -9.546994519078202349e-05f, + -9.576329329621814776e-05f, + -9.595866988323466294e-05f, + -9.605626915229089865e-05f, + -9.605638406600895262e-05f, + -9.595940565808516048e-05f, + -9.576582224440011919e-05f, + -9.547621853752977987e-05f, + -9.509127466593055836e-05f, + -9.461176509920040452e-05f, + -9.403855748086969134e-05f, + -9.337261137029724230e-05f, + -9.261497689531161055e-05f, + -9.176679331735186228e-05f, + -9.082928751089830238e-05f, + -8.980377235912744038e-05f, + -8.869164506774372268e-05f, + -8.749438539906182540e-05f, + -8.621355382846783715e-05f, + -8.485078962544303713e-05f, + -8.340780886146616484e-05f, + -8.188640234708234958e-05f, + -8.028843350057289605e-05f, + -7.861583615068542543e-05f, + -7.687061227593963936e-05f, + -7.505482968307974337e-05f, + -7.317061962734104652e-05f, + -7.122017437715785402e-05f, + -6.920574472607888617e-05f, + -6.712963745464778354e-05f, + -6.499421274506274500e-05f, + -6.280188155146197997e-05f, + -6.055510292871261671e-05f, + -5.825638132264141731e-05f, + -5.590826382463881251e-05f, + -5.351333739358024485e-05f, + -5.107422604809699472e-05f, + -4.859358803218347312e-05f, + -4.607411295717206477e-05f, + -4.351851892309470621e-05f, + -4.092954962253340614e-05f, + -3.830997142993496893e-05f, + -3.566257047950555911e-05f, + -3.299014973471602795e-05f, + -3.029552605247514392e-05f, + -2.758152724501864632e-05f, + -2.485098914252425363e-05f, + -2.210675265954265012e-05f, + -1.935166086816063607e-05f, + -1.658855608095106957e-05f, + -1.382027694664882434e-05f, + -1.104965556150336744e-05f, + -8.279514599188903814e-06f, + -5.512664462229372086e-06f, + -2.751900457687248369e-06f, + 0.000000000000000000e+00f, + 2.740280156290214512e-06f, + 5.466206651186378539e-06f, + 8.175072218564196470e-06f, + 1.086419834758086399e-05f, + 1.353093790349696553e-05f, + 1.617267770547626131e-05f, + 1.878684105880902989e-05f, + 2.137089023916455868e-05f, + 2.392232892650095790e-05f, + 2.643870458635503993e-05f, + 2.891761079620682311e-05f, + 3.135668951483809152e-05f, + 3.375363329250938944e-05f, + 3.610618741995035084e-05f, + 3.841215201419369719e-05f, + 4.066938403936110963e-05f, + 4.287579926060773578e-05f, + 4.502937412942688007e-05f, + 4.712814759873801425e-05f, + 4.917022286611355612e-05f, + 5.115376904367083672e-05f, + 5.307702275320218851e-05f, + 5.493828964523271308e-05f, + 5.673594584069856022e-05f, + 5.846843929414990829e-05f, + 6.013429107736878215e-05f, + 6.173209658237591092e-05f, + 6.326052664298879500e-05f, + 6.471832857406342385e-05f, + 6.610432712770806260e-05f, + 6.741742536584356324e-05f, + 6.865660544852231900e-05f, + 6.982092933759627743e-05f, + 7.090953941532209665e-05f, + 7.192165901764468636e-05f, + 7.285659288195965404e-05f, + 7.371372750925019328e-05f, + 7.449253144060441825e-05f, + 7.519255544814984439e-05f, + 7.581343264061586552e-05f, + 7.635487848374452387e-05f, + 7.681669073589902474e-05f, + 7.719874929929503027e-05f, + 7.750101598737158502e-05f, + 7.772353420888149114e-05f, + 7.786642856940284227e-05f, + 7.792990439101760668e-05f, + 7.791424715101048608e-05f, + 7.781982184050777879e-05f, + 7.764707224406404028e-05f, + 7.739652014127399414e-05f, + 7.706876443157189042e-05f, + 7.666448018344928735e-05f, + 7.618441760939247533e-05f, + 7.562940096792763350e-05f, + 7.500032739420971781e-05f, + 7.429816566067238063e-05f, + 7.352395486933000228e-05f, + 7.267880307736313862e-05f, + 7.176388585770229430e-05f, + 7.078044479637946680e-05f, + 6.972978592846818902e-05f, + 6.861327811449984264e-05f, + 6.743235135927742136e-05f, + 6.618849507510502698e-05f, + 6.488325629143087644e-05f, + 6.351823781301141390e-05f, + 6.209509632871848778e-05f, + 6.061554047316198814e-05f, + 5.908132884331902243e-05f, + 5.749426797245979628e-05f, + 5.585621026359582951e-05f, + 5.416905188480572637e-05f, + 5.243473062876452025e-05f, + 5.065522373885282526e-05f, + 4.883254570422391761e-05f, + 4.696874602629149840e-05f, + 4.506590695899598622e-05f, + 4.312614122539617790e-05f, + 4.115158971296881845e-05f, + 3.914441915014531378e-05f, + 3.710681976655663884e-05f, + 3.504100293947658921e-05f, + 3.294919882896850676e-05f, + 3.083365400421063813e-05f, + 2.869662906354593466e-05f, + 2.654039625068195532e-05f, + 2.436723706957190895e-05f, + 2.217943990043698863e-05f, + 1.997929761939633796e-05f, + 1.776910522413144273e-05f, + 1.555115746807415747e-05f, + 1.332774650545313544e-05f, + 1.110115954964658368e-05f, + 8.873676547184104307e-06f, + 6.647567869740949601e-06f, + 4.425092026438055660e-06f, + 2.208493398703637141e-06f, + 0.000000000000000000e+00f, + -2.198178737447286155e-06f, + -4.383854146707416475e-06f, + -6.554860478846427014e-06f, + -8.709057022211050465e-06f, + -1.084433018625070958e-05f, + -1.295859554782643898e-05f, + -1.504979985813177589e-05f, + -1.711592300826502171e-05f, + -1.915497995162542054e-05f, + -2.116502258133142226e-05f, + -2.314414156091539193e-05f, + -2.509046810662869737e-05f, + -2.700217571967648383e-05f, + -2.887748186688327340e-05f, + -3.071464960822724050e-05f, + -3.251198916982059171e-05f, + -3.426785946094130863e-05f, + -3.598066953382340031e-05f, + -3.764887998489755495e-05f, + -3.927100429636594712e-05f, + -4.084561011694002843e-05f, + -4.237132048071104532e-05f, + -4.384681496316908579e-05f, + -4.527083077345597480e-05f, + -4.664216378202475170e-05f, + -4.795966948291004048e-05f, + -4.922226388992814933e-05f, + -5.042892436618977834e-05f, + -5.157869038634893284e-05f, + -5.267066423112145597e-05f, + -5.370401161365963874e-05f, + -5.467796223744639814e-05f, + -5.559181028545831532e-05f, + -5.644491484037703408e-05f, + -5.723670023577102494e-05f, + -5.796665633817722128e-05f, + -5.863433876011653090e-05f, + -5.923936900414046228e-05f, + -5.978143453809256339e-05f, + -6.026028880180132370e-05f, + -6.067575114554413853e-05f, + -6.102770670064889110e-05f, + -6.131610618268607763e-05f, + -6.154096562777286157e-05f, + -6.170236606257552899e-05f, + -6.180045310866599611e-05f, + -6.183543652194144397e-05f, + -6.180758966790510722e-05f, + -6.171724893364212428e-05f, + -6.156481307740533954e-05f, + -6.135074251677746099e-05f, + -6.107555855644340075e-05f, + -6.073984255665435130e-05f, + -6.034423504353361045e-05f, + -5.988943476241735355e-05f, + -5.937619767549151724e-05f, + -5.880533590502611506e-05f, + -5.817771662356323390e-05f, + -5.749426089246688652e-05f, + -5.675594245028995661e-05f, + -5.596378645244941432e-05f, + -5.511886816375996041e-05f, + -5.422231160540798414e-05f, + -5.327528815799189400e-05f, + -5.227901512228311736e-05f, + -5.123475423943163698e-05f, + -5.014381017231689294e-05f, + -4.900752894983425071e-05f, + -4.782729637590838818e-05f, + -4.660453640505390237e-05f, + -4.534070948633992719e-05f, + -4.403731087762476868e-05f, + -4.269586893198487468e-05f, + -4.131794335821765057e-05f, + -3.990512345738859756e-05f, + -3.845902633734535553e-05f, + -3.698129510720333325e-05f, + -3.547359705373742065e-05f, + -3.393762180168319212e-05f, + -3.237507945996893324e-05f, + -3.078769875582971604e-05f, + -2.917722515883962726e-05f, + -2.754541899685784069e-05f, + -2.589405356588684348e-05f, + -2.422491323584912912e-05f, + -2.253979155425681131e-05f, + -2.084048934980605179e-05f, + -1.912881283781196876e-05f, + -1.740657172949882254e-05f, + -1.567557734707370159e-05f, + -1.393764074653252662e-05f, + -1.219457085009355482e-05f, + -1.044817259020866579e-05f, + -8.700245066967668165e-06f, + -6.952579720797126885e-06f, + -5.206958522265940783e-06f, + -3.465152180804485261e-06f, + -1.728918374115329284e-06f, + 0.000000000000000000e+00f, + 1.719876547628855035e-06f, + 3.429003076962415618e-06f, + 5.125691268998652680e-06f, + 6.808274319193801364e-06f, + 8.475108548458095382e-06f, + 1.012457498199488445e-05f, + 1.175508089444992680e-05f, + 1.336506131998390598e-05f, + 1.495298052582536945e-05f, + 1.651733344796259886e-05f, + 1.805664708766448577e-05f, + 1.956948186756530129e-05f, + 2.105443294611633769e-05f, + 2.251013148919803211e-05f, + 2.393524589783997623e-05f, + 2.532848299093816370e-05f, + 2.668858914198573803e-05f, + 2.801435136885023771e-05f, + 2.930459837571368657e-05f, + 3.055820154629149815e-05f, + 3.177407588758812874e-05f, + 3.295118092341596186e-05f, + 3.408852153701416018e-05f, + 3.518514876214479022e-05f, + 3.624016052209482158e-05f, + 3.725270231609142734e-05f, + 3.822196785265903228e-05f, + 3.914719962953973575e-05f, + 4.002768945985303464e-05f, + 4.086277894419950948e-05f, + 4.165185988850534184e-05f, + 4.239437466744202404e-05f, + 4.308981653332471270e-05f, + 4.373772987044972097e-05f, + 4.433771039486739487e-05f, + 4.488940529969052062e-05f, + 4.539251334604474478e-05f, + 4.584678489985638750e-05f, + 4.625202191471458748e-05f, + 4.660807786111483166e-05f, + 4.691485760241596739e-05f, + 4.717231721794196576e-05f, + 4.738046377366677880e-05f, + 4.753935504100859647e-05f, + 4.764909916429116248e-05f, + 4.770985427749255010e-05f, + 4.772182807094424499e-05f, + 4.768527730869501094e-05f, + 4.760050729730926094e-05f, + 4.746787130690479115e-05f, + 4.728776994528908763e-05f, + 4.706065048609898603e-05f, + 4.678700615188301687e-05f, + 4.646737535312531160e-05f, + 4.610234088422814617e-05f, + 4.569252907753687694e-05f, + 4.523860891650402077e-05f, + 4.474129110914775088e-05f, + 4.420132712297902665e-05f, + 4.361950818261826370e-05f, + 4.299666423135587823e-05f, + 4.233366285792369062e-05f, + 4.163140818980473975e-05f, + 4.089083975440875428e-05f, + 4.011293130948711432e-05f, + 3.929868964417050821e-05f, + 3.844915335206358214e-05f, + 3.756539157780807174e-05f, + 3.664850273859330111e-05f, + 3.569961322208241148e-05f, + 3.471987606224959691e-05f, + 3.371046959463910820e-05f, + 3.267259609256267485e-05f, + 3.160748038579001628e-05f, + 3.051636846325336133e-05f, + 2.940052606132795206e-05f, + 2.826123723927484845e-05f, + 2.709980294337047645e-05f, + 2.591753956132967314e-05f, + 2.471577746857528420e-05f, + 2.349585956792650177e-05f, + 2.225913982430233876e-05f, + 2.100698179596996784e-05f, + 1.974075716392971998e-05f, + 1.846184426098673837e-05f, + 1.717162660205524496e-05f, + 1.587149141723013810e-05f, + 1.456282818918089089e-05f, + 1.324702719634344427e-05f, + 1.192547806344194722e-05f, + 1.059956832081574480e-05f, + 9.270681974018148597e-06f, + 7.940198085143243810e-06f, + 6.609489367292647408e-06f, + 5.279920793626897963e-06f, + 3.952848222338136709e-06f, + 2.629617038940430149e-06f, + 1.311560817197689786e-06f, + 0.000000000000000000e+00f, + -1.303759398535709597e-06f, + -2.598427068487143802e-06f, + -3.882729655845572457e-06f, + -5.155411989361711008e-06f, + -6.415238281346936499e-06f, + -7.660993301316896363e-06f, + -8.891483521387926858e-06f, + -1.010553823239075562e-05f, + -1.130201062965311224e-05f, + -1.247977886752223057e-05f, + -1.363774708165704589e-05f, + -1.477484637820374348e-05f, + -1.589003578899699857e-05f, + -1.698230319197812681e-05f, + -1.805066619602823882e-05f, + -1.909417298952157264e-05f, + -2.011190315188001194e-05f, + -2.110296842749134194e-05f, + -2.206651346138940222e-05f, + -2.300171649612773008e-05f, + -2.390779002935145109e-05f, + -2.478398143156065395e-05f, + -2.562957352368102888e-05f, + -2.644388511403268635e-05f, + -2.722627149437084187e-05f, + -2.797612489471199853e-05f, + -2.869287489668749573e-05f, + -2.937598880525030119e-05f, + -3.002497197854884801e-05f, + -3.063936811588928184e-05f, + -3.121875950370617492e-05f, + -3.176276721952791073e-05f, + -3.227105129396500970e-05f, + -3.274331083079011072e-05f, + -3.317928408523108317e-05f, + -3.357874850062376207e-05f, + -3.394152070364435874e-05f, + -3.426745645835545690e-05f, + -3.455645057935714278e-05f, + -3.480843680437391041e-05f, + -3.502338762665158155e-05f, + -3.520131408756888464e-05f, + -3.534226552992613248e-05f, + -3.544632931239619902e-05f, + -3.551363048567052514e-05f, + -3.554433143086765164e-05f, + -3.553863146080914930e-05f, + -3.549676638480726685e-05f, + -3.541900803763526229e-05f, + -3.530566377340024634e-05f, + -3.515707592505213643e-05f, + -3.497362123031461193e-05f, + -3.475571022484123395e-05f, + -3.450378660343666126e-05f, + -3.421832655021186221e-05f, + -3.389983803856685431e-05f, + -3.354886010192489469e-05f, + -3.316596207616956312e-05f, + -3.275174281475231333e-05f, + -3.230682987747619881e-05f, + -3.183187869396395209e-05f, + -3.132757170286612567e-05f, + -3.079461746785293406e-05f, + -3.023374977148131389e-05f, + -2.964572668803002056e-05f, + -2.903132963641206598e-05f, + -2.839136241429471749e-05f, + -2.772665021457329989e-05f, + -2.703803862533824987e-05f, + -2.632639261451207689e-05f, + -2.559259550032325886e-05f, + -2.483754790880125541e-05f, + -2.406216671948075119e-05f, + -2.326738400050288322e-05f, + -2.245414593433224767e-05f, + -2.162341173525594566e-05f, + -2.077615255991108366e-05f, + -1.991335041200381325e-05f, + -1.903599704245014085e-05f, + -1.814509284612314400e-05f, + -1.724164575641496121e-05f, + -1.632667013878813598e-05f, + -1.540118568453151252e-05f, + -1.446621630586251739e-05f, + -1.352278903357414166e-05f, + -1.257193291837421751e-05f, + -1.161467793707110403e-05f, + -1.065205390473139910e-05f, + -9.685089393960801953e-06f, + -8.714810662380517595e-06f, + -7.742240589422758301e-06f, + -6.768397623508250075e-06f, + -5.794294740669309052e-06f, + -4.820938415660515435e-06f, + -3.849327606567640099e-06f, + -2.880452753939940837e-06f, + -1.915294795392051711e-06f, + -9.548241966549667941e-07f, + 0.000000000000000000e+00f, + 9.482311090557935979e-07f, + 1.888935715883699196e-06f, + 2.821194570845099363e-06f, + 3.744103462554891212e-06f, + 4.656774069485003328e-06f, + 5.558334789141776895e-06f, + 6.447931544071930670e-06f, + 7.324728563978056132e-06f, + 8.187909143270469283e-06f, + 9.036676373374730734e-06f, + 9.870253849204916702e-06f, + 1.068788634918657437e-05f, + 1.148884048828036910e-05f, + 1.227240534347507200e-05f, + 1.303789305126774333e-05f, + 1.378463937664554480e-05f, + 1.451200425317579174e-05f, + 1.521937229378508572e-05f, + 1.590615327188085737e-05f, + 1.657178257248893217e-05f, + 1.721572161311536899e-05f, + 1.783745823408358416e-05f, + 1.843650705811206880e-05f, + 1.901240981896380926e-05f, + 1.956473565900515327e-05f, + 2.009308139556312985e-05f, + 2.059707175598756487e-05f, + 2.107635958138817672e-05f, + 2.153062599901698230e-05f, + 2.195958056332863746e-05f, + 2.236296136575796357e-05f, + 2.274053511332031568e-05f, + 2.309209717614148783e-05f, + 2.341747160407918292e-05f, + 2.371651111261625155e-05f, + 2.398909703825292155e-05f, + 2.423513926363566866e-05f, + 2.445457611271804443e-05f, + 2.464737421625526288e-05f, + 2.481352834797943618e-05f, + 2.495306123182613461e-05f, + 2.506602332061461824e-05f, + 2.515249254661017629e-05f, + 2.521257404442358010e-05f, + 2.524639984673718367e-05f, + 2.525412855336374039e-05f, + 2.523594497417534085e-05f, + 2.519205974646584022e-05f, + 2.512270892732973375e-05f, + 2.502815356166727978e-05f, + 2.490867922644573402e-05f, + 2.476459555187455187e-05f, + 2.459623572016065511e-05f, + 2.440395594254615678e-05f, + 2.418813491533502720e-05f, + 2.394917325564173359e-05f, + 2.368749291761338170e-05f, + 2.340353658988623544e-05f, + 2.309776707505748077e-05f, + 2.277066665197028110e-05f, + 2.242273642161569420e-05f, + 2.205449563747421783e-05f, + 2.166648102113158283e-05f, + 2.125924606400766132e-05f, + 2.083336031605244481e-05f, + 2.038940866226966761e-05f, + 1.992799058793915062e-05f, + 1.944971943340819870e-05f, + 1.895522163933315886e-05f, + 1.844513598326477953e-05f, + 1.792011280845339264e-05f, + 1.738081324577142443e-05f, + 1.682790842964813208e-05f, + 1.626207870890487679e-05f, + 1.568401285338399734e-05f, + 1.509440725727218157e-05f, + 1.449396513998789486e-05f, + 1.388339574554209775e-05f, + 1.326341354123314987e-05f, + 1.263473741656307925e-05f, + 1.199808988324299363e-05f, + 1.135419627714907315e-05f, + 1.070378396308057514e-05f, + 1.004758154317770732e-05f, + 9.386318069818621378e-06f, + 8.720722263832011000e-06f, + 8.051521738837318949e-06f, + 7.379442232510721810e-06f, + 6.705206845569983647e-06f, + 6.029535289243417829e-06f, + 5.353143142001254931e-06f, + 4.676741116269359137e-06f, + 4.001034335873452788e-06f, + 3.326721624913985331e-06f, + 2.654494808772660456e-06f, + 1.985038027915242428e-06f, + 1.319027065167622758e-06f, + 6.571286870779092537e-07f, + 0.000000000000000000e+00f, + -6.517121785112947791e-07f, + -1.297371932417118936e-06f, + -1.936354843466996782e-06f, + -2.568048570502482838e-06f, + -3.191853411264083243e-06f, + -3.807182846237992518e-06f, + -4.413464064061555844e-06f, + -5.010138468054313338e-06f, + -5.596662163456622115e-06f, + -6.172506424989349086e-06f, + -6.737158144353800846e-06f, + -7.290120257347119171e-06f, + -7.830912150263285036e-06f, + -8.359070045291263937e-06f, + -8.874147364643450859e-06f, + -9.375715073171476542e-06f, + -9.863361999259346438e-06f, + -1.033669513378841540e-05f, + -1.079533990703045404e-05f, + -1.123894044331291381e-05f, + -1.166715979335118242e-05f, + -1.207968014415581310e-05f, + -1.247620300645970784e-05f, + -1.285644937961374137e-05f, + -1.322015989395755990e-05f, + -1.356709493066716393e-05f, + -1.389703471911742539e-05f, + -1.420977941183009213e-05f, + -1.450514913708843372e-05f, + -1.478298402933197354e-05f, + -1.504314423747151812e-05f, + -1.528550991127199633e-05f, + -1.550998116600103277e-05f, + -1.571647802553678724e-05f, + -1.590494034416860253e-05f, + -1.607532770733858182e-05f, + -1.622761931159687079e-05f, + -1.636181382406056196e-05f, + -1.647792922169452577e-05f, + -1.657600261074252277e-05f, + -1.665609002666740320e-05f, + -1.671826621496820962e-05f, + -1.676262439326730422e-05f, + -1.678927599507833507e-05f, + -1.679835039567758540e-05f, + -1.678999462052671192e-05f, + -1.676437303670283319e-05f, + -1.672166702781419629e-05f, + -1.666207465288855371e-05f, + -1.658581028974159263e-05f, + -1.649310426334120225e-05f, + -1.638420245970092517e-05f, + -1.625936592584267462e-05f, + -1.611887045638726128e-05f, + -1.596300616733423785e-05f, + -1.579207705761010350e-05f, + -1.560640055896726747e-05f, + -1.540630707483150961e-05f, + -1.519213950869398463e-05f, + -1.496425278266009707e-05f, + -1.472301334677091966e-05f, + -1.446879867971653761e-05f, + -1.420199678156508936e-05f, + -1.392300565914552601e-05f, + -1.363223280470680123e-05f, + -1.333009466849801069e-05f, + -1.301701612590346651e-05f, + -1.269342993977575572e-05f, + -1.235977621860146935e-05f, + -1.201650187114281883e-05f, + -1.166406005819747346e-05f, + -1.130290964210320150e-05f, + -1.093351463463301477e-05f, + -1.055634364390535124e-05f, + -1.017186932094184607e-05f, + -9.780567806489146604e-06f, + -9.382918178734033738e-06f, + -8.979401902509168731e-06f, + -8.570502280611855256e-06f, + -8.156703907820469213e-06f, + -7.738492128206995299e-06f, + -7.316352496326938200e-06f, + -6.890770242859669408e-06f, + -6.462229745260318158e-06f, + -6.031214003986479169e-06f, + -5.598204124829813786e-06f, + -5.163678807894833656e-06f, + -4.728113843739430985e-06f, + -4.291981617188459184e-06f, + -3.855750619313580188e-06f, + -3.419884968058363287e-06f, + -2.984843937987475483e-06f, + -2.551081499598767520e-06f, + -2.119045868650204413e-06f, + -1.689179065920102918e-06f, + -1.261916487812816974e-06f, + -8.376864881983608732e-07f, + -4.169099718748218678e-07f, + 0.000000000000000000e+00f, + 4.126385921509365552e-07f, + 8.206095647815305072e-07f, + 1.223525630207122030e-06f, + 1.621008796236126059e-06f, + 2.012690696024970467e-06f, + 2.398212904138698659e-06f, + 2.777227238591446030e-06f, + 3.149396048634148933e-06f, + 3.514392488089205312e-06f, + 3.871900774045785298e-06f, + 4.221616430751789221e-06f, + 4.563246518543961347e-06f, + 4.896509847698758431e-06f, + 5.221137177081410397e-06f, + 5.536871397505274410e-06f, + 5.843467699721675325e-06f, + 6.140693726988073073e-06f, + 6.428329712173628339e-06f, + 6.706168599377329854e-06f, + 6.974016150064908968e-06f, + 7.231691033732799246e-06f, + 7.479024903134298036e-06f, + 7.715862454119090782e-06f, + 7.942061470155300043e-06f, + 8.157492851613173758e-06f, + 8.362040629923898268e-06f, + 8.555601966717204414e-06f, + 8.738087138086968224e-06f, + 8.909419504128689090e-06f, + 9.069535463915167161e-06f, + 9.218384396096766158e-06f, + 9.355928585322825753e-06f, + 9.482143134692021052e-06f, + 9.597015864467235791e-06f, + 9.700547197287537744e-06f, + 9.792750030137629163e-06f, + 9.873649593339112619e-06f, + 9.943283296844531363e-06f, + 1.000170056413215178e-05f, + 1.004896265399734296e-05f, + 1.008514247056514156e-05f, + 1.011032436185004009e-05f, + 1.012460390719635526e-05f, + 1.012808769395258744e-05f, + 1.012089308373725277e-05f, + 1.010314796865800678e-05f, + 1.007499051786728413e-05f, + 1.003656891483040004e-05f, + 9.988041085702172294e-06f, + 9.929574419209254656e-06f, + 9.861345478440398626e-06f, + 9.783539704959164481e-06f, + 9.696351115651413914e-06f, + 9.599981992730900805e-06f, + 9.494642567327615031e-06f, + 9.380550697087179814e-06f, + 9.257931538216254041e-06f, + 9.127017212404176378e-06f, + 8.988046469065492662e-06f, + 8.841264343334779069e-06f, + 8.686921810258770176e-06f, + 8.525275435626184639e-06f, + 8.356587023873447459e-06f, + 8.181123263510028723e-06f, + 7.999155370499712271e-06f, + 7.810958730038508927e-06f, + 7.616812537163261916e-06f, + 7.416999436624914182e-06f, + 7.211805162456990385e-06f, + 7.001518177666605594e-06f, + 6.786429314468350961e-06f, + 6.566831415485732412e-06f, + 6.343018976325844570e-06f, + 6.115287789940895410e-06f, + 5.883934593178742717e-06f, + 5.649256715913496299e-06f, + 5.411551733154688679e-06f, + 5.171117120509288493e-06f, + 4.928249913373739521e-06f, + 4.683246370226741163e-06f, + 4.436401640376830997e-06f, + 4.188009436517276560e-06f, + 3.938361712429462095e-06f, + 3.687748346167128183e-06f, + 3.436456829041018457e-06f, + 3.184771960722456336e-06f, + 2.932975550760869950e-06f, + 2.681346126811560784e-06f, + 2.430158649854029301e-06f, + 2.179684236669581299e-06f, + 1.930189889838635696e-06f, + 1.681938235501949860e-06f, + 1.435187269127313838e-06f, + 1.190190109498106053e-06f, + 9.471947611406282867e-07f, + 7.064438853882597620e-07f, + 4.681745802695258113e-07f, + 2.326181693934783062e-07f, + 0.000000000000000000e+00f, + -2.294607496822518279e-07f, + -4.555512536303946545e-07f, + -6.780652116471304469e-07f, + -8.968030132995199105e-07f, + -1.111571892074599649e-06f, + -1.322186069669318649e-06f, + -1.528466890336115189e-06f, + -1.730242945231773840e-06f, + -1.927350186716386900e-06f, + -2.119632032570274826e-06f, + -2.306939460105835373e-06f, + -2.489131090168029246e-06f, + -2.666073261019773634e-06f, + -2.837640092136482743e-06f, + -3.003713537930782497e-06f, + -3.164183431450152543e-06f, + -3.318947518098628411e-06f, + -3.467911479445268386e-06f, + -3.610988947198002060e-06f, + -3.748101507421474508e-06f, + -3.879178695106657928e-06f, + -4.004157979193569750e-06f, + -4.122984738168565981e-06f, + -4.235612226366478793e-06f, + -4.342001531119113841e-06f, + -4.442121520894592501e-06f, + -4.535948784595755533e-06f, + -4.623467562178467021e-06f, + -4.704669666773933905e-06f, + -4.779554398499982279e-06f, + -4.848128450155944567e-06f, + -4.910405805006164935e-06f, + -4.966407626865209352e-06f, + -5.016162142699305776e-06f, + -5.059704517976509766e-06f, + -5.097076724993110270e-06f, + -5.128327404419833975e-06f, + -5.153511720311018673e-06f, + -5.172691208831328023e-06f, + -5.185933620952477709e-06f, + -5.193312759386582571e-06f, + -5.194908310018822646e-06f, + -5.190805668113285727e-06f, + -5.181095759564734449e-06f, + -5.165874857474497392e-06f, + -5.145244394333831128e-06f, + -5.119310770095809750e-06f, + -5.088185156423761042e-06f, + -5.051983297406574915e-06f, + -5.010825307025710792e-06f, + -4.964835463670194371e-06f, + -4.914142001988321737e-06f, + -4.858876902370465571e-06f, + -4.799175678352467995e-06f, + -4.735177162236423786e-06f, + -4.667023289215640662e-06f, + -4.594858880296614592e-06f, + -4.518831424306328092e-06f, + -4.439090859272008081e-06f, + -4.355789353459791187e-06f, + -4.269081086352130785e-06f, + -4.179122029845473253e-06f, + -4.086069729946137843e-06f, + -3.990083089234567233e-06f, + -3.891322150369041671e-06f, + -3.789947880894861469e-06f, + -3.686121959618365274e-06f, + -3.580006564802584169e-06f, + -3.471764164435954700e-06f, + -3.361557308819947231e-06f, + -3.249548425715061173e-06f, + -3.135899618280506402e-06f, + -3.020772466037677946e-06f, + -2.904327829076243898e-06f, + -2.786725655720860965e-06f, + -2.668124793866750565e-06f, + -2.548682806187309839e-06f, + -2.428555789406447020e-06f, + -2.307898197824789105e-06f, + -2.186862671278643330e-06f, + -2.065599867705792124e-06f, + -1.944258300480321568e-06f, + -1.822984180674020067e-06f, + -1.701921264393156922e-06f, + -1.581210705329814697e-06f, + -1.460990912660235641e-06f, + -1.341397414412057306e-06f, + -1.222562726419054144e-06f, + -1.104616226963808055e-06f, + -9.876840372108532818e-07f, + -8.718889075168336299e-07f, + -7.573501096980523593e-07f, + -6.441833353263205178e-07f, + -5.325006001176824594e-07f, + -4.224101544649153790e-07f, + -3.140164001606101186e-07f, + -2.074198133468546951e-07f, + -1.027168737185703904e-07f, + 0.000000000000000000e+00f, + 1.006425082962560188e-07f, + 1.991265228250998696e-07f, + 2.953721320865672257e-07f, + 3.893036808413146083e-07f, + 4.808498032861632466e-07f, + 5.699434500219715067e-07f, + 6.565219088541263631e-07f, + 7.405268194708413983e-07f, + 8.219041820579037521e-07f, + 9.006043599106572324e-07f, + 9.765820761143821518e-07f, + 1.049796404370967154e-06f, + 1.120210754056259219e-06f, + 1.187792849601788622e-06f, + 1.252514704296207476e-06f, + 1.314352588615897804e-06f, + 1.373286993192450102e-06f, + 1.429302586538256487e-06f, + 1.482388167650501341e-06f, + 1.532536613626721034e-06f, + 1.579744822422699780e-06f, + 1.624013650897105724e-06f, + 1.665347848284486069e-06f, + 1.703755985248906983e-06f, + 1.739250378670976522e-06f, + 1.771847012329051112e-06f, + 1.801565453633872846e-06f, + 1.828428766587697603e-06f, + 1.852463421131862093e-06f, + 1.873699199062873253e-06f, + 1.892169096686314783e-06f, + 1.907909224391436775e-06f, + 1.920958703325515738e-06f, + 1.931359559352847449e-06f, + 1.939156614480256200e-06f, + 1.944397375938704227e-06f, + 1.947131923107859303e-06f, + 1.947412792470748310e-06f, + 1.945294860790306117e-06f, + 1.940835226696380303e-06f, + 1.934093090874000321e-06f, + 1.925129635041577493e-06f, + 1.914007899911128539e-06f, + 1.900792662316812488e-06f, + 1.885550311703490783e-06f, + 1.868348726157043199e-06f, + 1.849257148168054309e-06f, + 1.828346060309234932e-06f, + 1.805687061008333849e-06f, + 1.781352740599210893e-06f, + 1.755416557827082551e-06f, + 1.727952716981022353e-06f, + 1.699036045830707816e-06f, + 1.668741874531441462e-06f, + 1.637145915666299804e-06f, + 1.604324145587388401e-06f, + 1.570352687212907484e-06f, + 1.535307694438660471e-06f, + 1.499265238310532749e-06f, + 1.462301195107119339e-06f, + 1.424491136473709433e-06f, + 1.385910221746217664e-06f, + 1.346633092594916054e-06f, + 1.306733770119299951e-06f, + 1.266285554515691827e-06f, + 1.225360927433250136e-06f, + 1.184031457134546194e-06f, + 1.142367706564255042e-06f, + 1.100439144428898935e-06f, + 1.058314059384136389e-06f, + 1.016059477418145401e-06f, + 9.737410825169423452e-07f, + 9.314231406881861787e-07f, + 8.891684274188879932e-07f, + 8.470381586302859329e-07f, + 8.050919251930470272e-07f, + 7.633876310564211735e-07f, + 7.219814350382115897e-07f, + 6.809276963207535929e-07f, + 6.402789236869417325e-07f, + 6.000857285259880680e-07f, + 5.603967816352038095e-07f, + 5.212587738328753669e-07f, + 4.827163803963257315e-07f, + 4.448122293282582582e-07f, + 4.075868734547717757e-07f, + 3.710787663445438682e-07f, + 3.353242420407537163e-07f, + 3.003574985858815201e-07f, + 2.662105853160385845e-07f, + 2.329133938960602585e-07f, + 2.004936530600967300e-07f, + 1.689769270175546171e-07f, + 1.383866174786039171e-07f, + 1.087439692488582841e-07f, + 8.006807933651531888e-08f, + 5.237590951157132493e-08f, + 2.568230225109257904e-08f, + 0.000000000000000000e+00f, + -2.466033232770569548e-08f, + -4.829008168683121073e-08f, + -7.088265816141993268e-08f, + -9.243346323606733125e-08f, + -1.129398551695146863e-07f, + -1.324011115659184628e-07f, + -1.508183892432858115e-07f, + -1.681946815011221211e-07f, + -1.845347728928822297e-07f, + -1.998451916121546072e-07f, + -2.141341596039432244e-07f, + -2.274115405148332402e-07f, + -2.396887855988568836e-07f, + -2.509788776975187057e-07f, + -2.612962734148978839e-07f, + -2.706568436096965910e-07f, + -2.790778123294188281e-07f, + -2.865776943115482094e-07f, + -2.931762311773865084e-07f, + -2.988943264486187393e-07f, + -3.037539795124567178e-07f, + -3.077782186659332945e-07f, + -3.109910333676799518e-07f, + -3.134173058274048922e-07f, + -3.150827420621620873e-07f, + -3.160138025468559683e-07f, + -3.162376325911064067e-07f, + -3.157819925664867536e-07f, + -3.146751881132046538e-07f, + -3.129460004522320042e-07f, + -3.106236169256348513e-07f, + -3.077375618915215213e-07f, + -3.043176280902072482e-07f, + -3.003938086063936412e-07f, + -2.959962295410709180e-07f, + -2.911550835096173451e-07f, + -2.859005640803434774e-07f, + -2.802628012618049063e-07f, + -2.742717981466135591e-07f, + -2.679573688192066510e-07f, + -2.613490776251264430e-07f, + -2.544761799041636744e-07f, + -2.473675642799770811e-07f, + -2.400516965988118414e-07f, + -2.325565656058897010e-07f, + -2.249096304424925012e-07f, + -2.171377700460247078e-07f, + -2.092672345282480135e-07f, + -2.013235986056343617e-07f, + -1.933317171473633572e-07f, + -1.853156829093616031e-07f, + -1.772987865099094365e-07f, + -1.693034787059287238e-07f, + -1.613513350178359175e-07f, + -1.534630227503889525e-07f, + -1.456582704530633583e-07f, + -1.379558398535355063e-07f, + -1.303735002995515733e-07f, + -1.229280057368551819e-07f, + -1.156350742435759375e-07f, + -1.085093701420685361e-07f, + -1.015644887007500715e-07f, + -9.481294343366335435e-08f, + -8.826615600362021996e-08f, + -8.193444872566309993e-08f, + -7.582703966755611925e-08f, + -6.995204033572834065e-08f, + -6.431645593190529234e-08f, + -5.892618816136430419e-08f, + -5.378604056816772665e-08f, + -4.889972636892558379e-08f, + -4.426987875170946693e-08f, + -3.989806360360980105e-08f, + -3.578479462389621212e-08f, + -3.192955077725143908e-08f, + -2.833079603795987602e-08f, + -2.498600136841822765e-08f, + -2.189166887745841221e-08f, + -1.904335809309968632e-08f, + -1.643571428675994097e-08f, + -1.406249877778086397e-08f, + -1.191662114752070737e-08f, + -9.990173286071856191e-09f, + -8.274465192170869078e-09f, + -6.760062445140820835e-09f, + -5.436825263828806997e-09f, + -4.293949063640696908e-09f, + -3.320006422643590005e-09f, + -2.502990363837817991e-09f, + -1.830358857702062856e-09f, + -1.289080449029138733e-09f, + -8.656809086711142593e-10f, + -5.462908092693271412e-10f, + -3.166939230097100569e-10f, + -1.623763376571505723e-10f, + -6.857618579388846575e-11f, + -2.033388168720926172e-11f, + -2.542758678303834900e-12f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f +}; + +} // namespace juce diff --git a/modules/juce_core/maths/juce_MathsFunctions.h b/modules/juce_core/maths/juce_MathsFunctions.h index 6faa880ae9..ca6ca67af8 100644 --- a/modules/juce_core/maths/juce_MathsFunctions.h +++ b/modules/juce_core/maths/juce_MathsFunctions.h @@ -130,6 +130,50 @@ Type jmap (Type sourceValue, Type sourceRangeMin, Type sourceRangeMax, Type targ return targetRangeMin + ((targetRangeMax - targetRangeMin) * (sourceValue - sourceRangeMin)) / (sourceRangeMax - sourceRangeMin); } +/** Remaps a normalised value (between 0 and 1) to a logarithmic target range. + + The entire target range must be greater than zero. + + @see mapFromLog10 + + @code + mapToLog10 (0.5, 0.4, 40.0) == 4.0 + @endcode +*/ +template +Type mapToLog10 (Type value0To1, Type logRangeMin, Type logRangeMax) +{ + jassert (logRangeMin > 0); + jassert (logRangeMax > 0); + + auto logMin = std::log10 (logRangeMin); + auto logMax = std::log10 (logRangeMax); + + return std::pow ((Type) 10.0, value0To1 * (logMax - logMin) + logMin); +} + +/** Remaps a logarithmic value in a target range to a normalised value (between 0 and 1). + + The entire target range must be greater than zero. + + @see mapToLog10 + + @code + mapFromLog10 (4.0, 0.4, 40.0) == 0.5 + @endcode +*/ +template +Type mapFromLog10 (Type valueInLogRange, Type logRangeMin, Type logRangeMax) +{ + jassert (logRangeMin > 0); + jassert (logRangeMax > 0); + + auto logMin = std::log10 (logRangeMin); + auto logMax = std::log10 (logRangeMax); + + return (std::log10 (valueInLogRange) - logMin) / (logMax - logMin); +} + /** Scans an array of values, returning the minimum value that it contains. */ template Type findMinimum (const Type* data, int numValues) diff --git a/modules/juce_core/threads/juce_SpinLock.h b/modules/juce_core/threads/juce_SpinLock.h index 532df8e418..14f7c6b021 100644 --- a/modules/juce_core/threads/juce_SpinLock.h +++ b/modules/juce_core/threads/juce_SpinLock.h @@ -75,6 +75,9 @@ public: /** Provides the type of scoped unlocker to use with a SpinLock. */ using ScopedUnlockType = GenericScopedUnlock; + /** Provides the type of scoped try-lock to use for locking a SpinLock. */ + using ScopedTryLockType = GenericScopedTryLock; + private: //============================================================================== mutable Atomic lock; diff --git a/modules/juce_dsp/filter_design/juce_FilterDesign.cpp b/modules/juce_dsp/filter_design/juce_FilterDesign.cpp index c8e0ebf7df..3b28c462e9 100644 --- a/modules/juce_dsp/filter_design/juce_FilterDesign.cpp +++ b/modules/juce_dsp/filter_design/juce_FilterDesign.cpp @@ -545,7 +545,7 @@ ReferenceCountedArray> { arrayFilters.add (*IIR::Coefficients::makeFirstOrderLowPass (sampleRate, frequency)); - for (auto i = 0; i < order / 2; ++i) + for (int i = 0; i < order / 2; ++i) { auto Q = 1.0 / (2.0 * std::cos ((i + 1.0) * MathConstants::pi / order)); arrayFilters.add (*IIR::Coefficients::makeLowPass (sampleRate, frequency, @@ -554,7 +554,7 @@ ReferenceCountedArray> } else { - for (auto i = 0; i < order / 2; ++i) + for (int i = 0; i < order / 2; ++i) { auto Q = 1.0 / (2.0 * std::cos ((2.0 * i + 1.0) * MathConstants::pi / (order * 2.0))); arrayFilters.add (*IIR::Coefficients::makeLowPass (sampleRate, frequency, @@ -580,7 +580,7 @@ ReferenceCountedArray> { arrayFilters.add (*IIR::Coefficients::makeFirstOrderHighPass (sampleRate, frequency)); - for (auto i = 0; i < order / 2; ++i) + for (int i = 0; i < order / 2; ++i) { auto Q = 1.0 / (2.0 * std::cos ((i + 1.0) * MathConstants::pi / order)); arrayFilters.add (*IIR::Coefficients::makeHighPass (sampleRate, frequency, @@ -589,7 +589,7 @@ ReferenceCountedArray> } else { - for (auto i = 0; i < order / 2; ++i) + for (int i = 0; i < order / 2; ++i) { auto Q = 1.0 / (2.0 * std::cos ((2.0 * i + 1.0) * MathConstants::pi / (order * 2.0))); arrayFilters.add (*IIR::Coefficients::makeHighPass (sampleRate, frequency, diff --git a/modules/juce_dsp/frequency/juce_Convolution.cpp b/modules/juce_dsp/frequency/juce_Convolution.cpp index 4b51d850b6..dcfef0a00e 100644 --- a/modules/juce_dsp/frequency/juce_Convolution.cpp +++ b/modules/juce_dsp/frequency/juce_Convolution.cpp @@ -685,7 +685,7 @@ struct Convolution::Pimpl : private Thread /** This function copies a buffer to a temporary location, so that any external audio source can be processed then in the dedicated thread. */ - void copyBufferToTemporaryLocation (dsp::AudioBlock block) + void copyBufferToTemporaryLocation (AudioBlock block) { const SpinLock::ScopedLockType sl (processLock); @@ -725,7 +725,7 @@ struct Convolution::Pimpl : private Thread } else { - auto interpolated = dsp::AudioBlock (interpolationBuffer).getSubBlock (0, numSamples); + auto interpolated = AudioBlock (interpolationBuffer).getSubBlock (0, numSamples); for (size_t channel = 0; channel < numChannels; ++channel) { diff --git a/modules/juce_dsp/frequency/juce_FFT.cpp b/modules/juce_dsp/frequency/juce_FFT.cpp index a69cd462f4..d3c82a966e 100644 --- a/modules/juce_dsp/frequency/juce_FFT.cpp +++ b/modules/juce_dsp/frequency/juce_FFT.cpp @@ -167,7 +167,7 @@ struct FFTFallback : public FFT::Instance { auto* input = reinterpret_cast*> (d); - for (auto i = size >> 1; i < size; ++i) + for (int i = size >> 1; i < size; ++i) input[i] = std::conj (input[size - i]); perform (input, scratch, true); @@ -681,7 +681,7 @@ struct FFTWImpl : public FFT::Instance auto size = (1 << order); if (! ignoreNegativeFreqs) - for (auto i = size >> 1; i < size; ++i) + for (int i = size >> 1; i < size; ++i) out[i] = std::conj (out[size - i]); } @@ -780,7 +780,7 @@ struct IntelFFT : public FFT::Instance auto size = (1 << order); if (! ignoreNegativeFreqs) - for (auto i = size >> 1; i < size; ++i) + for (int i = size >> 1; i < size; ++i) out[i] = std::conj (out[size - i]); } @@ -971,7 +971,7 @@ void FFT::performFrequencyOnlyForwardTransform (float* inputOutputData) const no performRealOnlyForwardTransform (inputOutputData); auto* out = reinterpret_cast*> (inputOutputData); - for (auto i = 0; i < size; ++i) + for (int i = 0; i < size; ++i) inputOutputData[i] = std::abs (out[i]); zeromem (&inputOutputData[size], static_cast (size) * sizeof (float)); diff --git a/modules/juce_dsp/juce_dsp.cpp b/modules/juce_dsp/juce_dsp.cpp index 07a397228d..ebe502e312 100644 --- a/modules/juce_dsp/juce_dsp.cpp +++ b/modules/juce_dsp/juce_dsp.cpp @@ -49,8 +49,14 @@ #include "processors/juce_FIRFilter.cpp" #include "processors/juce_IIRFilter.cpp" -#include "processors/juce_LadderFilter.cpp" +#include "processors/juce_FirstOrderTPTFilter.cpp" +#include "processors/juce_Panner.cpp" #include "processors/juce_Oversampling.cpp" +#include "processors/juce_BallisticsFilter.cpp" +#include "processors/juce_LinkwitzRileyFilter.cpp" +#include "processors/juce_DelayLine.cpp" +#include "processors/juce_DryWetMixer.cpp" +#include "processors/juce_StateVariableTPTFilter.cpp" #include "maths/juce_SpecialFunctions.cpp" #include "maths/juce_Matrix.cpp" #include "maths/juce_LookupTable.cpp" @@ -58,6 +64,12 @@ #include "frequency/juce_Convolution.cpp" #include "frequency/juce_Windowing.cpp" #include "filter_design/juce_FilterDesign.cpp" +#include "widgets/juce_LadderFilter.cpp" +#include "widgets/juce_Compressor.cpp" +#include "widgets/juce_NoiseGate.cpp" +#include "widgets/juce_Limiter.cpp" +#include "widgets/juce_Phaser.cpp" +#include "widgets/juce_Chorus.cpp" #if JUCE_USE_SIMD #if defined(__i386__) || defined(__amd64__) || defined(_M_X64) || defined(_X86_) || defined(_M_IX86) diff --git a/modules/juce_dsp/juce_dsp.h b/modules/juce_dsp/juce_dsp.h index 31fd8ec895..3ba412ba04 100644 --- a/modules/juce_dsp/juce_dsp.h +++ b/modules/juce_dsp/juce_dsp.h @@ -243,17 +243,29 @@ namespace juce #include "processors/juce_ProcessorWrapper.h" #include "processors/juce_ProcessorChain.h" #include "processors/juce_ProcessorDuplicator.h" -#include "processors/juce_Bias.h" -#include "processors/juce_Gain.h" -#include "processors/juce_WaveShaper.h" #include "processors/juce_IIRFilter.h" #include "processors/juce_FIRFilter.h" -#include "processors/juce_Oscillator.h" -#include "processors/juce_LadderFilter.h" #include "processors/juce_StateVariableFilter.h" +#include "processors/juce_FirstOrderTPTFilter.h" +#include "processors/juce_Panner.h" +#include "processors/juce_DelayLine.h" #include "processors/juce_Oversampling.h" -#include "processors/juce_Reverb.h" +#include "processors/juce_BallisticsFilter.h" +#include "processors/juce_LinkwitzRileyFilter.h" +#include "processors/juce_DryWetMixer.h" +#include "processors/juce_StateVariableTPTFilter.h" #include "frequency/juce_FFT.h" #include "frequency/juce_Convolution.h" #include "frequency/juce_Windowing.h" #include "filter_design/juce_FilterDesign.h" +#include "widgets/juce_Reverb.h" +#include "widgets/juce_Bias.h" +#include "widgets/juce_Gain.h" +#include "widgets/juce_WaveShaper.h" +#include "widgets/juce_Oscillator.h" +#include "widgets/juce_LadderFilter.h" +#include "widgets/juce_Compressor.h" +#include "widgets/juce_NoiseGate.h" +#include "widgets/juce_Limiter.h" +#include "widgets/juce_Phaser.h" +#include "widgets/juce_Chorus.h" diff --git a/modules/juce_dsp/processors/juce_BallisticsFilter.cpp b/modules/juce_dsp/processors/juce_BallisticsFilter.cpp new file mode 100644 index 0000000000..627b2116f8 --- /dev/null +++ b/modules/juce_dsp/processors/juce_BallisticsFilter.cpp @@ -0,0 +1,121 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +BallisticsFilter::BallisticsFilter() +{ + setAttackTime (attackTime); + setReleaseTime (releaseTime); +} + +template +void BallisticsFilter::setAttackTime (SampleType attackTimeMs) +{ + attackTime = attackTimeMs; + cteAT = calculateLimitedCte (static_cast (attackTime)); +} + +template +void BallisticsFilter::setReleaseTime (SampleType releaseTimeMs) +{ + releaseTime = releaseTimeMs; + cteRL = calculateLimitedCte (static_cast (releaseTime)); +} + +template +void BallisticsFilter::setLevelCalculationType (LevelCalculationType newLevelType) +{ + levelType = newLevelType; + reset(); +} + +template +void BallisticsFilter::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + expFactor = -2.0 * MathConstants::pi * 1000.0 / sampleRate; + + setAttackTime (attackTime); + setReleaseTime (releaseTime); + + yold.resize (spec.numChannels); + + reset(); +} + +template +void BallisticsFilter::reset() +{ + reset (0); +} + +template +void BallisticsFilter::reset (SampleType initialValue) +{ + for (auto& old : yold) + old = initialValue; +} + +template +SampleType BallisticsFilter::processSample (int channel, SampleType inputValue) +{ + jassert (isPositiveAndBelow (channel, yold.size())); + + SampleType cte = (inputValue > yold[(size_t) channel] ? cteAT : cteRL); + + if (levelType == LevelCalculationType::RMS) + inputValue *= inputValue; + + SampleType result = inputValue + cte * (yold[(size_t) channel] - inputValue); + yold[(size_t) channel] = result; + + if (levelType == LevelCalculationType::RMS) + return std::sqrt (result); + + return result; +} + +template +void BallisticsFilter::snapToZero() noexcept +{ + for (auto& old : yold) + util::snapToZero (old); +} + +template +SampleType BallisticsFilter::calculateLimitedCte (SampleType timeMs) const noexcept +{ + return timeMs < static_cast (1.0e-3) ? 0 + : static_cast (std::exp (expFactor / timeMs)); +} + +//============================================================================== +template class BallisticsFilter; +template class BallisticsFilter; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_BallisticsFilter.h b/modules/juce_dsp/processors/juce_BallisticsFilter.h new file mode 100644 index 0000000000..f110ad2e65 --- /dev/null +++ b/modules/juce_dsp/processors/juce_BallisticsFilter.h @@ -0,0 +1,142 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class BallisticsFilterLevelCalculationType +{ + peak, + RMS +}; + +/** + A processor to apply standard attack / release ballistics to an input signal. + This is useful in dynamics processors, envelope followers, modulated audio + effects and for smoothing animation in data visualisation. + + @tags{DSP} +*/ +template +class BallisticsFilter +{ +public: + //============================================================================== + using LevelCalculationType = BallisticsFilterLevelCalculationType; + + //============================================================================== + /** Constructor. */ + BallisticsFilter(); + + //============================================================================== + /** Sets the attack time in ms. + + Attack times less that 0.001 will be snapped to zero and very long attack + times will eventually saturate depending on the numerical precision used. + */ + void setAttackTime (SampleType attackTimeMs); + + /** Sets the release time in ms. + + Release times less that 0.001 will be snapped to zero and very long release + times will eventually saturate depending on the numerical precision used. + */ + void setReleaseTime (SampleType releaseTimeMs); + + /** Sets how the filter levels are calculated. + + Level calculation in digital envelope followers is usually performed using + peak detection with a rectifier function (like std::abs) and filtering, + which returns an envelope dependant on the peak or maximum values of the + signal amplitude. + + To perform an estimation of the average value of the signal you can use + an RMS (root mean squared) implementation of the ballistics filter instead. + This is useful in some compressor and noise-gate designs, or in specific + types of volume meters. + */ + void setLevelCalculationType (LevelCalculationType newCalculationType); + + //============================================================================== + /** Initialises the filter. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the filter. */ + void reset(); + + /** Resets the internal state variables of the filter to the given initial value. */ + void reset (SampleType initialValue); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() <= yold.size()); + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample (inputSamples[i], (int) channel); + } + + #if JUCE_SNAP_TO_ZERO + snapToZero(); + #endif + } + + /** Processes one sample at a time on a given channel. */ + SampleType processSample (int channel, SampleType inputValue); + + /** Ensure that the state variables are rounded to zero if the state + variables are denormals. This is only needed if you are doing + sample by sample processing. + */ + void snapToZero() noexcept; + +private: + //============================================================================== + SampleType calculateLimitedCte (SampleType) const noexcept; + + //============================================================================== + std::vector yold; + double sampleRate = 44100.0, expFactor = -0.142; + SampleType attackTime = 1.0, releaseTime = 100.0, cteAT = 0.0, cteRL = 0.0; + LevelCalculationType levelType = LevelCalculationType::peak; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_DelayLine.cpp b/modules/juce_dsp/processors/juce_DelayLine.cpp new file mode 100644 index 0000000000..01bf4605d9 --- /dev/null +++ b/modules/juce_dsp/processors/juce_DelayLine.cpp @@ -0,0 +1,121 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +DelayLine::DelayLine() + : DelayLine (0) +{ +} + +template +DelayLine::DelayLine (int maximumDelayInSamples) +{ + jassert (maximumDelayInSamples >= 0); + + totalSize = jmax (4, maximumDelayInSamples + 1); + sampleRate = 44100.0; +} + +//============================================================================== +template +void DelayLine::setDelay (SampleType newDelayInSamples) +{ + auto upperLimit = (SampleType) (totalSize - 1); + jassert (isPositiveAndNotGreaterThan (newDelayInSamples, upperLimit)); + + delay = jlimit ((SampleType) 0, upperLimit, newDelayInSamples); + delayInt = static_cast (std::floor (delay)); + delayFrac = delay - (SampleType) delayInt; + + updateInternalVariables(); +} + +template +SampleType DelayLine::getDelay() const +{ + return delay; +} + +//============================================================================== +template +void DelayLine::prepare (const ProcessSpec& spec) +{ + jassert (spec.numChannels > 0); + + bufferData.setSize ((int) spec.numChannels, totalSize, false, false, true); + + writePos.resize (spec.numChannels); + readPos.resize (spec.numChannels); + + v.resize (spec.numChannels); + sampleRate = spec.sampleRate; + + reset(); +} + +template +void DelayLine::reset() +{ + for (auto vec : { &writePos, &readPos }) + std::fill (vec->begin(), vec->end(), 0); + + std::fill (v.begin(), v.end(), static_cast (0)); + + bufferData.clear(); +} + +//============================================================================== +template +void DelayLine::pushSample (int channel, SampleType sample) +{ + bufferData.setSample (channel, writePos[(size_t) channel], sample); + writePos[(size_t) channel] = (writePos[(size_t) channel] + totalSize - 1) % totalSize; +} + +template +SampleType DelayLine::popSample (int channel, SampleType delayInSamples, bool updateReadPointer) +{ + if (delayInSamples >= 0) + setDelay(delayInSamples); + + auto result = interpolateSample (channel); + + if (updateReadPointer) + readPos[(size_t) channel] = (readPos[(size_t) channel] + totalSize - 1) % totalSize; + + return result; +} + +//============================================================================== +template class DelayLine; +template class DelayLine; +template class DelayLine; +template class DelayLine; +template class DelayLine; +template class DelayLine; +template class DelayLine; +template class DelayLine; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_DelayLine.h b/modules/juce_dsp/processors/juce_DelayLine.h new file mode 100644 index 0000000000..250ac07c98 --- /dev/null +++ b/modules/juce_dsp/processors/juce_DelayLine.h @@ -0,0 +1,309 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +/** + A collection of structs to pass as the template argument when setting the + interpolation type for the DelayLine class. +*/ +namespace DelayLineInterpolationTypes +{ + /** + No interpolation between successive samples in the delay line will be + performed. This is useful when the delay is a constant integer or to + create lo-fi audio effects. + */ + struct None {}; + + /** + Successive samples in the delay line will be linearly interpolated. This + type of interpolation has a low compuational cost where the delay can be + modulated in real time, but it also introduces a low-pass filtering effect + into your audio signal. + */ + struct Linear {}; + + /** + Successive samples in the delay line will be interpolated using a 3rd order + Lagrange interpolator. This method incurs more computational overhead than + linear interpolation but reduces the low-pass filtering effect whilst + remaining amenable to real time delay modulation. + */ + struct Lagrange3rd {}; + + /** + Successive samples in the delay line will be interpolated using 1st order + Thiran interpolation. This method is very efficient, and features a flat + amplitude frequency response in exchange for less accuracy in the phase + response. This interpolation method is stateful so is unsuitable for + applications requiring fast delay modulation. + */ + struct Thiran {}; +} + +//============================================================================== +/** + A delay line processor featuring several algorithms for the fractional delay + calculation, block processing, and sample-by-sample processing useful when + modulating the delay in real time or creating a standard delay effect with + feedback. + + Note: If you intend to change the delay in real time, you may want to smooth + changes to the delay systematically using either a ramp or a low-pass filter. + + @see SmoothedValue, FirstOrderTPTFilter + + @tags{DSP} +*/ +template +class DelayLine +{ +public: + //============================================================================== + /** Default constructor. */ + DelayLine(); + + /** Constructor. */ + explicit DelayLine (int maximumDelayInSamples); + + //============================================================================== + /** Sets the delay in samples. */ + void setDelay (SampleType newDelayInSamples); + + /** Returns the current delay in samples. */ + SampleType getDelay() const; + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Pushes a single sample into one channel of the delay line. + + Use this function and popSample instead of process if you need to modulate + the delay in real time instead of using a fixed delay value, or if you want + to code a delay effect with a feedback loop. + + @see setDelay, popSample, process + */ + void pushSample (int channel, SampleType sample); + + /** Pops a single sample from one channel of the delay line. + + Use this function to modulate the delay in real time or implement standard + delay effects with feedback. + + @param channel the target channel for the delay line. + + @param delayInSamples sets the wanted fractional delay in samples, or -1 + to use the value being used before or set with + setDelay function. + + @param updateReadPointer should be set to true if you use the function + once for each sample, or false if you need + multi-tap delay capabilities. + + @see setDelay, pushSample, process + */ + SampleType popSample (int channel, SampleType delayInSamples = -1, bool updateReadPointer = true); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. + + Can be used for block processing when the delay is not going to change + during processing. The delay must first be set by calling setDelay. + + @see setDelay + */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumChannels() == writePos.size()); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock.getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + { + pushSample ((int) channel, inputSamples[i]); + outputSamples[i] = popSample ((int) channel); + } + } + } + +private: + //============================================================================== + template + typename std::enable_if ::value, SampleType>::type + interpolateSample (int channel) const + { + auto index = (readPos[(size_t) channel] + delayInt) % totalSize; + return bufferData.getSample (channel, index); + } + + template + typename std::enable_if ::value, SampleType>::type + interpolateSample (int channel) const + { + auto index1 = readPos[(size_t) channel] + delayInt; + auto index2 = index1 + 1; + + if (index2 >= totalSize) + { + index1 %= totalSize; + index2 %= totalSize; + } + + auto value1 = bufferData.getSample (channel, index1); + auto value2 = bufferData.getSample (channel, index2); + + return value1 + delayFrac * (value2 - value1); + } + + template + typename std::enable_if ::value, SampleType>::type + interpolateSample (int channel) const + { + auto index1 = readPos[(size_t) channel] + delayInt; + auto index2 = index1 + 1; + auto index3 = index2 + 1; + auto index4 = index3 + 1; + + if (index4 >= totalSize) + { + index1 %= totalSize; + index2 %= totalSize; + index3 %= totalSize; + index4 %= totalSize; + } + + auto* samples = bufferData.getReadPointer (channel); + + auto value1 = samples[index1]; + auto value2 = samples[index2]; + auto value3 = samples[index3]; + auto value4 = samples[index4]; + + auto d1 = delayFrac - 1.f; + auto d2 = delayFrac - 2.f; + auto d3 = delayFrac - 3.f; + + auto c1 = -d1 * d2 * d3 / 6.f; + auto c2 = d2 * d3 * 0.5f; + auto c3 = -d1 * d3 * 0.5f; + auto c4 = d1 * d2 / 6.f; + + return value1 * c1 + delayFrac * (value2 * c2 + value3 * c3 + value4 * c4); + } + + template + typename std::enable_if ::value, SampleType>::type + interpolateSample (int channel) + { + auto index1 = readPos[(size_t) channel] + delayInt; + auto index2 = index1 + 1; + + if (index2 >= totalSize) + { + index1 %= totalSize; + index2 %= totalSize; + } + + auto value1 = bufferData.getSample (channel, index1); + auto value2 = bufferData.getSample (channel, index2); + + auto output = delayFrac == 0 ? value1 : value2 + alpha * (value1 - v[(size_t) channel]); + v[(size_t) channel] = output; + + return output; + } + + //============================================================================== + template + typename std::enable_if ::value, void>::type + updateInternalVariables() + { + } + + template + typename std::enable_if ::value, void>::type + updateInternalVariables() + { + } + + template + typename std::enable_if ::value, void>::type + updateInternalVariables() + { + if (delayInt >= 1) + { + delayFrac++; + delayInt--; + } + } + + template + typename std::enable_if ::value, void>::type + updateInternalVariables() + { + if (delayFrac < (SampleType) 0.618 && delayInt >= 1) + { + delayFrac++; + delayInt--; + } + + alpha = (1 - delayFrac) / (1 + delayFrac); + } + + //============================================================================== + double sampleRate; + + //============================================================================== + AudioBuffer bufferData; + std::vector v; + std::vector writePos, readPos; + SampleType delay = 0.0, delayFrac = 0.0; + int delayInt = 0, totalSize = 4; + SampleType alpha = 0.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_DryWetMixer.cpp b/modules/juce_dsp/processors/juce_DryWetMixer.cpp new file mode 100644 index 0000000000..450400b8ad --- /dev/null +++ b/modules/juce_dsp/processors/juce_DryWetMixer.cpp @@ -0,0 +1,172 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +DryWetMixer::DryWetMixer() + : DryWetMixer (0) +{ +} + +template +DryWetMixer::DryWetMixer (int maximumWetLatencyInSamples) + : dryDelayLine (maximumWetLatencyInSamples) +{ + dryDelayLine.setDelay (0); + + update(); + reset(); +} + +//============================================================================== +template +void DryWetMixer::setMixingRule (MixingRule newRule) +{ + currentMixingRule = newRule; + update(); +} + +template +void DryWetMixer::setWetMixProportion (SampleType newWetMixProportion) +{ + jassert (isPositiveAndNotGreaterThan (newWetMixProportion, 1.0)); + + mix = jlimit (static_cast (0.0), static_cast (1.0), newWetMixProportion); + update(); +} + +template +void DryWetMixer::setWetLatency (SampleType wetLatencySamples) +{ + dryDelayLine.setDelay (wetLatencySamples); +} + +//============================================================================== +template +void DryWetMixer::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + dryDelayLine.prepare (spec); + bufferDry.setSize ((int) spec.numChannels, (int) spec.maximumBlockSize, false, false, true); + + update(); + reset(); +} + +template +void DryWetMixer::reset() +{ + dryVolume.reset (sampleRate, 0.05); + wetVolume.reset (sampleRate, 0.05); + + dryDelayLine.reset(); +} + +//============================================================================== +template +void DryWetMixer::pushDrySamples (const AudioBlock drySamples) +{ + jassert (drySamples.getNumChannels() <= (size_t) bufferDry.getNumChannels()); + + auto dryBlock = AudioBlock (bufferDry); + dryBlock = dryBlock.getSubsetChannelBlock (0, drySamples.getNumChannels()).getSubBlock (0, drySamples.getNumSamples()); + + auto context = ProcessContextNonReplacing(drySamples, dryBlock); + dryDelayLine.process (context); +} + +template +void DryWetMixer::mixWetSamples (AudioBlock inOutBlock) +{ + auto dryBlock = AudioBlock (bufferDry); + dryBlock = dryBlock.getSubsetChannelBlock (0, inOutBlock.getNumChannels()).getSubBlock (0, inOutBlock.getNumSamples()); + + dryBlock.multiplyBy (dryVolume); + inOutBlock.multiplyBy (wetVolume); + + inOutBlock.add (dryBlock); +} + +//============================================================================== +template +void DryWetMixer::update() +{ + SampleType dryValue, wetValue; + + switch (currentMixingRule) + { + case MixingRule::balanced: + dryValue = static_cast (2.0) * jmin (static_cast (0.5), static_cast (1.0) - mix); + wetValue = static_cast (2.0) * jmin (static_cast (0.5), mix); + break; + + case MixingRule::linear: + dryValue = static_cast (1.0) - mix; + wetValue = mix; + break; + + case MixingRule::sin3dB: + dryValue = static_cast (std::sin (0.5 * MathConstants::pi * (1.0 - mix))); + wetValue = static_cast (std::sin (0.5 * MathConstants::pi * mix)); + break; + + case MixingRule::sin4p5dB: + dryValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * (1.0 - mix)), 1.5)); + wetValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * mix), 1.5)); + break; + + case MixingRule::sin6dB: + dryValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * (1.0 - mix)), 2.0)); + wetValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * mix), 2.0)); + break; + + case MixingRule::squareRoot3dB: + dryValue = std::sqrt (static_cast (1.0) - mix); + wetValue = std::sqrt (mix); + break; + + case MixingRule::squareRoot4p5dB: + dryValue = static_cast (std::pow (std::sqrt (1.0 - mix), 1.5)); + wetValue = static_cast (std::pow (std::sqrt (mix), 1.5)); + break; + + default: + dryValue = jmin (static_cast (0.5), static_cast (1.0) - mix); + wetValue = jmin (static_cast (0.5), mix); + break; + } + + dryVolume.setTargetValue (dryValue); + wetVolume.setTargetValue (wetValue); +} + +//============================================================================== +template class DryWetMixer; +template class DryWetMixer; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_DryWetMixer.h b/modules/juce_dsp/processors/juce_DryWetMixer.h new file mode 100644 index 0000000000..11b4998518 --- /dev/null +++ b/modules/juce_dsp/processors/juce_DryWetMixer.h @@ -0,0 +1,110 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class DryWetMixingRule +{ + linear, + balanced, + sin3dB, + sin4p5dB, + sin6dB, + squareRoot3dB, + squareRoot4p5dB +}; + +/** + A processor to handle dry/wet mixing of two audio signals, where the wet signal + may have additional latency. + + Once a DryWetMixer object is configured, push the dry samples using pushDrySamples + and mix into the fully wet samples using mixWetSamples. + + @tags{DSP} +*/ +template +class DryWetMixer +{ +public: + //============================================================================== + using MixingRule = DryWetMixingRule; + + //============================================================================== + /** Default constructor. */ + DryWetMixer(); + + /** Constructor. */ + explicit DryWetMixer (int maximumWetLatencyInSamples); + + //============================================================================== + /** Sets the mix rule. */ + void setMixingRule (MixingRule newRule); + + /** Sets the current dry/wet mix proportion, with 0.0 being full dry and 1.0 + being fully wet. + */ + void setWetMixProportion (SampleType newWetMixProportion); + + /** Sets the relative latency of the wet signal path compared to the dry signal + path, and thus the amount of latency compensation that will be added to the + dry samples in this processor. + */ + void setWetLatency (SampleType wetLatencyInSamples); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Copies the dry path samples into an internal delay line. */ + void pushDrySamples (const AudioBlock drySamples); + + /** Mixes the supplied wet samples with the latency-compensated dry samples from + pushDrySamples. + + @param wetSamples Input: The AudioBlock references fully wet samples. + Output: The AudioBlock references the wet samples mixed + with the latency compensated dry samples. + + @see pushDrySamples + */ + void mixWetSamples (AudioBlock wetSamples); + +private: + //============================================================================== + void update(); + + //============================================================================== + SmoothedValue dryVolume, wetVolume; + DelayLine dryDelayLine; + AudioBuffer bufferDry; + + SampleType mix = 1.0; + MixingRule currentMixingRule = MixingRule::linear; + double sampleRate = 44100.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp b/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp new file mode 100644 index 0000000000..812a9cdf8c --- /dev/null +++ b/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp @@ -0,0 +1,114 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +FirstOrderTPTFilter::FirstOrderTPTFilter() +{ + update(); +} + +//============================================================================== +template +void FirstOrderTPTFilter::setType (Type newValue) +{ + filterType = newValue; +} + +template +void FirstOrderTPTFilter::setCutoffFrequency (SampleType newValue) +{ + jassert (isPositiveAndBelow (newValue, static_cast (sampleRate * 0.5))); + + cutoffFrequency = newValue; + update(); +} + +//============================================================================== +template +void FirstOrderTPTFilter::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + s1.resize (spec.numChannels); + + reset(); +} + +template +void FirstOrderTPTFilter::reset() +{ + reset (static_cast (0)); +} + +template +void FirstOrderTPTFilter::reset (SampleType newValue) +{ + std::fill (s1.begin(), s1.end(), newValue); +} + +//============================================================================== +template +SampleType FirstOrderTPTFilter::processSample (int channel, SampleType inputValue) +{ + auto& s = s1[(size_t) channel]; + + auto v = G * (inputValue - s); + auto y = v + s; + s = y + v; + + switch (filterType) + { + case Type::lowpass: return y; + case Type::highpass: return inputValue - y; + case Type::allpass: return 2 * y - inputValue; + default: break; + } + + jassertfalse; + return y; +} + +template +void FirstOrderTPTFilter::snapToZero() noexcept +{ + for (auto& s : s1) + util::snapToZero (s); +} + +//============================================================================== +template +void FirstOrderTPTFilter::update() +{ + auto g = SampleType (std::tan (juce::MathConstants::pi * cutoffFrequency / sampleRate)); + G = g / (1 + g); +} + +//============================================================================== +template class FirstOrderTPTFilter; +template class FirstOrderTPTFilter; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h b/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h new file mode 100644 index 0000000000..b2d884d696 --- /dev/null +++ b/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h @@ -0,0 +1,144 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class FirstOrderTPTFilterType +{ + lowpass, + highpass, + allpass +}; + +//============================================================================== +/** + A first order filter class using the TPT (Topology-Preserving Transform) structure. + + This filter can be modulated at high rates without producing audio artefacts. See + Vadim Zavalishin's documentation about TPT structures for more information. + + Note: Using this class prevents some loud audio artefacts commonly encountered when + changing the cutoff frequency using of other filter simulation structures and IIR + filter classes. However, this class may still require additional smoothing for + cutoff frequency changes. + + see StateVariableFilter, IIRFilter, SmoothedValue + + @tags{DSP} +*/ +template +class FirstOrderTPTFilter +{ +public: + //============================================================================== + using Type = FirstOrderTPTFilterType; + + //============================================================================== + /** Constructor. */ + FirstOrderTPTFilter(); + + //============================================================================== + /** Sets the filter type. */ + void setType (Type newType); + + /** Sets the cutoff frequency of the filter. + + @param newFrequencyHz cutoff frequency in Hz. + */ + void setCutoffFrequency (SampleType newFrequencyHz); + + //============================================================================== + /** Returns the type of the filter. */ + Type getType() const noexcept { return filterType; } + + /** Returns the cutoff frequency of the filter. */ + SampleType getCutoffFrequency() const noexcept { return cutoffFrequency; } + + //============================================================================== + /** Initialises the filter. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the filter. */ + void reset(); + + /** Resets the internal state variables of the filter to a given value. */ + void reset (SampleType newValue); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() <= s1.size()); + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + + #if JUCE_SNAP_TO_ZERO + snapToZero(); + #endif + } + + //============================================================================== + /** Processes one sample at a time on a given channel. */ + SampleType processSample (int channel, SampleType inputValue); + + /** Ensure that the state variables are rounded to zero if the state + variables are denormals. This is only needed if you are doing + sample by sample processing. + */ + void snapToZero() noexcept; + +private: + //============================================================================== + void update(); + + //============================================================================== + SampleType G = 0; + std::vector s1 { 2 }; + double sampleRate = 44100.0; + + //============================================================================== + Type filterType = Type::lowpass; + SampleType cutoffFrequency = 1000.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_IIRFilter.h b/modules/juce_dsp/processors/juce_IIRFilter.h index 7acb921c64..f295590b02 100644 --- a/modules/juce_dsp/processors/juce_IIRFilter.h +++ b/modules/juce_dsp/processors/juce_IIRFilter.h @@ -86,7 +86,7 @@ namespace IIR Note that this clears the processing state, but the type of filter and its coefficients aren't changed. */ - void reset() { reset (SampleType {0}); } + void reset() { reset (SampleType {0}); } /** Resets the filter's processing pipeline to a specific value. @see reset @@ -105,6 +105,10 @@ namespace IIR processInternal (context); else processInternal (context); + + #if JUCE_SNAP_TO_ZERO + snapToZero(); + #endif } /** Processes a single sample, without any locking. diff --git a/modules/juce_dsp/processors/juce_LadderFilter.cpp b/modules/juce_dsp/processors/juce_LadderFilter.cpp deleted file mode 100644 index 55d7b983c6..0000000000 --- a/modules/juce_dsp/processors/juce_LadderFilter.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE 6 technical preview. - Copyright (c) 2020 - Raw Material Software Limited - - You may use this code under the terms of the GPL v3 - (see www.gnu.org/licenses). - - For this technical preview, this file is not subject to commercial licensing. - - JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER - EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE - DISCLAIMED. - - ============================================================================== -*/ - -namespace juce -{ -namespace dsp -{ - -//============================================================================== -template -LadderFilter::LadderFilter() : state (2) -{ - setSampleRate (Type (1000)); // intentionally setting unrealistic default - // sample rate to catch missing initialisation bugs - setResonance (Type (0)); - setDrive (Type (1.2)); - setMode (Mode::LPF12); -} - -//============================================================================== -template -void LadderFilter::setMode (Mode newValue) noexcept -{ - switch (newValue) - { - case Mode::LPF12: A = {{ Type (0), Type (0), Type (1), Type (0), Type (0) }}; comp = Type (0.5); break; - case Mode::HPF12: A = {{ Type (1), Type (-2), Type (1), Type (0), Type (0) }}; comp = Type (0); break; - case Mode::LPF24: A = {{ Type (0), Type (0), Type (0), Type (0), Type (1) }}; comp = Type (0.5); break; - case Mode::HPF24: A = {{ Type (1), Type (-4), Type (6), Type (-4), Type (1) }}; comp = Type (0); break; - default: jassertfalse; break; - } - - static constexpr auto outputGain = Type (1.2); - - for (auto& a : A) - a *= outputGain; - - mode = newValue; - reset(); -} - -//============================================================================== -template -void LadderFilter::prepare (const juce::dsp::ProcessSpec& spec) -{ - setSampleRate (Type (spec.sampleRate)); - setNumChannels (spec.numChannels); - reset(); -} - -//============================================================================== -template -void LadderFilter::reset() noexcept -{ - for (auto& s : state) - s.fill (Type (0)); - - cutoffTransformSmoother.setCurrentAndTargetValue (cutoffTransformSmoother.getTargetValue()); - scaledResonanceSmoother.setCurrentAndTargetValue (scaledResonanceSmoother.getTargetValue()); -} - -//============================================================================== -template -void LadderFilter::setCutoffFrequencyHz (Type newValue) noexcept -{ - jassert (newValue > Type (0)); - cutoffFreqHz = newValue; - updateCutoffFreq(); -} - -//============================================================================== -template -void LadderFilter::setResonance (Type newValue) noexcept -{ - jassert (newValue >= Type (0) && newValue <= Type (1)); - resonance = newValue; - updateResonance(); -} - -//============================================================================== -template -void LadderFilter::setDrive (Type newValue) noexcept -{ - jassert (newValue >= Type (1)); - - drive = newValue; - gain = std::pow (drive, Type (-2.642)) * Type (0.6103) + Type (0.3903); - drive2 = drive * Type (0.04) + Type (0.96); - gain2 = std::pow (drive2, Type (-2.642)) * Type (0.6103) + Type (0.3903); -} - -//============================================================================== -template -Type LadderFilter::processSample (Type inputValue, size_t channelToUse) noexcept -{ - auto& s = state[channelToUse]; - - const auto a1 = cutoffTransformValue; - const auto g = a1 * Type (-1) + Type (1); - const auto b0 = g * Type (0.76923076923); - const auto b1 = g * Type (0.23076923076); - - const auto dx = gain * saturationLUT (drive * inputValue); - const auto a = dx + scaledResonanceValue * Type (-4) * (gain2 * saturationLUT (drive2 * s[4]) - dx * comp); - - const auto b = b1 * s[0] + a1 * s[1] + b0 * a; - const auto c = b1 * s[1] + a1 * s[2] + b0 * b; - const auto d = b1 * s[2] + a1 * s[3] + b0 * c; - const auto e = b1 * s[3] + a1 * s[4] + b0 * d; - - s[0] = a; - s[1] = b; - s[2] = c; - s[3] = d; - s[4] = e; - - return a * A[0] + b * A[1] + c * A[2] + d * A[3] + e * A[4]; -} - -//============================================================================== -template -void LadderFilter::updateSmoothers() noexcept -{ - cutoffTransformValue = cutoffTransformSmoother.getNextValue(); - scaledResonanceValue = scaledResonanceSmoother.getNextValue(); -} - -//============================================================================== -template -void LadderFilter::setSampleRate (Type newValue) noexcept -{ - jassert (newValue > Type (0)); - cutoffFreqScaler = Type (-2.0 * juce::MathConstants::pi) / newValue; - - static constexpr Type smootherRampTimeSec = Type (0.05); - cutoffTransformSmoother.reset (newValue, smootherRampTimeSec); - scaledResonanceSmoother.reset (newValue, smootherRampTimeSec); - - updateCutoffFreq(); -} - -//============================================================================== -template class LadderFilter; -template class LadderFilter; - -} // namespace dsp -} // namespace juce diff --git a/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp b/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp new file mode 100644 index 0000000000..5987445993 --- /dev/null +++ b/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp @@ -0,0 +1,142 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +LinkwitzRileyFilter::LinkwitzRileyFilter() +{ + update(); +} + +//============================================================================== +template +void LinkwitzRileyFilter::setType (Type newType) +{ + filterType = newType; +} + +template +void LinkwitzRileyFilter::setCutoffFrequency (SampleType newCutoffFrequencyHz) +{ + jassert (isPositiveAndBelow (newCutoffFrequencyHz, static_cast (sampleRate * 0.5))); + + cutoffFrequency = newCutoffFrequencyHz; + update(); +} + +//============================================================================== +template +void LinkwitzRileyFilter::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + update(); + + s1.resize (spec.numChannels); + s2.resize (spec.numChannels); + s3.resize (spec.numChannels); + s4.resize (spec.numChannels); + + reset(); +} + +template +void LinkwitzRileyFilter::reset() +{ + for (auto s : { &s1, &s2, &s3, &s4 }) + std::fill (s->begin(), s->end(), static_cast (0)); +} + +template +void LinkwitzRileyFilter::snapToZero() noexcept +{ + for (auto s : { &s1, &s2, &s3, &s4 }) + for (auto& element : *s) + util::snapToZero (element); +} + +//============================================================================== +template +SampleType LinkwitzRileyFilter::processSample (int channel, SampleType inputValue) +{ + auto yH = (inputValue - (R2 + g) * s1[(size_t) channel] - s2[(size_t) channel]) * h; + + auto yB = g * yH + s1[(size_t) channel]; + s1[(size_t) channel] = g * yH + yB; + + auto yL = g * yB + s2[(size_t) channel]; + s2[(size_t) channel] = g * yB + yL; + + if (filterType == Type::allpass) + return yL - R2 * yB + yH; + + auto yH2 = ((filterType == Type::lowpass ? yL : yH) - (R2 + g) * s3[(size_t) channel] - s4[(size_t) channel]) * h; + + auto yB2 = g * yH2 + s3[(size_t) channel]; + s3[(size_t) channel] = g * yH2 + yB2; + + auto yL2 = g * yB2 + s4[(size_t) channel]; + s4[(size_t) channel] = g * yB2 + yL2; + + return filterType == Type::lowpass ? yL2 : yH2; +} + +template +void LinkwitzRileyFilter::processSample (int channel, SampleType inputValue, SampleType &outputLow, SampleType &outputHigh) +{ + auto yH = (inputValue - (R2 + g) * s1[(size_t) channel] - s2[(size_t) channel]) * h; + + auto yB = g * yH + s1[(size_t) channel]; + s1[(size_t) channel] = g * yH + yB; + + auto yL = g * yB + s2[(size_t) channel]; + s2[(size_t) channel] = g * yB + yL; + + auto yH2 = (yL - (R2 + g) * s3[(size_t) channel] - s4[(size_t) channel]) * h; + + auto yB2 = g * yH2 + s3[(size_t) channel]; + s3[(size_t) channel] = g * yH2 + yB2; + + auto yL2 = g * yB2 + s4[(size_t) channel]; + s4[(size_t) channel] = g * yB2 + yL2; + + outputLow = yL2; + outputHigh = yL - R2 * yB + yH - yL2; +} + +template +void LinkwitzRileyFilter::update() +{ + g = (SampleType) std::tan (MathConstants::pi * cutoffFrequency / sampleRate); + R2 = (SampleType) std::sqrt (2.0); + h = (SampleType) (1.0 / (1.0 + R2 * g + g * g)); +} + +//============================================================================== +template class LinkwitzRileyFilter; +template class LinkwitzRileyFilter; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h b/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h new file mode 100644 index 0000000000..b918845fdd --- /dev/null +++ b/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h @@ -0,0 +1,136 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class LinkwitzRileyFilterType +{ + lowpass, + highpass, + allpass +}; + +/** + A filter class designed to perform multi-band separation using the TPT + (Topology-Preserving Transform) structure. + + Linkwitz-Riley filters are widely used in audio crossovers that have two outputs, + a low-pass and a high-pass, such that their sum is equivalent to an all-pass filter + with a flat magnitude frequency response. The Linkwitz-Riley filters available in + this class are designed to have a -24 dB/octave slope (LR 4th order). + + @tags{DSP} +*/ +template +class LinkwitzRileyFilter +{ +public: + //============================================================================== + using Type = LinkwitzRileyFilterType; + + //============================================================================== + /** Constructor. */ + LinkwitzRileyFilter(); + + //============================================================================== + /** Sets the filter type. */ + void setType (Type newType); + + /** Sets the cutoff frequency of the filter in Hz. */ + void setCutoffFrequency (SampleType newCutoffFrequencyHz); + + //============================================================================== + /** Returns the type of the filter. */ + Type getType() const noexcept { return filterType; } + + /** Returns the cutoff frequency of the filter. */ + SampleType getCutoffFrequency() const noexcept { return cutoffFrequency; } + + //============================================================================== + /** Initialises the filter. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the filter. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() <= s1.size()); + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock.getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + + #if JUCE_SNAP_TO_ZERO + snapToZero(); + #endif + } + + /** Performs the filter operation on a single sample at a time. */ + SampleType processSample (int channel, SampleType inputValue); + + /** Performs the filter operation on a single sample at a time, and returns both + the low-pass and the high-pass outputs of the TPT structure. + */ + void processSample (int channel, SampleType inputValue, SampleType &outputLow, SampleType &outputHigh); + + /** Ensure that the state variables are rounded to zero if the state + variables are denormals. This is only needed if you are doing + sample by sample processing. + */ + void snapToZero() noexcept; + +private: + //============================================================================== + void update(); + + //============================================================================== + SampleType g, R2, h; + std::vector s1, s2, s3, s4; + + double sampleRate = 44100.0; + SampleType cutoffFrequency = 2000.0; + Type filterType = Type::lowpass; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Oversampling.cpp b/modules/juce_dsp/processors/juce_Oversampling.cpp index ebf3ebe134..f3fc9912dd 100644 --- a/modules/juce_dsp/processors/juce_Oversampling.cpp +++ b/modules/juce_dsp/processors/juce_Oversampling.cpp @@ -356,8 +356,9 @@ struct Oversampling2TimesPolyphaseIIR : public Oversampling::Oversa } } - // Snap To Zero + #if JUCE_SNAP_TO_ZERO snapToZero (true); + #endif } void processSamplesDown (AudioBlock& outputBlock) override @@ -414,8 +415,9 @@ struct Oversampling2TimesPolyphaseIIR : public Oversampling::Oversa delayDown.setUnchecked (static_cast (channel), delay); } - // Snap To Zero + #if JUCE_SNAP_TO_ZERO snapToZero (false); + #endif } void snapToZero (bool snapUpProcessing) @@ -498,10 +500,10 @@ private: coeffs.coefficients.clear(); auto inversion = one / denominator[0]; - for (auto i = 0; i <= numerator.getOrder(); ++i) + for (int i = 0; i <= numerator.getOrder(); ++i) coeffs.coefficients.add (numerator[i] * inversion); - for (auto i = 1; i <= denominator.getOrder(); ++i) + for (int i = 1; i <= denominator.getOrder(); ++i) coeffs.coefficients.add (denominator[i] * inversion); return coeffs; @@ -531,8 +533,9 @@ Oversampling::Oversampling (size_t newNumChannels) template Oversampling::Oversampling (size_t newNumChannels, size_t newFactor, - FilterType newType, bool isMaximumQuality) - : numChannels (newNumChannels) + FilterType newType, bool isMaximumQuality, + bool useIntegerLatency) + : numChannels (newNumChannels), shouldUseIntegerLatency (useIntegerLatency) { jassert (isPositiveAndBelow (newFactor, 5) && numChannels > 0); @@ -620,8 +623,21 @@ void Oversampling::clearOversamplingStages() } //============================================================================== +template +void Oversampling::setUsingIntegerLatency (bool useIntegerLatency) noexcept +{ + shouldUseIntegerLatency = useIntegerLatency; +} + template SampleType Oversampling::getLatencyInSamples() const noexcept +{ + auto latency = getUncompensatedLatency(); + return shouldUseIntegerLatency ? latency + fractionalDelay : latency; +} + +template +SampleType Oversampling::getUncompensatedLatency() const noexcept { auto latency = static_cast (0); size_t order = 1; @@ -654,6 +670,10 @@ void Oversampling::initProcessing (size_t maximumNumberOfSamplesBefo currentNumSamples *= stage->factor; } + ProcessSpec spec = { 0.0, (uint32) maximumNumberOfSamplesBeforeOversampling, (uint32) numChannels }; + delay.prepare (spec); + updateDelayLine(); + isReady = true; reset(); } @@ -666,6 +686,8 @@ void Oversampling::reset() noexcept if (isReady) for (auto* stage : stages) stage->reset(); + + delay.reset(); } template @@ -712,6 +734,26 @@ void Oversampling::processSamplesDown (AudioBlock& outpu } stages.getFirst()->processSamplesDown (outputBlock); + + if (shouldUseIntegerLatency && fractionalDelay > static_cast (0.0)) + { + auto context = ProcessContextReplacing (outputBlock); + delay.process (context); + } +} + +template +void Oversampling::updateDelayLine() +{ + auto latency = getUncompensatedLatency(); + fractionalDelay = static_cast (1.0) - (latency - std::floor (latency)); + + if (fractionalDelay == static_cast (1.0)) + fractionalDelay = static_cast (0.0); + else if (fractionalDelay < static_cast (0.618)) + fractionalDelay += static_cast (1.0); + + delay.setDelay (fractionalDelay); } template class Oversampling; diff --git a/modules/juce_dsp/processors/juce_Oversampling.h b/modules/juce_dsp/processors/juce_Oversampling.h index b1eb1f4315..d673916f78 100644 --- a/modules/juce_dsp/processors/juce_Oversampling.h +++ b/modules/juce_dsp/processors/juce_Oversampling.h @@ -21,24 +21,23 @@ namespace juce namespace dsp { -//============================================================================== +//=============================================================================== /** - A processing class performing multi-channel oversampling. + A processor that performs multi-channel oversampling. - It can be configured to do 2 times, 4 times, 8 times or 16 times oversampling - using a multi-stage approach, either polyphase allpass IIR filters or FIR - filters for the filtering, and reports successfully the latency added by the - filter stages. + This class can be configured to do a factor of 2, 4, 8 or 16 times + oversampling, using multiple stages, with polyphase allpass IIR filters or FIR + filters, and latency compensation. The principle of oversampling is to increase the sample rate of a given - non-linear process, to prevent it from creating aliasing. Oversampling works - by upsampling N times the input signal, processing the upsampled signal - with the increased internal sample rate, and downsampling the result to get - back the original processing sample rate. - - Choose between FIR or IIR filtering depending on your needs in term of - latency and phase distortion. With FIR filters, the phase is linear but the - latency is maximised. With IIR filtering, the phase is compromised around the + non-linear process to prevent it from creating aliasing. Oversampling works + by upsampling the input signal N times, processing the upsampled signal + with the increased internal sample rate, then downsampling the result to get + back to the original sample rate. + + Choose between FIR or IIR filtering depending on your needs in terms of + latency and phase distortion. With FIR filters the phase is linear but the + latency is maximised. With IIR filtering the phase is compromised around the Nyquist frequency but the latency is minimised. @see FilterDesign. @@ -57,52 +56,62 @@ public: numFilterTypes }; - //============================================================================== - /** - Constructor of the oversampling class. All the processing parameters must be - provided at the creation of the oversampling object. - - @param numChannels the number of channels to process with this object - @param factor the processing will perform 2 ^ factor times oversampling - @param type the type of filter design employed for filtering during - oversampling - @param isMaxQuality if the oversampling is done using the maximum quality, - the filters will be more efficient, but the CPU load will - increase as well - */ - Oversampling (size_t numChannels, - size_t factor, - FilterType type, - bool isMaxQuality = true); + //=============================================================================== + /** The default constructor. - /** The default constructor of the oversampling class, which can be used to create an - empty object and then add the appropriate stages. - - Note: This creates a "dummy" oversampling stage, which needs to be removed first + Note: This creates a "dummy" oversampling stage, which needs to be removed before adding proper oversampling stages. + @param numChannels the number of channels to process with this object + @see clearOversamplingStages, addOversamplingStage */ explicit Oversampling (size_t numChannels = 1); + /** Constructor. + + @param numChannels the number of channels to process with this object + @param factor the processing will perform 2 ^ factor times oversampling + @param type the type of filter design employed for filtering during + oversampling + @param isMaxQuality if the oversampling is done using the maximum quality, where + the filters will be more efficient but the CPU load will + increase as well + @param useIntegerLatency if true this processor will add some fractional delay at the + end of the signal path to ensure that the overall latency of + the oversampling is an integer + */ + Oversampling (size_t numChannels, + size_t factor, + FilterType type, + bool isMaxQuality = true, + bool useIntegerLatency = false); + /** Destructor. */ ~Oversampling(); - //============================================================================== - /** Returns the latency in samples of the whole processing. Use this information - in your main processor to compensate the additional latency involved with - the oversampling, for example with a dry / wet functionality, and to report - the latency to the DAW. + //=============================================================================== + /* Sets if this processor should add some fractional delay at the end of the signal + path to ensure that the overall latency of the oversampling is an integer. + */ + void setUsingIntegerLatency (bool shouldUseIntegerLatency) noexcept; + + /** Returns the latency in samples of the overall processing. You can use this + information in your main processor to compensate the additional latency + involved with the oversampling, for example with a dry / wet mixer, and to + report the latency to the DAW. - Note: The latency might not be integer, so you might need to round its value - or to compensate it properly in your processing code. + Note: If you have not opted to use an integer latency then the latency may not be + integer, so you might need to round its value or to compensate it properly in + your processing code since plug-ins can only report integer latency values in + samples to the DAW. */ SampleType getLatencyInSamples() const noexcept; /** Returns the current oversampling factor. */ size_t getOversamplingFactor() const noexcept; - //============================================================================== + //=============================================================================== /** Must be called before any processing, to set the buffer sizes of the internal buffers of the oversampling processing. */ @@ -127,7 +136,7 @@ public: */ void processSamplesDown (AudioBlock& outputBlock) noexcept; - //============================================================================== + //=============================================================================== /** Adds a new oversampling stage to the Oversampling class, multiplying the current oversampling factor by two. This is used with the default constructor to create custom oversampling chains, requiring a call to the @@ -171,7 +180,7 @@ public: */ void clearOversamplingStages(); - //============================================================================== + //=============================================================================== size_t factorOversampling = 1; size_t numChannels = 1; @@ -180,11 +189,17 @@ public: #endif private: - //============================================================================== + //=============================================================================== + void updateDelayLine(); + SampleType getUncompensatedLatency() const noexcept; + + //=============================================================================== OwnedArray stages; - bool isReady = false; + bool isReady = false, shouldUseIntegerLatency = false; + DelayLine delay { 8 }; + SampleType fractionalDelay = 0; - //============================================================================== + //=============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oversampling) }; diff --git a/modules/juce_dsp/processors/juce_Panner.cpp b/modules/juce_dsp/processors/juce_Panner.cpp new file mode 100644 index 0000000000..1986a5b5b7 --- /dev/null +++ b/modules/juce_dsp/processors/juce_Panner.cpp @@ -0,0 +1,136 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +Panner::Panner() +{ + update(); + reset(); +} + +//============================================================================== +template +void Panner::setRule (Rule newRule) +{ + currentRule = newRule; + update(); +} + +template +void Panner::setPan (SampleType newPan) +{ + jassert (newPan >= -1.0 && newPan <= 1.0); + + pan = jlimit (static_cast (-1.0), static_cast (1.0), newPan); + update(); +} + +//============================================================================== +template +void Panner::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + reset(); +} + +template +void Panner::reset() +{ + leftVolume .reset (sampleRate, 0.05); + rightVolume.reset (sampleRate, 0.05); +} + +//============================================================================== +template +void Panner::update() +{ + SampleType leftValue, rightValue, boostValue; + + auto normalisedPan = static_cast (0.5) * (pan + static_cast (1.0)); + + switch (currentRule) + { + case Rule::balanced: + leftValue = jmin (static_cast (0.5), static_cast (1.0) - normalisedPan); + rightValue = jmin (static_cast (0.5), normalisedPan); + boostValue = static_cast (2.0); + break; + + case Rule::linear: + leftValue = static_cast (1.0) - normalisedPan; + rightValue = normalisedPan; + boostValue = static_cast (2.0); + break; + + case Rule::sin3dB: + leftValue = static_cast (std::sin (0.5 * MathConstants::pi * (1.0 - normalisedPan))); + rightValue = static_cast (std::sin (0.5 * MathConstants::pi * normalisedPan)); + boostValue = std::sqrt (static_cast (2.0)); + break; + + case Rule::sin4p5dB: + leftValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * (1.0 - normalisedPan)), 1.5)); + rightValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * normalisedPan), 1.5)); + boostValue = static_cast (std::pow (2.0, 3.0 / 4.0)); + break; + + case Rule::sin6dB: + leftValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * (1.0 - normalisedPan)), 2.0)); + rightValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * normalisedPan), 2.0)); + boostValue = static_cast (2.0); + break; + + case Rule::squareRoot3dB: + leftValue = std::sqrt (static_cast (1.0) - normalisedPan); + rightValue = std::sqrt (normalisedPan); + boostValue = std::sqrt (static_cast (2.0)); + break; + + case Rule::squareRoot4p5dB: + leftValue = static_cast (std::pow (std::sqrt (1.0 - normalisedPan), 1.5)); + rightValue = static_cast (std::pow (std::sqrt (normalisedPan), 1.5)); + boostValue = static_cast (std::pow (2.0, 3.0 / 4.0)); + break; + + default: + leftValue = jmin (static_cast (0.5), static_cast (1.0) - normalisedPan); + rightValue = jmin (static_cast (0.5), normalisedPan); + boostValue = static_cast (2.0); + break; + } + + leftVolume .setTargetValue (leftValue * boostValue); + rightVolume.setTargetValue (rightValue * boostValue); +} + +//============================================================================== +template class Panner; +template class Panner; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Panner.h b/modules/juce_dsp/processors/juce_Panner.h new file mode 100644 index 0000000000..7991051409 --- /dev/null +++ b/modules/juce_dsp/processors/juce_Panner.h @@ -0,0 +1,112 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class PannerRule +{ + linear, + balanced, + sin3dB, + sin4p5dB, + sin6dB, + squareRoot3dB, + squareRoot4p5dB +}; + +/** + A processor to perform panning operations on stereo buffers. + + @tags{DSP} +*/ +template +class Panner +{ +public: + //============================================================================== + using Rule = PannerRule; + + //============================================================================== + /** Constructor. */ + Panner(); + + //============================================================================== + /** Sets the panning rule. */ + void setRule (Rule newRule); + + /** Sets the current panning value, between -1 (full left) and 1 (full right). */ + void setPan (SampleType newPan); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + + const auto numInputChannels = inputBlock.getNumChannels(); + const auto numOutputChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumSamples() == numSamples); + ignoreUnused (numSamples); + + if (numOutputChannels != 2 || numInputChannels == 0 || numInputChannels > 2) + return; + + if (numInputChannels == 2) + { + outputBlock.copyFrom (inputBlock); + } + else + { + outputBlock.getSingleChannelBlock (0).copyFrom (inputBlock); + outputBlock.getSingleChannelBlock (1).copyFrom (inputBlock); + } + + if (context.isBypassed) + return; + + outputBlock.getSingleChannelBlock (0).multiplyBy (leftVolume); + outputBlock.getSingleChannelBlock (1).multiplyBy (rightVolume); + } + +private: + //============================================================================== + void update(); + + //============================================================================== + Rule currentRule = Rule::balanced; + SampleType pan = 0.0; + SmoothedValue leftVolume, rightVolume; + double sampleRate = 44100.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_StateVariableFilter.h b/modules/juce_dsp/processors/juce_StateVariableFilter.h index 8638f27af9..dc43c65b94 100644 --- a/modules/juce_dsp/processors/juce_StateVariableFilter.h +++ b/modules/juce_dsp/processors/juce_StateVariableFilter.h @@ -31,14 +31,21 @@ namespace StateVariableFilter /** An IIR filter that can perform low, band and high-pass filtering on an audio - signal, with 12 dB of attenuation / octave, using a TPT structure, designed + signal, with 12 dB of attenuation per octave, using a TPT structure, designed for fast modulation (see Vadim Zavalishin's documentation about TPT structures for more information). Its behaviour is based on the analog state variable filter circuit. - Note: The bandpass here is not the one in the RBJ CookBook, its gain can be + Note: The bandpass here is not the one in the RBJ CookBook as its gain can be higher than 0 dB. For the classic 0 dB bandpass, we need to multiply the - result with R2 + result by R2. + + Note 2: Using this class prevents some loud audio artefacts commonly encountered when + changing the cutoff frequency using other filter simulation structures and IIR + filter classes. However, this class may still require additional smoothing for + cutoff frequency changes. + + see IIRFilter, SmoothedValue @tags{DSP} */ @@ -56,10 +63,19 @@ namespace StateVariableFilter using ParametersPtr = typename Parameters::Ptr; //============================================================================== - /** Creates a filter with default parameters. */ - Filter() : parameters (new Parameters) { reset(); } + /** Creates a filter with default parameters. + + The classes in the StateVariableFilter namespace are deprecated. you should + use the equivalent functionality in the StateVariableTPTFilter class. + */ + JUCE_DEPRECATED_WITH_BODY (Filter(), : parameters (new Parameters) { reset(); }) + + /** Creates a filter using some parameters. - Filter (ParametersPtr parametersToUse) : parameters (std::move (parametersToUse)) { reset(); } + The classes in the StateVariableFilter namespace are deprecated. you should + use the equivalent functionality in the StateVariableTPTFilter class. + */ + JUCE_DEPRECATED_WITH_BODY (Filter (ParametersPtr parametersToUse), : parameters (std::move (parametersToUse)) { reset(); }) /** Creates a copy of another filter. */ Filter (const Filter&) = default; @@ -137,7 +153,10 @@ namespace StateVariableFilter for (size_t i = 0 ; i < n; ++i) output[i] = processLoop (input[i], state); + #if JUCE_SNAP_TO_ZERO snapToZero(); + #endif + *parameters = state; } @@ -173,6 +192,13 @@ namespace StateVariableFilter JUCE_LEAK_DETECTOR (Filter) }; + enum class StateVariableFilterType + { + lowPass, + bandPass, + highPass + }; + //============================================================================== /** Structure used for the state variable filter parameters. @@ -183,12 +209,7 @@ namespace StateVariableFilter struct Parameters : public ProcessorState { //============================================================================== - enum class Type - { - lowPass, - bandPass, - highPass - }; + using Type = StateVariableFilterType; //============================================================================== /** The type of the IIR filter */ diff --git a/modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp b/modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp new file mode 100644 index 0000000000..4dc30db241 --- /dev/null +++ b/modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp @@ -0,0 +1,130 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +StateVariableTPTFilter::StateVariableTPTFilter() +{ + update(); +} + +template +void StateVariableTPTFilter::setType (Type newValue) +{ + filterType = newValue; +} + +template +void StateVariableTPTFilter::setCutoffFrequency (SampleType newCutoffFrequencyHz) +{ + jassert (isPositiveAndBelow (newCutoffFrequencyHz, static_cast (sampleRate * 0.5))); + + cutoffFrequency = newCutoffFrequencyHz; + update(); +} + +template +void StateVariableTPTFilter::setResonance (SampleType newResonance) +{ + jassert (newResonance > static_cast (0)); + + resonance = newResonance; + update(); +} + +//============================================================================== +template +void StateVariableTPTFilter::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + s1.resize (spec.numChannels); + s2.resize (spec.numChannels); + + reset(); + update(); +} + +template +void StateVariableTPTFilter::reset() +{ + reset (static_cast (0)); +} + +template +void StateVariableTPTFilter::reset (SampleType newValue) +{ + for (auto v : { &s1, &s2 }) + std::fill (v->begin(), v->end(), newValue); +} + +template +void StateVariableTPTFilter::snapToZero() noexcept +{ + for (auto v : { &s1, &s2 }) + for (auto& element : *v) + util::snapToZero (element); +} + +//============================================================================== +template +SampleType StateVariableTPTFilter::processSample (int channel, SampleType inputValue) +{ + auto& ls1 = s1[(size_t) channel]; + auto& ls2 = s2[(size_t) channel]; + + auto yHP = h * (inputValue - ls1 * (g + R2) - ls2); + + auto yBP = yHP * g + ls1; + ls1 = yHP * g + yBP; + + auto yLP = yBP * g + ls2; + ls2 = yBP * g + yLP; + + switch (filterType) + { + case Type::lowpass: return yLP; + case Type::bandpass: return yBP; + case Type::highpass: return yHP; + default: return yLP; + } +} + +//============================================================================== +template +void StateVariableTPTFilter::update() +{ + g = static_cast (std::tan (juce::MathConstants::pi * cutoffFrequency / sampleRate)); + R2 = static_cast (1.0 / resonance); + h = static_cast (1.0 / (1.0 + R2 * g + g * g)); +} + +//============================================================================== +template class StateVariableTPTFilter; +template class StateVariableTPTFilter; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_StateVariableTPTFilter.h b/modules/juce_dsp/processors/juce_StateVariableTPTFilter.h new file mode 100644 index 0000000000..8594397fc8 --- /dev/null +++ b/modules/juce_dsp/processors/juce_StateVariableTPTFilter.h @@ -0,0 +1,159 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class StateVariableTPTFilterType +{ + lowpass, + bandpass, + highpass +}; + +//============================================================================== +/** An IIR filter that can perform low, band and high-pass filtering on an audio + signal, with 12 dB of attenuation per octave, using a TPT structure, designed + for fast modulation (see Vadim Zavalishin's documentation about TPT + structures for more information). Its behaviour is based on the analog + state variable filter circuit. + + Note: The bandpass here is not the one in the RBJ CookBook as its gain can be + higher than 0 dB. For the classic 0 dB bandpass, we need to multiply the + result by R2. + + Note 2: Using this class prevents some loud audio artefacts commonly encountered when + changing the cutoff frequency using other filter simulation structures and IIR + filter classes. However, this class may still require additional smoothing for + cutoff frequency changes. + + see IIRFilter, SmoothedValue + + @tags{DSP} +*/ +template +class StateVariableTPTFilter +{ +public: + //============================================================================== + using Type = StateVariableTPTFilterType; + + //============================================================================== + /** Constructor. */ + StateVariableTPTFilter(); + + //============================================================================== + /** Sets the filter type. */ + void setType (Type newType); + + /** Sets the cutoff frequency of the filter. + + @param newFrequencyHz the new cutoff frequency in Hz. + */ + void setCutoffFrequency (SampleType newFrequencyHz); + + /** Sets the resonance of the filter. + + Note: The bandwidth of the resonance increases with the value of the + parameter. To have a standard 12 dB / octave filter, the value must be set + at 1 / sqrt(2). + */ + void setResonance (SampleType newResonance); + + //============================================================================== + /** Returns the type of the filter. */ + Type getType() const noexcept { return filterType; } + + /** Returns the cutoff frequency of the filter. */ + SampleType getCutoffFrequency() const noexcept { return cutoffFrequency; } + + /** Returns the resonance of the filter. */ + SampleType getResonance() const noexcept { return resonance; } + + //============================================================================== + /** Initialises the filter. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the filter. */ + void reset(); + + /** Resets the internal state variables of the filter to a given value. */ + void reset (SampleType newValue); + + /** Ensure that the state variables are rounded to zero if the state + variables are denormals. This is only needed if you are doing + sample by sample processing. + */ + void snapToZero() noexcept; + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() <= s1.size()); + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + + #if JUCE_SNAP_TO_ZERO + snapToZero(); + #endif + } + + //============================================================================== + /** Processes one sample at a time on a given channel. */ + SampleType processSample (int channel, SampleType inputValue); + +private: + //============================================================================== + void update(); + + //============================================================================== + SampleType g, h, R2; + std::vector s1 { 2 }, s2 { 2 }; + + double sampleRate = 44100.0; + Type filterType = Type::lowpass; + SampleType cutoffFrequency = static_cast (1000.0), + resonance = static_cast (1.0 / std::sqrt (2.0)); +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Bias.h b/modules/juce_dsp/widgets/juce_Bias.h similarity index 95% rename from modules/juce_dsp/processors/juce_Bias.h rename to modules/juce_dsp/widgets/juce_Bias.h index 0a89aa83a2..70a685da70 100644 --- a/modules/juce_dsp/processors/juce_Bias.h +++ b/modules/juce_dsp/widgets/juce_Bias.h @@ -96,7 +96,7 @@ public: auto&& outBlock = context.getOutputBlock(); jassert (inBlock.getNumChannels() == outBlock.getNumChannels()); - jassert (inBlock.getNumSamples() == outBlock.getNumSamples()); + jassert (inBlock.getNumSamples() == outBlock.getNumSamples()); auto len = inBlock.getNumSamples(); auto numChannels = inBlock.getNumChannels(); diff --git a/modules/juce_dsp/widgets/juce_Chorus.cpp b/modules/juce_dsp/widgets/juce_Chorus.cpp new file mode 100644 index 0000000000..8c0e2896e9 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Chorus.cpp @@ -0,0 +1,131 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +Chorus::Chorus() +{ + auto oscFunction = [] (SampleType x) { return std::sin (x); }; + osc.initialise (oscFunction); + + dryWet.setMixingRule (DryWetMixingRule::linear); +} + +template +void Chorus::setRate (SampleType newRateHz) +{ + jassert (isPositiveAndBelow (newRateHz, static_cast (100.0))); + + rate = newRateHz; + update(); +} + +template +void Chorus::setDepth (SampleType newDepth) +{ + jassert (isPositiveAndNotGreaterThan (newDepth, static_cast (1.0))); + + depth = newDepth; + update(); +} + +template +void Chorus::setCentreDelay (SampleType newDelayMs) +{ + jassert (isPositiveAndBelow (newDelayMs, static_cast (100.0))); + + centreDelay = jlimit (static_cast (1.0), static_cast (100.0), newDelayMs); +} + +template +void Chorus::setFeedback (SampleType newFeedback) +{ + jassert (newFeedback >= static_cast (-1.0) && newFeedback <= static_cast (1.0)); + + feedback = newFeedback; + update(); +} + +template +void Chorus::setMix (SampleType newMix) +{ + jassert (isPositiveAndNotGreaterThan (newMix, static_cast (1.0))); + + mix = newMix; + update(); +} + +//============================================================================== +template +void Chorus::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + delay.prepare (spec); + + dryWet.prepare (spec); + feedbackVolume.resize (spec.numChannels); + lastOutput.resize (spec.numChannels); + + osc.prepare (spec); + bufferDelayTimes.setSize (1, (int) spec.maximumBlockSize, false, false, true); + + update(); + reset(); +} + +template +void Chorus::reset() +{ + std::fill (lastOutput.begin(), lastOutput.end(), static_cast (0)); + + delay.reset(); + osc.reset(); + dryWet.reset(); + + oscVolume.reset (sampleRate, 0.05); + + for (auto& vol : feedbackVolume) + vol.reset (sampleRate, 0.05); +} + +template +void Chorus::update() +{ + osc.setFrequency (rate); + oscVolume.setTargetValue (depth * (SampleType) 0.5); + dryWet.setWetMixProportion (mix); + + for (auto& vol : feedbackVolume) + vol.setTargetValue (feedback); +} + +//============================================================================== +template class Chorus; +template class Chorus; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_Chorus.h b/modules/juce_dsp/widgets/juce_Chorus.h new file mode 100644 index 0000000000..42934a8a49 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Chorus.h @@ -0,0 +1,157 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +/** + A simple chorus DSP widget that modulates the delay of a delay line in order to + create sweeping notches in the magnitude frequency response. + + This audio effect can be controlled via the speed and depth of the LFO controlling + the frequency response, a mix control, a feedback control, and the centre delay + of the modulation. + + Note: To get classic chorus sounds try to use a centre delay time around 7-8 ms + with a low feeback volume and a low depth. This effect can also be used as a + flanger with a lower centre delay time and a lot of feedback, and as a vibrato + effect if the mix value is 1. + + @tags{DSP} +*/ +template +class Chorus +{ +public: + //============================================================================== + /** Constructor. */ + Chorus(); + + //============================================================================== + /** Sets the rate (in Hz) of the LFO modulating the chorus delay line. This rate + must be lower than 100 Hz. + */ + void setRate (SampleType newRateHz); + + /** Sets the volume of the LFO modulating the chorus delay line (between 0 and 1). + */ + void setDepth (SampleType newDepth); + + /** Sets the centre delay in milliseconds of the chorus delay line modulation. + This delay must be between 1 and 100 ms. + */ + void setCentreDelay (SampleType newDelayMs); + + /** Sets the feedback volume (between -1 and 1) of the chorus delay line. + Negative values can be used to get specific chorus sounds. + */ + void setFeedback (SampleType newFeedback); + + /** Sets the amount of dry and wet signal in the output of the chorus (between 0 + for full dry and 1 for full wet). + */ + void setMix (SampleType newMix); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumChannels() == lastOutput.size()); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + auto delayValuesBlock = AudioBlock(bufferDelayTimes).getSubBlock (0, numSamples); + auto contextDelay = ProcessContextReplacing (delayValuesBlock); + delayValuesBlock.clear(); + + osc.process (contextDelay); + delayValuesBlock.multiplyBy (oscVolume); + + auto* delaySamples = bufferDelayTimes.getWritePointer (0); + + for (size_t i = 0; i < numSamples; ++i) + { + auto lfo = jmax (static_cast (1.0), maximumDelayModulation * delaySamples[i] + centreDelay); + delaySamples[i] = static_cast (lfo * sampleRate / 1000.0); + } + + dryWet.pushDrySamples (inputBlock); + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + { + auto input = inputSamples[i]; + auto output = input - lastOutput[channel]; + + delay.pushSample ((int) channel, input); + delay.setDelay (delaySamples[i]); + output = delay.popSample ((int) channel); + + outputSamples[i] = output; + lastOutput[channel] = output * feedbackVolume[channel].getNextValue(); + } + } + + dryWet.mixWetSamples (outputBlock); + } + +private: + //============================================================================== + void update(); + + //============================================================================== + Oscillator osc; + DelayLine delay { 5000 }; + SmoothedValue oscVolume; + std::vector> feedbackVolume { 2 }; + DryWetMixer dryWet; + std::vector lastOutput { 2 }; + AudioBuffer bufferDelayTimes; + + double sampleRate = 44100.0; + SampleType rate = 1.0, depth = 0.25, feedback = 0.0, mix = 0.5, + centreDelay = 7.0, maximumDelayModulation = 20.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_Compressor.cpp b/modules/juce_dsp/widgets/juce_Compressor.cpp new file mode 100644 index 0000000000..80ce6aa01c --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Compressor.cpp @@ -0,0 +1,117 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +Compressor::Compressor() +{ + update(); +} + +//============================================================================== +template +void Compressor::setThreshold (SampleType newThreshold) +{ + thresholddB = newThreshold; + update(); +} + +template +void Compressor::setRatio (SampleType newRatio) +{ + jassert (newRatio >= static_cast (1.0)); + + ratio = newRatio; + update(); +} + +template +void Compressor::setAttack (SampleType newAttack) +{ + attackTime = newAttack; + update(); +} + +template +void Compressor::setRelease (SampleType newRelease) +{ + releaseTime = newRelease; + update(); +} + +//============================================================================== +template +void Compressor::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + envelopeFilter.prepare (spec); + + update(); + reset(); +} + +template +void Compressor::reset() +{ + envelopeFilter.reset(); +} + +//============================================================================== +template +SampleType Compressor::processSample (int channel, SampleType inputValue) +{ + // Rectifier + auto env = jmax ((SampleType) 0.0, inputValue); + + // Ballistics filter + env = envelopeFilter.processSample (channel, env); + + // VCA + auto gain = (env < threshold) ? static_cast (1.0) + : std::pow (env * thresholdInverse, ratioInverse - static_cast (1.0)); + + // Output + return gain * inputValue; +} + +template +void Compressor::update() +{ + threshold = Decibels::decibelsToGain (thresholddB, static_cast (-200.0)); + thresholdInverse = static_cast (1.0) / threshold; + ratioInverse = static_cast (1.0) / ratio; + + envelopeFilter.setAttackTime (attackTime); + envelopeFilter.setReleaseTime (releaseTime); +} + +//============================================================================== +template class Compressor; +template class Compressor; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_Compressor.h b/modules/juce_dsp/widgets/juce_Compressor.h new file mode 100644 index 0000000000..6a54404488 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Compressor.h @@ -0,0 +1,103 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +/** + A simple compressor with standard threshold, ratio, attack time and release time + controls. + + @tags{DSP} +*/ +template +class Compressor +{ +public: + //============================================================================== + /** Constructor. */ + Compressor(); + + //============================================================================== + /** Sets the threshold in dB of the compressor.*/ + void setThreshold (SampleType newThreshold); + + /** Sets the ratio of the compressor (must be higher or equal to 1).*/ + void setRatio (SampleType newRatio); + + /** Sets the attack time in milliseconds of the compressor.*/ + void setAttack (SampleType newAttack); + + /** Sets the release time in milliseconds of the compressor.*/ + void setRelease (SampleType newRelease); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + } + + /** Performs the processing operation on a single sample at a time. */ + SampleType processSample (int channel, SampleType inputValue); + +private: + //============================================================================== + void update(); + + //============================================================================== + SampleType threshold, thresholdInverse, ratioInverse; + BallisticsFilter envelopeFilter; + + double sampleRate = 44100.0; + SampleType thresholddB = 0.0, ratio = 1.0, attackTime = 1.0, releaseTime = 100.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Gain.h b/modules/juce_dsp/widgets/juce_Gain.h similarity index 100% rename from modules/juce_dsp/processors/juce_Gain.h rename to modules/juce_dsp/widgets/juce_Gain.h diff --git a/modules/juce_dsp/widgets/juce_LadderFilter.cpp b/modules/juce_dsp/widgets/juce_LadderFilter.cpp new file mode 100644 index 0000000000..c44bee8324 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_LadderFilter.cpp @@ -0,0 +1,169 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +LadderFilter::LadderFilter() : state (2) +{ + setSampleRate (SampleType (1000)); // intentionally setting unrealistic default + // sample rate to catch missing initialisation bugs + setResonance (SampleType (0)); + setDrive (SampleType (1.2)); + + mode = Mode::LPF24; + setMode (Mode::LPF12); +} + +//============================================================================== +template +void LadderFilter::setMode (Mode newMode) noexcept +{ + if (newMode == mode) + return; + + switch (newMode) + { + case Mode::LPF12: A = {{ SampleType (0), SampleType (0), SampleType (1), SampleType (0), SampleType (0) }}; comp = SampleType (0.5); break; + case Mode::HPF12: A = {{ SampleType (1), SampleType (-2), SampleType (1), SampleType (0), SampleType (0) }}; comp = SampleType (0); break; + case Mode::BPF12: A = {{ SampleType (0), SampleType (0), SampleType (-1), SampleType (1), SampleType (0) }}; comp = SampleType (0.5); break; + case Mode::LPF24: A = {{ SampleType (0), SampleType (0), SampleType (0), SampleType (0), SampleType (1) }}; comp = SampleType (0.5); break; + case Mode::HPF24: A = {{ SampleType (1), SampleType (-4), SampleType (6), SampleType (-4), SampleType (1) }}; comp = SampleType (0); break; + case Mode::BPF24: A = {{ SampleType (0), SampleType (0), SampleType (1), SampleType (-2), SampleType (1) }}; comp = SampleType (0.5); break; + default: jassertfalse; break; + } + + static constexpr auto outputGain = SampleType (1.2); + + for (auto& a : A) + a *= outputGain; + + mode = newMode; + reset(); +} + +//============================================================================== +template +void LadderFilter::prepare (const ProcessSpec& spec) +{ + setSampleRate (SampleType (spec.sampleRate)); + setNumChannels (spec.numChannels); + reset(); +} + +//============================================================================== +template +void LadderFilter::reset() noexcept +{ + for (auto& s : state) + s.fill (SampleType (0)); + + cutoffTransformSmoother.setCurrentAndTargetValue (cutoffTransformSmoother.getTargetValue()); + scaledResonanceSmoother.setCurrentAndTargetValue (scaledResonanceSmoother.getTargetValue()); +} + +//============================================================================== +template +void LadderFilter::setCutoffFrequencyHz (SampleType newCutoff) noexcept +{ + jassert (newCutoff > SampleType (0)); + cutoffFreqHz = newCutoff; + updateCutoffFreq(); +} + +//============================================================================== +template +void LadderFilter::setResonance (SampleType newResonance) noexcept +{ + jassert (newResonance >= SampleType (0) && newResonance <= SampleType (1)); + resonance = newResonance; + updateResonance(); +} + +//============================================================================== +template +void LadderFilter::setDrive (SampleType newDrive) noexcept +{ + jassert (newDrive >= SampleType (1)); + + drive = newDrive; + gain = std::pow (drive, SampleType (-2.642)) * SampleType (0.6103) + SampleType (0.3903); + drive2 = drive * SampleType (0.04) + SampleType (0.96); + gain2 = std::pow (drive2, SampleType (-2.642)) * SampleType (0.6103) + SampleType (0.3903); +} + +//============================================================================== +template +SampleType LadderFilter::processSample (SampleType inputValue, size_t channelToUse) noexcept +{ + auto& s = state[channelToUse]; + + const auto a1 = cutoffTransformValue; + const auto g = a1 * SampleType (-1) + SampleType (1); + const auto b0 = g * SampleType (0.76923076923); + const auto b1 = g * SampleType (0.23076923076); + + const auto dx = gain * saturationLUT (drive * inputValue); + const auto a = dx + scaledResonanceValue * SampleType (-4) * (gain2 * saturationLUT (drive2 * s[4]) - dx * comp); + + const auto b = b1 * s[0] + a1 * s[1] + b0 * a; + const auto c = b1 * s[1] + a1 * s[2] + b0 * b; + const auto d = b1 * s[2] + a1 * s[3] + b0 * c; + const auto e = b1 * s[3] + a1 * s[4] + b0 * d; + + s[0] = a; + s[1] = b; + s[2] = c; + s[3] = d; + s[4] = e; + + return a * A[0] + b * A[1] + c * A[2] + d * A[3] + e * A[4]; +} + +//============================================================================== +template +void LadderFilter::updateSmoothers() noexcept +{ + cutoffTransformValue = cutoffTransformSmoother.getNextValue(); + scaledResonanceValue = scaledResonanceSmoother.getNextValue(); +} + +//============================================================================== +template +void LadderFilter::setSampleRate (SampleType newValue) noexcept +{ + jassert (newValue > SampleType (0)); + cutoffFreqScaler = SampleType (-2.0 * juce::MathConstants::pi) / newValue; + + static constexpr SampleType smootherRampTimeSec = SampleType (0.05); + cutoffTransformSmoother.reset (newValue, smootherRampTimeSec); + scaledResonanceSmoother.reset (newValue, smootherRampTimeSec); + + updateCutoffFreq(); +} + +//============================================================================== +template class LadderFilter; +template class LadderFilter; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_LadderFilter.h b/modules/juce_dsp/widgets/juce_LadderFilter.h similarity index 63% rename from modules/juce_dsp/processors/juce_LadderFilter.h rename to modules/juce_dsp/widgets/juce_LadderFilter.h index e5ab9fb985..eed20521fe 100644 --- a/modules/juce_dsp/processors/juce_LadderFilter.h +++ b/modules/juce_dsp/widgets/juce_LadderFilter.h @@ -21,62 +21,67 @@ namespace juce namespace dsp { +enum class LadderFilterMode +{ + LPF12, // low-pass 12 dB/octave + HPF12, // high-pass 12 dB/octave + BPF12, // band-pass 12 dB/octave + LPF24, // low-pass 24 dB/octave + HPF24, // high-pass 24 dB/octave + BPF24 // band-pass 24 dB/octave +}; + /** Multi-mode filter based on the Moog ladder filter. @tags{DSP} */ -template +template class LadderFilter { public: - enum class Mode - { - LPF12, // low-pass 12 dB/octave - HPF12, // high-pass 12 dB/octave - LPF24, // low-pass 24 dB/octave - HPF24 // high-pass 24 dB/octave - }; + //============================================================================== + using Mode = LadderFilterMode; //============================================================================== /** Creates an uninitialised filter. Call prepare() before first use. */ LadderFilter(); /** Enables or disables the filter. If disabled it will simply pass through the input signal. */ - void setEnabled (bool newValue) noexcept { enabled = newValue; } + void setEnabled (bool isEnabled) noexcept { enabled = isEnabled; } /** Sets filter mode. */ - void setMode (Mode newValue) noexcept; + void setMode (Mode newMode) noexcept; /** Initialises the filter. */ - void prepare (const juce::dsp::ProcessSpec& spec); + void prepare (const ProcessSpec& spec); /** Returns the current number of channels. */ - size_t getNumChannels() const noexcept { return state.size(); } + size_t getNumChannels() const noexcept { return state.size(); } /** Resets the internal state variables of the filter. */ void reset() noexcept; /** Sets the cutoff frequency of the filter. @param newValue cutoff frequency in Hz */ - void setCutoffFrequencyHz (Type newValue) noexcept; + void setCutoffFrequencyHz (SampleType newCutoff) noexcept; /** Sets the resonance of the filter. @param newValue a value between 0 and 1; higher values increase the resonance and can result in self oscillation! */ - void setResonance (Type newValue) noexcept; + void setResonance (SampleType newResonance) noexcept; /** Sets the amount of saturation in the filter. @param newValue saturation amount; it can be any number greater than or equal to one. Higher values result in more distortion.*/ - void setDrive (Type newValue) noexcept; + void setDrive (SampleType newDrive) noexcept; //============================================================================== template void process (const ProcessContext& context) noexcept { const auto& inputBlock = context.getInputBlock(); - auto& outputBlock = context.getOutputBlock(); + auto& outputBlock = context.getOutputBlock(); const auto numChannels = outputBlock.getNumChannels(); - const auto numSamples = outputBlock.getNumSamples(); + const auto numSamples = outputBlock.getNumSamples(); jassert (inputBlock.getNumChannels() <= getNumChannels()); jassert (inputBlock.getNumChannels() == numChannels); @@ -99,35 +104,36 @@ public: protected: //============================================================================== - Type processSample (Type inputValue, size_t channelToUse) noexcept; + SampleType processSample (SampleType inputValue, size_t channelToUse) noexcept; void updateSmoothers() noexcept; private: //============================================================================== - Type drive, drive2, gain, gain2, comp; + void setSampleRate (SampleType newValue) noexcept; + void setNumChannels (size_t newValue) { state.resize (newValue); } + void updateCutoffFreq() noexcept { cutoffTransformSmoother.setTargetValue (std::exp (cutoffFreqHz * cutoffFreqScaler)); } + void updateResonance() noexcept { scaledResonanceSmoother.setTargetValue (jmap (resonance, SampleType (0.1), SampleType (1.0))); } + + //============================================================================== + SampleType drive, drive2, gain, gain2, comp; static constexpr size_t numStates = 5; - std::vector> state; - std::array A; + std::vector> state; + std::array A; - SmoothedValue cutoffTransformSmoother, scaledResonanceSmoother; - Type cutoffTransformValue, scaledResonanceValue; + SmoothedValue cutoffTransformSmoother, scaledResonanceSmoother; + SampleType cutoffTransformValue, scaledResonanceValue; - LookupTableTransform saturationLUT { [] (Type x) { return std::tanh (x); }, Type (-5), Type (5), 128 }; + LookupTableTransform saturationLUT { [] (SampleType x) { return std::tanh (x); }, + SampleType (-5), SampleType (5), 128 }; - Type cutoffFreqHz { Type (200) }; - Type resonance; + SampleType cutoffFreqHz { SampleType (200) }; + SampleType resonance; - Type cutoffFreqScaler; + SampleType cutoffFreqScaler; Mode mode; bool enabled = true; - - //============================================================================== - void setSampleRate (Type newValue) noexcept; - void setNumChannels (size_t newValue) { state.resize (newValue); } - void updateCutoffFreq() noexcept { cutoffTransformSmoother.setTargetValue (std::exp (cutoffFreqHz * cutoffFreqScaler)); } - void updateResonance() noexcept { scaledResonanceSmoother.setTargetValue (jmap (resonance, Type (0.1), Type (1.0))); } }; } // namespace dsp diff --git a/modules/juce_dsp/widgets/juce_Limiter.cpp b/modules/juce_dsp/widgets/juce_Limiter.cpp new file mode 100644 index 0000000000..16bf64562f --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Limiter.cpp @@ -0,0 +1,91 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +void Limiter::setThreshold (SampleType newThreshold) +{ + thresholddB = newThreshold; + update(); +} + +template +void Limiter::setRelease (SampleType newRelease) +{ + releaseTime = newRelease; + update(); +} + +//============================================================================== +template +void Limiter::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + firstStageCompressor.prepare (spec); + secondStageCompressor.prepare (spec); + + update(); + reset(); +} + +template +void Limiter::reset() +{ + firstStageCompressor.reset(); + secondStageCompressor.reset(); + + outputVolume.reset (sampleRate, 0.001); +} + +//============================================================================== +template +void Limiter::update() +{ + firstStageCompressor.setThreshold ((SampleType) -10.0); + firstStageCompressor.setRatio ((SampleType) 4.0); + firstStageCompressor.setAttack ((SampleType) 2.0); + firstStageCompressor.setRelease ((SampleType) 200.0); + + secondStageCompressor.setThreshold (thresholddB); + secondStageCompressor.setRatio ((SampleType) 1000.0); + secondStageCompressor.setAttack ((SampleType) 0.001); + secondStageCompressor.setRelease (releaseTime); + + auto ratioInverse = (SampleType) (1.0 / 4.0); + + auto gain = (SampleType) std::pow (10.0, 10.0 * (1.0 - ratioInverse) / 40.0); + gain *= Decibels::decibelsToGain (-thresholddB, (SampleType) -100.0); + + outputVolume.setTargetValue (gain); +} + +//============================================================================== +template class Limiter; +template class Limiter; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_Limiter.h b/modules/juce_dsp/widgets/juce_Limiter.h new file mode 100644 index 0000000000..e2732c2339 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Limiter.h @@ -0,0 +1,98 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +/** + A simple limiter with standard threshold and release time controls, featuring + two compressors and a hard clipper at 0 dB. + + @tags{DSP} +*/ +template +class Limiter +{ +public: + //============================================================================== + /** Constructor. */ + Limiter() = default; + + //============================================================================== + /** Sets the threshold in dB of the limiter.*/ + void setThreshold (SampleType newThreshold); + + /** Sets the release time in milliseconds of the limiter.*/ + void setRelease (SampleType newRelease); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + firstStageCompressor.process (context); + + auto secondContext = ProcessContextReplacing (outputBlock); + secondStageCompressor.process (secondContext); + + outputBlock.multiplyBy (outputVolume); + + for (size_t channel = 0; channel < numChannels; ++channel) + { + FloatVectorOperations::clip (outputBlock.getChannelPointer (channel), outputBlock.getChannelPointer (channel), + (SampleType) -1.0, (SampleType) 1.0, (int) numSamples); + } + } + +private: + //============================================================================== + void update(); + + //============================================================================== + Compressor firstStageCompressor, secondStageCompressor; + SmoothedValue outputVolume; + + double sampleRate = 44100.0; + SampleType thresholddB = -10.0, releaseTime = 100.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_NoiseGate.cpp b/modules/juce_dsp/widgets/juce_NoiseGate.cpp new file mode 100644 index 0000000000..3a4f59c134 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_NoiseGate.cpp @@ -0,0 +1,122 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +NoiseGate::NoiseGate() +{ + update(); + + RMSFilter.setLevelCalculationType (BallisticsFilterLevelCalculationType::RMS); + RMSFilter.setAttackTime (static_cast (0.0)); + RMSFilter.setReleaseTime (static_cast (50.0)); +} + +template +void NoiseGate::setThreshold (SampleType newValue) +{ + thresholddB = newValue; + update(); +} + +template +void NoiseGate::setRatio (SampleType newRatio) +{ + jassert (newRatio >= static_cast (1.0)); + + ratio = newRatio; + update(); +} + +template +void NoiseGate::setAttack (SampleType newAttack) +{ + attackTime = newAttack; + update(); +} + +template +void NoiseGate::setRelease (SampleType newRelease) +{ + releaseTime = newRelease; + update(); +} + +//============================================================================== +template +void NoiseGate::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + RMSFilter.prepare (spec); + envelopeFilter.prepare (spec); + + update(); + reset(); +} + +template +void NoiseGate::reset() +{ + RMSFilter.reset(); + envelopeFilter.reset(); +} + +//============================================================================== +template +SampleType NoiseGate::processSample (int channel, SampleType sample) +{ + // RMS ballistics filter + auto env = RMSFilter.processSample (channel, sample); + + // Ballistics filter + env = envelopeFilter.processSample (channel, env); + + // VCA + auto gain = (env > threshold) ? static_cast (1.0) + : std::pow (env * thresholdInverse, currentRatio - static_cast (1.0)); + + // Output + return gain * sample; +} + +template +void NoiseGate::update() +{ + threshold = Decibels::decibelsToGain (thresholddB, static_cast (-200.0)); + thresholdInverse = static_cast (1.0) / threshold; + currentRatio = ratio; + + envelopeFilter.setAttackTime (attackTime); + envelopeFilter.setReleaseTime (releaseTime); +} + +//============================================================================== +template class NoiseGate; +template class NoiseGate; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_NoiseGate.h b/modules/juce_dsp/widgets/juce_NoiseGate.h new file mode 100644 index 0000000000..fbf423ffee --- /dev/null +++ b/modules/juce_dsp/widgets/juce_NoiseGate.h @@ -0,0 +1,103 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +/** + A simple noise gate with standard threshold, ratio, attack time and + release time controls. Can be used as an expander if the ratio is low. + + @tags{DSP} +*/ +template +class NoiseGate +{ +public: + //============================================================================== + /** Constructor. */ + NoiseGate(); + + //============================================================================== + /** Sets the threshold in dB of the noise-gate.*/ + void setThreshold (SampleType newThreshold); + + /** Sets the ratio of the noise-gate (must be higher or equal to 1).*/ + void setRatio (SampleType newRatio); + + /** Sets the attack time in milliseconds of the noise-gate.*/ + void setAttack (SampleType newAttack); + + /** Sets the release time in milliseconds of the noise-gate.*/ + void setRelease (SampleType newRelease); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + } + + /** Performs the processing operation on a single sample at a time. */ + SampleType processSample (int channel, SampleType inputValue); + +private: + //============================================================================== + void update(); + + //============================================================================== + SampleType threshold, thresholdInverse, currentRatio; + BallisticsFilter envelopeFilter, RMSFilter; + + double sampleRate = 44100.0; + SampleType thresholddB = -100, ratio = 10.0, attackTime = 1.0, releaseTime = 100.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Oscillator.h b/modules/juce_dsp/widgets/juce_Oscillator.h similarity index 100% rename from modules/juce_dsp/processors/juce_Oscillator.h rename to modules/juce_dsp/widgets/juce_Oscillator.h diff --git a/modules/juce_dsp/widgets/juce_Phaser.cpp b/modules/juce_dsp/widgets/juce_Phaser.cpp new file mode 100644 index 0000000000..38a84eaa6a --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Phaser.cpp @@ -0,0 +1,147 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template +Phaser::Phaser() +{ + auto oscFunction = [] (SampleType x) { return std::sin (x); }; + osc.initialise (oscFunction); + + for (auto n = 0; n < numStages; ++n) + { + filters.add (new FirstOrderTPTFilter()); + filters[n]->setType (FirstOrderTPTFilterType::allpass); + } + + dryWet.setMixingRule (DryWetMixingRule::linear); +} + +template +void Phaser::setRate (SampleType newRateHz) +{ + jassert (isPositiveAndBelow (newRateHz, static_cast (100.0))); + + rate = newRateHz; + update(); +} + +template +void Phaser::setDepth (SampleType newDepth) +{ + jassert (isPositiveAndNotGreaterThan (newDepth, static_cast (1.0))); + + depth = newDepth; + update(); +} + +template +void Phaser::setCentreFrequency (SampleType newCentreHz) +{ + jassert (isPositiveAndBelow (newCentreHz, static_cast (sampleRate * 0.5))); + + centreFrequency = newCentreHz; + normCentreFrequency = mapToLog10 (centreFrequency, static_cast (20.0), static_cast (jmin (20000.0, 0.49 * sampleRate))); +} + +template +void Phaser::setFeedback (SampleType newFeedback) +{ + jassert (newFeedback >= static_cast (-1.0) && newFeedback <= static_cast (1.0)); + + feedback = newFeedback; + update(); +} + +template +void Phaser::setMix (SampleType newMix) +{ + jassert (isPositiveAndNotGreaterThan (newMix, static_cast (1.0))); + + mix = newMix; + update(); +} + +//============================================================================== +template +void Phaser::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + for (auto n = 0; n < numStages; ++n) + filters[n]->prepare (spec); + + dryWet.prepare (spec); + feedbackVolume.resize (spec.numChannels); + lastOutput.resize (spec.numChannels); + + auto specDown = spec; + specDown.sampleRate /= (double) maxUpdateCounter; + specDown.maximumBlockSize = specDown.maximumBlockSize / (uint32) maxUpdateCounter + 1; + + osc.prepare (specDown); + bufferFrequency.setSize (1, (int) specDown.maximumBlockSize, false, false, true); + + update(); + reset(); +} + +template +void Phaser::reset() +{ + std::fill (lastOutput.begin(), lastOutput.end(), static_cast (0)); + + for (auto n = 0; n < numStages; ++n) + filters[n]->reset(); + + osc.reset(); + dryWet.reset(); + + oscVolume.reset (sampleRate / (double) maxUpdateCounter, 0.05); + + for (auto& vol : feedbackVolume) + vol.reset (sampleRate, 0.05); + + updateCounter = 0; +} + +template +void Phaser::update() +{ + osc.setFrequency (rate); + oscVolume.setTargetValue (depth * (SampleType) 0.5); + dryWet.setWetMixProportion (mix); + + for (auto& vol : feedbackVolume) + vol.setTargetValue (feedback); +} + +//============================================================================== +template class Phaser; +template class Phaser; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_Phaser.h b/modules/juce_dsp/widgets/juce_Phaser.h new file mode 100644 index 0000000000..39bd381b70 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Phaser.h @@ -0,0 +1,199 @@ +/* + ============================================================================== + + This file is part of the JUCE 6 technical preview. + Copyright (c) 2020 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For this technical preview, this file is not subject to commercial licensing. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +/** + A 6 stage phaser that modulates first order all-pass filters to create sweeping + notches in the magnitude frequency response. + + This audio effect can be controlled with standard phaser parameters: the speed + and depth of the LFO controlling the frequency response, a mix control, a + feedback control, and the centre frequency of the modulation. + + @tags{DSP} +*/ +template +class Phaser +{ +public: + //============================================================================== + /** Constructor. */ + Phaser(); + + //============================================================================== + /** Sets the rate (in Hz) of the LFO modulating the phaser all-pass filters. This + rate must be lower than 100 Hz. + */ + void setRate (SampleType newRateHz); + + /** Sets the volume (between 0 and 1) of the LFO modulating the phaser all-pass + filters. + */ + void setDepth (SampleType newDepth); + + /** Sets the centre frequency (in Hz) of the phaser all-pass filters modulation. + */ + void setCentreFrequency (SampleType newCentreHz); + + /** Sets the feedback volume (between -1 and 1) of the phaser. Negative can be + used to get specific phaser sounds. + */ + void setFeedback (SampleType newFeedback); + + /** Sets the amount of dry and wet signal in the output of the phaser (between 0 + for full dry and 1 for full wet). + */ + void setMix (SampleType newMix); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumChannels() == lastOutput.size()); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + int numSamplesDown = 0; + auto counter = updateCounter; + + for (size_t i = 0; i < numSamples; ++i) + { + if (counter == 0) + numSamplesDown++; + + counter++; + + if (counter == maxUpdateCounter) + counter = 0; + } + + if (numSamplesDown > 0) + { + auto freqBlock = AudioBlock(bufferFrequency).getSubBlock (0, (size_t) numSamplesDown); + auto contextFreq = ProcessContextReplacing (freqBlock); + freqBlock.clear(); + + osc.process (contextFreq); + freqBlock.multiplyBy (oscVolume); + } + + auto* freqSamples = bufferFrequency.getWritePointer (0); + + for (int i = 0; i < numSamplesDown; ++i) + { + auto lfo = jlimit (static_cast (0.0), + static_cast (1.0), + freqSamples[i] + normCentreFrequency); + + freqSamples[i] = mapToLog10 (lfo, static_cast (20.0), + static_cast (jmin (20000.0, 0.49 * sampleRate))); + } + + auto currentFrequency = filters[0]->getCutoffFrequency(); + dryWet.pushDrySamples (inputBlock); + + for (size_t channel = 0; channel < numChannels; ++channel) + { + counter = updateCounter; + int k = 0; + + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + { + auto input = inputSamples[i]; + auto output = input - lastOutput[channel]; + + if (i == 0 && counter != 0) + for (int n = 0; n < numStages; ++n) + filters[n]->setCutoffFrequency (currentFrequency); + + if (counter == 0) + { + for (int n = 0; n < numStages; ++n) + filters[n]->setCutoffFrequency (freqSamples[k]); + + k++; + } + + for (int n = 0; n < numStages; ++n) + output = filters[n]->processSample ((int) channel, output); + + outputSamples[i] = output; + lastOutput[channel] = output * feedbackVolume[channel].getNextValue(); + + counter++; + + if (counter == maxUpdateCounter) + counter = 0; + } + } + + dryWet.mixWetSamples (outputBlock); + updateCounter = (updateCounter + (int) numSamples) % maxUpdateCounter; + } + +private: + //============================================================================== + void update(); + + //============================================================================== + Oscillator osc; + OwnedArray> filters; + SmoothedValue oscVolume; + std::vector> feedbackVolume { 2 }; + DryWetMixer dryWet; + std::vector lastOutput { 2 }; + AudioBuffer bufferFrequency; + SampleType normCentreFrequency = 0.5; + double sampleRate = 44100.0; + + int updateCounter = 0; + static constexpr int maxUpdateCounter = 4; + + SampleType rate = 1.0, depth = 0.5, feedback = 0.0, mix = 0.5; + SampleType centreFrequency = 1300.0; + static constexpr int numStages = 6; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Reverb.h b/modules/juce_dsp/widgets/juce_Reverb.h similarity index 95% rename from modules/juce_dsp/processors/juce_Reverb.h rename to modules/juce_dsp/widgets/juce_Reverb.h index 3d986005db..16a3b581c9 100644 --- a/modules/juce_dsp/processors/juce_Reverb.h +++ b/modules/juce_dsp/widgets/juce_Reverb.h @@ -53,7 +53,7 @@ public: //============================================================================== /** Initialises the reverb. */ - void prepare (const juce::dsp::ProcessSpec& spec) + void prepare (const ProcessSpec& spec) { reverb.setSampleRate (spec.sampleRate); } diff --git a/modules/juce_dsp/processors/juce_WaveShaper.h b/modules/juce_dsp/widgets/juce_WaveShaper.h similarity index 100% rename from modules/juce_dsp/processors/juce_WaveShaper.h rename to modules/juce_dsp/widgets/juce_WaveShaper.h