cyfaust 0.1.0__cp311-cp311-macosx_15_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cyfaust/CMakeLists.txt +93 -0
- cyfaust/__init__.py +0 -0
- cyfaust/__main__.py +819 -0
- cyfaust/box.pxd +46 -0
- cyfaust/box.pyx +2459 -0
- cyfaust/common.pxd +5 -0
- cyfaust/common.pyx +61 -0
- cyfaust/cyfaust.cpython-311-darwin.so +0 -0
- cyfaust/faust_box.pxd +298 -0
- cyfaust/faust_box_oo.pyx +66 -0
- cyfaust/faust_gui.pxd +261 -0
- cyfaust/faust_interp.pxd +160 -0
- cyfaust/faust_player.pxd +80 -0
- cyfaust/faust_signal.pxd +257 -0
- cyfaust/gui_statics.cpp +15 -0
- cyfaust/interp.pyx +673 -0
- cyfaust/player.cpp +32519 -0
- cyfaust/player.pyx +191 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUBase.cpp +2327 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUBase.h +1019 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUDispatch.cpp +423 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUDispatch.h +82 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUInputElement.cpp +151 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUInputElement.h +119 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUOutputElement.cpp +62 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUOutputElement.h +66 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUPlugInDispatch.cpp +615 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUPlugInDispatch.h +128 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUScopeElement.cpp +512 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/AUScopeElement.h +544 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/ComponentBase.cpp +370 -0
- cyfaust/resources/architecture/AU/AUPublic/AUBase/ComponentBase.h +340 -0
- cyfaust/resources/architecture/AU/AUPublic/AUEffectBase/AUEffectBase.cpp +463 -0
- cyfaust/resources/architecture/AU/AUPublic/AUEffectBase/AUEffectBase.h +391 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/AUInstrumentBase.cpp +837 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/AUInstrumentBase.h +267 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/AUMIDIBase.cpp +495 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/AUMIDIBase.h +213 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/LockFreeFIFO.h +168 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/MIDIControlHandler.h +92 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/MusicDeviceBase.cpp +354 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/MusicDeviceBase.h +126 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/SynthElement.cpp +419 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/SynthElement.h +227 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/SynthEvent.h +145 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/SynthNote.cpp +138 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/SynthNote.h +186 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/SynthNoteList.cpp +93 -0
- cyfaust/resources/architecture/AU/AUPublic/AUInstrumentBase/SynthNoteList.h +232 -0
- cyfaust/resources/architecture/AU/AUPublic/Utility/AUBaseHelper.cpp +134 -0
- cyfaust/resources/architecture/AU/AUPublic/Utility/AUBaseHelper.h +80 -0
- cyfaust/resources/architecture/AU/AUPublic/Utility/AUBuffer.cpp +217 -0
- cyfaust/resources/architecture/AU/AUPublic/Utility/AUBuffer.h +267 -0
- cyfaust/resources/architecture/AU/AUPublic/Utility/AUMIDIDefs.h +136 -0
- cyfaust/resources/architecture/AU/AUPublic/Utility/AUSilentTimeout.h +93 -0
- cyfaust/resources/architecture/AU/English.lproj/InfoPlist.strings +0 -0
- cyfaust/resources/architecture/AU/FaustAU.exp +2 -0
- cyfaust/resources/architecture/AU/FaustAU.xcodeproj/project.pbxproj +968 -0
- cyfaust/resources/architecture/AU/FaustAU.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- cyfaust/resources/architecture/AU/FaustAUCustomView.plist +14 -0
- cyfaust/resources/architecture/AU/Info.plist +47 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAAtomic.h +305 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAAtomicStack.h +239 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAAudioChannelLayout.cpp +153 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAAudioChannelLayout.h +199 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAAutoDisposer.h +508 -0
- cyfaust/resources/architecture/AU/PublicUtility/CABufferList.cpp +264 -0
- cyfaust/resources/architecture/AU/PublicUtility/CABufferList.h +319 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAByteOrder.h +161 -0
- cyfaust/resources/architecture/AU/PublicUtility/CADebugMacros.cpp +88 -0
- cyfaust/resources/architecture/AU/PublicUtility/CADebugMacros.h +580 -0
- cyfaust/resources/architecture/AU/PublicUtility/CADebugPrintf.cpp +89 -0
- cyfaust/resources/architecture/AU/PublicUtility/CADebugPrintf.h +115 -0
- cyfaust/resources/architecture/AU/PublicUtility/CADebugger.cpp +77 -0
- cyfaust/resources/architecture/AU/PublicUtility/CADebugger.h +56 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAException.h +83 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAGuard.cpp +339 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAGuard.h +133 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAHostTimeBase.cpp +110 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAHostTimeBase.h +231 -0
- cyfaust/resources/architecture/AU/PublicUtility/CALogMacros.h +140 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAMath.h +68 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAMutex.cpp +345 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAMutex.h +163 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAReferenceCounted.h +87 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAStreamBasicDescription.cpp +795 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAStreamBasicDescription.h +409 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAThreadSafeList.h +255 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAVectorUnit.cpp +191 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAVectorUnit.h +100 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAVectorUnitTypes.h +59 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAXException.cpp +49 -0
- cyfaust/resources/architecture/AU/PublicUtility/CAXException.h +338 -0
- cyfaust/resources/architecture/AU/SectionPatternLight.tiff +0 -0
- cyfaust/resources/architecture/AU/Source/AUSource/FaustAU.h +38 -0
- cyfaust/resources/architecture/AU/Source/AUSource/FaustAU.r +153 -0
- cyfaust/resources/architecture/AU/Source/AUSource/FaustAUVersion.h +64 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_Bargraph.h +18 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_Bargraph.m +21 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_Button.h +20 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_Button.m +56 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_CustomView.h +87 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_CustomView.m +834 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_CustomViewFactory.h +13 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_CustomViewFactory.m +22 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_Knob.h +81 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_Knob.m +199 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_Slider.h +18 -0
- cyfaust/resources/architecture/AU/Source/CocoaUI/FaustAU_Slider.m +21 -0
- cyfaust/resources/architecture/AU/version.plist +16 -0
- cyfaust/resources/architecture/VST/Info.plist +28 -0
- cyfaust/resources/architecture/VST/PkgInfo +1 -0
- cyfaust/resources/architecture/VST/README +11 -0
- cyfaust/resources/architecture/VST/VST.xcode/project.pbxproj +655 -0
- cyfaust/resources/architecture/alsa-console.cpp +246 -0
- cyfaust/resources/architecture/alsa-gtk.cpp +220 -0
- cyfaust/resources/architecture/alsa-qt.cpp +229 -0
- cyfaust/resources/architecture/api/DspFaust.cpp +612 -0
- cyfaust/resources/architecture/api/DspFaust.h +511 -0
- cyfaust/resources/architecture/api/README.md +237 -0
- cyfaust/resources/architecture/api/doc/Generic.md +38 -0
- cyfaust/resources/architecture/au-effect.cpp +487 -0
- cyfaust/resources/architecture/au-instrument.cpp +573 -0
- cyfaust/resources/architecture/bench.cpp +91 -0
- cyfaust/resources/architecture/c-jack-gtk.c +227 -0
- cyfaust/resources/architecture/ca-gtk.cpp +284 -0
- cyfaust/resources/architecture/ca-qt.cpp +424 -0
- cyfaust/resources/architecture/cpal.rs +195 -0
- cyfaust/resources/architecture/csound.cpp +245 -0
- cyfaust/resources/architecture/csvplot.cpp +227 -0
- cyfaust/resources/architecture/daisy/Makefile +14 -0
- cyfaust/resources/architecture/daisy/README.md +50 -0
- cyfaust/resources/architecture/daisy/ex_faust.cpp +173 -0
- cyfaust/resources/architecture/dssi.cpp +1262 -0
- cyfaust/resources/architecture/dummy-mem.cpp +186 -0
- cyfaust/resources/architecture/dummy.cpp +294 -0
- cyfaust/resources/architecture/faust/au/AUUI.h +404 -0
- cyfaust/resources/architecture/faust/audio/alsa-dsp.h +693 -0
- cyfaust/resources/architecture/faust/audio/android-dsp.h +583 -0
- cyfaust/resources/architecture/faust/audio/audio.h +115 -0
- cyfaust/resources/architecture/faust/audio/channels.h +122 -0
- cyfaust/resources/architecture/faust/audio/coreaudio-dsp.h +1543 -0
- cyfaust/resources/architecture/faust/audio/coreaudio-ios-dsp.h +743 -0
- cyfaust/resources/architecture/faust/audio/dummy-audio.h +255 -0
- cyfaust/resources/architecture/faust/audio/esp32-dsp.h +284 -0
- cyfaust/resources/architecture/faust/audio/fpe.h +164 -0
- cyfaust/resources/architecture/faust/audio/jack-dsp.h +534 -0
- cyfaust/resources/architecture/faust/audio/juce-dsp.h +119 -0
- cyfaust/resources/architecture/faust/audio/netjack-dsp.h +354 -0
- cyfaust/resources/architecture/faust/audio/oboe-dsp.h +308 -0
- cyfaust/resources/architecture/faust/audio/ofaudio-dsp.h +155 -0
- cyfaust/resources/architecture/faust/audio/opensles-android-dsp.h +631 -0
- cyfaust/resources/architecture/faust/audio/osc-dsp.h +120 -0
- cyfaust/resources/architecture/faust/audio/portaudio-dsp.h +236 -0
- cyfaust/resources/architecture/faust/audio/rtaudio-dsp.h +241 -0
- cyfaust/resources/architecture/faust/audio/samAudio.h +140 -0
- cyfaust/resources/architecture/faust/audio/teensy-dsp.h +171 -0
- cyfaust/resources/architecture/faust/dsp/cmajor-cpp-dsp.h +253 -0
- cyfaust/resources/architecture/faust/dsp/cmajorpatch-dsp.h +483 -0
- cyfaust/resources/architecture/faust/dsp/cpp-dsp-adapter.h +38 -0
- cyfaust/resources/architecture/faust/dsp/dsp-adapter.h +836 -0
- cyfaust/resources/architecture/faust/dsp/dsp-bench.h +611 -0
- cyfaust/resources/architecture/faust/dsp/dsp-checker.h +115 -0
- cyfaust/resources/architecture/faust/dsp/dsp-combiner.h +810 -0
- cyfaust/resources/architecture/faust/dsp/dsp-compute-adapter.h +159 -0
- cyfaust/resources/architecture/faust/dsp/dsp-multi.h +702 -0
- cyfaust/resources/architecture/faust/dsp/dsp-multifun.h +90 -0
- cyfaust/resources/architecture/faust/dsp/dsp-optimizer.h +511 -0
- cyfaust/resources/architecture/faust/dsp/dsp-tools.h +229 -0
- cyfaust/resources/architecture/faust/dsp/dsp.h +321 -0
- cyfaust/resources/architecture/faust/dsp/fastmath.cpp +301 -0
- cyfaust/resources/architecture/faust/dsp/faust-dynamic-engine.cpp +494 -0
- cyfaust/resources/architecture/faust/dsp/faust-dynamic-engine.h +386 -0
- cyfaust/resources/architecture/faust/dsp/faust-engine.h +75 -0
- cyfaust/resources/architecture/faust/dsp/faust-poly-engine.h +638 -0
- cyfaust/resources/architecture/faust/dsp/interpreter-dsp-c.h +288 -0
- cyfaust/resources/architecture/faust/dsp/interpreter-dsp.h +362 -0
- cyfaust/resources/architecture/faust/dsp/interpreter-machine-dsp.h +233 -0
- cyfaust/resources/architecture/faust/dsp/libfaust-box-c.h +817 -0
- cyfaust/resources/architecture/faust/dsp/libfaust-box.h +889 -0
- cyfaust/resources/architecture/faust/dsp/libfaust-c.h +116 -0
- cyfaust/resources/architecture/faust/dsp/libfaust-signal-c.h +649 -0
- cyfaust/resources/architecture/faust/dsp/libfaust-signal.h +731 -0
- cyfaust/resources/architecture/faust/dsp/llvm-dsp-adapter.h +160 -0
- cyfaust/resources/architecture/faust/dsp/llvm-dsp-c.h +524 -0
- cyfaust/resources/architecture/faust/dsp/llvm-dsp.h +575 -0
- cyfaust/resources/architecture/faust/dsp/llvm-machine-dsp.h +215 -0
- cyfaust/resources/architecture/faust/dsp/one-sample-dsp.h +477 -0
- cyfaust/resources/architecture/faust/dsp/poly-dsp.h +1079 -0
- cyfaust/resources/architecture/faust/dsp/poly-interpreter-dsp.h +143 -0
- cyfaust/resources/architecture/faust/dsp/poly-llvm-dsp.h +249 -0
- cyfaust/resources/architecture/faust/dsp/poly-wasm-dsp.h +257 -0
- cyfaust/resources/architecture/faust/dsp/proxy-dsp.h +108 -0
- cyfaust/resources/architecture/faust/dsp/proxy-osc-dsp.h +109 -0
- cyfaust/resources/architecture/faust/dsp/rnbo-dsp.h +187 -0
- cyfaust/resources/architecture/faust/dsp/sound-player.h +428 -0
- cyfaust/resources/architecture/faust/dsp/timed-dsp.h +279 -0
- cyfaust/resources/architecture/faust/dsp/wasm-dsp-imp.h +188 -0
- cyfaust/resources/architecture/faust/dsp/wasm-dsp.h +309 -0
- cyfaust/resources/architecture/faust/dsp/ysfx-dsp.h +188 -0
- cyfaust/resources/architecture/faust/export.h +61 -0
- cyfaust/resources/architecture/faust/gui/APIUI.h +726 -0
- cyfaust/resources/architecture/faust/gui/BelaOSCUI.h +170 -0
- cyfaust/resources/architecture/faust/gui/CGlue.h +667 -0
- cyfaust/resources/architecture/faust/gui/CInterface.h +142 -0
- cyfaust/resources/architecture/faust/gui/ControlSequenceUI.h +197 -0
- cyfaust/resources/architecture/faust/gui/ControlUI.h +137 -0
- cyfaust/resources/architecture/faust/gui/DaisyControlUI.h +283 -0
- cyfaust/resources/architecture/faust/gui/DaisyPatchInitControlUI.h +254 -0
- cyfaust/resources/architecture/faust/gui/DecoratorUI.h +115 -0
- cyfaust/resources/architecture/faust/gui/Esp32ControlUI.h +341 -0
- cyfaust/resources/architecture/faust/gui/Esp32Reader.h +102 -0
- cyfaust/resources/architecture/faust/gui/Esp32SensorUI.h +137 -0
- cyfaust/resources/architecture/faust/gui/FUI.h +147 -0
- cyfaust/resources/architecture/faust/gui/GTKUI.h +1414 -0
- cyfaust/resources/architecture/faust/gui/GUI.h +465 -0
- cyfaust/resources/architecture/faust/gui/JSONControl.h +48 -0
- cyfaust/resources/architecture/faust/gui/JSONUI.h +722 -0
- cyfaust/resources/architecture/faust/gui/JSONUIDecoder.h +589 -0
- cyfaust/resources/architecture/faust/gui/JuceGUI.h +2061 -0
- cyfaust/resources/architecture/faust/gui/JuceOSCUI.h +163 -0
- cyfaust/resources/architecture/faust/gui/JuceParameterUI.h +158 -0
- cyfaust/resources/architecture/faust/gui/JuceReader.h +103 -0
- cyfaust/resources/architecture/faust/gui/JuceStateUI.h +88 -0
- cyfaust/resources/architecture/faust/gui/LayoutUI.h +423 -0
- cyfaust/resources/architecture/faust/gui/LibsndfileReader.h +366 -0
- cyfaust/resources/architecture/faust/gui/MapUI.h +370 -0
- cyfaust/resources/architecture/faust/gui/MemoryReader.h +111 -0
- cyfaust/resources/architecture/faust/gui/MetaDataUI.h +357 -0
- cyfaust/resources/architecture/faust/gui/MidiUI.h +939 -0
- cyfaust/resources/architecture/faust/gui/OCVUI.h +688 -0
- cyfaust/resources/architecture/faust/gui/OSCUI.h +219 -0
- cyfaust/resources/architecture/faust/gui/PathBuilder.h +228 -0
- cyfaust/resources/architecture/faust/gui/PresetUI.h +337 -0
- cyfaust/resources/architecture/faust/gui/PrintCUI.h +152 -0
- cyfaust/resources/architecture/faust/gui/PrintUI.h +121 -0
- cyfaust/resources/architecture/faust/gui/QTUI.h +1891 -0
- cyfaust/resources/architecture/faust/gui/RosCI.h +493 -0
- cyfaust/resources/architecture/faust/gui/RosUI.h +488 -0
- cyfaust/resources/architecture/faust/gui/SaveUI.h +163 -0
- cyfaust/resources/architecture/faust/gui/SimpleParser.h +583 -0
- cyfaust/resources/architecture/faust/gui/SoundUI.h +217 -0
- cyfaust/resources/architecture/faust/gui/Soundfile.h +342 -0
- cyfaust/resources/architecture/faust/gui/Styles/Blue.qrc +5 -0
- cyfaust/resources/architecture/faust/gui/Styles/Blue.qss +177 -0
- cyfaust/resources/architecture/faust/gui/Styles/Default.qrc +5 -0
- cyfaust/resources/architecture/faust/gui/Styles/Default.qss +117 -0
- cyfaust/resources/architecture/faust/gui/Styles/Grey.qrc +5 -0
- cyfaust/resources/architecture/faust/gui/Styles/Grey.qss +174 -0
- cyfaust/resources/architecture/faust/gui/Styles/Salmon.qrc +5 -0
- cyfaust/resources/architecture/faust/gui/Styles/Salmon.qss +171 -0
- cyfaust/resources/architecture/faust/gui/UI.h +87 -0
- cyfaust/resources/architecture/faust/gui/ValueConverter.h +543 -0
- cyfaust/resources/architecture/faust/gui/WaveReader.h +364 -0
- cyfaust/resources/architecture/faust/gui/console.h +322 -0
- cyfaust/resources/architecture/faust/gui/httpdUI.h +372 -0
- cyfaust/resources/architecture/faust/gui/meta.h +39 -0
- cyfaust/resources/architecture/faust/gui/mspUI.h +580 -0
- cyfaust/resources/architecture/faust/gui/qrcodegen.h +269 -0
- cyfaust/resources/architecture/faust/gui/qrcodegen.impl.h +1025 -0
- cyfaust/resources/architecture/faust/gui/ring-buffer.h +414 -0
- cyfaust/resources/architecture/faust/midi/RtMidi.cpp +3054 -0
- cyfaust/resources/architecture/faust/midi/RtMidi.h +1034 -0
- cyfaust/resources/architecture/faust/midi/bela-midi.h +266 -0
- cyfaust/resources/architecture/faust/midi/daisy-midi.h +116 -0
- cyfaust/resources/architecture/faust/midi/esp32-midi.h +185 -0
- cyfaust/resources/architecture/faust/midi/gramophone-midi.h +107 -0
- cyfaust/resources/architecture/faust/midi/iplug2-midi.h +148 -0
- cyfaust/resources/architecture/faust/midi/jack-midi.h +247 -0
- cyfaust/resources/architecture/faust/midi/juce-midi.h +275 -0
- cyfaust/resources/architecture/faust/midi/midi.h +475 -0
- cyfaust/resources/architecture/faust/midi/rt-midi.h +315 -0
- cyfaust/resources/architecture/faust/midi/teensy-midi.h +89 -0
- cyfaust/resources/architecture/faust/misc.h +106 -0
- cyfaust/resources/architecture/faust/sound-file.h +132 -0
- cyfaust/resources/architecture/faust/unity/AudioPluginInterface.h +301 -0
- cyfaust/resources/architecture/faust/vst/faust.h +141 -0
- cyfaust/resources/architecture/faust/vst/voice.h +43 -0
- cyfaust/resources/architecture/faust/vst/vstui.h +524 -0
- cyfaust/resources/architecture/faustvst.cpp +3435 -0
- cyfaust/resources/architecture/faustvstqt.h +91 -0
- cyfaust/resources/architecture/gen-json.cpp +76 -0
- cyfaust/resources/architecture/jack-console.cpp +267 -0
- cyfaust/resources/architecture/jack-gtk-ros.cpp +139 -0
- cyfaust/resources/architecture/jack-gtk.cpp +282 -0
- cyfaust/resources/architecture/jack-internal.cpp +560 -0
- cyfaust/resources/architecture/jack-qt-chain-footer.cpp +87 -0
- cyfaust/resources/architecture/jack-qt-chain-header.cpp +92 -0
- cyfaust/resources/architecture/jack-qt.cpp +281 -0
- cyfaust/resources/architecture/jack.rs +171 -0
- cyfaust/resources/architecture/juce/README.md +84 -0
- cyfaust/resources/architecture/juce/juce-plugin.cpp +809 -0
- cyfaust/resources/architecture/juce/juce-standalone.cpp +413 -0
- cyfaust/resources/architecture/juce/plugin/plugin-llvm.jucer +184 -0
- cyfaust/resources/architecture/juce/plugin/plugin.jucer +159 -0
- cyfaust/resources/architecture/juce/standalone/standalone-llvm.jucer +216 -0
- cyfaust/resources/architecture/juce/standalone/standalone.jucer +191 -0
- cyfaust/resources/architecture/ladspa.cpp +543 -0
- cyfaust/resources/architecture/latexheader.tex +65 -0
- cyfaust/resources/architecture/lv2.cpp +2090 -0
- cyfaust/resources/architecture/lv2qtgui.h +62 -0
- cyfaust/resources/architecture/lv2ui.cpp +1966 -0
- cyfaust/resources/architecture/max-msp/README.md +109 -0
- cyfaust/resources/architecture/max-msp/faustgen-wrapper-poly.maxpat +184 -0
- cyfaust/resources/architecture/max-msp/faustgen-wrapper.maxpat +163 -0
- cyfaust/resources/architecture/max-msp/max-msp.cpp +734 -0
- cyfaust/resources/architecture/max-msp/max-msp64.cpp +789 -0
- cyfaust/resources/architecture/max-msp/py2max/README.md +277 -0
- cyfaust/resources/architecture/max-msp/py2max/py2max/__init__.py +3 -0
- cyfaust/resources/architecture/max-msp/py2max/py2max/common.py +7 -0
- cyfaust/resources/architecture/max-msp/py2max/py2max/core.py +1387 -0
- cyfaust/resources/architecture/max-msp/py2max/py2max/maxclassdb.py +318 -0
- cyfaust/resources/architecture/max-msp/py2max/py2max/utils.py +20 -0
- cyfaust/resources/architecture/max-msp/rnbo.py +1591 -0
- cyfaust/resources/architecture/max-msp/sndfile/sndfile.h +857 -0
- cyfaust/resources/architecture/max-msp/ui.js +230 -0
- cyfaust/resources/architecture/max-msp/wrapper-poly.maxpat +153 -0
- cyfaust/resources/architecture/max-msp/wrapper.maxpat +131 -0
- cyfaust/resources/architecture/minimal-bench.cpp +100 -0
- cyfaust/resources/architecture/minimal-effect.c +149 -0
- cyfaust/resources/architecture/minimal-effect.cpp +70 -0
- cyfaust/resources/architecture/minimal-fixed-point.cpp +195 -0
- cyfaust/resources/architecture/minimal-static.cpp +160 -0
- cyfaust/resources/architecture/minimal.c +103 -0
- cyfaust/resources/architecture/minimal.cpp +84 -0
- cyfaust/resources/architecture/minimal.rs +223 -0
- cyfaust/resources/architecture/module.cpp +91 -0
- cyfaust/resources/architecture/octave.cpp +471 -0
- cyfaust/resources/architecture/oscio-gtk.cpp +115 -0
- cyfaust/resources/architecture/oscio-qt.cpp +121 -0
- cyfaust/resources/architecture/owl.cpp +345 -0
- cyfaust/resources/architecture/pa-gtk.cpp +119 -0
- cyfaust/resources/architecture/pa-qt.cpp +261 -0
- cyfaust/resources/architecture/path-printer.cpp +100 -0
- cyfaust/resources/architecture/plot.cpp +128 -0
- cyfaust/resources/architecture/portaudio.rs +192 -0
- cyfaust/resources/architecture/puredata.cpp +636 -0
- cyfaust/resources/architecture/ra-qt.cpp +238 -0
- cyfaust/resources/architecture/sam/fast_pow2.h +69 -0
- cyfaust/resources/architecture/sam/fastexp.h +140 -0
- cyfaust/resources/architecture/sam/samFaustDSP.cpp +125 -0
- cyfaust/resources/architecture/sam/samFaustDSP.h +107 -0
- cyfaust/resources/architecture/scheduler.cpp +1391 -0
- cyfaust/resources/architecture/sndfile.cpp +291 -0
- cyfaust/resources/architecture/supercollider.cpp +611 -0
- cyfaust/resources/architecture/teensy/README.md +13 -0
- cyfaust/resources/architecture/teensy/teensy.cpp +214 -0
- cyfaust/resources/architecture/teensy/teensy.h +71 -0
- cyfaust/resources/architecture/thread.h +373 -0
- cyfaust/resources/architecture/vcvrack/README.md +78 -0
- cyfaust/resources/architecture/vcvrack/template/.gitignore +6 -0
- cyfaust/resources/architecture/vcvrack/template/Makefile +22 -0
- cyfaust/resources/architecture/vcvrack/template/res/FaustModule.svg +299 -0
- cyfaust/resources/architecture/vcvrack/template/src/FaustModule.cpp +942 -0
- cyfaust/resources/architecture/vst.cpp +947 -0
- cyfaust/resources/libraries/aanl.lib +900 -0
- cyfaust/resources/libraries/all.lib +36 -0
- cyfaust/resources/libraries/analyzers.lib +980 -0
- cyfaust/resources/libraries/basics.lib +2681 -0
- cyfaust/resources/libraries/compressors.lib +1341 -0
- cyfaust/resources/libraries/delays.lib +401 -0
- cyfaust/resources/libraries/demos.lib +1556 -0
- cyfaust/resources/libraries/dx7.lib +1036 -0
- cyfaust/resources/libraries/effect.lib +1645 -0
- cyfaust/resources/libraries/envelopes.lib +666 -0
- cyfaust/resources/libraries/examples/README.md +13 -0
- cyfaust/resources/libraries/examples/ambisonics/fourSourcesToOcto.dsp +20 -0
- cyfaust/resources/libraries/examples/ambisonics/oneSourceToStereo.dsp +12 -0
- cyfaust/resources/libraries/examples/analysis/FFT.dsp +26 -0
- cyfaust/resources/libraries/examples/analysis/dbmeter.dsp +19 -0
- cyfaust/resources/libraries/examples/analysis/spectralLevel.dsp +8 -0
- cyfaust/resources/libraries/examples/analysis/spectralTiltLab.dsp +20 -0
- cyfaust/resources/libraries/examples/analysis/vumeter.dsp +18 -0
- cyfaust/resources/libraries/examples/autodiff/delay/diff.dsp +2 -0
- cyfaust/resources/libraries/examples/autodiff/delay/gt.dsp +2 -0
- cyfaust/resources/libraries/examples/autodiff/gain/diff.dsp +7 -0
- cyfaust/resources/libraries/examples/autodiff/gain/gt.dsp +1 -0
- cyfaust/resources/libraries/examples/autodiff/gain_dc/diff.dsp +7 -0
- cyfaust/resources/libraries/examples/autodiff/gain_dc/gt.dsp +4 -0
- cyfaust/resources/libraries/examples/autodiff/gain_exp/diff.dsp +9 -0
- cyfaust/resources/libraries/examples/autodiff/gain_exp/gt.dsp +1 -0
- cyfaust/resources/libraries/examples/autodiff/gain_pow/diff.dsp +9 -0
- cyfaust/resources/libraries/examples/autodiff/gain_pow/gt.dsp +1 -0
- cyfaust/resources/libraries/examples/autodiff/gain_pow_trig/diff.dsp +12 -0
- cyfaust/resources/libraries/examples/autodiff/gain_pow_trig/gt.dsp +1 -0
- cyfaust/resources/libraries/examples/autodiff/gain_sq/diff.dsp +7 -0
- cyfaust/resources/libraries/examples/autodiff/gain_sq/gt.dsp +1 -0
- cyfaust/resources/libraries/examples/autodiff/mem/diff.dsp +1 -0
- cyfaust/resources/libraries/examples/autodiff/mem/gt.dsp +1 -0
- cyfaust/resources/libraries/examples/autodiff/noise.dsp +2 -0
- cyfaust/resources/libraries/examples/autodiff/noop.dsp +2 -0
- cyfaust/resources/libraries/examples/autodiff/one_zero/diff.dsp +2 -0
- cyfaust/resources/libraries/examples/autodiff/one_zero/gt.dsp +2 -0
- cyfaust/resources/libraries/examples/autodiff/ramp.dsp +1 -0
- cyfaust/resources/libraries/examples/autodiff/recursion/diff.dsp +2 -0
- cyfaust/resources/libraries/examples/autodiff/recursion/gt.dsp +1 -0
- cyfaust/resources/libraries/examples/autodiff/recursion/target.dsp +13 -0
- cyfaust/resources/libraries/examples/autodiff/tremolo/diff.dsp +14 -0
- cyfaust/resources/libraries/examples/autodiff/tremolo/diffable.lib +7 -0
- cyfaust/resources/libraries/examples/autodiff/tremolo/gt.dsp +11 -0
- cyfaust/resources/libraries/examples/delayEcho/echo.dsp +15 -0
- cyfaust/resources/libraries/examples/delayEcho/quadEcho.dsp +21 -0
- cyfaust/resources/libraries/examples/delayEcho/smoothDelay.dsp +26 -0
- cyfaust/resources/libraries/examples/delayEcho/stereoEcho.dsp +16 -0
- cyfaust/resources/libraries/examples/delayEcho/tapiir.dsp +44 -0
- cyfaust/resources/libraries/examples/dynamic/compressor.dsp +8 -0
- cyfaust/resources/libraries/examples/dynamic/distortion.dsp +8 -0
- cyfaust/resources/libraries/examples/dynamic/gateCompressor.dsp +10 -0
- cyfaust/resources/libraries/examples/dynamic/noiseGate.dsp +8 -0
- cyfaust/resources/libraries/examples/dynamic/volume.dsp +15 -0
- cyfaust/resources/libraries/examples/filtering/APF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/BPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/DNN.dsp +25 -0
- cyfaust/resources/libraries/examples/filtering/HPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/LPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/bandFilter.dsp +44 -0
- cyfaust/resources/libraries/examples/filtering/cryBaby.dsp +4 -0
- cyfaust/resources/libraries/examples/filtering/diodeLadder.dsp +12 -0
- cyfaust/resources/libraries/examples/filtering/filterBank.dsp +6 -0
- cyfaust/resources/libraries/examples/filtering/graphicEqLab.dsp +10 -0
- cyfaust/resources/libraries/examples/filtering/highShelf.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/korg35HPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/korg35LPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/lfBoost.dsp +40 -0
- cyfaust/resources/libraries/examples/filtering/lowBoost.dsp +40 -0
- cyfaust/resources/libraries/examples/filtering/lowCut.dsp +40 -0
- cyfaust/resources/libraries/examples/filtering/lowShelf.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/moogHalfLadder.dsp +12 -0
- cyfaust/resources/libraries/examples/filtering/moogLadder.dsp +12 -0
- cyfaust/resources/libraries/examples/filtering/moogVCF.dsp +6 -0
- cyfaust/resources/libraries/examples/filtering/multibandFilter.dsp +14 -0
- cyfaust/resources/libraries/examples/filtering/notch.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/oberheim.dsp +14 -0
- cyfaust/resources/libraries/examples/filtering/oberheimBPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/oberheimBSF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/oberheimHPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/oberheimLPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/parametricEqLab.dsp +10 -0
- cyfaust/resources/libraries/examples/filtering/parametricEqualizer.dsp +6 -0
- cyfaust/resources/libraries/examples/filtering/peakNotch.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/peakingEQ.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/sallenKey2ndOrder.dsp +14 -0
- cyfaust/resources/libraries/examples/filtering/sallenKey2ndOrderBPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/sallenKey2ndOrderHPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/sallenKey2ndOrderLPF.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/sallenKeyOnePole.dsp +13 -0
- cyfaust/resources/libraries/examples/filtering/sallenKeyOnePoleHPF.dsp +12 -0
- cyfaust/resources/libraries/examples/filtering/sallenKeyOnePoleLPF.dsp +12 -0
- cyfaust/resources/libraries/examples/filtering/spectralTilt.dsp +8 -0
- cyfaust/resources/libraries/examples/filtering/vcfWahLab.dsp +12 -0
- cyfaust/resources/libraries/examples/filtering/vocoder.dsp +8 -0
- cyfaust/resources/libraries/examples/filtering/wahPedal.dsp +6 -0
- cyfaust/resources/libraries/examples/gameaudio/bubble.dsp +42 -0
- cyfaust/resources/libraries/examples/gameaudio/door.dsp +58 -0
- cyfaust/resources/libraries/examples/gameaudio/fire.dsp +46 -0
- cyfaust/resources/libraries/examples/gameaudio/insects.dsp +148 -0
- cyfaust/resources/libraries/examples/gameaudio/rain.dsp +27 -0
- cyfaust/resources/libraries/examples/gameaudio/wind.dsp +23 -0
- cyfaust/resources/libraries/examples/generator/filterOsc.dsp +8 -0
- cyfaust/resources/libraries/examples/generator/noise.dsp +52 -0
- cyfaust/resources/libraries/examples/generator/noiseMetadata.dsp +74 -0
- cyfaust/resources/libraries/examples/generator/osc.dsp +17 -0
- cyfaust/resources/libraries/examples/generator/osci.dsp +17 -0
- cyfaust/resources/libraries/examples/generator/sawtoothLab.dsp +8 -0
- cyfaust/resources/libraries/examples/generator/virtualAnalog.dsp +8 -0
- cyfaust/resources/libraries/examples/generator/virtualAnalogLab.dsp +10 -0
- cyfaust/resources/libraries/examples/misc/UITester.dsp +71 -0
- cyfaust/resources/libraries/examples/misc/autopan.dsp +59 -0
- cyfaust/resources/libraries/examples/misc/capture.dsp +24 -0
- cyfaust/resources/libraries/examples/misc/drumkit.dsp +36 -0
- cyfaust/resources/libraries/examples/misc/guitarix.dsp +184 -0
- cyfaust/resources/libraries/examples/misc/matrix.dsp +17 -0
- cyfaust/resources/libraries/examples/misc/midiTester.dsp +122 -0
- cyfaust/resources/libraries/examples/misc/mixer.dsp +27 -0
- cyfaust/resources/libraries/examples/misc/statespace.dsp +39 -0
- cyfaust/resources/libraries/examples/misc/switcher.dsp +20 -0
- cyfaust/resources/libraries/examples/misc/tester.dsp +32 -0
- cyfaust/resources/libraries/examples/misc/tester2.dsp +31 -0
- cyfaust/resources/libraries/examples/old/README.md +5 -0
- cyfaust/resources/libraries/examples/old/freeverb.dsp +109 -0
- cyfaust/resources/libraries/examples/old/rewriting/Makefile +21 -0
- cyfaust/resources/libraries/examples/old/rewriting/fact.dsp +3 -0
- cyfaust/resources/libraries/examples/old/rewriting/fold.dsp +61 -0
- cyfaust/resources/libraries/examples/old/rewriting/mesh.dsp +43 -0
- cyfaust/resources/libraries/examples/old/rewriting/mesh.pd +37 -0
- cyfaust/resources/libraries/examples/old/rewriting/sample.pd +12 -0
- cyfaust/resources/libraries/examples/old/rewriting/serial.dsp +7 -0
- cyfaust/resources/libraries/examples/old/rewriting/sum.dsp +55 -0
- cyfaust/resources/libraries/examples/old/rewriting/test.pd +48 -0
- cyfaust/resources/libraries/examples/phasing/flanger.dsp +8 -0
- cyfaust/resources/libraries/examples/phasing/phaser.dsp +8 -0
- cyfaust/resources/libraries/examples/phasing/phaserFlangerLab.dsp +12 -0
- cyfaust/resources/libraries/examples/physicalModeling/brass.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/brassMIDI.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/churchBell.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/clarinet.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/clarinetMIDI.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/djembeMIDI.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/elecGuitarMIDI.dsp +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/englishBell.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/NLFeks.dsp +91 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/NLFfm.dsp +70 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/README +125 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/bass.dsp +84 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/bass.h +91 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/blowBottle.dsp +102 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/bowed.dsp +114 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/brass.dsp +103 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/clarinet.dsp +110 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/flute.dsp +116 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/fluteStk.dsp +121 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/glassHarmonica.dsp +131 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/harpsi.dsp +90 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/harpsichord.h +185 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/instrument.h +114 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/modalBar.dsp +122 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/modalBar.h +48 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/audio-out.pd +33 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/bottle.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/clarinets.pd +15 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/canon/audio-out.pd +33 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/canon/bass.pd +162 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/canon/canon.pd +55 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/canon/flute.pd +343 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/canon/pachelbel.mid +0 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/daisy/audio-out.pd +33 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/daisy/daisy.mid +0 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/daisy/daisy.pd +45 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/daisy/piano.pd +205 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/daisy/voiceForm.pd +340 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/take5/audio-out.pd +33 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/take5/blowHole.pd +330 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/take5/piano.pd +205 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/take5/take5.mid +0 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/take5/take5.pd +45 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/turkish-march/audio-out.pd +33 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/turkish-march/harpsi.pd +204 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/turkish-march/turkish-march.mid +0 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/turkish-march/turkish-march.pd +31 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/what-a-friend/audio-out.pd +33 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/what-a-friend/bass.pd +162 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/what-a-friend/modalBar.pd +258 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/what-a-friend/piano.pd +205 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/what-a-friend/what-a-friend.pd +52 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fancy/what-a-friend/what_a_friend.mid +0 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/flutes.pd +15 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/fm.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/glassBare.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/harpsichord-poly.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/ironBare.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/midi-in.pd +111 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/modal.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/osc.pd +26 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/piano-poly.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/plucked.pd +20 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/saxophone.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/tibetan.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/trumpet.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/violin.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/voiceSynth.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/pd-patches/woodenBare.pd +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/phonemes.h +189 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/piano.dsp +255 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/piano.h +751 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/saxophony.dsp +114 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/sitar.dsp +48 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/tibetanBowl.dsp +155 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/tunedBar.dsp +123 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/uniBar.dsp +100 -0
- cyfaust/resources/libraries/examples/physicalModeling/faust-stk/voiceForm.dsp +125 -0
- cyfaust/resources/libraries/examples/physicalModeling/fds/1dDampedWaveEquation.dsp +43 -0
- cyfaust/resources/libraries/examples/physicalModeling/fds/2dKirchhoffThinPlate.dsp +75 -0
- cyfaust/resources/libraries/examples/physicalModeling/fds/BowedString.dsp +61 -0
- cyfaust/resources/libraries/examples/physicalModeling/fds/ControllableNonPhysicalString.dsp +72 -0
- cyfaust/resources/libraries/examples/physicalModeling/fds/HammeredString.dsp +74 -0
- cyfaust/resources/libraries/examples/physicalModeling/fds/PianoHammeredString.dsp +85 -0
- cyfaust/resources/libraries/examples/physicalModeling/fds/StiffString.dsp +54 -0
- cyfaust/resources/libraries/examples/physicalModeling/flute.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/fluteMIDI.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/frenchBell.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/germanBell.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/guitarMIDI.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/karplus.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/marimbaMIDI.dsp +10 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/00_BasicOscillator/harmonicOscillator.dsp +58 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/00_BasicOscillator/harmonicOscillator2.dsp +62 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/00_BasicOscillator/harmonicOscillator3.dsp +65 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/01_ParamControl/paramOsc.dsp +63 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/02_AudioParamControl/audioParamOsc.dsp +63 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/03_HammerTime/hammerOsc.dsp +71 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/04_Gravity/bouncingOsc.dsp +64 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/05_PluckedOscillator/pluckedOsc.dsp +57 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/06_BowedOscillator/bowedOsc.dsp +65 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/07_NonLinearOscillator/nlOsc.dsp +78 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/08_TwoMassChain/2massChain.dsp +75 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/09_TinyString/tinyString.dsp +101 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/10_PluckedString/pluckedString.dsp +678 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/11_BowedString/bowedString.dsp +671 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/12_TriangleMesh/triangleMesh.dsp +448 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/13_Construction/construction.dsp +1036 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/14_Polyphonic/polyTriangle.dsp +79 -0
- cyfaust/resources/libraries/examples/physicalModeling/mi-faust/15_PhysicalLFO/physicalLFO.dsp +107 -0
- cyfaust/resources/libraries/examples/physicalModeling/modularInterpInstrMIDI.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/nylonGuitarMIDI.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/old/harpe.dsp +45 -0
- cyfaust/resources/libraries/examples/physicalModeling/old/karplus.dsp +34 -0
- cyfaust/resources/libraries/examples/physicalModeling/old/karplus32.dsp +47 -0
- cyfaust/resources/libraries/examples/physicalModeling/russianBell.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/standardBell.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/violin.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/violinMIDI.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/vocalBP.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/vocalBPMIDI.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/vocalFOF.dsp +8 -0
- cyfaust/resources/libraries/examples/physicalModeling/vocalFOFMIDI.dsp +8 -0
- cyfaust/resources/libraries/examples/pitchShifting/pitchShifter.dsp +20 -0
- cyfaust/resources/libraries/examples/psychoacoustic/harmonicExciter.dsp +10 -0
- cyfaust/resources/libraries/examples/quantizing/quantizedChords.dsp +49 -0
- cyfaust/resources/libraries/examples/reverb/dattorro.dsp +8 -0
- cyfaust/resources/libraries/examples/reverb/fdnRev.dsp +8 -0
- cyfaust/resources/libraries/examples/reverb/freeverb.dsp +8 -0
- cyfaust/resources/libraries/examples/reverb/greyhole.dsp +8 -0
- cyfaust/resources/libraries/examples/reverb/jprev.dsp +8 -0
- cyfaust/resources/libraries/examples/reverb/reverbDesigner.dsp +12 -0
- cyfaust/resources/libraries/examples/reverb/reverbTester.dsp +8 -0
- cyfaust/resources/libraries/examples/reverb/zitaRev.dsp +8 -0
- cyfaust/resources/libraries/examples/reverb/zitaRevFDN.dsp +8 -0
- cyfaust/resources/libraries/examples/smartKeyboard/acGuitar.dsp +100 -0
- cyfaust/resources/libraries/examples/smartKeyboard/associatedEffects/elecGuitarEffect.dsp +8 -0
- cyfaust/resources/libraries/examples/smartKeyboard/associatedEffects/myEffect.dsp +5 -0
- cyfaust/resources/libraries/examples/smartKeyboard/associatedEffects/reverb.dsp +5 -0
- cyfaust/resources/libraries/examples/smartKeyboard/bells.dsp +80 -0
- cyfaust/resources/libraries/examples/smartKeyboard/bowed.dsp +87 -0
- cyfaust/resources/libraries/examples/smartKeyboard/brass.dsp +82 -0
- cyfaust/resources/libraries/examples/smartKeyboard/clarinet.dsp +113 -0
- cyfaust/resources/libraries/examples/smartKeyboard/crazyGuiro.dsp +96 -0
- cyfaust/resources/libraries/examples/smartKeyboard/drums.dsp +74 -0
- cyfaust/resources/libraries/examples/smartKeyboard/dubDub.dsp +87 -0
- cyfaust/resources/libraries/examples/smartKeyboard/elecGuitar.dsp +67 -0
- cyfaust/resources/libraries/examples/smartKeyboard/fm.dsp +78 -0
- cyfaust/resources/libraries/examples/smartKeyboard/frog.dsp +74 -0
- cyfaust/resources/libraries/examples/smartKeyboard/harp.dsp +84 -0
- cyfaust/resources/libraries/examples/smartKeyboard/midiOnly.dsp +62 -0
- cyfaust/resources/libraries/examples/smartKeyboard/multiSynth.dsp +75 -0
- cyfaust/resources/libraries/examples/smartKeyboard/toy.dsp +71 -0
- cyfaust/resources/libraries/examples/smartKeyboard/trumpet.dsp +59 -0
- cyfaust/resources/libraries/examples/smartKeyboard/turenas.dsp +114 -0
- cyfaust/resources/libraries/examples/smartKeyboard/violin.dsp +91 -0
- cyfaust/resources/libraries/examples/smartKeyboard/violin2.dsp +84 -0
- cyfaust/resources/libraries/examples/smartKeyboard/vocal.dsp +43 -0
- cyfaust/resources/libraries/examples/spat/panpot.dsp +17 -0
- cyfaust/resources/libraries/examples/spat/spat.dsp +25 -0
- cyfaust/resources/libraries/fds.lib +535 -0
- cyfaust/resources/libraries/filter.lib +1710 -0
- cyfaust/resources/libraries/filters.lib +3125 -0
- cyfaust/resources/libraries/hoa.lib +1081 -0
- cyfaust/resources/libraries/instruments.lib +263 -0
- cyfaust/resources/libraries/interpolators.lib +675 -0
- cyfaust/resources/libraries/math.lib +602 -0
- cyfaust/resources/libraries/maths.lib +798 -0
- cyfaust/resources/libraries/maxmsp.lib +237 -0
- cyfaust/resources/libraries/mi.lib +528 -0
- cyfaust/resources/libraries/misceffects.lib +998 -0
- cyfaust/resources/libraries/music.lib +496 -0
- cyfaust/resources/libraries/noises.lib +487 -0
- cyfaust/resources/libraries/oscillator.lib +450 -0
- cyfaust/resources/libraries/oscillators.lib +1838 -0
- cyfaust/resources/libraries/phaflangers.lib +235 -0
- cyfaust/resources/libraries/physmodels.lib +3990 -0
- cyfaust/resources/libraries/platform.lib +59 -0
- cyfaust/resources/libraries/quantizers.lib +310 -0
- cyfaust/resources/libraries/reducemaps.lib +235 -0
- cyfaust/resources/libraries/reverbs.lib +686 -0
- cyfaust/resources/libraries/routes.lib +262 -0
- cyfaust/resources/libraries/sf.lib +53 -0
- cyfaust/resources/libraries/signals.lib +570 -0
- cyfaust/resources/libraries/soundfiles.lib +234 -0
- cyfaust/resources/libraries/spats.lib +173 -0
- cyfaust/resources/libraries/stdfaust.lib +38 -0
- cyfaust/resources/libraries/synths.lib +322 -0
- cyfaust/resources/libraries/tonestacks.lib +427 -0
- cyfaust/resources/libraries/tubes.lib +5039 -0
- cyfaust/resources/libraries/vaeffects.lib +984 -0
- cyfaust/resources/libraries/version.lib +22 -0
- cyfaust/resources/libraries/wdmodels.lib +2276 -0
- cyfaust/resources/libraries/webaudio.lib +402 -0
- cyfaust/signal.pxd +44 -0
- cyfaust/signal.pyx +1993 -0
- cyfaust-0.1.0.dist-info/METADATA +355 -0
- cyfaust-0.1.0.dist-info/RECORD +693 -0
- cyfaust-0.1.0.dist-info/WHEEL +5 -0
- cyfaust-0.1.0.dist-info/entry_points.txt +3 -0
- cyfaust-0.1.0.dist-info/licenses/LICENSE +26 -0
|
@@ -0,0 +1,3990 @@
|
|
|
1
|
+
//##################################### physmodels.lib ###################################
|
|
2
|
+
// Faust physical modeling library. Its official prefix is `pm`.
|
|
3
|
+
//
|
|
4
|
+
// This library provides an environment to facilitate physical modeling of musical
|
|
5
|
+
// instruments. It contains dozens of functions implementing low and high level
|
|
6
|
+
// elements going from a simple waveguide to fully operational models with
|
|
7
|
+
// built-in UI, etc.
|
|
8
|
+
//
|
|
9
|
+
// It is organized as follows:
|
|
10
|
+
//
|
|
11
|
+
// * [Global Variables](#global-variables): useful pre-defined variables for
|
|
12
|
+
// physical modeling (e.g., speed of sound, etc.).
|
|
13
|
+
// * [Conversion Tools](#conversion-tools-1): conversion functions specific
|
|
14
|
+
// to physical modeling (e.g., length to frequency, etc.).
|
|
15
|
+
// * [Bidirectional Utilities](#bidirectional-utilities): functions to create
|
|
16
|
+
// bidirectional block diagrams for physical modeling.
|
|
17
|
+
// * [Basic Elements](#basic-elements-1): waveguides, specific types of filters, etc.
|
|
18
|
+
// * [String Instruments](#string-instruments): various types of strings
|
|
19
|
+
// (e.g., steel, nylon, etc.), bridges, guitars, etc.
|
|
20
|
+
// * [Bowed String Instruments](#bowed-string-instruments): parts and models
|
|
21
|
+
// specific to bowed string instruments (e.g., bows, bridges, violins, etc.).
|
|
22
|
+
// * [Wind Instrument](#wind-instruments): parts and models specific to wind
|
|
23
|
+
// instruments (e.g., reeds, mouthpieces, flutes, clarinets, etc.).
|
|
24
|
+
// * [Exciters](#exciters): pluck generators, "blowers", etc.
|
|
25
|
+
// * [Modal Percussions](#modal-percussions): percussion instruments based on
|
|
26
|
+
// modal models.
|
|
27
|
+
// * [Vocal Synthesis](#vocal-synthesis): functions for various vocal synthesis
|
|
28
|
+
// techniques (e.g., fof, source/filter, etc.) and vocal synthesizers.
|
|
29
|
+
// * [Misc Functions](#misc-functions): any other functions that don't fit in
|
|
30
|
+
// the previous category (e.g., nonlinear filters, etc.).
|
|
31
|
+
//
|
|
32
|
+
// This library is part of the Faust Physical Modeling ToolKit.
|
|
33
|
+
// More information on how to use this library can be found on [this page](https://ccrma.stanford.edu/~rmichon/pmFaust). Tutorials on how to make
|
|
34
|
+
// physical models of musical instruments using Faust can be found
|
|
35
|
+
// [here](https://ccrma.stanford.edu/~rmichon/faustTutorials/#making-physical-models-of-musical-instruments-with-faust) as well.
|
|
36
|
+
//
|
|
37
|
+
// #### References
|
|
38
|
+
// * <https://github.com/grame-cncm/faustlibraries/blob/master/physmodels.lib>
|
|
39
|
+
//########################################################################################
|
|
40
|
+
// Authors: Romain Michon, Pierre-Amaury Grumiaux, and Yann Orlarey
|
|
41
|
+
|
|
42
|
+
import("stdfaust.lib");
|
|
43
|
+
|
|
44
|
+
declare name "Faust Physical Models Library";
|
|
45
|
+
declare version "1.1.0";
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
TODO:
|
|
49
|
+
- It'd be cool to have a version of the block diagram generator that automatically flips
|
|
50
|
+
things based on the use of chains, etc.
|
|
51
|
+
- When setting pole of filters by hand (e.g. smooth, should adjust pole in function of SR)
|
|
52
|
+
- Probably need a single resonator function / see how to integrate that with "mode"
|
|
53
|
+
- Need a non-linear function and see how this can be integrated with modal synthesis
|
|
54
|
+
- See how bowed modal models could be integrated to this
|
|
55
|
+
- Currently still missing keyboard instruments
|
|
56
|
+
- Currently still missing vocal synth: easy to fix (create a formant filter function)
|
|
57
|
+
- Real polyphonic instruments should be designated with some kind of prefix (e.g.,
|
|
58
|
+
full)
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
//=============================Global Variables===========================================
|
|
62
|
+
// Useful pre-defined variables for physical modeling.
|
|
63
|
+
//========================================================================================
|
|
64
|
+
|
|
65
|
+
//--------------`(pm.)speedOfSound`----------
|
|
66
|
+
// Speed of sound in meters per second (340m/s).
|
|
67
|
+
//--------------------------------------
|
|
68
|
+
speedOfSound = 340;
|
|
69
|
+
|
|
70
|
+
//--------------`(pm.)maxLength`----------
|
|
71
|
+
// The default maximum length (3) in meters of strings and tubes used in this
|
|
72
|
+
// library. This variable should be overriden to allow longer strings or tubes.
|
|
73
|
+
//--------------------------------------
|
|
74
|
+
maxLength = 3;
|
|
75
|
+
|
|
76
|
+
//================================Conversion Tools=======================================
|
|
77
|
+
// Useful conversion tools for physical modeling.
|
|
78
|
+
//========================================================================================
|
|
79
|
+
|
|
80
|
+
//--------------`(pm.)f2l`----------
|
|
81
|
+
// Frequency to length in meters.
|
|
82
|
+
//
|
|
83
|
+
// #### Usage
|
|
84
|
+
//
|
|
85
|
+
// ```
|
|
86
|
+
// f2l(freq) : distanceInMeters
|
|
87
|
+
// ```
|
|
88
|
+
//
|
|
89
|
+
// Where:
|
|
90
|
+
//
|
|
91
|
+
// * `freq`: the frequency
|
|
92
|
+
//-------------------------------
|
|
93
|
+
f2l(freq) = speedOfSound/freq;
|
|
94
|
+
|
|
95
|
+
//--------------`(pm.)l2f`----------
|
|
96
|
+
// Length in meters to frequency.
|
|
97
|
+
//
|
|
98
|
+
// #### Usage
|
|
99
|
+
//
|
|
100
|
+
// ```
|
|
101
|
+
// l2f(length) : freq
|
|
102
|
+
// ```
|
|
103
|
+
//
|
|
104
|
+
// Where:
|
|
105
|
+
//
|
|
106
|
+
// * `length`: length/distance in meters
|
|
107
|
+
//-------------------------------
|
|
108
|
+
l2f(length) = speedOfSound/length;
|
|
109
|
+
|
|
110
|
+
//--------------`(pm.)l2s`----------
|
|
111
|
+
// Length in meters to number of samples.
|
|
112
|
+
//
|
|
113
|
+
// #### Usage
|
|
114
|
+
//
|
|
115
|
+
// ```
|
|
116
|
+
// l2s(l) : numberOfSamples
|
|
117
|
+
// ```
|
|
118
|
+
//
|
|
119
|
+
// Where:
|
|
120
|
+
//
|
|
121
|
+
// * `l`: length in meters
|
|
122
|
+
//-------------------------------
|
|
123
|
+
l2s(l) = l*ma.SR/speedOfSound;
|
|
124
|
+
|
|
125
|
+
//=============================Bidirectional Utilities====================================
|
|
126
|
+
// Set of fundamental functions to create bi-directional block diagrams in Faust.
|
|
127
|
+
// These elements are used as the basis of this library to connect high level
|
|
128
|
+
// elements (e.g., mouthpieces, strings, bridge, instrument body, etc.). Each
|
|
129
|
+
// block has 3 inputs and 3 outputs. The first input/output carry left going
|
|
130
|
+
// waves, the second input/output carry right going waves, and the third
|
|
131
|
+
// input/output is used to carry any potential output signal to the end of the
|
|
132
|
+
// algorithm.
|
|
133
|
+
//========================================================================================
|
|
134
|
+
|
|
135
|
+
//--------------`(pm.)basicBlock`----------
|
|
136
|
+
// Empty bidirectional block to be used with [`chain`](#chain): 3 signals ins
|
|
137
|
+
// and 3 signals out.
|
|
138
|
+
//
|
|
139
|
+
// #### Usage
|
|
140
|
+
//
|
|
141
|
+
// ```
|
|
142
|
+
// chain(basicBlock : basicBlock : etc.)
|
|
143
|
+
// ```
|
|
144
|
+
//-------------------------------
|
|
145
|
+
basicBlock = _,_,_;
|
|
146
|
+
|
|
147
|
+
//-------`(pm.)chain`----------
|
|
148
|
+
// Creates a chain of bidirectional blocks.
|
|
149
|
+
// Blocks must have 3 inputs and outputs. The first input/output carry left
|
|
150
|
+
// going waves, the second input/output carry right going waves, and the third
|
|
151
|
+
// input/output is used to carry any potential output signal to the end of the
|
|
152
|
+
// algorithm. The implied one sample delay created by the `~` operator is
|
|
153
|
+
// generalized to the left and right going waves. Thus, `n` blocks in `chain()`
|
|
154
|
+
// will add an `n` samples delay to both left and right going waves.
|
|
155
|
+
//
|
|
156
|
+
// #### Usage
|
|
157
|
+
//
|
|
158
|
+
// ```
|
|
159
|
+
// leftGoingWaves,rightGoingWaves,mixedOutput : chain( A : B ) : leftGoingWaves,rightGoingWaves,mixedOutput
|
|
160
|
+
// with{
|
|
161
|
+
// A = _,_,_;
|
|
162
|
+
// B = _,_,_;
|
|
163
|
+
// };
|
|
164
|
+
// ```
|
|
165
|
+
//-----------------------------
|
|
166
|
+
chain(A:As) = ((ro.crossnn(1),_',_ : _,A : ro.crossnn(1),_,_ : _,chain(As) : ro.crossnn(1),_,_)) ~ _ : !,_,_,_;
|
|
167
|
+
chain(A) = A;
|
|
168
|
+
|
|
169
|
+
//-------`(pm.)inLeftWave`--------------
|
|
170
|
+
// Adds a signal to left going waves anywhere in a [`chain`](#chain) of blocks.
|
|
171
|
+
//
|
|
172
|
+
// #### Usage
|
|
173
|
+
//
|
|
174
|
+
// ```
|
|
175
|
+
// model(x) = chain(A : inLeftWave(x) : B)
|
|
176
|
+
// ```
|
|
177
|
+
//
|
|
178
|
+
// Where `A` and `B` are bidirectional blocks and `x` is the signal added to left
|
|
179
|
+
// going waves in that chain.
|
|
180
|
+
//--------------------------------
|
|
181
|
+
inLeftWave(x) = +(x),_,_;
|
|
182
|
+
|
|
183
|
+
//-------`(pm.)inRightWave`--------------
|
|
184
|
+
// Adds a signal to right going waves anywhere in a [`chain`](#chain) of blocks.
|
|
185
|
+
//
|
|
186
|
+
// #### Usage
|
|
187
|
+
//
|
|
188
|
+
// ```
|
|
189
|
+
// model(x) = chain(A : inRightWave(x) : B)
|
|
190
|
+
// ```
|
|
191
|
+
//
|
|
192
|
+
// Where `A` and `B` are bidirectional blocks and `x` is the signal added to right
|
|
193
|
+
// going waves in that chain.
|
|
194
|
+
//--------------------------------
|
|
195
|
+
inRightWave(x) = _,+(x),_;
|
|
196
|
+
|
|
197
|
+
//-------`(pm.)in`--------------
|
|
198
|
+
// Adds a signal to left and right going waves anywhere in a [`chain`](#chain)
|
|
199
|
+
// of blocks.
|
|
200
|
+
//
|
|
201
|
+
// #### Usage
|
|
202
|
+
//
|
|
203
|
+
// ```
|
|
204
|
+
// model(x) = chain(A : in(x) : B)
|
|
205
|
+
// ```
|
|
206
|
+
//
|
|
207
|
+
// Where `A` and `B` are bidirectional blocks and `x` is the signal added to
|
|
208
|
+
// left and right going waves in that chain.
|
|
209
|
+
//--------------------------------
|
|
210
|
+
in(x) = +(x),+(x),_;
|
|
211
|
+
|
|
212
|
+
//-------`(pm.)outLeftWave`--------------
|
|
213
|
+
// Sends the signal of left going waves to the output channel of the [`chain`](#chain).
|
|
214
|
+
//
|
|
215
|
+
// #### Usage
|
|
216
|
+
//
|
|
217
|
+
// ```
|
|
218
|
+
// chain(A : outLeftWave : B)
|
|
219
|
+
// ```
|
|
220
|
+
//
|
|
221
|
+
// Where `A` and `B` are bidirectional blocks.
|
|
222
|
+
//--------------------------------
|
|
223
|
+
outLeftWave(x,y,s) = x,y,x+s;
|
|
224
|
+
|
|
225
|
+
//-------`(pm.)outRightWave`--------------
|
|
226
|
+
// Sends the signal of right going waves to the output channel of the [`chain`](#chain).
|
|
227
|
+
//
|
|
228
|
+
// #### Usage
|
|
229
|
+
//
|
|
230
|
+
// ```
|
|
231
|
+
// chain(A : outRightWave : B)
|
|
232
|
+
// ```
|
|
233
|
+
//
|
|
234
|
+
// Where `A` and `B` are bidirectional blocks.
|
|
235
|
+
//--------------------------------
|
|
236
|
+
outRightWave(x,y,s) = x,y,y+s;
|
|
237
|
+
|
|
238
|
+
//-------`(pm.)out`--------------
|
|
239
|
+
// Sends the signal of right and left going waves to the output channel of the
|
|
240
|
+
// [`chain`](#chain).
|
|
241
|
+
//
|
|
242
|
+
// #### Usage
|
|
243
|
+
//
|
|
244
|
+
// ```
|
|
245
|
+
// chain(A : out : B)
|
|
246
|
+
// ```
|
|
247
|
+
//
|
|
248
|
+
// Where `A` and `B` are bidirectional blocks.
|
|
249
|
+
//--------------------------------
|
|
250
|
+
out(x,y,s) = x,y,x+y+s;
|
|
251
|
+
|
|
252
|
+
//-------`(pm.)terminations`--------------
|
|
253
|
+
// Creates terminations on both sides of a [`chain`](#chain) without closing
|
|
254
|
+
// the inputs and outputs of the bidirectional signals chain. As for
|
|
255
|
+
// [`chain`](#chain), this function adds a 1 sample delay to the bidirectional
|
|
256
|
+
// signal, both ways. Of course, this function can be nested within a
|
|
257
|
+
// [`chain`](#chain).
|
|
258
|
+
//
|
|
259
|
+
// #### Usage
|
|
260
|
+
//
|
|
261
|
+
// ```
|
|
262
|
+
// terminations(a,b,c)
|
|
263
|
+
// with{
|
|
264
|
+
// a = *(-1); // left termination
|
|
265
|
+
// b = chain(D : E : F); // bidirectional chain of blocks (D, E, F, etc.)
|
|
266
|
+
// c = *(-1); // right termination
|
|
267
|
+
// };
|
|
268
|
+
// ```
|
|
269
|
+
//----------------------------------------
|
|
270
|
+
terminations(a,b,c) = (_,ro.crossnn(1),_,_ : +,+,_ : b) ~ (a,c : ro.crossnn(1));
|
|
271
|
+
|
|
272
|
+
//-------`(pm.)lTermination`----------
|
|
273
|
+
// Creates a termination on the left side of a [`chain`](#chain) without
|
|
274
|
+
// closing the inputs and outputs of the bidirectional signals chain. This
|
|
275
|
+
// function adds a 1 sample delay near the termination and can be nested
|
|
276
|
+
// within another [`chain`](#chain).
|
|
277
|
+
//
|
|
278
|
+
// #### Usage
|
|
279
|
+
//
|
|
280
|
+
// ```
|
|
281
|
+
// lTerminations(a,b)
|
|
282
|
+
// with{
|
|
283
|
+
// a = *(-1); // left termination
|
|
284
|
+
// b = chain(D : E : F); // bidirectional chain of blocks (D, E, F, etc.)
|
|
285
|
+
// };
|
|
286
|
+
// ```
|
|
287
|
+
//----------------------------------------
|
|
288
|
+
lTermination(a,b) = (ro.crossnn(1),_,_ : _,+,_ : b) ~ a;
|
|
289
|
+
|
|
290
|
+
//-------`(pm.)rTermination`----------
|
|
291
|
+
// Creates a termination on the right side of a [`chain`](#chain) without
|
|
292
|
+
// closing the inputs and outputs of the bidirectional signals chain. This
|
|
293
|
+
// function adds a 1 sample delay near the termination and can be nested
|
|
294
|
+
// within another [`chain`](#chain).
|
|
295
|
+
//
|
|
296
|
+
// #### Usage
|
|
297
|
+
//
|
|
298
|
+
// ```
|
|
299
|
+
// rTerminations(b,c)
|
|
300
|
+
// with{
|
|
301
|
+
// b = chain(D : E : F); // bidirectional chain of blocks (D, E, F, etc.)
|
|
302
|
+
// c = *(-1); // right termination
|
|
303
|
+
// };
|
|
304
|
+
// ```
|
|
305
|
+
//----------------------------------------
|
|
306
|
+
rTermination(b,c) = (_,_,_,_ : +,_,_ : b) ~ (!,c);
|
|
307
|
+
|
|
308
|
+
//-------`(pm.)closeIns`----------
|
|
309
|
+
// Closes the inputs of a bidirectional chain in all directions.
|
|
310
|
+
//
|
|
311
|
+
// #### Usage
|
|
312
|
+
//
|
|
313
|
+
// ```
|
|
314
|
+
// closeIns : chain(...) : _,_,_
|
|
315
|
+
// ```
|
|
316
|
+
//----------------------------------------
|
|
317
|
+
closeIns = 0,0,0;
|
|
318
|
+
|
|
319
|
+
//-------`(pm.)closeOuts`----------
|
|
320
|
+
// Closes the outputs of a bidirectional chain in all directions except for the
|
|
321
|
+
// main signal output (3d output).
|
|
322
|
+
//
|
|
323
|
+
// #### Usage
|
|
324
|
+
//
|
|
325
|
+
// ```
|
|
326
|
+
// _,_,_ : chain(...) : _
|
|
327
|
+
// ```
|
|
328
|
+
//----------------------------------------
|
|
329
|
+
closeOuts = !,!,_;
|
|
330
|
+
|
|
331
|
+
//-------`(pm.)endChain`----------
|
|
332
|
+
// Closes the inputs and outputs of a bidirectional chain in all directions
|
|
333
|
+
// except for the main signal output (3d output).
|
|
334
|
+
//
|
|
335
|
+
// #### Usage
|
|
336
|
+
//
|
|
337
|
+
// ```
|
|
338
|
+
// endChain(chain(...)) : _
|
|
339
|
+
// ```
|
|
340
|
+
//----------------------------------------
|
|
341
|
+
endChain(b) = closeIns : b : closeOuts;
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
//==================================Basic Elements========================================
|
|
345
|
+
// Basic elements for physical modeling (e.g., waveguides, specific filters,
|
|
346
|
+
// etc.).
|
|
347
|
+
//========================================================================================
|
|
348
|
+
|
|
349
|
+
//-------`(pm.)waveguideN`----------
|
|
350
|
+
// A series of waveguide functions based on various types of delays (see
|
|
351
|
+
// [`fdelay[n]`](#fdelayn)).
|
|
352
|
+
//
|
|
353
|
+
// #### List of functions
|
|
354
|
+
//
|
|
355
|
+
// * `waveguideUd`: unit delay waveguide
|
|
356
|
+
// * `waveguideFd`: fractional delay waveguide
|
|
357
|
+
// * `waveguideFd2`: second order fractional delay waveguide
|
|
358
|
+
// * `waveguideFd4`: fourth order fractional delay waveguide
|
|
359
|
+
//
|
|
360
|
+
// #### Usage
|
|
361
|
+
//
|
|
362
|
+
// ```
|
|
363
|
+
// chain(A : waveguideUd(nMax,n) : B)
|
|
364
|
+
// ```
|
|
365
|
+
//
|
|
366
|
+
// Where:
|
|
367
|
+
//
|
|
368
|
+
// * `nMax`: the maximum length of the delays in the waveguide
|
|
369
|
+
// * `n`: the length of the delay lines in samples.
|
|
370
|
+
//----------------------------------
|
|
371
|
+
waveguideUd(nMax,n) = par(i,2,de.delay(nMax,n)),_;
|
|
372
|
+
waveguideFd(nMax,n) = par(i,2,de.fdelay(nMax,n)),_;
|
|
373
|
+
waveguideFd2(nMax,n) = par(i,2,de.fdelay2(nMax,n)),_;
|
|
374
|
+
waveguideFd4(nMax,n) = par(i,2,de.fdelay4(nMax,n)),_;
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
//-------`(pm.)waveguide`----------
|
|
378
|
+
// Standard `pm.lib` waveguide (based on [`waveguideFd4`](#waveguiden)).
|
|
379
|
+
//
|
|
380
|
+
// #### Usage
|
|
381
|
+
//
|
|
382
|
+
// ```
|
|
383
|
+
// chain(A : waveguide(nMax,n) : B)
|
|
384
|
+
// ```
|
|
385
|
+
//
|
|
386
|
+
// Where:
|
|
387
|
+
//
|
|
388
|
+
// * `nMax`: the maximum length of the delays in the waveguide
|
|
389
|
+
// * `n`: the length of the delay lines in samples.
|
|
390
|
+
//----------------------------------
|
|
391
|
+
waveguide(nMax,n) = waveguideFd4(nMax,n);
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
//-------`(pm.)bridgeFilter`----------
|
|
395
|
+
// Generic two zeros bridge FIR filter (as implemented in the
|
|
396
|
+
// [STK](https://ccrma.stanford.edu/software/stk/)) that can be used to
|
|
397
|
+
// implement the reflectance violin, guitar, etc. bridges.
|
|
398
|
+
//
|
|
399
|
+
// #### Usage
|
|
400
|
+
//
|
|
401
|
+
// ```
|
|
402
|
+
// _ : bridge(brightness,absorption) : _
|
|
403
|
+
// ```
|
|
404
|
+
//
|
|
405
|
+
// Where:
|
|
406
|
+
//
|
|
407
|
+
// * `brightness`: controls the damping of high frequencies (0-1)
|
|
408
|
+
// * `absorption`: controls the absorption of the brige and thus the t60 of
|
|
409
|
+
// the string plugged to it (0-1) (1 = 20 seconds)
|
|
410
|
+
//----------------------------------
|
|
411
|
+
// TODO: perhaps, the coefs of this filter should be adapted in function of SR
|
|
412
|
+
bridgeFilter(brightness,absorption,x) = rho * (h0 * x' + h1*(x+x''))
|
|
413
|
+
with{
|
|
414
|
+
freq = 320;
|
|
415
|
+
t60 = (1-absorption)*20;
|
|
416
|
+
h0 = (1.0 + brightness)/2;
|
|
417
|
+
h1 = (1.0 - brightness)/4;
|
|
418
|
+
rho = pow(0.001,1.0/(freq*t60));
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
//-------`(pm.)modeFilter`----------
|
|
423
|
+
// Resonant bandpass filter that can be used to implement a single resonance
|
|
424
|
+
// (mode).
|
|
425
|
+
//
|
|
426
|
+
// #### Usage
|
|
427
|
+
//
|
|
428
|
+
// ```
|
|
429
|
+
// _ : modeFilter(freq,t60,gain) : _
|
|
430
|
+
// ```
|
|
431
|
+
//
|
|
432
|
+
// Where:
|
|
433
|
+
//
|
|
434
|
+
// * `freq`: mode frequency
|
|
435
|
+
// * `t60`: mode resonance duration (in seconds)
|
|
436
|
+
// * `gain`: mode gain (0-1)
|
|
437
|
+
//----------------------------------
|
|
438
|
+
modeFilter(freq,t60,gain) = fi.tf2(b0,b1,b2,a1,a2)*gain
|
|
439
|
+
with{
|
|
440
|
+
b0 = 1;
|
|
441
|
+
b1 = 0;
|
|
442
|
+
b2 = -1;
|
|
443
|
+
w = 2*ma.PI*freq/ma.SR;
|
|
444
|
+
r = pow(0.001,1/float(t60*ma.SR));
|
|
445
|
+
a1 = -2*r*cos(w);
|
|
446
|
+
a2 = r^2;
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
//================================String Instruments======================================
|
|
451
|
+
// Low and high level string instruments parts. Most of the elements in
|
|
452
|
+
// this section can be used in a bidirectional chain.
|
|
453
|
+
//========================================================================================
|
|
454
|
+
|
|
455
|
+
//-------`(pm.)stringSegment`----------
|
|
456
|
+
// A string segment without terminations (just a simple waveguide).
|
|
457
|
+
//
|
|
458
|
+
// #### Usage
|
|
459
|
+
//
|
|
460
|
+
// ```
|
|
461
|
+
// chain(A : stringSegment(maxLength,length) : B)
|
|
462
|
+
// ```
|
|
463
|
+
//
|
|
464
|
+
// Where:
|
|
465
|
+
//
|
|
466
|
+
// * `maxLength`: the maximum length of the string in meters (should be static)
|
|
467
|
+
// * `length`: the length of the string in meters
|
|
468
|
+
//----------------------------------
|
|
469
|
+
stringSegment(maxLength,length) = waveguide(nMax,n)
|
|
470
|
+
with{
|
|
471
|
+
nMax = maxLength : l2s;
|
|
472
|
+
n = length : l2s/2;
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
//-------`(pm.)openString`----------
|
|
477
|
+
// A bidirectional block implementing a basic "generic" string with a
|
|
478
|
+
// selectable excitation position. Lowpass filters are built-in and
|
|
479
|
+
// allow to simulate the effect of dispersion on the sound and thus
|
|
480
|
+
// to change the "stiffness" of the string.
|
|
481
|
+
//
|
|
482
|
+
// #### Usage
|
|
483
|
+
//
|
|
484
|
+
// ```
|
|
485
|
+
// chain(... : openString(length,stiffness,pluckPosition,excitation) : ...)
|
|
486
|
+
// ```
|
|
487
|
+
//
|
|
488
|
+
// Where:
|
|
489
|
+
//
|
|
490
|
+
// * `length`: the length of the string in meters
|
|
491
|
+
// * `stiffness`: the stiffness of the string (0-1) (1 for max stiffness)
|
|
492
|
+
// * `pluckPosition`: excitation position (0-1) (1 is bottom)
|
|
493
|
+
// * `excitation`: the excitation signal
|
|
494
|
+
//----------------------------------
|
|
495
|
+
openString(length,stiffness,pluckPosition,excitation) = chain(stringSegment(maxStringLength,ntbd) : in(excitation) : dispersionFilters : stringSegment(maxStringLength,btbd))
|
|
496
|
+
with{
|
|
497
|
+
dispersionFilters = par(i,2,si.smooth(stiffness)),_; // one pole filters
|
|
498
|
+
maxStringLength = maxLength;
|
|
499
|
+
ntbd = length*pluckPosition; // length of the upper portion of the string
|
|
500
|
+
btbd = length*(1-pluckPosition); // length of the lower portion of the string
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
//-------`(pm.)nylonString`----------
|
|
505
|
+
// A bidirectional block implementing a basic nylon string with selectable
|
|
506
|
+
// excitation position. This element is based on [`openString`](#openstring)
|
|
507
|
+
// and has a fix stiffness corresponding to that of a nylon string.
|
|
508
|
+
//
|
|
509
|
+
// #### Usage
|
|
510
|
+
//
|
|
511
|
+
// ```
|
|
512
|
+
// chain(... : nylonString(length,pluckPosition,excitation) : ...)
|
|
513
|
+
// ```
|
|
514
|
+
//
|
|
515
|
+
// Where:
|
|
516
|
+
//
|
|
517
|
+
// * `length`: the length of the string in meters
|
|
518
|
+
// * `pluckPosition`: excitation position (0-1) (1 is bottom)
|
|
519
|
+
// * `excitation`: the excitation signal
|
|
520
|
+
//----------------------------------
|
|
521
|
+
nylonString(length,pluckPosition,excitation) =
|
|
522
|
+
openString(length,stiffness,pluckPosition,excitation)
|
|
523
|
+
with{
|
|
524
|
+
stiffness = 0.4; // empirically set but it sounds good ;)
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
//-------`(pm.)steelString`----------
|
|
529
|
+
// A bidirectional block implementing a basic steel string with selectable
|
|
530
|
+
// excitation position. This element is based on [`openString`](#openstring)
|
|
531
|
+
// and has a fix stiffness corresponding to that of a steel string.
|
|
532
|
+
//
|
|
533
|
+
// #### Usage
|
|
534
|
+
//
|
|
535
|
+
// ```
|
|
536
|
+
// chain(... : steelString(length,pluckPosition,excitation) : ...)
|
|
537
|
+
// ```
|
|
538
|
+
//
|
|
539
|
+
// Where:
|
|
540
|
+
//
|
|
541
|
+
// * `length`: the length of the string in meters
|
|
542
|
+
// * `pluckPosition`: excitation position (0-1) (1 is bottom)
|
|
543
|
+
// * `excitation`: the excitation signal
|
|
544
|
+
//----------------------------------
|
|
545
|
+
steelString(length,pluckPosition,excitation) =
|
|
546
|
+
openString(length,stiffness,pluckPosition,excitation)
|
|
547
|
+
with{
|
|
548
|
+
stiffness = 0.05; // empirically set but it sounds good ;)
|
|
549
|
+
// in fact, we could almost get rid of the filters in that case,
|
|
550
|
+
// but I think it's good to keep them for consistency
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
//-------`(pm.)openStringPick`----------
|
|
555
|
+
// A bidirectional block implementing a "generic" string with selectable
|
|
556
|
+
// excitation position. It also has a built-in pickup whose position is the
|
|
557
|
+
// same as the excitation position. Thus, moving the excitation position
|
|
558
|
+
// will also move the pickup.
|
|
559
|
+
//
|
|
560
|
+
// #### Usage
|
|
561
|
+
//
|
|
562
|
+
// ```
|
|
563
|
+
// chain(... : openStringPick(length,stiffness,pluckPosition,excitation) : ...)
|
|
564
|
+
// ```
|
|
565
|
+
//
|
|
566
|
+
// Where:
|
|
567
|
+
//
|
|
568
|
+
// * `length`: the length of the string in meters
|
|
569
|
+
// * `stiffness`: the stiffness of the string (0-1) (1 for max stiffness)
|
|
570
|
+
// * `pluckPosition`: excitation position (0-1) (1 is bottom)
|
|
571
|
+
// * `excitation`: the excitation signal
|
|
572
|
+
//----------------------------------
|
|
573
|
+
openStringPick(length,stiffness,pluckPosition,excitation) = strChain
|
|
574
|
+
with{
|
|
575
|
+
dispersionFilters = par(i,2,si.smooth(stiffness)),_;
|
|
576
|
+
maxStringLength = maxLength;
|
|
577
|
+
nti = length*pluckPosition; // length of the upper portion of the string
|
|
578
|
+
itb = length*(1-pluckPosition); // length of the lower portion of the string
|
|
579
|
+
strChain = chain(stringSegment(maxStringLength,nti) : in(excitation) : out :
|
|
580
|
+
dispersionFilters : stringSegment(maxStringLength,itb));
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
//-------`(pm.)openStringPickUp`----------
|
|
585
|
+
// A bidirectional block implementing a "generic" string with selectable
|
|
586
|
+
// excitation position and stiffness. It also has a built-in pickup whose
|
|
587
|
+
// position can be independenly selected. The only constraint is that the
|
|
588
|
+
// pickup has to be placed after the excitation position.
|
|
589
|
+
//
|
|
590
|
+
// #### Usage
|
|
591
|
+
//
|
|
592
|
+
// ```
|
|
593
|
+
// chain(... : openStringPickUp(length,stiffness,pluckPosition,excitation) : ...)
|
|
594
|
+
// ```
|
|
595
|
+
//
|
|
596
|
+
// Where:
|
|
597
|
+
//
|
|
598
|
+
// * `length`: the length of the string in meters
|
|
599
|
+
// * `stiffness`: the stiffness of the string (0-1) (1 for max stiffness)
|
|
600
|
+
// * `pluckPosition`: pluck position between the top of the string and the
|
|
601
|
+
// pickup (0-1) (1 for same as pickup position)
|
|
602
|
+
// * `pickupPosition`: position of the pickup on the string (0-1) (1 is bottom)
|
|
603
|
+
// * `excitation`: the excitation signal
|
|
604
|
+
//----------------------------------
|
|
605
|
+
openStringPickUp(length,stiffness,pluckPosition,pickupPosition,excitation) = strChain
|
|
606
|
+
with{
|
|
607
|
+
dispersionFilters = par(i,2,si.smooth(stiffness)),_;
|
|
608
|
+
maxStringLength = maxLength;
|
|
609
|
+
nti = length*pluckPosition; // top to excitation length
|
|
610
|
+
nto = nti*pickupPosition; // nuts to pickup length
|
|
611
|
+
oti = nti*(1-pickupPosition); // pickup to excitation length
|
|
612
|
+
itb = length*(1-pluckPosition); // pickup to bottom length
|
|
613
|
+
strChain = chain(stringSegment(maxStringLength,nto) : out :
|
|
614
|
+
stringSegment(maxStringLength,oti) : in(excitation) : dispersionFilters :
|
|
615
|
+
stringSegment(maxStringLength,itb));
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
//-------`(pm.)openStringPickDown`----------
|
|
620
|
+
// A bidirectional block implementing a "generic" string with selectable
|
|
621
|
+
// excitation position and stiffness. It also has a built-in pickup whose
|
|
622
|
+
// position can be independenly selected. The only constraint is that the
|
|
623
|
+
// pickup has to be placed before the excitation position.
|
|
624
|
+
//
|
|
625
|
+
// #### Usage
|
|
626
|
+
//
|
|
627
|
+
// ```
|
|
628
|
+
// chain(... : openStringPickDown(length,stiffness,pluckPosition,excitation) : ...)
|
|
629
|
+
// ```
|
|
630
|
+
//
|
|
631
|
+
// Where:
|
|
632
|
+
//
|
|
633
|
+
// * `length`: the length of the string in meters
|
|
634
|
+
// * `stiffness`: the stiffness of the string (0-1) (1 for max stiffness)
|
|
635
|
+
// * `pluckPosition`: pluck position on the string (0-1) (1 is bottom)
|
|
636
|
+
// * `pickupPosition`: position of the pickup between the top of the string
|
|
637
|
+
// and the excitation position (0-1) (1 is excitation position)
|
|
638
|
+
// * `excitation`: the excitation signal
|
|
639
|
+
//----------------------------------
|
|
640
|
+
openStringPickDown(length,stiffness,pluckPosition,pickupPosition,excitation) =
|
|
641
|
+
strChain
|
|
642
|
+
with{
|
|
643
|
+
dispersionFilters = par(i,2,si.smooth(stiffness)),_;
|
|
644
|
+
maxStringLength = maxLength;
|
|
645
|
+
nto = length*pickupPosition; // top to pickup length
|
|
646
|
+
nti = nto*pluckPosition; // top to excitation length
|
|
647
|
+
ito = nto*(1-pluckPosition); // excitation to pickup length
|
|
648
|
+
otb = length*(1-pickupPosition); // pickup to bottom length
|
|
649
|
+
strChain = chain(stringSegment(maxStringLength,nti) : in(excitation) :
|
|
650
|
+
stringSegment(maxStringLength,ito) : out : dispersionFilters :
|
|
651
|
+
stringSegment(maxStringLength,otb));
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
// TODO: eventually, we'd want to implement a generic function here that
|
|
656
|
+
// automatically switches the position of elements in the algorithm
|
|
657
|
+
// depending on the position of the pick. Even though this is currently
|
|
658
|
+
// possible, it will pose optimization issues (we'd want the new mute
|
|
659
|
+
// feature of Faust to be generalized in order to do that)
|
|
660
|
+
|
|
661
|
+
//-------`(pm.)ksReflexionFilter`----------
|
|
662
|
+
// The "typical" one-zero Karplus-strong feedforward reflexion filter. This
|
|
663
|
+
// filter will be typically used in a termination (see below).
|
|
664
|
+
//
|
|
665
|
+
// #### Usage
|
|
666
|
+
//
|
|
667
|
+
// ```
|
|
668
|
+
// terminations(_,chain(...),ksReflexionFilter)
|
|
669
|
+
// ```
|
|
670
|
+
//----------------------------------
|
|
671
|
+
ksReflexionFilter = _ <: (_+_')/2;
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
//-------`(pm.)rStringRigidTermination`----------
|
|
675
|
+
// Bidirectional block implementing a right rigid string termination (no damping,
|
|
676
|
+
// just phase inversion).
|
|
677
|
+
//
|
|
678
|
+
// #### Usage
|
|
679
|
+
//
|
|
680
|
+
// ```
|
|
681
|
+
// chain(rStringRigidTermination : stringSegment : ...)
|
|
682
|
+
// ```
|
|
683
|
+
//----------------------------------
|
|
684
|
+
rStringRigidTermination = rTermination(basicBlock,*(-1));
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
//-------`(pm.)lStringRigidTermination`----------
|
|
688
|
+
// Bidirectional block implementing a left rigid string termination (no damping,
|
|
689
|
+
// just phase inversion).
|
|
690
|
+
//
|
|
691
|
+
// #### Usage
|
|
692
|
+
//
|
|
693
|
+
// ```
|
|
694
|
+
// chain(... : stringSegment : lStringRigidTermination)
|
|
695
|
+
// ```
|
|
696
|
+
//----------------------------------
|
|
697
|
+
lStringRigidTermination = lTermination(*(-1),basicBlock);
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
//-------`(pm.)elecGuitarBridge`----------
|
|
701
|
+
// Bidirectional block implementing a simple electric guitar bridge. This
|
|
702
|
+
// block is based on [`bridgeFilter`](#bridgeFilter). The bridge doesn't
|
|
703
|
+
// implement transmittance since it is not meant to be connected to a
|
|
704
|
+
// body (unlike acoustic guitar). It also partially sets the resonance
|
|
705
|
+
// duration of the string with the nuts used on the other side.
|
|
706
|
+
//
|
|
707
|
+
// #### Usage
|
|
708
|
+
//
|
|
709
|
+
// ```
|
|
710
|
+
// chain(... : stringSegment : elecGuitarBridge)
|
|
711
|
+
// ```
|
|
712
|
+
//----------------------------------
|
|
713
|
+
elecGuitarBridge = rTermination(basicBlock,-bridgeFilter(0.8,0.6));
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
//-------`(pm.)elecGuitarNuts`----------
|
|
717
|
+
// Bidirectional block implementing a simple electric guitar nuts. This
|
|
718
|
+
// block is based on [`bridgeFilter`](#bridgeFilter) and does essentially
|
|
719
|
+
// the same thing as [`elecGuitarBridge`](#elecguitarbridge), but on the
|
|
720
|
+
// other side of the chain. It also partially sets the resonance duration of
|
|
721
|
+
// the string with the bridge used on the other side.
|
|
722
|
+
//
|
|
723
|
+
// #### Usage
|
|
724
|
+
//
|
|
725
|
+
// ```
|
|
726
|
+
// chain(elecGuitarNuts : stringSegment : ...)
|
|
727
|
+
// ```
|
|
728
|
+
//----------------------------------
|
|
729
|
+
elecGuitarNuts = lTermination(-bridgeFilter(0.8,0.6),basicBlock);
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
//-------`(pm.)guitarBridge`----------
|
|
733
|
+
// Bidirectional block implementing a simple acoustic guitar bridge. This
|
|
734
|
+
// bridge damps more hight frequencies than
|
|
735
|
+
// [`elecGuitarBridge`](#elecguitarbridge) and implements a transmittance
|
|
736
|
+
// filter. It also partially sets the resonance duration of the string with
|
|
737
|
+
// the nuts used on the other side.
|
|
738
|
+
//
|
|
739
|
+
// #### Usage
|
|
740
|
+
//
|
|
741
|
+
// ```
|
|
742
|
+
// chain(... : stringSegment : guitarBridge)
|
|
743
|
+
// ```
|
|
744
|
+
//----------------------------------
|
|
745
|
+
guitarBridge = rTermination(basicBlock,reflectance) : _,transmittance,_
|
|
746
|
+
with{
|
|
747
|
+
reflectance = -bridgeFilter(0.4,0.5);
|
|
748
|
+
transmittance = _; // TODO
|
|
749
|
+
};
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
//-------`(pm.)guitarNuts`----------
|
|
753
|
+
// Bidirectional block implementing a simple acoustic guitar nuts. This
|
|
754
|
+
// nuts damps more hight frequencies than
|
|
755
|
+
// [`elecGuitarNuts`](#elecguitarnuts) and implements a transmittance
|
|
756
|
+
// filter. It also partially sets the resonance duration of the string with
|
|
757
|
+
// the bridge used on the other side.
|
|
758
|
+
//
|
|
759
|
+
// #### Usage
|
|
760
|
+
//
|
|
761
|
+
// ```
|
|
762
|
+
// chain(guitarNuts : stringSegment : ...)
|
|
763
|
+
// ```
|
|
764
|
+
//----------------------------------
|
|
765
|
+
guitarNuts = lTermination(-bridgeFilter(0.4,0.5),basicBlock);
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
//-------`(pm.)idealString`----------
|
|
769
|
+
// An "ideal" string with rigid terminations and where the plucking position
|
|
770
|
+
// and the pick-up position are the same. Since terminations are rigid, this
|
|
771
|
+
// string will ring forever.
|
|
772
|
+
//
|
|
773
|
+
// #### Usage
|
|
774
|
+
//
|
|
775
|
+
// ```
|
|
776
|
+
// 1-1' : idealString(length,reflexion,xPosition,excitation)
|
|
777
|
+
// ```
|
|
778
|
+
//
|
|
779
|
+
// With:
|
|
780
|
+
// * `length`: the length of the string in meters
|
|
781
|
+
// * `pluckPosition`: the plucking position (0.001-0.999)
|
|
782
|
+
// * `excitation`: the input signal for the excitation.
|
|
783
|
+
//----------------------------------------------------------
|
|
784
|
+
idealString(length,pluckPosition,excitation) = wg
|
|
785
|
+
with{
|
|
786
|
+
maxStringLength = maxLength;
|
|
787
|
+
lengthTuning = 0.08; // tuned "by hand"
|
|
788
|
+
tunedLength = length-lengthTuning;
|
|
789
|
+
nUp = tunedLength*pluckPosition; // upper string segment length
|
|
790
|
+
nDown = tunedLength*(1-pluckPosition); // lower string segment length
|
|
791
|
+
wg = chain(lStringRigidTermination : stringSegment(maxStringLength,nUp) :
|
|
792
|
+
in(excitation) : out : stringSegment(maxStringLength,nDown) :
|
|
793
|
+
rStringRigidTermination); // waveguide chain
|
|
794
|
+
};
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
//-------`(pm.)ks`----------
|
|
798
|
+
// A Karplus-Strong string (in that case, the string is implemented as a
|
|
799
|
+
// one dimension waveguide).
|
|
800
|
+
//
|
|
801
|
+
// #### Usage
|
|
802
|
+
//
|
|
803
|
+
// ```
|
|
804
|
+
// ks(length,damping,excitation) : _
|
|
805
|
+
// ```
|
|
806
|
+
//
|
|
807
|
+
// Where:
|
|
808
|
+
//
|
|
809
|
+
// * `length`: the length of the string in meters
|
|
810
|
+
// * `damping`: string damping (0-1)
|
|
811
|
+
// * `excitation`: excitation signal
|
|
812
|
+
//----------------------------------
|
|
813
|
+
ks(length,damping,excitation) = endChain(ksChain)
|
|
814
|
+
with{
|
|
815
|
+
maxStringLength = maxLength;
|
|
816
|
+
lengthTuning = 0.05; // tuned "by hand"
|
|
817
|
+
tunedLength = length-lengthTuning;
|
|
818
|
+
refCoef = (1-damping)*0.2+0.8;
|
|
819
|
+
refFilter = ksReflexionFilter*refCoef;
|
|
820
|
+
ksChain = terminations(_,chain(in(excitation) :
|
|
821
|
+
stringSegment(maxStringLength,tunedLength) : out),refFilter);
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
//-------`(pm.)ks_ui_MIDI`----------
|
|
826
|
+
// Ready-to-use, MIDI-enabled Karplus-Strong string with buil-in UI.
|
|
827
|
+
//
|
|
828
|
+
// #### Usage
|
|
829
|
+
//
|
|
830
|
+
// ```
|
|
831
|
+
// ks_ui_MIDI : _
|
|
832
|
+
// ```
|
|
833
|
+
//----------------------------------
|
|
834
|
+
ks_ui_MIDI = gate : impulseExcitation*gain : ks( (freq : f2l), damping )
|
|
835
|
+
with{
|
|
836
|
+
f = hslider("v:karplus/h:[0]params/[0]freq[style:knob]",440,50,1000,0.01);
|
|
837
|
+
bend = ba.semi2ratio(hslider("v:karplus/h:[0]params/[1]bend[style:knob][hidden:1][midi:pitchwheel]"
|
|
838
|
+
,0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
839
|
+
gain = hslider("v:karplus/h:[0]params/[2]gain[style:knob]",0.8,0,1,0.01);
|
|
840
|
+
s = hslider("v:karplus/h:[0]params/[3]sustain[hidden:1][midi:ctrl 64][style:knob]"
|
|
841
|
+
,0,0,1,1);
|
|
842
|
+
damping = hslider("v:karplus/h:[0]params/[1]damping[midi:ctrl 1][style:knob]"
|
|
843
|
+
,0.01,0,1,0.01) : si.smoo;
|
|
844
|
+
t = button("v:karplus/[1]gate");
|
|
845
|
+
|
|
846
|
+
gate = t+s : min(1);
|
|
847
|
+
freq = f*bend;
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
//-------`(pm.)elecGuitarModel`----------
|
|
852
|
+
// A simple electric guitar model (without audio effects, of course) with
|
|
853
|
+
// selectable pluck position.
|
|
854
|
+
// This model implements a single string. Additional strings should be created
|
|
855
|
+
// by making a polyphonic application out of this function. Pitch is changed by
|
|
856
|
+
// changing the length of the string and not through a finger model.
|
|
857
|
+
//
|
|
858
|
+
// #### Usage
|
|
859
|
+
//
|
|
860
|
+
// ```
|
|
861
|
+
// elecGuitarModel(length,pluckPosition,mute,excitation) : _
|
|
862
|
+
// ```
|
|
863
|
+
//
|
|
864
|
+
// Where:
|
|
865
|
+
//
|
|
866
|
+
// * `length`: the length of the string in meters
|
|
867
|
+
// * `pluckPosition`: pluck position (0-1) (1 is on the bridge)
|
|
868
|
+
// * `mute`: mute coefficient (1 for no mute and 0 for instant mute)
|
|
869
|
+
// * `excitation`: excitation signal
|
|
870
|
+
//----------------------------------
|
|
871
|
+
elecGuitarModel(length,pluckPosition,mute,excitation) = endChain(egChain)
|
|
872
|
+
with{
|
|
873
|
+
maxStringLength = maxLength;
|
|
874
|
+
lengthTuning = 0.11; // tuned "by hand"
|
|
875
|
+
stringL = length-lengthTuning;
|
|
876
|
+
muteBlock = *(mute),*(mute),_;
|
|
877
|
+
egChain = chain(
|
|
878
|
+
elecGuitarNuts :
|
|
879
|
+
openStringPick(stringL,0.05,pluckPosition,excitation) :
|
|
880
|
+
muteBlock :
|
|
881
|
+
elecGuitarBridge);
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
//-------`(pm.)elecGuitar`----------
|
|
886
|
+
// A simple electric guitar model with steel strings (based on
|
|
887
|
+
// [`elecGuitarModel`](#elecguitarmodel)) implementing an excitation
|
|
888
|
+
// model.
|
|
889
|
+
// This model implements a single string. Additional strings should be created
|
|
890
|
+
// by making a polyphonic application out of this function.
|
|
891
|
+
//
|
|
892
|
+
// #### Usage
|
|
893
|
+
//
|
|
894
|
+
// ```
|
|
895
|
+
// elecGuitar(length,pluckPosition,trigger) : _
|
|
896
|
+
// ```
|
|
897
|
+
//
|
|
898
|
+
// Where:
|
|
899
|
+
//
|
|
900
|
+
// * `length`: the length of the string in meters
|
|
901
|
+
// * `pluckPosition`: pluck position (0-1) (1 is on the bridge)
|
|
902
|
+
// * `mute`: mute coefficient (1 for no mute and 0 for instant mute)
|
|
903
|
+
// * `gain`: gain of the pluck (0-1)
|
|
904
|
+
// * `trigger`: trigger signal (1 for on, 0 for off)
|
|
905
|
+
//----------------------------------
|
|
906
|
+
elecGuitar(stringLength,pluckPosition,mute,gain,trigger) =
|
|
907
|
+
pluckString(stringLength,1,1,1,gain,trigger) :
|
|
908
|
+
elecGuitarModel(stringLength,pluckPosition,mute);
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
//-------`(pm.)elecGuitar_ui_MIDI`----------
|
|
912
|
+
// Ready-to-use MIDI-enabled electric guitar physical model with built-in UI.
|
|
913
|
+
//
|
|
914
|
+
// #### Usage
|
|
915
|
+
//
|
|
916
|
+
// ```
|
|
917
|
+
// elecGuitar_ui_MIDI : _
|
|
918
|
+
// ```
|
|
919
|
+
//----------------------------------
|
|
920
|
+
elecGuitar_ui_MIDI = elecGuitar(stringLength,pluckPosition,1,gain,gate)*outGain
|
|
921
|
+
with{
|
|
922
|
+
f = hslider("v:elecGuitar/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
923
|
+
bend = ba.semi2ratio(hslider("v:elecGuitar/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel][style:knob]"
|
|
924
|
+
,0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
925
|
+
gain = hslider("v:elecGuitar/h:[0]midi/[2]gain[style:knob]",0.8,0,1,0.01);
|
|
926
|
+
s = hslider("v:elecGuitar/h:[0]midi/[3]sustain[hidden:1]
|
|
927
|
+
[midi:ctrl 64][style:knob]",0,0,1,1);
|
|
928
|
+
pluckPosition = hslider("v:elecGuitar/[1]pluckPosition[midi:ctrl 1]",0.8,0,1,0.01) : si.smoo;
|
|
929
|
+
outGain = hslider("v:elecGuitar/[2]outGain",0.5,0,1,0.01);
|
|
930
|
+
t = button("v:elecGuitar/[3]gate");
|
|
931
|
+
gate = t+s : min(1);
|
|
932
|
+
freq = f*bend;
|
|
933
|
+
stringLength = freq : f2l;
|
|
934
|
+
};
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
//-------`(pm.)guitarBody`----------
|
|
938
|
+
// WARNING: not implemented yet!
|
|
939
|
+
// Bidirectional block implementing a simple acoustic guitar body.
|
|
940
|
+
//
|
|
941
|
+
// #### Usage
|
|
942
|
+
//
|
|
943
|
+
// ```
|
|
944
|
+
// chain(... : guitarBody)
|
|
945
|
+
// ```
|
|
946
|
+
//----------------------------------
|
|
947
|
+
// TODO: not implemented yet
|
|
948
|
+
guitarBody = reflectance,transmittance,_
|
|
949
|
+
with{
|
|
950
|
+
transmittance = _;
|
|
951
|
+
reflectance = _;
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
//-------`(pm.)guitarModel`----------
|
|
956
|
+
// A simple acoustic guitar model with steel strings and selectable excitation
|
|
957
|
+
// position. This model implements a single string. Additional strings should be created
|
|
958
|
+
// by making a polyphonic application out of this function. Pitch is changed by
|
|
959
|
+
// changing the length of the string and not through a finger model.
|
|
960
|
+
// WARNING: this function doesn't currently implement a body (just strings and
|
|
961
|
+
// bridge).
|
|
962
|
+
//
|
|
963
|
+
// #### Usage
|
|
964
|
+
//
|
|
965
|
+
// ```
|
|
966
|
+
// guitarModel(length,pluckPosition,excitation) : _
|
|
967
|
+
// ```
|
|
968
|
+
//
|
|
969
|
+
// Where:
|
|
970
|
+
//
|
|
971
|
+
// * `length`: the length of the string in meters
|
|
972
|
+
// * `pluckPosition`: pluck position (0-1) (1 is on the bridge)
|
|
973
|
+
// * `excitation`: excitation signal
|
|
974
|
+
//----------------------------------
|
|
975
|
+
guitarModel(length,pluckPosition,excitation) = endChain(egChain)
|
|
976
|
+
with{
|
|
977
|
+
maxStringLength = maxLength;
|
|
978
|
+
lengthTuning = 0.1; // tuned "by hand"
|
|
979
|
+
stringL = length-lengthTuning;
|
|
980
|
+
egChain = chain(guitarNuts : steelString(stringL,pluckPosition,excitation) :
|
|
981
|
+
guitarBridge : guitarBody : out);
|
|
982
|
+
};
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
//-------`(pm.)guitar`----------
|
|
986
|
+
// A simple acoustic guitar model with steel strings (based on
|
|
987
|
+
// [`guitarModel`](#guitarmodel)) implementing an excitation model.
|
|
988
|
+
// This model implements a single string. Additional strings should be created
|
|
989
|
+
// by making a polyphonic application out of this function.
|
|
990
|
+
//
|
|
991
|
+
// #### Usage
|
|
992
|
+
//
|
|
993
|
+
// ```
|
|
994
|
+
// guitar(length,pluckPosition,trigger) : _
|
|
995
|
+
// ```
|
|
996
|
+
//
|
|
997
|
+
// Where:
|
|
998
|
+
//
|
|
999
|
+
// * `length`: the length of the string in meters
|
|
1000
|
+
// * `pluckPosition`: pluck position (0-1) (1 is on the bridge)
|
|
1001
|
+
// * `gain`: gain of the excitation
|
|
1002
|
+
// * `trigger`: trigger signal (1 for on, 0 for off)
|
|
1003
|
+
//----------------------------------
|
|
1004
|
+
guitar(stringLength,pluckPosition,gain,trigger) =
|
|
1005
|
+
pluckString(stringLength,1,1.5,1,gain,trigger) : guitarModel(stringLength, pluckPosition);
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
//-------`(pm.)guitar_ui_MIDI`----------
|
|
1009
|
+
// Ready-to-use MIDI-enabled steel strings acoustic guitar physical model with
|
|
1010
|
+
// built-in UI.
|
|
1011
|
+
//
|
|
1012
|
+
// #### Usage
|
|
1013
|
+
//
|
|
1014
|
+
// ```
|
|
1015
|
+
// guitar_ui_MIDI : _
|
|
1016
|
+
// ```
|
|
1017
|
+
//----------------------------------
|
|
1018
|
+
guitar_ui_MIDI = guitar(stringLength,pluckPosition,gain,gate)*outGain
|
|
1019
|
+
with{
|
|
1020
|
+
f = hslider("v:guitar/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
1021
|
+
bend = ba.semi2ratio(hslider("v:guitar/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel]
|
|
1022
|
+
[style:knob]",0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
1023
|
+
gain = hslider("v:guitar/h:[0]midi/[2]gain[style:knob]",0.8,0,1,0.01);
|
|
1024
|
+
s = hslider("v:guitar/h:[0]midi/[3]sustain[hidden:1][midi:ctrl 64]
|
|
1025
|
+
[style:knob]",0,0,1,1);
|
|
1026
|
+
pluckPosition = hslider("v:guitar/pluckPosition[midi:ctrl 1]"
|
|
1027
|
+
,0.8,0,1,0.01) : si.smoo;
|
|
1028
|
+
outGain = hslider("v:guitar/outGain",0.5,0,1,0.01);
|
|
1029
|
+
t = button("v:guitar/[4]gate");
|
|
1030
|
+
gate = t+s : min(1);
|
|
1031
|
+
freq = f*bend;
|
|
1032
|
+
stringLength = freq : f2l;
|
|
1033
|
+
};
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
//-------`(pm.)nylonGuitarModel`----------
|
|
1037
|
+
// A simple acoustic guitar model with nylon strings and selectable excitation
|
|
1038
|
+
// position. This model implements a single string. Additional strings should be created
|
|
1039
|
+
// by making a polyphonic application out of this function. Pitch is changed by
|
|
1040
|
+
// changing the length of the string and not through a finger model.
|
|
1041
|
+
// WARNING: this function doesn't currently implement a body (just strings and
|
|
1042
|
+
// bridge).
|
|
1043
|
+
//
|
|
1044
|
+
// #### Usage
|
|
1045
|
+
//
|
|
1046
|
+
// ```
|
|
1047
|
+
// nylonGuitarModel(length,pluckPosition,excitation) : _
|
|
1048
|
+
// ```
|
|
1049
|
+
//
|
|
1050
|
+
// Where:
|
|
1051
|
+
//
|
|
1052
|
+
// * `length`: the length of the string in meters
|
|
1053
|
+
// * `pluckPosition`: pluck position (0-1) (1 is on the bridge)
|
|
1054
|
+
// * `excitation`: excitation signal
|
|
1055
|
+
//----------------------------------
|
|
1056
|
+
nylonGuitarModel(length,pluckPosition,excitation) = endChain(egChain)
|
|
1057
|
+
with{
|
|
1058
|
+
maxStringLength = maxLength; // meters
|
|
1059
|
+
lengthTuning = 0.11;
|
|
1060
|
+
stringL = length-lengthTuning;
|
|
1061
|
+
egChain = chain(guitarNuts : nylonString(stringL,pluckPosition,excitation) :
|
|
1062
|
+
guitarBridge : guitarBody : out);
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
//-------`(pm.)nylonGuitar`----------
|
|
1067
|
+
// A simple acoustic guitar model with nylon strings (based on
|
|
1068
|
+
// [`nylonGuitarModel`](#nylonguitarmodel)) implementing an excitation model.
|
|
1069
|
+
// This model implements a single string. Additional strings should be created
|
|
1070
|
+
// by making a polyphonic application out of this function.
|
|
1071
|
+
//
|
|
1072
|
+
// #### Usage
|
|
1073
|
+
//
|
|
1074
|
+
// ```
|
|
1075
|
+
// nylonGuitar(length,pluckPosition,trigger) : _
|
|
1076
|
+
// ```
|
|
1077
|
+
//
|
|
1078
|
+
// Where:
|
|
1079
|
+
//
|
|
1080
|
+
// * `length`: the length of the string in meters
|
|
1081
|
+
// * `pluckPosition`: pluck position (0-1) (1 is on the bridge)
|
|
1082
|
+
// * `gain`: gain of the excitation (0-1)
|
|
1083
|
+
// * `trigger`: trigger signal (1 for on, 0 for off)
|
|
1084
|
+
//----------------------------------
|
|
1085
|
+
nylonGuitar(stringLength,pluckPosition,gain,trigger) =
|
|
1086
|
+
pluckString(stringLength,1,1.5,1,gain,trigger) : nylonGuitarModel(stringLength, pluckPosition);
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
//-------`(pm.)nylonGuitar_ui_MIDI`----------
|
|
1090
|
+
// Ready-to-use MIDI-enabled nylon strings acoustic guitar physical model with
|
|
1091
|
+
// built-in UI.
|
|
1092
|
+
//
|
|
1093
|
+
// #### Usage
|
|
1094
|
+
//
|
|
1095
|
+
// ```
|
|
1096
|
+
// nylonGuitar_ui_MIDI : _
|
|
1097
|
+
// ```
|
|
1098
|
+
//----------------------------------
|
|
1099
|
+
nylonGuitar_ui_MIDI = nylonGuitar(stringLength,pluckPosition,gain,gate)*outGain
|
|
1100
|
+
with{
|
|
1101
|
+
f = hslider("v:nylonGuitar/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
1102
|
+
bend = ba.semi2ratio(hslider("v:nylonGuitar/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel]
|
|
1103
|
+
[style:knob]",0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
1104
|
+
gain = hslider("v:nylonGuitar/h:[0]midi/[2]gain[style:knob]",0.8,0,1,0.01);
|
|
1105
|
+
s = hslider("v:nylonGuitar/h:[0]midi/[3]sustain[hidden:1][midi:ctrl 64]
|
|
1106
|
+
[style:knob]",0,0,1,1);
|
|
1107
|
+
pluckPosition = hslider("v:nylonGuitar/pluckPosition[midi:ctrl 1]"
|
|
1108
|
+
,0.8,0,1,0.01) : si.smoo;
|
|
1109
|
+
outGain = hslider("v:nylonGuitar/outGain",0.5,0,1,0.01);
|
|
1110
|
+
t = button("v:nylonGuitar/[4]gate");
|
|
1111
|
+
gate = t+s : min(1);
|
|
1112
|
+
freq = f*bend;
|
|
1113
|
+
stringLength = freq : f2l;
|
|
1114
|
+
};
|
|
1115
|
+
|
|
1116
|
+
|
|
1117
|
+
//-------`(pm.)modeInterpRes`----------
|
|
1118
|
+
// Modular string instrument resonator based on IR measurements made on 3D
|
|
1119
|
+
// printed models. The 2D space allowing for the control of the shape and the
|
|
1120
|
+
// scale of the model is enabled by interpolating between modes parameters.
|
|
1121
|
+
// More information about this technique/project can be found here:
|
|
1122
|
+
// <https://ccrma.stanford.edu/~rmichon/3dPrintingModeling/>.
|
|
1123
|
+
//
|
|
1124
|
+
// #### Usage
|
|
1125
|
+
//
|
|
1126
|
+
// ```
|
|
1127
|
+
// _ : modeInterpRes(nModes,x,y) : _
|
|
1128
|
+
// ```
|
|
1129
|
+
//
|
|
1130
|
+
// Where:
|
|
1131
|
+
//
|
|
1132
|
+
// * `nModes`: number of modeled modes (40 max)
|
|
1133
|
+
// * `x`: shape of the resonator (0: square, 1: square with rounded corners, 2: round)
|
|
1134
|
+
// * `y`: scale of the resonator (0: small, 1: medium, 2: large)
|
|
1135
|
+
//----------------------------------
|
|
1136
|
+
modeInterpRes(nModes,x,y) = _ <: par(i,min(40,nModes),modeFilter(modeFreq(i),modeT60(i),modeGain(i))) :> /(nModes)
|
|
1137
|
+
with{
|
|
1138
|
+
// modes parameters
|
|
1139
|
+
roundBigCenterFreq(i) = ba.take(i+1,(286.134404,476.384455,602.872587,831.823345,862.773611,1024.985313,1209.932428,1515.548598,1777.819591,2001.806241,2674.135433,3154.282144,3329.555657,3431.385589,3673.656995,4228.801853,4389.842060,4552.745406,4766.151594,4854.354993,4970.516137,5064.203325,5200.399916,5347.650831,5459.807495,5630.144253,5870.258034,6121.961406,6244.522341,6677.052569,7233.100711,7520.031251,7677.902736,7805.138717,9918.905945,10418.988301,11296.101954,11432.719867,13422.238365,13679.232778));
|
|
1140
|
+
roundBigCenterGain(i) = ba.take(i+1,(1.000000,0.609711,0.222375,0.025505,0.026108,0.026840,0.605767,0.368186,0.093526,0.016656,0.159600,0.013836,0.044000,0.023103,0.107971,0.013696,0.043615,0.039848,0.041903,0.043671,0.055018,0.041730,0.062832,0.030464,0.028049,0.012880,0.047154,0.084707,0.050532,0.032735,0.031938,0.023554,0.017534,0.017268,0.026202,0.013725,0.015611,0.021294,0.011486,0.011875));
|
|
1141
|
+
roundBigCenterT60(i) = ba.take(i+1,(0.283544,0.076723,0.287423,0.058391,0.075172,0.120794,0.131540,0.081173,0.088549,0.034991,0.060237,0.014153,0.074709,0.068893,0.033354,0.032013,0.019088,0.020992,0.026703,0.018040,0.015815,0.016671,0.028732,0.017929,0.021520,0.024622,0.022706,0.023138,0.027323,0.020556,0.024577,0.023669,0.024714,0.024420,0.017733,0.017881,0.018715,0.017737,0.015660,0.016464));
|
|
1142
|
+
roundMidCenterFreq(i) = ba.take(i+1,(380.910663,615.862831,933.855656,1128.769825,1231.353452,1404.948092,1764.641239,2095.586536,2451.220548,2566.435588,2781.467120,2946.757398,3522.047891,3748.375254,3892.352583,4340.896246,4454.851770,4629.302932,4806.417393,5024.545475,5604.684752,5671.112515,6533.147087,6751.949816,6862.781990,6951.226279,7180.863112,7901.631311,8074.662174,8979.395914,10075.249374,10521.350963,11964.859921,14227.213322,15501.455250,15587.852956,16290.138756,16418.172746,16663.266694,17991.614994));
|
|
1143
|
+
roundMidCenterGain(i) = ba.take(i+1,(1.000000,0.437495,0.110598,0.025858,0.010841,0.022400,0.245241,0.187990,0.029650,0.058174,0.007035,0.013188,0.009767,0.059284,0.160848,0.007463,0.016816,0.008689,0.031644,0.045608,0.019773,0.018546,0.013495,0.018482,0.020130,0.015417,0.031109,0.007624,0.008526,0.032539,0.009846,0.007605,0.019866,0.007583,0.008991,0.009194,0.010128,0.008557,0.009333,0.007494));
|
|
1144
|
+
roundMidCenterT60(i) = ba.take(i+1,(0.193654,0.076056,0.197517,0.019475,0.043087,0.063829,0.074308,0.059791,0.082616,0.081949,0.042855,0.036140,0.068564,0.041711,0.043799,0.025988,0.057494,0.028353,0.018586,0.018651,0.025380,0.021250,0.019217,0.016326,0.019469,0.020754,0.019487,0.019590,0.011348,0.015969,0.015674,0.016305,0.026772,0.010597,0.009926,0.007595,0.008676,0.008274,0.011471,0.012424));
|
|
1145
|
+
roundSmallCenterFreq(i) = ba.take(i+1,(511.119501,860.897453,977.675690,1245.454667,1408.823199,1604.478891,1825.857776,1960.985105,2340.204377,2594.337460,2700.041698,3277.766643,3388.510632,3505.100505,4151.457765,4257.308449,4425.319123,4526.878869,4629.688075,4819.012204,5493.628166,6323.383769,6514.513248,6709.979636,6823.104590,7009.748398,7198.916858,9019.248381,9492.252653,9706.451249,9858.889433,10080.422278,10252.000811,10389.864946,12327.892342,12465.475093,13491.187794,15072.291233,15176.746743,20143.302052));
|
|
1146
|
+
roundSmallCenterGain(i) = ba.take(i+1,(1.000000,0.686570,0.362616,0.178685,0.113981,0.158727,0.024067,0.023659,0.085113,0.192224,0.174412,0.160279,0.042275,0.042204,0.027219,0.040505,0.064866,0.069074,0.029473,0.033054,0.055311,0.073694,0.071341,0.068366,0.026735,0.037359,0.026008,0.025958,0.025327,0.052859,0.082911,0.038156,0.046079,0.034839,0.022738,0.024480,0.158056,0.026848,0.028009,0.031387));
|
|
1147
|
+
roundSmallCenterT60(i) = ba.take(i+1,(0.200041,0.030199,0.050855,0.020135,0.020101,0.026910,0.043249,0.040814,0.058128,0.047490,0.051189,0.069063,0.047344,0.049448,0.024720,0.027275,0.028407,0.030171,0.026606,0.030289,0.040772,0.023856,0.020889,0.032859,0.027543,0.026427,0.032154,0.020576,0.032990,0.019344,0.019827,0.018571,0.017213,0.019002,0.020440,0.021329,0.023027,0.018833,0.018344,0.018811));
|
|
1148
|
+
semBigCenterFreq(i) = ba.take(i+1,(318.812824,545.646717,727.103717,813.406232,938.026296,1067.472803,1239.311077,1478.409235,1567.366603,1840.215865,2162.299536,2302.660906,2394.006715,2499.397129,2724.662564,2876.713036,3051.447083,3219.116214,3378.667296,3507.736722,3687.907343,3827.904993,4039.858029,4208.742422,4385.651803,4574.818448,4744.136436,4866.893882,5090.532579,5200.283111,5448.339367,5751.719886,6040.059676,6500.665192,6780.883377,6878.732474,7127.463954,7701.025454,10337.623684,17411.019601));
|
|
1149
|
+
semBigCenterGain(i) = ba.take(i+1,(1.000000,0.386065,0.297923,0.235171,0.346593,0.219093,0.050655,0.310031,0.175387,0.180464,0.064716,0.070721,0.027399,0.076973,0.086367,0.024188,0.100553,0.028776,0.027974,0.040200,0.031680,0.021694,0.035362,0.031821,0.027726,0.037219,0.026308,0.016164,0.022938,0.046669,0.031128,0.027430,0.032404,0.018356,0.026887,0.041003,0.012779,0.028785,0.013346,0.017281));
|
|
1150
|
+
semBigCenterT60(i) = ba.take(i+1,(0.195061,0.269748,0.108389,0.132557,0.127125,0.113759,0.159514,0.058527,0.067333,0.071996,0.067001,0.054194,0.052818,0.050935,0.045373,0.051611,0.051410,0.061272,0.050844,0.029415,0.021966,0.023483,0.022866,0.023418,0.033572,0.026764,0.017334,0.021394,0.025984,0.026146,0.018801,0.018242,0.022440,0.020939,0.011937,0.011739,0.020314,0.013848,0.016504,0.085830));
|
|
1151
|
+
semMidCenterFreq(i) = ba.take(i+1,(316.511541,548.598445,682.927606,764.088220,1145.795222,1280.068992,1524.562996,1677.146625,2083.900770,2285.783756,2452.226740,2779.274140,3196.405966,3569.262928,3798.251779,4071.264178,4413.799330,4550.364404,4966.398087,5156.799448,5363.124121,5611.038360,5995.650074,6162.624225,6583.973014,7029.525719,7207.893991,7706.775019,7844.032020,10298.804956,10564.531850,11615.688447,12056.168362,12661.205157,12876.405687,13082.890228,13851.437211,14452.383106,15683.910228,16667.950883));
|
|
1152
|
+
semMidCenterGain(i) = ba.take(i+1,(0.999641,0.798181,0.200080,0.280473,0.042761,0.079955,0.286673,0.162652,1.000000,0.309945,0.097527,0.023964,0.124529,0.155314,0.075600,0.178980,0.089168,0.134962,0.120730,0.036885,0.024020,0.102628,0.085255,0.059439,0.023339,0.027443,0.141618,0.044053,0.024269,0.046682,0.034465,0.068930,0.070502,0.025912,0.076088,0.024972,0.038501,0.051135,0.027801,0.022469));
|
|
1153
|
+
semMidCenterT60(i) = ba.take(i+1,(0.210670,0.062329,0.097470,0.136802,0.077790,0.025877,0.054632,0.060485,0.061625,0.061352,0.060614,0.030867,0.039440,0.030054,0.037956,0.030948,0.046137,0.045345,0.025326,0.025515,0.022514,0.043142,0.018663,0.015057,0.052844,0.016478,0.025993,0.017880,0.014006,0.022971,0.017720,0.032173,0.015391,0.009217,0.028936,0.011895,0.012607,0.018141,0.018341,0.018180));
|
|
1154
|
+
semSmallCenterFreq(i) = ba.take(i+1,(440.578370,637.619026,828.182637,978.279267,1088.401911,1321.315700,1648.932125,1817.216790,1938.686740,2173.897496,2450.967026,2582.312643,2748.003128,2858.292897,2973.003533,3235.482621,3348.561906,3496.046199,3706.507771,3934.307821,4418.408376,5239.069796,5428.018005,5771.733971,6106.378549,6304.512786,6788.234913,6905.001294,7054.694449,7227.988097,7348.344488,8450.449049,9000.316477,10930.327581,11271.451255,11418.301881,13448.385700,13938.733921,14334.394664,17413.449273));
|
|
1155
|
+
semSmallCenterGain(i) = ba.take(i+1,(1.000000,0.297197,0.715097,0.178811,0.229363,0.183731,0.107685,0.120764,0.060436,0.503361,0.352264,0.056432,0.042926,0.090906,0.224894,0.128151,0.257120,0.076416,0.096971,0.078669,0.065573,0.057421,0.085378,0.085397,0.050578,0.046534,0.213480,0.090142,0.078632,0.089706,0.276299,0.061182,0.038941,0.045447,0.043447,0.051347,0.055647,0.071836,0.040813,0.066853));
|
|
1156
|
+
semSmallCenterT60(i) = ba.take(i+1,(0.136710,0.070656,0.049965,0.034104,0.023973,0.032990,0.049605,0.026798,0.024777,0.040671,0.039262,0.035240,0.019214,0.053001,0.045917,0.045864,0.048770,0.040981,0.020747,0.022565,0.031089,0.026788,0.013828,0.023917,0.022485,0.035319,0.017955,0.014831,0.018902,0.014661,0.032984,0.027729,0.025067,0.021211,0.016910,0.027488,0.013164,0.012325,0.019985,0.079428));
|
|
1157
|
+
squareBigCenterFreq(i) = ba.take(i+1,(222.231629,336.343611,555.041069,772.219662,911.261442,1096.774273,1203.102824,1404.011001,1540.420421,1628.944840,1994.925663,2197.106949,2533.354244,2672.470165,2821.185962,2967.436266,3342.189608,3479.723368,3631.705350,3806.882908,3910.078404,4173.779128,4292.901543,4519.288440,4631.053559,4855.405142,5079.828139,5182.392108,5328.291818,5636.817979,5983.629129,6104.013800,6184.547942,6602.614840,6718.247643,6835.844044,6882.254514,7220.774814,7283.263950,7407.672066));
|
|
1158
|
+
squareBigCenterGain(i) = ba.take(i+1,(0.581227,1.000000,0.167366,0.663184,0.127173,0.141424,0.232076,0.043454,0.168681,0.244908,0.193343,0.147543,0.062214,0.112585,0.383899,0.053139,0.104651,0.093521,0.029220,0.027646,0.020979,0.031887,0.052610,0.045000,0.023542,0.049426,0.029063,0.049062,0.015097,0.030925,0.032215,0.032146,0.050862,0.016861,0.019228,0.021428,0.021039,0.016988,0.017971,0.033065));
|
|
1159
|
+
squareBigCenterT60(i) = ba.take(i+1,(0.417113,0.247980,0.103791,0.131234,0.194764,0.130569,0.119615,0.103862,0.102785,0.079975,0.068871,0.120830,0.066401,0.064964,0.037272,0.057999,0.038435,0.036927,0.036970,0.069147,0.036096,0.049136,0.046268,0.029452,0.025066,0.020942,0.040527,0.027374,0.030986,0.019875,0.028632,0.032344,0.033709,0.024938,0.063833,0.032297,0.028473,0.025768,0.024877,0.026385));
|
|
1160
|
+
squareMidCenterFreq(i) = ba.take(i+1,(306.243391,426.381556,523.626577,637.813655,855.576390,992.200454,1098.863347,1226.922784,1545.950522,1704.776255,1839.163057,1983.832482,2190.814571,2445.409860,2672.907579,2782.642755,2983.850376,3268.313978,3458.038380,3590.850048,3783.143602,4123.002328,4250.310528,4408.442518,4531.916055,4865.211680,5248.660726,5387.011592,5780.593786,5880.954673,6095.291499,6432.605387,6596.403501,6820.917687,6907.055108,7030.829711,7337.883035,7602.739152,7926.836412,12248.346109));
|
|
1161
|
+
squareMidCenterGain(i) = ba.take(i+1,(1.000000,0.292592,0.554710,0.359595,0.041223,0.283249,0.182057,0.078666,0.898203,0.105021,0.037156,0.128493,0.302569,0.134081,0.090181,0.116704,0.041711,0.268207,0.079651,0.034128,0.296838,0.051959,0.124454,0.077586,0.084915,0.126202,0.019697,0.017643,0.077301,0.068367,0.023764,0.015924,0.022163,0.017954,0.029917,0.021449,0.019083,0.026076,0.017965,0.017018));
|
|
1162
|
+
squareMidCenterT60(i) = ba.take(i+1,(0.236061,0.179001,0.084440,0.165197,0.083836,0.055543,0.067029,0.054547,0.046195,0.055390,0.052760,0.079021,0.073765,0.059744,0.071780,0.050510,0.036326,0.036162,0.039268,0.031777,0.037990,0.072567,0.045824,0.026516,0.027684,0.034229,0.040867,0.037800,0.026894,0.023151,0.023381,0.021277,0.023057,0.020207,0.019672,0.016358,0.024757,0.017036,0.016600,0.010195));
|
|
1163
|
+
squareSmallCenterFreq(i) = ba.take(i+1,(375.008194,527.945584,775.002560,981.584262,1125.203834,1287.701398,1394.790058,1577.138666,1727.825366,1860.700270,1950.809059,2020.169063,2185.798879,2382.343983,2587.140759,2792.652735,2970.443881,3047.515682,3332.695227,3416.636119,3513.876416,3994.492272,4128.261485,4247.828681,4425.131019,4686.893838,4731.141754,5553.904972,5702.206389,6415.071752,6552.422900,6785.461423,6990.104471,7256.116515,7884.508530,8787.479467,10529.849261,10641.861836,12075.018006,17405.170359));
|
|
1164
|
+
squareSmallCenterGain(i) = ba.take(i+1,(0.991070,1.000000,0.515946,0.549911,0.115279,0.157813,0.463743,0.206985,0.131491,0.244054,0.160114,0.116274,0.161678,0.048839,0.071332,0.072482,0.097678,0.083415,0.057484,0.059259,0.034662,0.064479,0.061452,0.110522,0.045770,0.053318,0.051225,0.034998,0.051538,0.081127,0.039422,0.226011,0.053013,0.052620,0.041956,0.058147,0.061262,0.046118,0.038256,0.124151));
|
|
1165
|
+
squareSmallCenterT60(i) = ba.take(i+1,(0.102256,0.088069,0.026433,0.131998,0.050149,0.052897,0.066531,0.060621,0.045315,0.047413,0.058375,0.059098,0.029950,0.018537,0.024086,0.032984,0.036868,0.032205,0.023710,0.023430,0.015516,0.022773,0.025265,0.028872,0.019743,0.036565,0.032704,0.025234,0.028383,0.018356,0.018609,0.017534,0.018699,0.015762,0.022800,0.013151,0.012300,0.018114,0.013192,0.085670));
|
|
1166
|
+
|
|
1167
|
+
// computing modes freq in function of x and y
|
|
1168
|
+
modeFreq(i) = zxd + (zxu-zxd)*select2(y<1,(y-1),y)
|
|
1169
|
+
with{
|
|
1170
|
+
zx0 = squareSmallCenterFreq(i) + (semSmallCenterFreq(i)-squareSmallCenterFreq(i))*x;
|
|
1171
|
+
zx1 = semSmallCenterFreq(i) + (roundSmallCenterFreq(i)-semSmallCenterFreq(i))*(x-1);
|
|
1172
|
+
zx2 = squareMidCenterFreq(i) + (semMidCenterFreq(i)-squareMidCenterFreq(i))*x;
|
|
1173
|
+
zx3 = semMidCenterFreq(i) + (roundMidCenterFreq(i)-semMidCenterFreq(i))*(x-1);
|
|
1174
|
+
zx4 = squareBigCenterFreq(i) + (semBigCenterFreq(i)-squareBigCenterFreq(i))*x;
|
|
1175
|
+
zx5 = semBigCenterFreq(i) + (roundBigCenterFreq(i)-semBigCenterFreq(i))*(x-1);
|
|
1176
|
+
zxd = select2(y<1,select2(x<1,zx3,zx2),select2(x<1,zx1,zx0));
|
|
1177
|
+
zxu = select2(y<1,select2(x<1,zx5,zx4),select2(x<1,zx3,zx2));
|
|
1178
|
+
};
|
|
1179
|
+
|
|
1180
|
+
// computing modes gain in function of x and y
|
|
1181
|
+
modeGain(i) = zxd + (zxu-zxd)*select2(y<1,(y-1),y)
|
|
1182
|
+
with{
|
|
1183
|
+
zx0 = squareSmallCenterGain(i) + (semSmallCenterGain(i)-squareSmallCenterGain(i))*x;
|
|
1184
|
+
zx1 = semSmallCenterGain(i) + (roundSmallCenterGain(i)-semSmallCenterGain(i))*(x-1);
|
|
1185
|
+
zx2 = squareMidCenterGain(i) + (semMidCenterGain(i)-squareMidCenterGain(i))*x;
|
|
1186
|
+
zx3 = semMidCenterGain(i) + (roundMidCenterGain(i)-semMidCenterGain(i))*(x-1);
|
|
1187
|
+
zx4 = squareBigCenterGain(i) + (semBigCenterGain(i)-squareBigCenterGain(i))*x;
|
|
1188
|
+
zx5 = semBigCenterGain(i) + (roundBigCenterGain(i)-semBigCenterGain(i))*(x-1);
|
|
1189
|
+
zxd = select2(y<1,select2(x<1,zx3,zx2),select2(x<1,zx1,zx0));
|
|
1190
|
+
zxu = select2(y<1,select2(x<1,zx5,zx4),select2(x<1,zx3,zx2));
|
|
1191
|
+
};
|
|
1192
|
+
|
|
1193
|
+
// computing modes T60 in function of x and y
|
|
1194
|
+
modeT60(i) = zxd + (zxu-zxd)*select2(y<1,(y-1),y) //: min(0.1)
|
|
1195
|
+
with{
|
|
1196
|
+
zx0 = squareSmallCenterT60(i) + (semSmallCenterT60(i)-squareSmallCenterT60(i))*x;
|
|
1197
|
+
zx1 = semSmallCenterT60(i) + (roundSmallCenterT60(i)-semSmallCenterT60(i))*(x-1);
|
|
1198
|
+
zx2 = squareMidCenterT60(i) + (semMidCenterT60(i)-squareMidCenterT60(i))*x;
|
|
1199
|
+
zx3 = semMidCenterT60(i) + (roundMidCenterT60(i)-semMidCenterT60(i))*(x-1);
|
|
1200
|
+
zx4 = squareBigCenterT60(i) + (semBigCenterT60(i)-squareBigCenterT60(i))*x;
|
|
1201
|
+
zx5 = semBigCenterT60(i) + (roundBigCenterT60(i)-semBigCenterT60(i))*(x-1);
|
|
1202
|
+
zxd = select2(y<1,select2(x<1,zx3,zx2),select2(x<1,zx1,zx0));
|
|
1203
|
+
zxu = select2(y<1,select2(x<1,zx5,zx4),select2(x<1,zx3,zx2));
|
|
1204
|
+
};
|
|
1205
|
+
};
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
//-------`(pm.)modularInterpBody`----------
|
|
1209
|
+
// Bidirectional block implementing a modular string instrument resonator
|
|
1210
|
+
// (see [`modeInterpRes`](#pm.modeinterpres)).
|
|
1211
|
+
//
|
|
1212
|
+
// #### Usage
|
|
1213
|
+
//
|
|
1214
|
+
// ```
|
|
1215
|
+
// chain(... : modularInterpBody(nModes,shape,scale) : ...)
|
|
1216
|
+
// ```
|
|
1217
|
+
//
|
|
1218
|
+
// Where:
|
|
1219
|
+
//
|
|
1220
|
+
// * `nModes`: number of modeled modes (40 max)
|
|
1221
|
+
// * `shape`: shape of the resonator (0: square, 1: square with rounded corners, 2: round)
|
|
1222
|
+
// * `scale`: scale of the resonator (0: small, 1: medium, 2: large)
|
|
1223
|
+
//----------------------------------
|
|
1224
|
+
modularInterpBody(nModes,shape,scale) = _,modeInterpRes(nModes,shape,scale),_;
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
//-------`(pm.)modularInterpStringModel`----------
|
|
1228
|
+
// String instrument model with a modular body (see
|
|
1229
|
+
// [`modeInterpRes`](#pm.modeinterpres) and
|
|
1230
|
+
// <https://ccrma.stanford.edu/~rmichon/3dPrintingModeling/>).
|
|
1231
|
+
//
|
|
1232
|
+
// #### Usage
|
|
1233
|
+
//
|
|
1234
|
+
// ```
|
|
1235
|
+
// modularInterpStringModel(length,pluckPosition,shape,scale,bodyExcitation,stringExcitation) : _
|
|
1236
|
+
// ```
|
|
1237
|
+
//
|
|
1238
|
+
// Where:
|
|
1239
|
+
//
|
|
1240
|
+
// * `stringLength`: the length of the string in meters
|
|
1241
|
+
// * `pluckPosition`: pluck position (0-1) (1 is on the bridge)
|
|
1242
|
+
// * `shape`: shape of the resonator (0: square, 1: square with rounded corners, 2: round)
|
|
1243
|
+
// * `scale`: scale of the resonator (0: small, 1: medium, 2: large)
|
|
1244
|
+
// * `bodyExcitation`: excitation signal for the body
|
|
1245
|
+
// * `stringExcitation`: excitation signal for the string
|
|
1246
|
+
//----------------------------------
|
|
1247
|
+
modularInterpStringModel(stringLength,pluckPosition,shape,scale,bodyExcitation,stringExcitation) = endChain(egChain)*0.5
|
|
1248
|
+
with{
|
|
1249
|
+
maxStringLength = maxLength;
|
|
1250
|
+
lengthTuning = 0.1; // tuned "by hand"
|
|
1251
|
+
stringL = stringLength-lengthTuning;
|
|
1252
|
+
nBodyModes = 40;
|
|
1253
|
+
egChain = chain(guitarNuts : steelString(stringL,pluckPosition,stringExcitation) :
|
|
1254
|
+
guitarBridge : inRightWave(bodyExcitation) : modularInterpBody(nBodyModes,shape,scale) : out);
|
|
1255
|
+
};
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
//-------`(pm.)modularInterpInstr`----------
|
|
1259
|
+
// String instrument with a modular body (see
|
|
1260
|
+
// [`modeInterpRes`](#pm.modeinterpres) and
|
|
1261
|
+
// <https://ccrma.stanford.edu/~rmichon/3dPrintingModeling/>).
|
|
1262
|
+
//
|
|
1263
|
+
// #### Usage
|
|
1264
|
+
//
|
|
1265
|
+
// ```
|
|
1266
|
+
// modularInterpInstr(stringLength,pluckPosition,shape,scale,gain,tapBody,triggerString) : _
|
|
1267
|
+
// ```
|
|
1268
|
+
//
|
|
1269
|
+
// Where:
|
|
1270
|
+
//
|
|
1271
|
+
// * `stringLength`: the length of the string in meters
|
|
1272
|
+
// * `pluckPosition`: pluck position (0-1) (1 is on the bridge)
|
|
1273
|
+
// * `shape`: shape of the resonator (0: square, 1: square with rounded corners, 2: round)
|
|
1274
|
+
// * `scale`: scale of the resonator (0: small, 1: medium, 2: large)
|
|
1275
|
+
// * `gain`: of the string excitation
|
|
1276
|
+
// * `tapBody`: send an impulse in the body of the instrument where the string is connected (1 for on, 0 for off)
|
|
1277
|
+
// * `triggerString`: trigger signal for the string (1 for on, 0 for off)
|
|
1278
|
+
//----------------------------------
|
|
1279
|
+
modularInterpInstr(stringLength,pluckPosition,shape,scale,gain,tapBody,triggerString) =
|
|
1280
|
+
(tapBody : ba.impulsify), pluckString(stringLength,1,1,1,gain,triggerString) :
|
|
1281
|
+
modularInterpStringModel(stringLength,pluckPosition,shape,scale);
|
|
1282
|
+
|
|
1283
|
+
|
|
1284
|
+
//-------`(pm.)modularInterpInstr_ui_MIDI`----------
|
|
1285
|
+
// Ready-to-use MIDI-enabled string instrument with a modular body (see
|
|
1286
|
+
// [`modeInterpRes`](#pm.modeinterpres) and
|
|
1287
|
+
// <https://ccrma.stanford.edu/~rmichon/3dPrintingModeling/>)
|
|
1288
|
+
// with built-in UI.
|
|
1289
|
+
//
|
|
1290
|
+
// #### Usage
|
|
1291
|
+
//
|
|
1292
|
+
// ```
|
|
1293
|
+
// modularInterpInstr_ui_MIDI : _
|
|
1294
|
+
// ```
|
|
1295
|
+
//----------------------------------
|
|
1296
|
+
modularInterpInstr_ui_MIDI = modularInterpInstr(stringLength,pluckPosition,shape,scale,gain,tapBody,gate)*outGain
|
|
1297
|
+
with{
|
|
1298
|
+
f = hslider("v:modularInterpInstr/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
1299
|
+
bend = ba.semi2ratio(hslider("v:modularInterpInstr/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel]
|
|
1300
|
+
[style:knob]",0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
1301
|
+
gain = hslider("v:modularInterpInstr/h:[0]midi/[2]gain[style:knob]",0.8,0,1,0.01);
|
|
1302
|
+
s = hslider("v:modularInterpInstr/h:[0]midi/[3]sustain[hidden:1][midi:ctrl 64]
|
|
1303
|
+
[style:knob]",0,0,1,1);
|
|
1304
|
+
shape = hslider("v:modularInterpInstr/h:[1]body/[0]shape[style:knob]",0,0,1,0.01)*2;
|
|
1305
|
+
scale = hslider("v:modularInterpInstr/h:[1]body/[1]scale[style:knob]",0,0,1,0.011)*2;
|
|
1306
|
+
tapBody = button("v:modularInterpInstr/h:[1]body/[2]tapBody");
|
|
1307
|
+
pluckPosition = hslider("v:modularInterpInstr/[2]pluckPosition[midi:ctrl 1]"
|
|
1308
|
+
,0.8,0,1,0.01) : si.smoo;
|
|
1309
|
+
outGain = hslider("v:modularInterpInstr/[3]outGain",0.5,0,1,0.01);
|
|
1310
|
+
t = button("v:modularInterpInstr/[4]gate");
|
|
1311
|
+
gate = t+s : min(1);
|
|
1312
|
+
freq = f*bend;
|
|
1313
|
+
stringLength = freq : f2l;
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
//=============================Bowed String Instruments===================================
|
|
1318
|
+
// Low and high level basic string instruments parts. Most of the elements in
|
|
1319
|
+
// this section can be used in a bidirectional chain.
|
|
1320
|
+
//========================================================================================
|
|
1321
|
+
|
|
1322
|
+
//-------`(pm.)bowTable`----------
|
|
1323
|
+
// Extremely basic bow table that can be used to implement a wide range of
|
|
1324
|
+
// bow types for many different bowed string instruments (violin, cello, etc.).
|
|
1325
|
+
//
|
|
1326
|
+
// #### Usage
|
|
1327
|
+
//
|
|
1328
|
+
// ```
|
|
1329
|
+
// excitation : bowTable(offeset,slope) : _
|
|
1330
|
+
// ```
|
|
1331
|
+
//
|
|
1332
|
+
// Where:
|
|
1333
|
+
//
|
|
1334
|
+
// * `excitation`: an excitation signal
|
|
1335
|
+
// * `offset`: table offset
|
|
1336
|
+
// * `slope`: table slope
|
|
1337
|
+
//----------------------------------
|
|
1338
|
+
bowTable(offset,slope) = pow(abs(sample) + 0.75, -4) : min(1)
|
|
1339
|
+
with{
|
|
1340
|
+
sample = +(offset)*slope;
|
|
1341
|
+
};
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
//-------`(pm.)violinBowTable`----------
|
|
1345
|
+
// Violin bow table based on [`bowTable`](#bowtable).
|
|
1346
|
+
//
|
|
1347
|
+
// #### Usage
|
|
1348
|
+
//
|
|
1349
|
+
// ```
|
|
1350
|
+
// bowVelocity : violinBowTable(bowPressure) : _
|
|
1351
|
+
// ```
|
|
1352
|
+
//
|
|
1353
|
+
// Where:
|
|
1354
|
+
//
|
|
1355
|
+
// * `bowVelocity`: velocity of the bow/excitation signal (0-1)
|
|
1356
|
+
// * `bowPressure`: bow pressure on the string (0-1)
|
|
1357
|
+
//----------------------------------
|
|
1358
|
+
violinBowTable(bowPressure) = bowTable(0,tableSlope)
|
|
1359
|
+
with{
|
|
1360
|
+
tableSlope = 5 - (4*bowPressure);
|
|
1361
|
+
};
|
|
1362
|
+
|
|
1363
|
+
|
|
1364
|
+
//-------`(pm.)bowInteraction`----------
|
|
1365
|
+
// Bidirectional block implementing the interaction of a bow in a
|
|
1366
|
+
// [`chain`](#chain).
|
|
1367
|
+
//
|
|
1368
|
+
// #### Usage
|
|
1369
|
+
//
|
|
1370
|
+
// ```
|
|
1371
|
+
// chain(... : stringSegment : bowInteraction(bowTable) : stringSegment : ...)
|
|
1372
|
+
// ```
|
|
1373
|
+
//
|
|
1374
|
+
// Where:
|
|
1375
|
+
//
|
|
1376
|
+
// * `bowTable`: the bow table
|
|
1377
|
+
//----------------------------------
|
|
1378
|
+
bowInteraction(b) = (_,_ <: b,_,_ :> _,_),_;
|
|
1379
|
+
|
|
1380
|
+
|
|
1381
|
+
//-------`(pm.)violinBow`----------
|
|
1382
|
+
// Bidirectional block implementing a violin bow and its interaction with
|
|
1383
|
+
// a string.
|
|
1384
|
+
//
|
|
1385
|
+
// #### Usage
|
|
1386
|
+
//
|
|
1387
|
+
// ```
|
|
1388
|
+
// chain(... : stringSegment : violinBow(bowPressure,bowVelocity) : stringSegment : ...)
|
|
1389
|
+
// ```
|
|
1390
|
+
//
|
|
1391
|
+
// Where:
|
|
1392
|
+
//
|
|
1393
|
+
// * `bowVelocity`: velocity of the bow / excitation signal (0-1)
|
|
1394
|
+
// * `bowPressure`: bow pressure on the string (0-1)
|
|
1395
|
+
//----------------------------------
|
|
1396
|
+
violinBow(bowPressure,bowVelocity) = bowInteraction(bowSystem)
|
|
1397
|
+
with{
|
|
1398
|
+
bowSystem = + : bowVelocity-_ <: *(violinBowTable(bowPressure)) <: _,_;
|
|
1399
|
+
};
|
|
1400
|
+
|
|
1401
|
+
|
|
1402
|
+
//-------`(pm.)violinBowedString`----------
|
|
1403
|
+
// Violin bowed string bidirectional block with controllable bow position.
|
|
1404
|
+
// Terminations are not implemented in this model.
|
|
1405
|
+
//
|
|
1406
|
+
// #### Usage
|
|
1407
|
+
//
|
|
1408
|
+
// ```
|
|
1409
|
+
// chain(nuts : violinBowedString(stringLength,bowPressure,bowVelocity,bowPosition) : bridge)
|
|
1410
|
+
// ```
|
|
1411
|
+
//
|
|
1412
|
+
// Where:
|
|
1413
|
+
//
|
|
1414
|
+
// * `stringLength`: the length of the string in meters
|
|
1415
|
+
// * `bowVelocity`: velocity of the bow / excitation signal (0-1)
|
|
1416
|
+
// * `bowPressure`: bow pressure on the string (0-1)
|
|
1417
|
+
// * `bowPosition`: the position of the bow on the string (0-1)
|
|
1418
|
+
//----------------------------------
|
|
1419
|
+
violinBowedString(stringLength,bowPressure,bowVelocity,bowPosition) =
|
|
1420
|
+
chain(
|
|
1421
|
+
stringSegment(maxStringLength,ntbd) :
|
|
1422
|
+
violinBow(bowPressure,bowVelocity) :
|
|
1423
|
+
stringSegment(maxStringLength,btbd)
|
|
1424
|
+
)
|
|
1425
|
+
with{
|
|
1426
|
+
maxStringLength = maxLength;
|
|
1427
|
+
ntbd = stringLength*bowPosition; // upper portion of the string length
|
|
1428
|
+
btbd = stringLength*(1-bowPosition); // lower portion of the string length
|
|
1429
|
+
};
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
//-------`(pm.)violinNuts`----------
|
|
1433
|
+
// Bidirectional block implementing simple violin nuts. This function is
|
|
1434
|
+
// based on [`bridgeFilter`](#bridgefilter).
|
|
1435
|
+
//
|
|
1436
|
+
// #### Usage
|
|
1437
|
+
//
|
|
1438
|
+
// ```
|
|
1439
|
+
// chain(violinNuts : stringSegment : ...)
|
|
1440
|
+
// ```
|
|
1441
|
+
//----------------------------------
|
|
1442
|
+
violinNuts = lTermination(-bridgeFilter(0.6,0.1),basicBlock);
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
//-------`(pm.)violinBridge`----------
|
|
1446
|
+
// Bidirectional block implementing a simple violin bridge. This function is
|
|
1447
|
+
// based on [`bridgeFilter`](#bridgefilter).
|
|
1448
|
+
//
|
|
1449
|
+
// #### Usage
|
|
1450
|
+
//
|
|
1451
|
+
// ```
|
|
1452
|
+
// chain(... : stringSegment : violinBridge
|
|
1453
|
+
// ```
|
|
1454
|
+
//----------------------------------
|
|
1455
|
+
// TODO:
|
|
1456
|
+
// * reflectance is not implemented yet
|
|
1457
|
+
violinBridge = rTermination(basicBlock,reflectance) : _,transmittance,_
|
|
1458
|
+
with{
|
|
1459
|
+
reflectance = -bridgeFilter(0.2,0.9);
|
|
1460
|
+
transmittance = _;
|
|
1461
|
+
};
|
|
1462
|
+
|
|
1463
|
+
|
|
1464
|
+
//-------`(pm.)violinBody`----------
|
|
1465
|
+
// Bidirectional block implementing a simple violin body (just a simple
|
|
1466
|
+
// resonant lowpass filter).
|
|
1467
|
+
//
|
|
1468
|
+
// #### Usage
|
|
1469
|
+
//
|
|
1470
|
+
// ```
|
|
1471
|
+
// chain(... : stringSegment : violinBridge : violinBody)
|
|
1472
|
+
// ```
|
|
1473
|
+
//----------------------------------
|
|
1474
|
+
// TODO:
|
|
1475
|
+
// * reflectance is not implemented yet
|
|
1476
|
+
violinBody = reflectance,transmittance,_
|
|
1477
|
+
with{
|
|
1478
|
+
transmittance = fi.resonbp(500,2,1);
|
|
1479
|
+
reflectance = _;
|
|
1480
|
+
};
|
|
1481
|
+
|
|
1482
|
+
|
|
1483
|
+
//-------`(pm.)violinModel`----------
|
|
1484
|
+
// Ready-to-use simple violin physical model. This model implements a single
|
|
1485
|
+
// string. Additional strings should be created
|
|
1486
|
+
// by making a polyphonic application out of this function. Pitch is changed
|
|
1487
|
+
// by changing the length of the string (and not through a finger model).
|
|
1488
|
+
//
|
|
1489
|
+
// #### Usage
|
|
1490
|
+
//
|
|
1491
|
+
// ```
|
|
1492
|
+
// violinModel(stringLength,bowPressure,bowVelocity,bridgeReflexion,
|
|
1493
|
+
// bridgeAbsorption,bowPosition) : _
|
|
1494
|
+
// ```
|
|
1495
|
+
//
|
|
1496
|
+
// Where:
|
|
1497
|
+
//
|
|
1498
|
+
// * `stringLength`: the length of the string in meters
|
|
1499
|
+
// * `bowVelocity`: velocity of the bow / excitation signal (0-1)
|
|
1500
|
+
// * `bowPressure`: bow pressure on the string (0-1))
|
|
1501
|
+
// * `bowPosition`: the position of the bow on the string (0-1)
|
|
1502
|
+
//----------------------------------
|
|
1503
|
+
violinModel(stringLength,bowPressure,bowVelocity,bowPosition) =
|
|
1504
|
+
endChain(modelChain)
|
|
1505
|
+
with{
|
|
1506
|
+
stringTuning = 0.08;
|
|
1507
|
+
stringL = stringLength-stringTuning;
|
|
1508
|
+
modelChain = chain(
|
|
1509
|
+
violinNuts :
|
|
1510
|
+
violinBowedString(stringL,bowPressure,bowVelocity,bowPosition) :
|
|
1511
|
+
violinBridge :
|
|
1512
|
+
violinBody :
|
|
1513
|
+
out
|
|
1514
|
+
);
|
|
1515
|
+
};
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
//-------`(pm.)violin_ui`----------
|
|
1519
|
+
// Ready-to-use violin physical model with built-in UI.
|
|
1520
|
+
//
|
|
1521
|
+
// #### Usage
|
|
1522
|
+
//
|
|
1523
|
+
// ```
|
|
1524
|
+
// violinModel_ui : _
|
|
1525
|
+
// ```
|
|
1526
|
+
//----------------------------------
|
|
1527
|
+
violin_ui = violinModel(stringLength,bowPress,bowVel,bowPos)*outGain
|
|
1528
|
+
with{
|
|
1529
|
+
stringLength = hslider("v:violin/v:[0]string/[0]length",0.75,0,2,0.01) : si.smoo;
|
|
1530
|
+
bowVel = hslider("v:violin/v:[1]bow/[0]velocity",0,0,1,0.01) : si.smoo;
|
|
1531
|
+
bowPress = hslider("v:violin/v:[1]bow/[1]pressure",0.5,0,1,0.01) : si.smoo;
|
|
1532
|
+
bowPos = hslider("v:violin/v:[1]bow/[2]position",0.7,0,1,0.01) : si.smoo;
|
|
1533
|
+
outGain = hslider("v:violin/outGain",0.5,0,1,0.01);
|
|
1534
|
+
};
|
|
1535
|
+
|
|
1536
|
+
|
|
1537
|
+
//-------`(pm.)violin_ui_MIDI`----------
|
|
1538
|
+
// Ready-to-use MIDI-enabled violin physical model with built-in UI.
|
|
1539
|
+
//
|
|
1540
|
+
// #### Usage
|
|
1541
|
+
//
|
|
1542
|
+
// ```
|
|
1543
|
+
// violin_ui_MIDI : _
|
|
1544
|
+
// ```
|
|
1545
|
+
//----------------------------------
|
|
1546
|
+
violin_ui_MIDI = violinModel(stringLength,bowPress,bowVel,bowPos)*outGain
|
|
1547
|
+
with{
|
|
1548
|
+
f = hslider("v:violin/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
1549
|
+
bend = ba.semi2ratio(hslider("v:violin/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel]
|
|
1550
|
+
[style:knob]",0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
1551
|
+
gain = hslider("v:violin/h:[0]midi/[2]gain[style:knob]
|
|
1552
|
+
",0.6,0,1,0.01);
|
|
1553
|
+
envAttack = hslider("v:violin/h:[0]midi/[3]envAttack[style:knob]
|
|
1554
|
+
",1,0,30,0.01)*0.001;
|
|
1555
|
+
s = hslider("v:violin/h:[0]midi/[4]sustain[hidden:1][midi:ctrl 64]
|
|
1556
|
+
[style:knob]",0,0,1,1);
|
|
1557
|
+
bowPress = hslider("v:violin/h:[1]bow/[0]pressure[style:knob]
|
|
1558
|
+
[midi:ctrl 1]",0.5,0,1,0.01) : si.smoo;
|
|
1559
|
+
bowPos = hslider("v:violin/h:[1]bow/[1]position[style:knob]
|
|
1560
|
+
",0.7,0,1,0.01) : si.smoo;
|
|
1561
|
+
vibratoFreq = hslider("v:violin/h:[2]otherParams/[0]vibratoFrequency
|
|
1562
|
+
[style:knob]",6,1,10,0.01);
|
|
1563
|
+
vibratoGain = hslider("v:violin/h:[2]otherParams/[1]vibratoGain
|
|
1564
|
+
[style:knob]",0.5,0,1,0.01)*0.01;
|
|
1565
|
+
outGain = hslider("v:violin/h:[2]otherParams/[2]outGain[style:knob]
|
|
1566
|
+
",0.5,0,1,0.01);
|
|
1567
|
+
t = button("v:violin/[3]gate");
|
|
1568
|
+
|
|
1569
|
+
gate = t+s : min(1);
|
|
1570
|
+
vibrato = 1+os.osc(vibratoFreq)*vibratoGain*envelope;
|
|
1571
|
+
freq = f*bend*vibrato;
|
|
1572
|
+
envelope = gate*gain : si.smooth(ba.tau2pole(envAttack));
|
|
1573
|
+
|
|
1574
|
+
stringLength = freq : f2l;
|
|
1575
|
+
bowVel = envelope;
|
|
1576
|
+
};
|
|
1577
|
+
|
|
1578
|
+
|
|
1579
|
+
//=================================Wind Instruments=======================================
|
|
1580
|
+
// Low and high level basic wind instruments parts. Most of the elements in
|
|
1581
|
+
// this section can be used in a bidirectional chain.
|
|
1582
|
+
//========================================================================================
|
|
1583
|
+
|
|
1584
|
+
//-------`(pm.)openTube`----------
|
|
1585
|
+
// A tube segment without terminations (same as [`stringSegment`](#stringsegment)).
|
|
1586
|
+
//
|
|
1587
|
+
// #### Usage
|
|
1588
|
+
//
|
|
1589
|
+
// ```
|
|
1590
|
+
// chain(A : openTube(maxLength,length) : B)
|
|
1591
|
+
// ```
|
|
1592
|
+
//
|
|
1593
|
+
// Where:
|
|
1594
|
+
//
|
|
1595
|
+
// * `maxLength`: the maximum length of the tube in meters (should be static)
|
|
1596
|
+
// * `length`: the length of the tube in meters
|
|
1597
|
+
//----------------------------------
|
|
1598
|
+
openTube = stringSegment;
|
|
1599
|
+
|
|
1600
|
+
|
|
1601
|
+
//-------`(pm.)reedTable`----------
|
|
1602
|
+
// Extremely basic reed table that can be used to implement a wide range of
|
|
1603
|
+
// single reed types for many different instruments (saxophone, clarinet, etc.).
|
|
1604
|
+
//
|
|
1605
|
+
// #### Usage
|
|
1606
|
+
//
|
|
1607
|
+
// ```
|
|
1608
|
+
// excitation : reedTable(offeset,slope) : _
|
|
1609
|
+
// ```
|
|
1610
|
+
//
|
|
1611
|
+
// Where:
|
|
1612
|
+
//
|
|
1613
|
+
// * `excitation`: an excitation signal
|
|
1614
|
+
// * `offset`: table offset
|
|
1615
|
+
// * `slope`: table slope
|
|
1616
|
+
//----------------------------------
|
|
1617
|
+
reedTable(offset,slope) = reedTable : min(1) : max(-1)
|
|
1618
|
+
with {
|
|
1619
|
+
reedTable = *(slope) + offset;
|
|
1620
|
+
};
|
|
1621
|
+
|
|
1622
|
+
|
|
1623
|
+
//-------`(pm.)fluteJetTable`----------
|
|
1624
|
+
// Extremely basic flute jet table.
|
|
1625
|
+
//
|
|
1626
|
+
// #### Usage
|
|
1627
|
+
//
|
|
1628
|
+
// ```
|
|
1629
|
+
// excitation : fluteJetTable : _
|
|
1630
|
+
// ```
|
|
1631
|
+
//
|
|
1632
|
+
// Where:
|
|
1633
|
+
//
|
|
1634
|
+
// * `excitation`: an excitation signal
|
|
1635
|
+
//----------------------------------
|
|
1636
|
+
fluteJetTable = _ <: *(* : -(1)) : clipping
|
|
1637
|
+
with{
|
|
1638
|
+
clipping = min(1) : max(-1);
|
|
1639
|
+
};
|
|
1640
|
+
|
|
1641
|
+
|
|
1642
|
+
//-------`(pm.)brassLipsTable`----------
|
|
1643
|
+
// Simple brass lips/mouthpiece table. Since this implementation is very basic
|
|
1644
|
+
// and that the lips and tube of the instrument are coupled to each other, the
|
|
1645
|
+
// length of that tube must be provided here.
|
|
1646
|
+
//
|
|
1647
|
+
// #### Usage
|
|
1648
|
+
//
|
|
1649
|
+
// ```
|
|
1650
|
+
// excitation : brassLipsTable(tubeLength,lipsTension) : _
|
|
1651
|
+
// ```
|
|
1652
|
+
//
|
|
1653
|
+
// Where:
|
|
1654
|
+
//
|
|
1655
|
+
// * `excitation`: an excitation signal (can be DC)
|
|
1656
|
+
// * `tubeLength`: length in meters of the tube connected to the mouthpiece
|
|
1657
|
+
// * `lipsTension`: tension of the lips (0-1) (default: 0.5)
|
|
1658
|
+
//----------------------------------
|
|
1659
|
+
brassLipsTable(tubeLength,lipsTension) = *(0.03) : lipFilter <: * : clipping
|
|
1660
|
+
with{
|
|
1661
|
+
clipping = min(1) : max(-1);
|
|
1662
|
+
freq = (tubeLength : l2f)*pow(4,(2*lipsTension)-1);
|
|
1663
|
+
filterR = 0.997;
|
|
1664
|
+
a1 = -2*filterR*cos(ma.PI*2*freq/ma.SR);
|
|
1665
|
+
lipFilter = fi.tf2(1,0,0,a1,pow(filterR,2)); // resonance with same freq as tube
|
|
1666
|
+
};
|
|
1667
|
+
|
|
1668
|
+
|
|
1669
|
+
//-------`(pm.)clarinetReed`----------
|
|
1670
|
+
// Clarinet reed based on [`reedTable`](#reedtable) with controllable
|
|
1671
|
+
// stiffness.
|
|
1672
|
+
//
|
|
1673
|
+
// #### Usage
|
|
1674
|
+
//
|
|
1675
|
+
// ```
|
|
1676
|
+
// excitation : clarinetReed(stiffness) : _
|
|
1677
|
+
// ```
|
|
1678
|
+
//
|
|
1679
|
+
// Where:
|
|
1680
|
+
//
|
|
1681
|
+
// * `excitation`: an excitation signal
|
|
1682
|
+
// * `stiffness`: reed stiffness (0-1)
|
|
1683
|
+
//----------------------------------
|
|
1684
|
+
clarinetReed(stiffness) = reedTable(0.7,tableSlope)
|
|
1685
|
+
with{
|
|
1686
|
+
tableSlope = -0.44 + 0.26*stiffness;
|
|
1687
|
+
};
|
|
1688
|
+
|
|
1689
|
+
|
|
1690
|
+
//-------`(pm.)clarinetMouthPiece`----------
|
|
1691
|
+
// Bidirectional block implementing a clarinet mouthpiece as well as the various
|
|
1692
|
+
// interactions happening with traveling waves. This element is ready to be
|
|
1693
|
+
// plugged to a tube...
|
|
1694
|
+
//
|
|
1695
|
+
// #### Usage
|
|
1696
|
+
//
|
|
1697
|
+
// ```
|
|
1698
|
+
// chain(clarinetMouthPiece(reedStiffness,pressure) : tube : etc.)
|
|
1699
|
+
// ```
|
|
1700
|
+
//
|
|
1701
|
+
// Where:
|
|
1702
|
+
//
|
|
1703
|
+
// * `pressure`: the pressure of the air flow (DC) created by the virtual performer (0-1).
|
|
1704
|
+
// This can also be any kind of signal that will directly injected in the mouthpiece
|
|
1705
|
+
// (e.g., breath noise, etc.).
|
|
1706
|
+
// * `reedStiffness`: reed stiffness (0-1)
|
|
1707
|
+
//----------------------------------
|
|
1708
|
+
clarinetMouthPiece(reedStiffness,pressure) = lTermination(reedInteraction,in(pressure))
|
|
1709
|
+
with{
|
|
1710
|
+
reedInteraction = *(-1) <: *(clarinetReed(reedStiffness));
|
|
1711
|
+
};
|
|
1712
|
+
|
|
1713
|
+
|
|
1714
|
+
//-------`(pm.)brassLips`----------
|
|
1715
|
+
// Bidirectional block implementing a brass mouthpiece as well as the various
|
|
1716
|
+
// interactions happening with traveling waves. This element is ready to be
|
|
1717
|
+
// plugged to a tube...
|
|
1718
|
+
//
|
|
1719
|
+
// #### Usage
|
|
1720
|
+
//
|
|
1721
|
+
// ```
|
|
1722
|
+
// chain(brassLips(tubeLength,lipsTension,pressure) : tube : etc.)
|
|
1723
|
+
// ```
|
|
1724
|
+
//
|
|
1725
|
+
// Where:
|
|
1726
|
+
//
|
|
1727
|
+
// * `tubeLength`: length in meters of the tube connected to the mouthpiece
|
|
1728
|
+
// * `lipsTension`: tension of the lips (0-1) (default: 0.5)
|
|
1729
|
+
// * `pressure`: the pressure of the air flow (DC) created by the virtual performer (0-1).
|
|
1730
|
+
// This can also be any kind of signal that will directly injected in the mouthpiece
|
|
1731
|
+
// (e.g., breath noise, etc.).
|
|
1732
|
+
//----------------------------------
|
|
1733
|
+
brassLips(tubeLength,lipsTension,pressure) = lTermination(mpInteraction,basicBlock)
|
|
1734
|
+
with{
|
|
1735
|
+
absorption = *(0.85); // absorption coefficient
|
|
1736
|
+
p = pressure*0.3; // scaling pressure
|
|
1737
|
+
mpInteraction = absorption <:
|
|
1738
|
+
(p-_ : brassLipsTable(tubeLength,lipsTension) <: *(p),1-_),_ : _,* : + : fi.dcblocker;
|
|
1739
|
+
};
|
|
1740
|
+
|
|
1741
|
+
|
|
1742
|
+
//-------`(pm.)fluteEmbouchure`----------
|
|
1743
|
+
// Bidirectional block implementing a flute embouchure as well as the various
|
|
1744
|
+
// interactions happening with traveling waves. This element is ready to be
|
|
1745
|
+
// plugged between tubes segments...
|
|
1746
|
+
//
|
|
1747
|
+
// #### Usage
|
|
1748
|
+
//
|
|
1749
|
+
// ```
|
|
1750
|
+
// chain(... : tube : fluteEmbouchure(pressure) : tube : etc.)
|
|
1751
|
+
// ```
|
|
1752
|
+
//
|
|
1753
|
+
// Where:
|
|
1754
|
+
//
|
|
1755
|
+
// * `pressure`: the pressure of the air flow (DC) created by the virtual
|
|
1756
|
+
// performer (0-1).
|
|
1757
|
+
// This can also be any kind of signal that will directly injected in the
|
|
1758
|
+
// mouthpiece (e.g., breath noise, etc.).
|
|
1759
|
+
//----------------------------------
|
|
1760
|
+
fluteEmbouchure(pressure) =
|
|
1761
|
+
(_ <: _,_),_,_ : _,*(0.5)+(pressure-_*0.5 : fluteJetTable),_;
|
|
1762
|
+
|
|
1763
|
+
|
|
1764
|
+
//-------`(pm.)wBell`----------
|
|
1765
|
+
// Generic wind instrument bell bidirectional block that should be placed at
|
|
1766
|
+
// the end of a [`chain`](#chain).
|
|
1767
|
+
//
|
|
1768
|
+
// #### Usage
|
|
1769
|
+
//
|
|
1770
|
+
// ```
|
|
1771
|
+
// chain(... : wBell(opening))
|
|
1772
|
+
// ```
|
|
1773
|
+
//
|
|
1774
|
+
// Where:
|
|
1775
|
+
//
|
|
1776
|
+
// * `opening`: the "opening" of bell (0-1)
|
|
1777
|
+
//----------------------------------
|
|
1778
|
+
wBell(opening) = rTermination(basicBlock,si.smooth(opening));
|
|
1779
|
+
|
|
1780
|
+
|
|
1781
|
+
//-------`(pm.)fluteHead`----------
|
|
1782
|
+
// Simple flute head implementing waves reflexion.
|
|
1783
|
+
//
|
|
1784
|
+
// #### Usage
|
|
1785
|
+
//
|
|
1786
|
+
// ```
|
|
1787
|
+
// chain(fluteHead : tube : ...)
|
|
1788
|
+
// ```
|
|
1789
|
+
//----------------------------------
|
|
1790
|
+
fluteHead = lTermination(*(absorption),basicBlock)
|
|
1791
|
+
with{
|
|
1792
|
+
absorption = 0.95; // same as for foot
|
|
1793
|
+
};
|
|
1794
|
+
|
|
1795
|
+
|
|
1796
|
+
//-------`(pm.)fluteFoot`----------
|
|
1797
|
+
// Simple flute foot implementing waves reflexion and dispersion.
|
|
1798
|
+
//
|
|
1799
|
+
// #### Usage
|
|
1800
|
+
//
|
|
1801
|
+
// ```
|
|
1802
|
+
// chain(... : tube : fluteFoot)
|
|
1803
|
+
// ```
|
|
1804
|
+
//----------------------------------
|
|
1805
|
+
fluteFoot = rTermination(basicBlock,*(absorption) : dispersion)
|
|
1806
|
+
with{
|
|
1807
|
+
dispersion = si.smooth(0.7); // just a simple lowpass
|
|
1808
|
+
absorption = 0.95; // same as for head
|
|
1809
|
+
};
|
|
1810
|
+
|
|
1811
|
+
|
|
1812
|
+
//-------`(pm.)clarinetModel`----------
|
|
1813
|
+
// A simple clarinet physical model without tone holes (pitch is changed by
|
|
1814
|
+
// changing the length of the tube of the instrument).
|
|
1815
|
+
//
|
|
1816
|
+
// #### Usage
|
|
1817
|
+
//
|
|
1818
|
+
// ```
|
|
1819
|
+
// clarinetModel(length,pressure,reedStiffness,bellOpening) : _
|
|
1820
|
+
// ```
|
|
1821
|
+
//
|
|
1822
|
+
// Where:
|
|
1823
|
+
//
|
|
1824
|
+
// * `tubeLength`: the length of the tube in meters
|
|
1825
|
+
// * `pressure`: the pressure of the air flow created by the virtual performer (0-1).
|
|
1826
|
+
// This can also be any kind of signal that will directly injected in the mouthpiece
|
|
1827
|
+
// (e.g., breath noise, etc.).
|
|
1828
|
+
// * `reedStiffness`: reed stiffness (0-1)
|
|
1829
|
+
// * `bellOpening`: the opening of bell (0-1)
|
|
1830
|
+
//----------------------------------
|
|
1831
|
+
clarinetModel(tubeLength,pressure,reedStiffness,bellOpening) = endChain(modelChain)
|
|
1832
|
+
with{
|
|
1833
|
+
lengthTuning = 0.05; // empirical adjustment of the tuning of the tube
|
|
1834
|
+
maxTubeLength = maxLength;
|
|
1835
|
+
tunedLength = tubeLength/2-lengthTuning; // not really sure why we had to shift octave here
|
|
1836
|
+
modelChain =
|
|
1837
|
+
chain(
|
|
1838
|
+
clarinetMouthPiece(reedStiffness,pressure) :
|
|
1839
|
+
openTube(maxTubeLength,tunedLength) :
|
|
1840
|
+
wBell(bellOpening) : out
|
|
1841
|
+
);
|
|
1842
|
+
};
|
|
1843
|
+
|
|
1844
|
+
|
|
1845
|
+
//-------`(pm.)clarinetModel_ui`----------
|
|
1846
|
+
// Same as [`clarinetModel`](#clarinetModel) but with a built-in UI. This function
|
|
1847
|
+
// doesn't implement a virtual "blower", thus `pressure` remains an argument here.
|
|
1848
|
+
//
|
|
1849
|
+
// #### Usage
|
|
1850
|
+
//
|
|
1851
|
+
// ```
|
|
1852
|
+
// clarinetModel_ui(pressure) : _
|
|
1853
|
+
// ```
|
|
1854
|
+
//
|
|
1855
|
+
// Where:
|
|
1856
|
+
//
|
|
1857
|
+
// * `pressure`: the pressure of the air flow created by the virtual performer (0-1).
|
|
1858
|
+
// This can also be any kind of signal that will be directly injected in the mouthpiece
|
|
1859
|
+
// (e.g., breath noise, etc.).
|
|
1860
|
+
//----------------------------------
|
|
1861
|
+
clarinetModel_ui(pressure) = clarinetModel(tubeLength,pressure,reedStiffness,bellOpening)*outGain
|
|
1862
|
+
with{
|
|
1863
|
+
tubeLength = hslider("v:clarinetModel/[0]tubeLength",0.8,0.01,3,0.01) : si.smoo;
|
|
1864
|
+
reedStiffness = hslider("v:clarinetModel/[1]reedStiffness",0.5,0,1,0.01);
|
|
1865
|
+
bellOpening = hslider("v:clarinetModel/[2]bellOpening",0.5,0,1,0.01);
|
|
1866
|
+
outGain = hslider("v:clarinetModel/[3]outGain",0.5,0,1,0.01);
|
|
1867
|
+
};
|
|
1868
|
+
|
|
1869
|
+
|
|
1870
|
+
//-------`(pm.)clarinet_ui`----------
|
|
1871
|
+
// Ready-to-use clarinet physical model with built-in UI based on
|
|
1872
|
+
// [`clarinetModel`](#clarinetmodel).
|
|
1873
|
+
//
|
|
1874
|
+
// #### Usage
|
|
1875
|
+
//
|
|
1876
|
+
// ```
|
|
1877
|
+
// clarinet_ui : _
|
|
1878
|
+
// ```
|
|
1879
|
+
//----------------------------------
|
|
1880
|
+
clarinet_ui = hgroup("clarinet",blower_ui : clarinetModel_ui);
|
|
1881
|
+
|
|
1882
|
+
|
|
1883
|
+
//-------`(pm.)clarinet_ui_MIDI`----------
|
|
1884
|
+
// Ready-to-use MIDI compliant clarinet physical model with built-in UI.
|
|
1885
|
+
//
|
|
1886
|
+
// #### Usage
|
|
1887
|
+
//
|
|
1888
|
+
// ```
|
|
1889
|
+
// clarinet_ui_MIDI : _
|
|
1890
|
+
// ```
|
|
1891
|
+
//----------------------------------
|
|
1892
|
+
clarinet_ui_MIDI =
|
|
1893
|
+
clarinetModel(tubeLength,blow,reedStiffness,bellOpening)*outGain
|
|
1894
|
+
with{
|
|
1895
|
+
f = hslider("v:clarinet/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
1896
|
+
bend = ba.semi2ratio(hslider("v:clarinet/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel]
|
|
1897
|
+
[style:knob]",0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
1898
|
+
gain = hslider("v:clarinet/h:[0]midi/[2]gain[style:knob]
|
|
1899
|
+
",0.6,0,1,0.01);
|
|
1900
|
+
envAttack = hslider("v:clarinet/h:[0]midi/[3]envAttack[style:knob]
|
|
1901
|
+
",1,0,30,0.01)*0.001;
|
|
1902
|
+
s = hslider("v:clarinet/h:[0]midi/[4]sustain[hidden:1][midi:ctrl 64]
|
|
1903
|
+
[style:knob]",0,0,1,1);
|
|
1904
|
+
reedStiffness = hslider("v:clarinet/h:[1]otherParams/[0]reedStiffness
|
|
1905
|
+
[midi:ctrl 1][style:knob]",0.5,0,1,0.01);
|
|
1906
|
+
bellOpening = hslider("v:clarinet/h:[1]otherParams/[1]bellOpening
|
|
1907
|
+
[midi:ctrl 3][style:knob]",0.5,0,1,0.01);
|
|
1908
|
+
vibratoFreq = hslider("v:clarinet/h:[1]otherParams/[2]vibratoFreq
|
|
1909
|
+
[style:knob]",5,1,10,0.01);
|
|
1910
|
+
vibratoGain = hslider("v:clarinet/h:[1]otherParams/[3]vibratoGain
|
|
1911
|
+
[style:knob]",0.25,0,1,0.01)*0.01;
|
|
1912
|
+
outGain = hslider("v:clarinet/h:[1]otherParams/[4]outGain[style:knob]
|
|
1913
|
+
",0.5,0,1,0.01);
|
|
1914
|
+
t = button("v:clarinet/[2]gate");
|
|
1915
|
+
|
|
1916
|
+
gate = t+s : min(1);
|
|
1917
|
+
vibrato = 1+os.osc(vibratoFreq)*vibratoGain*envelope;
|
|
1918
|
+
freq = f*bend*vibrato;
|
|
1919
|
+
envelope = gate*gain : si.smooth(ba.tau2pole(envAttack));
|
|
1920
|
+
|
|
1921
|
+
tubeLength = freq : f2l;
|
|
1922
|
+
pressure = envelope; // TODO: double vibrato here!!
|
|
1923
|
+
blow = blower(pressure,0.05,2000,vibratoFreq,vibratoGain);
|
|
1924
|
+
};
|
|
1925
|
+
|
|
1926
|
+
|
|
1927
|
+
//-------`(pm.)brassModel`----------
|
|
1928
|
+
// A simple generic brass instrument physical model without pistons
|
|
1929
|
+
// (pitch is changed by changing the length of the tube of the instrument).
|
|
1930
|
+
// This model is kind of hard to control and might not sound very good if
|
|
1931
|
+
// bad parameters are given to it...
|
|
1932
|
+
//
|
|
1933
|
+
// #### Usage
|
|
1934
|
+
//
|
|
1935
|
+
// ```
|
|
1936
|
+
// brassModel(tubeLength,lipsTension,mute,pressure) : _
|
|
1937
|
+
// ```
|
|
1938
|
+
//
|
|
1939
|
+
// Where:
|
|
1940
|
+
//
|
|
1941
|
+
// * `tubeLength`: the length of the tube in meters
|
|
1942
|
+
// * `lipsTension`: tension of the lips (0-1) (default: 0.5)
|
|
1943
|
+
// * `mute`: mute opening at the end of the instrument (0-1) (default: 0.5)
|
|
1944
|
+
// * `pressure`: the pressure of the air flow created by the virtual performer (0-1).
|
|
1945
|
+
// This can also be any kind of signal that will directly injected in the mouthpiece
|
|
1946
|
+
// (e.g., breath noise, etc.).
|
|
1947
|
+
//----------------------------------
|
|
1948
|
+
brassModel(tubeLength,lipsTension,mute,pressure) = endChain(brassChain)
|
|
1949
|
+
with{
|
|
1950
|
+
maxTubeLength = maxLength;
|
|
1951
|
+
lengthTuning = 0; // Not that important for that one because of lips tension
|
|
1952
|
+
tunedLength = tubeLength + lengthTuning;
|
|
1953
|
+
brassChain = chain(brassLips(tunedLength,lipsTension,pressure) : openTube(maxTubeLength,tunedLength) : wBell(mute) : out);
|
|
1954
|
+
};
|
|
1955
|
+
|
|
1956
|
+
|
|
1957
|
+
//-------`(pm.)brassModel_ui`----------
|
|
1958
|
+
// Same as [`brassModel`](#brassModel) but with a built-in UI. This function
|
|
1959
|
+
// doesn't implement a virtual "blower", thus `pressure` remains an argument here.
|
|
1960
|
+
//
|
|
1961
|
+
// #### Usage
|
|
1962
|
+
//
|
|
1963
|
+
// ```
|
|
1964
|
+
// brassModel_ui(pressure) : _
|
|
1965
|
+
// ```
|
|
1966
|
+
//
|
|
1967
|
+
// Where:
|
|
1968
|
+
//
|
|
1969
|
+
// * `pressure`: the pressure of the air flow created by the virtual performer (0-1).
|
|
1970
|
+
// This can also be any kind of signal that will be directly injected in the mouthpiece
|
|
1971
|
+
// (e.g., breath noise, etc.).
|
|
1972
|
+
//----------------------------------
|
|
1973
|
+
brassModel_ui(pressure) = brassModel(tubeLength,lipsTension,mute,pressure)
|
|
1974
|
+
with{
|
|
1975
|
+
tubeLength = hslider("v:brassModel/[1]tubeLength",0.5,0.01,2.5,0.01) : si.smoo;
|
|
1976
|
+
lipsTension = hslider("v:brassModel/[2]lipsTension",0.5,0,1,0.01) : si.smoo;
|
|
1977
|
+
mute = hslider("v:brassModel/[3]mute",0.5,0,1,0.01) : si.smoo;
|
|
1978
|
+
};
|
|
1979
|
+
|
|
1980
|
+
|
|
1981
|
+
//-------`(pm.)brass_ui`----------
|
|
1982
|
+
// Ready-to-use brass instrument physical model with built-in UI based on
|
|
1983
|
+
// [`brassModel`](#brassmodel).
|
|
1984
|
+
//
|
|
1985
|
+
// #### Usage
|
|
1986
|
+
//
|
|
1987
|
+
// ```
|
|
1988
|
+
// brass_ui : _
|
|
1989
|
+
// ```
|
|
1990
|
+
//----------------------------------
|
|
1991
|
+
brass_ui = hgroup("brass",blower_ui : brassModel_ui);
|
|
1992
|
+
|
|
1993
|
+
|
|
1994
|
+
//-------`(pm.)brass_ui_MIDI`----------
|
|
1995
|
+
// Ready-to-use MIDI-controllable brass instrument physical model with built-in UI.
|
|
1996
|
+
//
|
|
1997
|
+
// #### Usage
|
|
1998
|
+
//
|
|
1999
|
+
// ```
|
|
2000
|
+
// brass_ui_MIDI : _
|
|
2001
|
+
// ```
|
|
2002
|
+
//----------------------------------
|
|
2003
|
+
brass_ui_MIDI = brassModel(tubeLength,lipsTension,mute,pressure)*outGain
|
|
2004
|
+
with{
|
|
2005
|
+
f = hslider("v:brass/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
2006
|
+
bend = ba.semi2ratio(hslider("v:brass/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel]
|
|
2007
|
+
[style:knob]",0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
2008
|
+
gain = hslider("v:brass/h:[0]midi/[2]gain[style:knob]
|
|
2009
|
+
",0.5,0,1,0.01);
|
|
2010
|
+
envAttack = hslider("v:brass/h:[0]midi/[3]envAttack[style:knob]
|
|
2011
|
+
",1,0,30,0.01)*0.001;
|
|
2012
|
+
s = hslider("v:brass/h:[0]midi/[4]sustain[hidden:1][midi:ctrl 64]
|
|
2013
|
+
[style:knob]",0,0,1,1);
|
|
2014
|
+
lipsTension = hslider("v:brass/h:[1]otherParams/[0]lipsTension[style:knob]
|
|
2015
|
+
[midi:ctrl 1]",0.5,0,1,0.01) : si.smoo;
|
|
2016
|
+
mute = hslider("v:brass/h:[1]otherParams/[1]mute[style:knob]
|
|
2017
|
+
",0.5,0,1,0.01) : si.smoo;
|
|
2018
|
+
vibratoFreq = hslider("v:brass/h:[1]otherParams/[2]vibratoFreq[style:knob]
|
|
2019
|
+
",5,1,10,0.01);
|
|
2020
|
+
vibratoGain = hslider("v:brass/h:[1]otherParams/[3]vibratoGain[style:knob]
|
|
2021
|
+
",0.5,0,1,0.01)*0.04;
|
|
2022
|
+
outGain = hslider("v:brass/h:[1]otherParams/[4]outGain[style:knob]
|
|
2023
|
+
",0.5,0,1,0.01);
|
|
2024
|
+
t = button("v:brass/[2]gate");
|
|
2025
|
+
|
|
2026
|
+
gate = t+s : min(1);
|
|
2027
|
+
vibrato = 1+os.osc(vibratoFreq)*vibratoGain*envelope;
|
|
2028
|
+
freq = f*bend;
|
|
2029
|
+
envelope = gate*gain : si.smooth(ba.tau2pole(envAttack));
|
|
2030
|
+
|
|
2031
|
+
tubeLength = freq : f2l;
|
|
2032
|
+
pressure = envelope*vibrato;
|
|
2033
|
+
};
|
|
2034
|
+
|
|
2035
|
+
|
|
2036
|
+
//-------`(pm.)fluteModel`----------
|
|
2037
|
+
// A simple generic flute instrument physical model without tone holes
|
|
2038
|
+
// (pitch is changed by changing the length of the tube of the instrument).
|
|
2039
|
+
//
|
|
2040
|
+
// #### Usage
|
|
2041
|
+
//
|
|
2042
|
+
// ```
|
|
2043
|
+
// fluteModel(tubeLength,mouthPosition,pressure) : _
|
|
2044
|
+
// ```
|
|
2045
|
+
//
|
|
2046
|
+
// Where:
|
|
2047
|
+
//
|
|
2048
|
+
// * `tubeLength`: the length of the tube in meters
|
|
2049
|
+
// * `mouthPosition`: position of the mouth on the embouchure (0-1) (default: 0.5)
|
|
2050
|
+
// * `pressure`: the pressure of the air flow created by the virtual performer (0-1).
|
|
2051
|
+
// This can also be any kind of signal that will directly injected in the mouthpiece
|
|
2052
|
+
// (e.g., breath noise, etc.).
|
|
2053
|
+
//----------------------------------
|
|
2054
|
+
// TODO: this model is out of tune and we're not really sure why
|
|
2055
|
+
fluteModel(tubeLength,mouthPosition,pressure) = endChain(fluteChain) : fi.dcblocker
|
|
2056
|
+
with{
|
|
2057
|
+
maxTubeLength = maxLength;
|
|
2058
|
+
tubeTuning = 0.27; // set "by hand"
|
|
2059
|
+
tLength = tubeLength+tubeTuning; // global tube length
|
|
2060
|
+
embouchurePos = 0.27 + (mouthPosition-0.5)*0.4; // position of the embouchure on the tube
|
|
2061
|
+
tted = tLength*embouchurePos; // head to embouchure distance
|
|
2062
|
+
eted = tLength*(1-embouchurePos); // embouchure to foot distance
|
|
2063
|
+
fluteChain = chain(fluteHead : openTube(maxTubeLength,tted) : fluteEmbouchure(pressure) : openTube(maxTubeLength,eted) : fluteFoot : out);
|
|
2064
|
+
};
|
|
2065
|
+
|
|
2066
|
+
|
|
2067
|
+
//-------`(pm.)fluteModel_ui`----------
|
|
2068
|
+
// Same as [`fluteModel`](#fluteModel) but with a built-in UI. This function
|
|
2069
|
+
// doesn't implement a virtual "blower", thus `pressure` remains an argument here.
|
|
2070
|
+
//
|
|
2071
|
+
// #### Usage
|
|
2072
|
+
//
|
|
2073
|
+
// ```
|
|
2074
|
+
// fluteModel_ui(pressure) : _
|
|
2075
|
+
// ```
|
|
2076
|
+
//
|
|
2077
|
+
// Where:
|
|
2078
|
+
//
|
|
2079
|
+
// * `pressure`: the pressure of the air flow created by the virtual performer (0-1).
|
|
2080
|
+
// This can also be any kind of signal that will be directly injected in the mouthpiece
|
|
2081
|
+
// (e.g., breath noise, etc.).
|
|
2082
|
+
//----------------------------------
|
|
2083
|
+
fluteModel_ui(pressure) =
|
|
2084
|
+
fluteModel(tubeLength,mouthPosition,pressure)*outGain
|
|
2085
|
+
with{
|
|
2086
|
+
tubeLength = hslider("v:fluteModel/[0]tubeLength",0.8,0.01,3,0.01) : si.smoo;
|
|
2087
|
+
mouthPosition = hslider("v:fluteModel/[1]mouthPosition",0.5,0,1,0.01) : si.smoo;
|
|
2088
|
+
outGain = hslider("v:fluteModel/[2]outGain",0.5,0,1,0.01);
|
|
2089
|
+
};
|
|
2090
|
+
|
|
2091
|
+
|
|
2092
|
+
//-------`(pm.)flute_ui`----------
|
|
2093
|
+
// Ready-to-use flute physical model with built-in UI based on
|
|
2094
|
+
// [`fluteModel`](#flutemodel).
|
|
2095
|
+
//
|
|
2096
|
+
// #### Usage
|
|
2097
|
+
//
|
|
2098
|
+
// ```
|
|
2099
|
+
// flute_ui : _
|
|
2100
|
+
// ```
|
|
2101
|
+
//----------------------------------
|
|
2102
|
+
flute_ui = hgroup("flute",blower_ui : fluteModel_ui);
|
|
2103
|
+
|
|
2104
|
+
|
|
2105
|
+
//-------`(pm.)flute_ui_MIDI`----------
|
|
2106
|
+
// Ready-to-use MIDI-controllable flute physical model with built-in UI.
|
|
2107
|
+
//
|
|
2108
|
+
// #### Usage
|
|
2109
|
+
//
|
|
2110
|
+
// ```
|
|
2111
|
+
// flute_ui_MIDI : _
|
|
2112
|
+
// ```
|
|
2113
|
+
//----------------------------------
|
|
2114
|
+
flute_ui_MIDI = fluteModel(tubeLength,mouthPosition,blow)*outGain
|
|
2115
|
+
with{
|
|
2116
|
+
f = hslider("v:flute/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
2117
|
+
bend = ba.semi2ratio(hslider("v:flute/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel]
|
|
2118
|
+
[style:knob]",0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
2119
|
+
gain = hslider("v:flute/h:[0]midi/[2]gain[style:knob]
|
|
2120
|
+
",0.9,0,1,0.01);
|
|
2121
|
+
envAttack = hslider("v:flute/h:[0]midi/[3]envAttack[style:knob]
|
|
2122
|
+
",1,0,30,0.01)*0.001;
|
|
2123
|
+
s = hslider("v:flute/h:[0]midi/[4]sustain[hidden:1][midi:ctrl 64]
|
|
2124
|
+
[style:knob]",0,0,1,1);
|
|
2125
|
+
mouthPosition = hslider("v:flute/h:[1]otherParams/[0]mouthPosition
|
|
2126
|
+
[style:knob][midi:ctrl 1]",0.5,0,1,0.01)
|
|
2127
|
+
: si.smoo;
|
|
2128
|
+
vibratoFreq = hslider("v:flute/h:[1]otherParams/[1]vibratoFreq[style:knob]
|
|
2129
|
+
",5,1,10,0.01);
|
|
2130
|
+
vibratoGain = hslider("v:flute/h:[1]otherParams/[2]vibratoGain[style:knob]
|
|
2131
|
+
",0.5,0,1,0.01)*0.04;
|
|
2132
|
+
outGain = hslider("v:flute/h:[1]otherParams/[3]outGain[style:knob]
|
|
2133
|
+
",0.5,0,1,0.01);
|
|
2134
|
+
t = button("v:flute/[2]gate");
|
|
2135
|
+
|
|
2136
|
+
gate = t+s : min(1);
|
|
2137
|
+
freq = f*bend;
|
|
2138
|
+
envelope = gate*gain : si.smooth(ba.tau2pole(envAttack));
|
|
2139
|
+
|
|
2140
|
+
tubeLength = freq : f2l;
|
|
2141
|
+
pressure = envelope;
|
|
2142
|
+
blow = blower(pressure,0.05,2000,vibratoFreq,vibratoGain);
|
|
2143
|
+
};
|
|
2144
|
+
|
|
2145
|
+
|
|
2146
|
+
//=====================================Exciters===========================================
|
|
2147
|
+
// Various kind of excitation signal generators.
|
|
2148
|
+
//========================================================================================
|
|
2149
|
+
|
|
2150
|
+
//-------`(pm.)impulseExcitation`--------------
|
|
2151
|
+
// Creates an impulse excitation of one sample.
|
|
2152
|
+
//
|
|
2153
|
+
// #### Usage
|
|
2154
|
+
//
|
|
2155
|
+
// ```
|
|
2156
|
+
// gate = button('gate');
|
|
2157
|
+
// impulseExcitation(gate) : chain;
|
|
2158
|
+
// ```
|
|
2159
|
+
//
|
|
2160
|
+
// Where:
|
|
2161
|
+
//
|
|
2162
|
+
// * `gate`: a gate button
|
|
2163
|
+
//--------------------------------------
|
|
2164
|
+
impulseExcitation(trigger) = trigger : ba.impulsify;
|
|
2165
|
+
|
|
2166
|
+
|
|
2167
|
+
//-------`(pm.)strikeModel`--------------
|
|
2168
|
+
// Creates a filtered noise excitation.
|
|
2169
|
+
//
|
|
2170
|
+
// #### Usage
|
|
2171
|
+
//
|
|
2172
|
+
// ```
|
|
2173
|
+
// gate = button('gate');
|
|
2174
|
+
// strikeModel(LPcutoff,HPcutoff,sharpness,gain,gate) : chain;
|
|
2175
|
+
// ```
|
|
2176
|
+
//
|
|
2177
|
+
// Where:
|
|
2178
|
+
//
|
|
2179
|
+
// * `HPcutoff`: highpass cutoff frequency
|
|
2180
|
+
// * `LPcutoff`: lowpass cutoff frequency
|
|
2181
|
+
// * `sharpness`: sharpness of the attack and release (0-1)
|
|
2182
|
+
// * `gain`: gain of the excitation
|
|
2183
|
+
// * `gate`: a gate button/trigger signal (0/1)
|
|
2184
|
+
//--------------------------------------
|
|
2185
|
+
strikeModel(HPcutoff,LPcutoff,sharpness,gain,trigger) =
|
|
2186
|
+
no.noise : fi.highpass(2,HPcutoff) : fi.lowpass(2,LPcutoff) :
|
|
2187
|
+
*(en.ar(att,rel,trigger))*gain
|
|
2188
|
+
with{
|
|
2189
|
+
att = 0.002*sharpness;
|
|
2190
|
+
rel = att;
|
|
2191
|
+
};
|
|
2192
|
+
|
|
2193
|
+
|
|
2194
|
+
//-------`(pm.)strike`--------------
|
|
2195
|
+
// Strikes generator with controllable excitation position.
|
|
2196
|
+
//
|
|
2197
|
+
// #### Usage
|
|
2198
|
+
//
|
|
2199
|
+
// ```
|
|
2200
|
+
// gate = button('gate');
|
|
2201
|
+
// strike(exPos,sharpness,gain,gate) : chain;
|
|
2202
|
+
// ```
|
|
2203
|
+
//
|
|
2204
|
+
// Where:
|
|
2205
|
+
//
|
|
2206
|
+
// * `exPos`: excitation position wiht 0: for max low freqs and 1: for max high
|
|
2207
|
+
// freqs. So, on membrane for example, 0 would be the middle and 1 the edge
|
|
2208
|
+
// * `sharpness`: sharpness of the attack and release (0-1)
|
|
2209
|
+
// * `gain`: gain of the excitation
|
|
2210
|
+
// * `gate`: a gate button/trigger signal (0/1)
|
|
2211
|
+
//--------------------------------------
|
|
2212
|
+
strike(exPos,sharpness,gain,trigger) = strikeModel(HPcutoff,LPcutoff,sharpness,gain,trigger)
|
|
2213
|
+
with{
|
|
2214
|
+
HPcutoff = 40+exPos*500;
|
|
2215
|
+
LPcutoff = 500+exPos*15000;
|
|
2216
|
+
};
|
|
2217
|
+
|
|
2218
|
+
|
|
2219
|
+
//-------`(pm.)pluckString`--------------
|
|
2220
|
+
// Creates a plucking excitation signal.
|
|
2221
|
+
//
|
|
2222
|
+
// #### Usage
|
|
2223
|
+
//
|
|
2224
|
+
// ```
|
|
2225
|
+
// trigger = button('gate');
|
|
2226
|
+
// pluckString(stringLength,cutoff,maxFreq,sharpness,trigger)
|
|
2227
|
+
// ```
|
|
2228
|
+
//
|
|
2229
|
+
// Where:
|
|
2230
|
+
//
|
|
2231
|
+
// * `stringLength`: length of the string to pluck
|
|
2232
|
+
// * `cutoff`: cutoff ratio (1 for default)
|
|
2233
|
+
// * `maxFreq`: max frequency ratio (1 for default)
|
|
2234
|
+
// * `sharpness`: sharpness of the attack and release (1 for default)
|
|
2235
|
+
// * `gain`: gain of the excitation (0-1)
|
|
2236
|
+
// * `trigger`: trigger signal (1 for on, 0 for off)
|
|
2237
|
+
//--------------------------------------
|
|
2238
|
+
pluckString(stringLength,cutoff,maxFreq,sharpness,gain,trigger) =
|
|
2239
|
+
no.noise : fi.lowpass(2,cutoffreq) : *(en.ar(att,rel,trigger))*gain
|
|
2240
|
+
with{
|
|
2241
|
+
freq = stringLength : l2f;
|
|
2242
|
+
maxF = 2000*maxFreq;
|
|
2243
|
+
att = 0.002*sharpness*pow((1 - freq/maxF),2);
|
|
2244
|
+
rel = att;
|
|
2245
|
+
cutoffreq = freq*5*cutoff;
|
|
2246
|
+
};
|
|
2247
|
+
|
|
2248
|
+
|
|
2249
|
+
//-------`(pm.)blower`--------------
|
|
2250
|
+
// A virtual blower creating a DC signal with some breath noise in it.
|
|
2251
|
+
//
|
|
2252
|
+
// #### Usage
|
|
2253
|
+
//
|
|
2254
|
+
// ```
|
|
2255
|
+
// blower(pressure,breathGain,breathCutoff) : _
|
|
2256
|
+
// ```
|
|
2257
|
+
//
|
|
2258
|
+
// Where:
|
|
2259
|
+
//
|
|
2260
|
+
// * `pressure`: pressure (0-1)
|
|
2261
|
+
// * `breathGain`: breath noise gain (0-1) (recommended: 0.005)
|
|
2262
|
+
// * `breathCutoff`: breath cuttoff frequency (Hz) (recommended: 2000)
|
|
2263
|
+
//--------------------------------------
|
|
2264
|
+
blower(pressure,breathGain,breathCutoff,vibratoFreq,vibratoGain) = pressure + vibrato + breathNoise
|
|
2265
|
+
with{
|
|
2266
|
+
vibrato = os.osc(vibratoFreq)*vibratoGain;
|
|
2267
|
+
breathNoise = no.noise : fi.lowpass(2,breathCutoff) : *(pressure*breathGain);
|
|
2268
|
+
};
|
|
2269
|
+
|
|
2270
|
+
|
|
2271
|
+
//-------`(pm.)blower_ui`--------------
|
|
2272
|
+
// Same as [`blower`](#blower) but with a built-in UI.
|
|
2273
|
+
//
|
|
2274
|
+
// #### Usage
|
|
2275
|
+
//
|
|
2276
|
+
// ```
|
|
2277
|
+
// blower : somethingToBeBlown
|
|
2278
|
+
// ```
|
|
2279
|
+
//--------------------------------------
|
|
2280
|
+
blower_ui = blower(pressure,breathGain,breathCutoff,vibratoFreq,vibratoGain)
|
|
2281
|
+
with{
|
|
2282
|
+
pressure = hslider("v:blower/[0]pressure",0,0,1,0.01) : si.smoo;
|
|
2283
|
+
breathGain = hslider("v:blower/[1]breathGain",0.1,0,1,0.01)*0.05;
|
|
2284
|
+
breathCutoff = hslider("v:blower/[2]breathCutoff",2000,20,20000,0.1);
|
|
2285
|
+
vibratoFreq = hslider("v:blower/[3]vibratoFreq",5,0.1,10,0.1);
|
|
2286
|
+
vibratoGain = hslider("v:blower/[4]vibratoGain",0.25,0,1,0.01)*0.03;
|
|
2287
|
+
};
|
|
2288
|
+
|
|
2289
|
+
|
|
2290
|
+
//============================Modal Percussions===========================================
|
|
2291
|
+
// High and low level functions for modal synthesis of percussion instruments.
|
|
2292
|
+
//========================================================================================
|
|
2293
|
+
|
|
2294
|
+
//-------`(pm.)djembeModel`----------
|
|
2295
|
+
// Dirt-simple djembe modal physical model. Mode parameters are empirically
|
|
2296
|
+
// calculated and don't correspond to any measurements or 3D model. They
|
|
2297
|
+
// kind of sound good though :).
|
|
2298
|
+
//
|
|
2299
|
+
// #### Usage
|
|
2300
|
+
//
|
|
2301
|
+
// ```
|
|
2302
|
+
// excitation : djembeModel(freq)
|
|
2303
|
+
// ```
|
|
2304
|
+
//
|
|
2305
|
+
// Where:
|
|
2306
|
+
//
|
|
2307
|
+
// * `excitation`: excitation signal
|
|
2308
|
+
// * `freq`: fundamental frequency of the bar
|
|
2309
|
+
//----------------------------------
|
|
2310
|
+
djembeModel(freq) = _ <: par(i,nModes,modeFilter(modeFreqs(i),modeT60s(i),modeGains(i))) :> /(nModes)
|
|
2311
|
+
with{
|
|
2312
|
+
nModes = 20;
|
|
2313
|
+
theta = 0; // angle
|
|
2314
|
+
modeFreqs(i) = freq + 200*i;
|
|
2315
|
+
modeT60s(i) = (nModes-i)*0.03;
|
|
2316
|
+
modeGains(i) = cos((i+1)*theta)/float(i+1)*(1/(i+1));
|
|
2317
|
+
};
|
|
2318
|
+
|
|
2319
|
+
|
|
2320
|
+
//-------`(pm.)djembe`----------
|
|
2321
|
+
// Dirt-simple djembe modal physical model. Mode parameters are empirically
|
|
2322
|
+
// calculated and don't correspond to any measurements or 3D model. They
|
|
2323
|
+
// kind of sound good though :).
|
|
2324
|
+
//
|
|
2325
|
+
// This model also implements a virtual "exciter".
|
|
2326
|
+
//
|
|
2327
|
+
// #### Usage
|
|
2328
|
+
//
|
|
2329
|
+
// ```
|
|
2330
|
+
// djembe(freq,strikePosition,strikeSharpness,gain,trigger)
|
|
2331
|
+
// ```
|
|
2332
|
+
//
|
|
2333
|
+
// Where:
|
|
2334
|
+
//
|
|
2335
|
+
// * `freq`: fundamental frequency of the model
|
|
2336
|
+
// * `strikePosition`: strike position (0 for the middle of the membrane and
|
|
2337
|
+
// 1 for the edge)
|
|
2338
|
+
// * `strikeSharpness`: sharpness of the strike (0-1, default: 0.5)
|
|
2339
|
+
// * `gain`: gain of the strike
|
|
2340
|
+
// * `trigger`: trigger signal (0: off, 1: on)
|
|
2341
|
+
//----------------------------------
|
|
2342
|
+
djembe(freq,strikePosition,strikeSharpness,gain,trigger) =
|
|
2343
|
+
strike(strikePosition,strikeSharpness,gain,trigger) : djembeModel(freq);
|
|
2344
|
+
|
|
2345
|
+
//-------`(pm.)djembe_ui_MIDI`----------
|
|
2346
|
+
// Simple MIDI controllable djembe physical model with built-in UI.
|
|
2347
|
+
//
|
|
2348
|
+
// #### Usage
|
|
2349
|
+
//
|
|
2350
|
+
// ```
|
|
2351
|
+
// djembe_ui_MIDI : _
|
|
2352
|
+
// ```
|
|
2353
|
+
//----------------------------------
|
|
2354
|
+
djembe_ui_MIDI =
|
|
2355
|
+
djembe(freq,strikePosition,strikeSharpness,gain,gate)*outGain
|
|
2356
|
+
with{
|
|
2357
|
+
freq = hslider("v:djembe/h:[0]midi/[0]freq[style:knob]",60,50,100,0.01);
|
|
2358
|
+
gain = hslider("v:djembe/h:[0]midi/[2]gain[style:knob]",1,0,1,0.01);
|
|
2359
|
+
strikePosition = hslider("v:djembe/h:[1]otherParams/[0]strikePosition
|
|
2360
|
+
[midi:ctrl 1][style:knob]",0.5,0,1,0.01);
|
|
2361
|
+
strikeSharpness = hslider("v:djembe/h:[1]otherParams/[1]strikeSharpness[style:knob]",0.5,0.01,5,0.01);
|
|
2362
|
+
outGain = hslider("v:djembe/h:[1]otherParams/[2]outGain
|
|
2363
|
+
[style:knob]",1,0,1,0.01);
|
|
2364
|
+
gate = button("v:djembe/[3]gate");
|
|
2365
|
+
};
|
|
2366
|
+
|
|
2367
|
+
|
|
2368
|
+
//-------`(pm.)marimbaBarModel`----------
|
|
2369
|
+
// Generic marimba tone bar modal model.
|
|
2370
|
+
//
|
|
2371
|
+
// This model was generated using
|
|
2372
|
+
// `mesh2faust` from a 3D CAD model of a marimba tone bar
|
|
2373
|
+
// (`libraries/modalmodels/marimbaBar`). The corresponding CAD model is that
|
|
2374
|
+
// of a C2 tone bar (original fundamental frequency: ~65Hz). While
|
|
2375
|
+
// `marimbaBarModel` allows to translate the harmonic content of the generated
|
|
2376
|
+
// sound by providing a frequency (`freq`), mode transposition has limits and
|
|
2377
|
+
// the model will sound less and less like a marimba tone bar as it
|
|
2378
|
+
// diverges from C2. To make an accurate model of a marimba, we'd want to have
|
|
2379
|
+
// an independent model for each bar...
|
|
2380
|
+
//
|
|
2381
|
+
// This model contains 5 excitation positions going linearly from the center
|
|
2382
|
+
// bottom to the center top of the bar. Obviously, a model with more excitation
|
|
2383
|
+
// position could be regenerated using `mesh2faust`.
|
|
2384
|
+
//
|
|
2385
|
+
// #### Usage
|
|
2386
|
+
//
|
|
2387
|
+
// ```
|
|
2388
|
+
// excitation : marimbaBarModel(freq,exPos,t60,t60DecayRatio,t60DecaySlope)
|
|
2389
|
+
// ```
|
|
2390
|
+
//
|
|
2391
|
+
// Where:
|
|
2392
|
+
//
|
|
2393
|
+
// * `excitation`: excitation signal
|
|
2394
|
+
// * `freq`: fundamental frequency of the bar
|
|
2395
|
+
// * `exPos`: excitation position (0-4)
|
|
2396
|
+
// * `t60`: T60 in seconds (recommended value: 0.1)
|
|
2397
|
+
// * `t60DecayRatio`: T60 decay ratio (recommended value: 1)
|
|
2398
|
+
// * `t60DecaySlope`: T60 decay slope (recommended value: 5)
|
|
2399
|
+
//----------------------------------
|
|
2400
|
+
marimbaBarModel(freq,exPos,t60,t60DecayRatio,t60DecaySlope) = _ <: par(i,nModes,modeFilter(modesFreqs(i),modesT60s(i),modesGains(int(exPos),i))) :> /(nModes)
|
|
2401
|
+
with{
|
|
2402
|
+
nModes = 50;
|
|
2403
|
+
nExPos = 5;
|
|
2404
|
+
modesFreqRatios(n) = ba.take(n+1,(1,3.31356,3.83469,8.06313,9.44778,14.1169,18.384,21.0102,26.1775,28.9944,37.0728,37.8703,40.0634,47.6439,51.019,52.43,58.286,63.5486,65.3628,66.9587,74.5301,78.692,80.8375,89.978,92.9661,95.1914,97.4807,110.62,112.069,113.826,119.356,127.045,129.982,132.259,133.477,144.549,149.438,152.033,153.166,155.597,158.183,168.105,171.863,174.464,178.937,181.482,185.398,190.369,192.19,195.505));
|
|
2405
|
+
modesFreqs(i) = freq*modesFreqRatios(i);
|
|
2406
|
+
modesGains(p,n) = waveform{1,0.776725,0.625723,0.855223,0.760159,0.698373,0.768011,0.641127,0.244034,0.707754,0.634013,0.247527,0.660849,0.450396,0.567783,0.106361,0.716814,0.66392,0.291208,0.310599,0.801495,0.635292,0.307435,0.874124,0.497668,0.487088,0.459115,0.733455,0.541818,0.441318,0.31392,0.40309,0.685353,0.60314,0.400552,0.453511,0.634386,0.291547,0.131605,0.368507,0.839907,0.60216,0.288296,0.57967,0.0242493,0.262746,0.368588,0.890284,0.408963,0.556072,0.884427,0.83211,0.612015,0.757176,0.919477,1,0.827963,0.89241,0.0357408,0.480789,0.752872,0.0546301,0.235937,0.362938,0.444472,0.101751,0.703418,0.453136,0.316629,0.490394,0.982508,0.551622,0.602009,0.666957,0.77683,0.905662,0.0987197,0.402968,0.829452,0.307645,0.64048,0.983971,0.584205,0.650365,0.334447,0.58357,0.540191,0.672534,0.245712,0.687298,0.883058,0.79295,0.600619,0.572682,0.122612,0.388248,0.290658,0.380255,0.290967,0.567819,0.0737721,0.42099,0.0786578,0.393995,0.268983,0.260614,0.494086,0.238026,0.0987824,0.277879,0.440563,0.0770212,0.450591,0.128137,0.0368275,0.128699,0.329605,0.374512,0.36359,0.272594,0.379052,0.305241,0.0741129,0.345728,0.29935,0.221284,0.0261391,0.293202,0.361885,0.11433,0.239005,0.434156,0.329583,0.21946,0.284175,0.198555,0.431976,0.302985,1,0.146221,0.140701,0.264243,0.185997,0.426322,0.30478,0.34399,0.19543,0.386955,0.1876,0.172812,0.0434115,0.303761,0.069454,0.453943,0.832451,0.317817,0.940601,1,0.180658,0.737921,0.832297,0.402352,0.126786,0.594398,0.485455,0.32447,0.365102,0.777922,0.588272,0.401353,0.610735,0.158693,0.0746072,0.825099,0.925459,0.65377,0.260792,0.719384,0.559908,0.37259,0.360035,0.622939,0.210271,0.444595,0.311286,0.464309,0.557231,0.52408,0.0701056,0.320749,0.19446,0.727609,0.522062,0.394004,0.235035,0.395646,0.494796,0.517318,0.109752,0.692849,0.00632009,0.0207583,0.00306107,0.0637191,0.081661,0.03511,0.127814,0.202294,0.0764145,0.263127,0.400199,0.267278,0.633385,1,0.739902,0.413763,0.41811,0.612715,0.672374,0.339674,0.21172,0.459645,0.1025,0.32589,0.148154,0.265442,0.0974305,0.286438,0.275213,0.109111,0.575089,0.370283,0.29411,0.259826,0.0648719,0.583418,0.282663,0.182004,0.117421,0.417727,0.16965,0.24853,0.122819,0.185486,0.0433618,0.373849,0.252768,0.195103,0.0927835,0.166543},int(p*nModes+n) : rdtable : select2(modesFreqs(n)<(ma.SR/2-1),0);
|
|
2407
|
+
modesT60s(i) = t60*pow(1-(modesFreqRatios(i)/195.955)*t60DecayRatio,t60DecaySlope);
|
|
2408
|
+
};
|
|
2409
|
+
|
|
2410
|
+
|
|
2411
|
+
//-------`(pm.)marimbaResTube`----------
|
|
2412
|
+
// Simple marimba resonance tube.
|
|
2413
|
+
//
|
|
2414
|
+
// #### Usage
|
|
2415
|
+
//
|
|
2416
|
+
// ```
|
|
2417
|
+
// marimbaResTube(tubeLength,excitation)
|
|
2418
|
+
// ```
|
|
2419
|
+
//
|
|
2420
|
+
// Where:
|
|
2421
|
+
//
|
|
2422
|
+
// * `tubeLength`: the length of the tube in meters
|
|
2423
|
+
// * `excitation`: the excitation signal (audio in)
|
|
2424
|
+
//----------------------------------
|
|
2425
|
+
marimbaResTube(tubeLength,excitation) = endChain(tubeChain)
|
|
2426
|
+
with{
|
|
2427
|
+
maxTubeLength = maxLength;
|
|
2428
|
+
lengthTuning = 0.04;
|
|
2429
|
+
tunedLength = tubeLength-lengthTuning;
|
|
2430
|
+
endTubeReflexion = si.smooth(0.95)*0.99;
|
|
2431
|
+
tubeChain =
|
|
2432
|
+
chain(
|
|
2433
|
+
in(excitation) :
|
|
2434
|
+
terminations(endTubeReflexion,
|
|
2435
|
+
openTube(maxTubeLength,tunedLength),
|
|
2436
|
+
endTubeReflexion) :
|
|
2437
|
+
out
|
|
2438
|
+
);
|
|
2439
|
+
};
|
|
2440
|
+
|
|
2441
|
+
|
|
2442
|
+
//-------`(pm.)marimbaModel`----------
|
|
2443
|
+
// Simple marimba physical model implementing a single tone bar connected to
|
|
2444
|
+
// tube. This model is scalable and can be adapted to any size of bar/tube
|
|
2445
|
+
// (see [`marimbaBarModel`](#marimbabarmodel) to know more about the
|
|
2446
|
+
// limitations of this type of system).
|
|
2447
|
+
//
|
|
2448
|
+
// #### Usage
|
|
2449
|
+
//
|
|
2450
|
+
// ```
|
|
2451
|
+
// excitation : marimbaModel(freq,exPos) : _
|
|
2452
|
+
// ```
|
|
2453
|
+
//
|
|
2454
|
+
// Where:
|
|
2455
|
+
//
|
|
2456
|
+
// * `freq`: the frequency of the bar/tube couple
|
|
2457
|
+
// * `exPos`: excitation position (0-4)
|
|
2458
|
+
//----------------------------------
|
|
2459
|
+
marimbaModel(freq,exPos) =
|
|
2460
|
+
marimbaBarModel(freq,exPos,maxT60,T60Decay,T60Slope) : marimbaResTube(resTubeLength)
|
|
2461
|
+
with{
|
|
2462
|
+
resTubeLength = freq : f2l;
|
|
2463
|
+
maxT60 = 0.1;
|
|
2464
|
+
T60Decay = 1;
|
|
2465
|
+
T60Slope = 5;
|
|
2466
|
+
};
|
|
2467
|
+
|
|
2468
|
+
|
|
2469
|
+
//-------`(pm.)marimba`----------
|
|
2470
|
+
// Simple marimba physical model implementing a single tone bar connected to
|
|
2471
|
+
// tube. This model is scalable and can be adapted to any size of bar/tube
|
|
2472
|
+
// (see [`marimbaBarModel`](#marimbabarmodel) to know more about the
|
|
2473
|
+
// limitations of this type of system).
|
|
2474
|
+
//
|
|
2475
|
+
// This function also implement a virtual exciter to drive the model.
|
|
2476
|
+
//
|
|
2477
|
+
// #### Usage
|
|
2478
|
+
//
|
|
2479
|
+
// ```
|
|
2480
|
+
// excitation : marimba(freq,strikePosition,strikeCutoff,strikeSharpness,gain,trigger) : _
|
|
2481
|
+
// ```
|
|
2482
|
+
//
|
|
2483
|
+
// Where:
|
|
2484
|
+
//
|
|
2485
|
+
// * `excitation`: the excitation signal
|
|
2486
|
+
// * `freq`: the frequency of the bar/tube couple
|
|
2487
|
+
// * `strikePosition`: strike position (0-4)
|
|
2488
|
+
// * `strikeCutoff`: cuttoff frequency of the strike genarator (recommended: ~7000Hz)
|
|
2489
|
+
// * `strikeSharpness`: sharpness of the strike (recommended: ~0.25)
|
|
2490
|
+
// * `gain`: gain of the strike (0-1)
|
|
2491
|
+
// * `trigger` signal (0: off, 1: on)
|
|
2492
|
+
//----------------------------------
|
|
2493
|
+
marimba(freq,strikePosition,strikeCutoff,strikeSharpness,gain,trigger) =
|
|
2494
|
+
strikeModel(10,strikeCutoff,strikeSharpness,gain,trigger) :
|
|
2495
|
+
marimbaModel(freq,strikePosition);
|
|
2496
|
+
|
|
2497
|
+
|
|
2498
|
+
//-------`(pm.)marimba_ui_MIDI`----------
|
|
2499
|
+
// Simple MIDI controllable marimba physical model with built-in UI
|
|
2500
|
+
// implementing a single tone bar connected to
|
|
2501
|
+
// tube. This model is scalable and can be adapted to any size of bar/tube
|
|
2502
|
+
// (see [`marimbaBarModel`](#marimbabarmodel) to know more about the
|
|
2503
|
+
// limitations of this type of system).
|
|
2504
|
+
//
|
|
2505
|
+
// #### Usage
|
|
2506
|
+
//
|
|
2507
|
+
// ```
|
|
2508
|
+
// marimba_ui_MIDI : _
|
|
2509
|
+
// ```
|
|
2510
|
+
//----------------------------------
|
|
2511
|
+
marimba_ui_MIDI =
|
|
2512
|
+
marimba(freq,strikePosition,strikeCutoff,strikeSharpness,gain,gate)*outGain
|
|
2513
|
+
with{
|
|
2514
|
+
freq = hslider("v:marimba/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
2515
|
+
gain = hslider("v:marimba/h:[0]midi/[2]gain[style:knob]",1,0,1,0.01);
|
|
2516
|
+
strikePosition = nentry("v:marimba/h:[1]otherParams/[0]strikePosition
|
|
2517
|
+
[midi:ctrl 1]",0,0,4,1);
|
|
2518
|
+
strikeCutoff = hslider("v:marimba/h:[1]otherParams/[1]strikeCutOff
|
|
2519
|
+
[midi:ctrl 1][style:knob]",6500,20,20000,1);
|
|
2520
|
+
strikeSharpness = hslider("v:marimba/h:[1]otherParams/[2]strikeSharpness
|
|
2521
|
+
[style:knob]",0.5,0.01,5,0.01);
|
|
2522
|
+
outGain = hslider("v:marimba/h:[1]otherParams/[2]outGain
|
|
2523
|
+
[style:knob]",0.8,0,1,0.01);
|
|
2524
|
+
gate = button("v:marimba/[3]gate");
|
|
2525
|
+
};
|
|
2526
|
+
|
|
2527
|
+
|
|
2528
|
+
//-------`(pm.)churchBellModel`----------
|
|
2529
|
+
// Generic church bell modal model generated by `mesh2faust` from
|
|
2530
|
+
// `libraries/modalmodels/churchBell`.
|
|
2531
|
+
//
|
|
2532
|
+
// Modeled after T. Rossing and R. Perrin, Vibrations of Bells, Applied
|
|
2533
|
+
// Acoustics 2, 1987.
|
|
2534
|
+
//
|
|
2535
|
+
// Model height is 301 mm.
|
|
2536
|
+
//
|
|
2537
|
+
// This model contains 7 excitation positions going linearly from the
|
|
2538
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
2539
|
+
// position could be regenerated using `mesh2faust`.
|
|
2540
|
+
//
|
|
2541
|
+
// #### Usage
|
|
2542
|
+
//
|
|
2543
|
+
// ```
|
|
2544
|
+
// excitation : churchBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope)
|
|
2545
|
+
// ```
|
|
2546
|
+
//
|
|
2547
|
+
// Where:
|
|
2548
|
+
//
|
|
2549
|
+
// * `excitation`: the excitation signal
|
|
2550
|
+
// * `nModes`: number of synthesized modes (max: 50)
|
|
2551
|
+
// * `exPos`: excitation position (0-6)
|
|
2552
|
+
// * `t60`: T60 in seconds (recommended value: 0.1)
|
|
2553
|
+
// * `t60DecayRatio`: T60 decay ratio (recommended value: 1)
|
|
2554
|
+
// * `t60DecaySlope`: T60 decay slope (recommended value: 5)
|
|
2555
|
+
//----------------------------------
|
|
2556
|
+
churchBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope) = _ <: par(i,nModes,modeFilter(modesFreqs(i),modesT60s(i),modesGains(int(exPos),i))) :> /(nModes)
|
|
2557
|
+
with{
|
|
2558
|
+
nExPos = 7;
|
|
2559
|
+
modesFreqs(n) = ba.take(n+1,(451.918,455,864.643,871.402,1072.47,1073.98,1292.23,1292.48,1504.6,1532.41,1646.2,1647,1677.83,1678.13,1866.63,1882.08,1985.2,1989.87,2114.93,2356.81,2444.32,2446.22,2528.77,2530.92,2668.86,2669.63,2738.06,2749.03,2750.53,2753.11,2827.19,2842.32,2992.56,2996.84,3172.61,3330.79,3390.33,3403.1,3516.43,3538.54,3582.79,3583.82,3730.04,3739.35,3758.66,3903.78,3942.59,3981.74,3983.25,4033.97));
|
|
2560
|
+
modesGains(p,n) = waveform{0.525285,0.814174,0.483261,0.296745,0.975056,0.472244,0.409501,0.425364,0.687559,0.288381,0.309285,0.123054,0.286333,0.576706,0.908322,0.626974,0.0801852,0.309835,0.45143,0.132845,0.470635,0.417008,0.265112,0.0752802,0.46347,0.47181,0.275324,0.547027,0.512519,0.394078,0.595404,0.941306,0.392501,0.381435,0.391232,0.118924,0.339495,0.101421,0.241755,0.0873255,0.378944,0.637705,0.171946,0.149859,0.23329,0.54181,1,0.115554,0.244172,0.574329,0.606171,0.938397,0.392555,0.277359,0.86857,0.432489,0.408856,0.407932,0.299815,0.256659,0.549572,0.406347,0.312331,0.627578,0.670167,0.524648,0.406926,0.637524,0.555837,1,0.818979,0.705347,0.678141,0.427382,0.674404,0.636105,0.643635,0.699136,0.836201,0.613085,0.319019,0.725259,0.545519,0.479861,0.49836,0.488654,0.861672,0.314287,0.671052,0.531905,0.421781,0.815066,0.772032,0.488722,0.0896674,0.291286,0.65873,0.635632,0.679357,0.459497,0.36024,0.582289,0.650605,0.49095,0.38191,0.157261,0.479624,0.477491,0.174435,0.013094,0.879113,0.608069,0.268877,0.604479,0.24513,0.170507,0.292888,0.545849,0.476646,0.922316,0.669192,0.578094,0.578797,0.311396,0.60121,0.549955,1,0.66573,0.980115,0.537848,0.0740531,0.252472,0.25575,0.223974,0.0865103,0.138209,0.198623,0.0453034,0.432453,0.292407,0.39441,0.857659,0.271668,0.201545,0.583994,0.0602378,0.190618,0.849505,0.975542,0.17314,0.206472,0.344793,0.761011,0.558125,0.117245,0.0338485,0.337597,0.336646,0.174253,0.23017,0.934873,0.593647,0.393225,0.683704,0.0566093,0.0405012,0.148972,0.338722,0.283419,0.394007,0.237475,0.269964,0.428313,0.177499,0.462585,0.443963,0.981793,0.408239,0.676527,0.402865,0.0163303,0.0515114,0.34139,0.311135,0.613276,0.805884,0.95329,0.406091,0.578705,0.386785,0.434103,0.77526,1,0.635909,0.782052,0.0137183,0.0387725,0.618964,0.857071,0.131522,0.184988,0.299495,0.789212,0.603114,0.0704989,0.0129339,0.252481,0.254121,0.189206,0.357713,0.950308,0.552573,0.466454,0.77736,0.0307886,0.0251943,0.378886,0.740187,0.247637,0.235201,0.493045,0.51785,0.883954,0.429473,0.409433,0.415266,0.940198,0.282334,0.43789,0.375385,0.0157366,0.0171763,0.485555,0.461015,0.858958,0.907991,0.935191,0.37551,1,0.585493,0.269981,0.423053,0.666067,0.43509,0.790252,0.00889586,0.0208844,0.449735,0.790808,0.159856,0.089599,0.161546,0.528168,0.380642,0.0206276,0.00726426,0.0315352,0.0315841,0.197649,0.475057,0.517232,0.360922,0.421204,0.63134,0.00952139,0.016105,0.499615,0.922958,0.214983,0.0655141,0.50397,0.514848,1,0.483619,0.254027,0.228372,0.436105,0.233125,0.152242,0.279513,0.00906739,0.0132332,0.451257,0.388566,0.737226,0.479378,0.233037,0.103767,0.845609,0.644127,0.261359,0.371457,0.527229,0.381373,0.334492,0.00833749,0.00861982,0.255919,0.254197,0.0872333,0.0461512,0.113018,0.345986,0.236344,0.01078,0.00816506,0.405181,0.38718,0.343681,0.816493,0.259082,0.211906,0.432455,0.696886,0.00576224,0.013131,0.455969,0.811609,0.426544,0.128489,0.215937,0.233934,0.72307,0.351623,0.394231,0.323766,0.168803,0.276932,0.264684,0.227703,0.00680935,0.0170703,0.603018,0.476461,0.585925,0.71696,1,0.576527,0.475524,0.447322,0.356902,0.597573,0.697246,0.505333,0.285421,0.0147193,0.0141618,0.136188,0.0336537,0.216437},int(p*nModes+n) : rdtable;
|
|
2561
|
+
modesT60s(i) = t60*pow(1-(modesFreqs(i)/4035.44)*t60DecayRatio,t60DecaySlope);
|
|
2562
|
+
};
|
|
2563
|
+
|
|
2564
|
+
|
|
2565
|
+
//-------`(pm.)churchBell`----------
|
|
2566
|
+
// Generic church bell modal model.
|
|
2567
|
+
//
|
|
2568
|
+
// Modeled after T. Rossing and R. Perrin, Vibrations of Bells, Applied
|
|
2569
|
+
// Acoustics 2, 1987.
|
|
2570
|
+
//
|
|
2571
|
+
// Model height is 301 mm.
|
|
2572
|
+
//
|
|
2573
|
+
// This model contains 7 excitation positions going linearly from the
|
|
2574
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
2575
|
+
// position could be regenerated using `mesh2faust`.
|
|
2576
|
+
//
|
|
2577
|
+
// This function also implement a virtual exciter to drive the model.
|
|
2578
|
+
//
|
|
2579
|
+
// #### Usage
|
|
2580
|
+
//
|
|
2581
|
+
// ```
|
|
2582
|
+
// excitation : churchBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) : _
|
|
2583
|
+
// ```
|
|
2584
|
+
//
|
|
2585
|
+
// Where:
|
|
2586
|
+
//
|
|
2587
|
+
// * `excitation`: the excitation signal
|
|
2588
|
+
// * `strikePosition`: strike position (0-6)
|
|
2589
|
+
// * `strikeCutoff`: cuttoff frequency of the strike genarator (recommended: ~7000Hz)
|
|
2590
|
+
// * `strikeSharpness`: sharpness of the strike (recommended: ~0.25)
|
|
2591
|
+
// * `gain`: gain of the strike (0-1)
|
|
2592
|
+
// * `trigger` signal (0: off, 1: on)
|
|
2593
|
+
//----------------------------------
|
|
2594
|
+
churchBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) =
|
|
2595
|
+
strikeModel(10,strikeCutoff,strikeSharpness,gain,trigger) :
|
|
2596
|
+
churchBellModel(50,strikePosition,30,1,2.5);
|
|
2597
|
+
|
|
2598
|
+
|
|
2599
|
+
//-------`(pm.)churchBell_ui`----------
|
|
2600
|
+
// Church bell physical model based on [`churchBell`](#churchbell) with
|
|
2601
|
+
// built-in UI.
|
|
2602
|
+
//
|
|
2603
|
+
// #### Usage
|
|
2604
|
+
//
|
|
2605
|
+
// ```
|
|
2606
|
+
// churchBell_ui : _
|
|
2607
|
+
// ```
|
|
2608
|
+
//----------------------------------
|
|
2609
|
+
churchBell_ui =
|
|
2610
|
+
churchBell(strikePosition,strikeCutoff,strikeSharpness,gain,gate)
|
|
2611
|
+
with{
|
|
2612
|
+
strikePosition = nentry("v:churchBell/[0]strikePosition",
|
|
2613
|
+
0,0,4,1);
|
|
2614
|
+
strikeCutoff = hslider("v:churchBell/[1]strikeCutOff",
|
|
2615
|
+
6500,20,20000,1);
|
|
2616
|
+
strikeSharpness = hslider("v:churchBell/[2]strikeSharpness",
|
|
2617
|
+
0.5,0.01,5,0.01);
|
|
2618
|
+
gain = hslider("v:churchBell/[3]gain",1,0,1,0.01);
|
|
2619
|
+
gate = button("v:churchBell/[4]gate");
|
|
2620
|
+
};
|
|
2621
|
+
|
|
2622
|
+
|
|
2623
|
+
//-------`(pm.)englishBellModel`----------
|
|
2624
|
+
// English church bell modal model generated by `mesh2faust` from
|
|
2625
|
+
// `libraries/modalmodels/englishBell`.
|
|
2626
|
+
//
|
|
2627
|
+
// Modeled after D.Bartocha and Baron, Influence of Tin Bronze Melting and
|
|
2628
|
+
// Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry
|
|
2629
|
+
// Engineering, 2016.
|
|
2630
|
+
//
|
|
2631
|
+
// Model height is 1 m.
|
|
2632
|
+
//
|
|
2633
|
+
// This model contains 7 excitation positions going linearly from the
|
|
2634
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
2635
|
+
// position could be regenerated using `mesh2faust`.
|
|
2636
|
+
//
|
|
2637
|
+
// #### Usage
|
|
2638
|
+
//
|
|
2639
|
+
// ```
|
|
2640
|
+
// excitation : englishBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope)
|
|
2641
|
+
// ```
|
|
2642
|
+
//
|
|
2643
|
+
// Where:
|
|
2644
|
+
//
|
|
2645
|
+
// * `excitation`: the excitation signal
|
|
2646
|
+
// * `nModes`: number of synthesized modes (max: 50)
|
|
2647
|
+
// * `exPos`: excitation position (0-6)
|
|
2648
|
+
// * `t60`: T60 in seconds (recommended value: 0.1)
|
|
2649
|
+
// * `t60DecayRatio`: T60 decay ratio (recommended value: 1)
|
|
2650
|
+
// * `t60DecaySlope`: T60 decay slope (recommended value: 5)
|
|
2651
|
+
//----------------------------------
|
|
2652
|
+
englishBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope) = _ <: par(i,nModes,modeFilter(modesFreqs(i),modesT60s(i),modesGains(int(exPos),i))) :> /(nModes)
|
|
2653
|
+
with{
|
|
2654
|
+
nExPos = 7;
|
|
2655
|
+
modesFreqs(n) = ba.take(n+1,(259.429,261.855,493.331,494.472,603.048,604.742,724.566,724.777,786.985,931.893,932.846,943.429,946.533,947.109,952.782,1024.24,1034.86,1211.59,1212.21,1236.28,1340.21,1341.15,1452.63,1453.38,1453.77,1457.45,1459.23,1460.7,1482.81,1483.04,1519.55,1547.27,1565.95,1576.95,1697.47,1826.61,1892.56,1896.09,1899.86,1908.29,2003.95,2005.07,2005.89,2005.99,2067.42,2082.42,2086.81,2120.56,2129.79,2133.23));
|
|
2656
|
+
modesGains(p,n) = waveform{0.694274,0.471698,0.17239,0.585446,0.397986,0.919579,0.531947,0.100205,0.639469,0.672209,0.144345,0.416595,0.124108,0.380591,0.256578,0.646031,0.8522,0.0224376,0.382762,0.143925,0.368691,0.430556,0.32318,0.142956,0.274521,0.713824,0.442794,0.352473,0.247756,0.415152,1,0.401869,0.197981,0.27951,0.210249,0.36974,0.369227,0.155769,0.272368,0.335712,0.31645,0.714103,0.285781,0.22006,0.827704,0.206342,0.180177,0.311478,0.197607,0.575475,0.473311,0.587232,0.50288,0.337308,0.304514,0.429039,0.351522,0.341373,0.175081,0.561748,0.439172,0.323164,0.540518,0.536523,0.0743865,0.213417,0.358012,0.474494,0.310274,0.839413,0.241372,0.202343,0.480634,0.995685,0.37374,0.133998,0.520674,0.207514,1,0.101239,0.279536,0.185985,0.436293,0.62411,0.334519,0.283585,0.179317,0.353847,0.449545,0.574128,0.135172,0.538275,0.476424,0.832903,0.164198,0.188562,0.135978,0.390128,0.131045,0.312065,0.142139,0.0255901,0.266947,0.371607,0.0168435,0.0249468,0.508917,0.35441,0.283348,0.628155,0.292478,0.35835,0.342569,0.441237,0.886699,0.0174698,0.00641843,0.55532,0.880129,0.0306909,0.290081,0.248816,0.981736,0.324624,0.213676,0.432885,0.0981559,0.444149,0.395554,0.525069,0.0771308,0.0488804,0.591321,0.108044,0.443802,0.740318,0.599438,0.293093,1,0.141662,0.910031,0.226126,0.299702,0.341472,0.0568061,0.222494,0.918718,0.199478,0.21662,0.107759,0.692324,0.556336,0.281718,0.430832,0.341656,0.608095,0.342129,0.311312,0.229953,0.695087,0.0761489,0.349818,0.361706,0.577611,0.147797,0.327376,0.465715,0.342902,0.521381,0.836828,0.241112,0.284394,0.539316,0.143408,0.51702,1,0.236336,0.480333,0.676744,0.807582,0.468621,0.236953,0.411604,0.579251,0.425098,0.37599,0.461176,0.27653,0.462368,0.613004,0.666849,0.954715,0.161507,0.170433,0.290461,0.117303,0.365133,0.233794,0.194568,0.338874,0.523381,0.39835,0.447839,0.652891,0.15708,0.340354,0.44217,0.338764,0.184397,0.771607,0.160502,0.324487,0.477499,0.831519,0.0168764,0.154264,0.201865,0.237786,0.390066,0.880164,0.284234,0.162837,0.437557,0.227846,0.39934,1,0.158107,0.396903,0.513029,0.676457,0.204282,0.0895575,0.55541,0.732486,0.125062,0.171229,0.081646,0.0541394,0.39616,0.454288,0.466863,0.928842,0.155393,0.26285,0.113453,0.133163,0.302021,0.612616,0.228392,0.195617,0.287236,0.198762,0.499884,0.809139,0.00929925,0.0840299,0.286446,0.182112,0.186044,0.754138,0.279556,0.266948,0.494291,1,0.321284,0.0230981,0.0375537,0.262531,0.602204,0.489925,0.633077,0.407409,0.422256,0.0910641,0.357935,0.550179,0.106192,0.132366,0.376231,0.351151,0.0420302,0.0372183,0.696335,0.840821,0.855235,0.249248,0.860011,0.340481,0.28558,0.363039,0.324122,0.515699,0.228131,0.172592,0.0188723,0.168243,0.995105,0.741759,0.107093,0.070349,0.136636,0.0780455,0.315748,0.502201,0.0190422,0.033914,0.225724,0.160236,0.184101,0.564203,0.247317,0.284225,0.327153,0.651443,0.593471,0.0163899,0.0141048,0.52113,1,0.105109,0.530936,0.363724,0.924809,0.25041,0.69288,0.414122,0.0793658,0.347813,0.441731,0.476428,0.0808834,0.0581638,0.557239,0.556515,0.746084,0.582228,0.177231,0.158425,0.850903,0.755271,0.673614,0.31706,0.0515386,0.201898,0.0577938,0.232031,0.734988,0.141594,0.267062,0.145807},int(p*nModes+n) : rdtable;
|
|
2657
|
+
modesT60s(i) = t60*pow(1-(modesFreqs(i)/2137.04)*t60DecayRatio,t60DecaySlope);
|
|
2658
|
+
};
|
|
2659
|
+
|
|
2660
|
+
|
|
2661
|
+
//-------`(pm.)englishBell`----------
|
|
2662
|
+
// English church bell modal model.
|
|
2663
|
+
//
|
|
2664
|
+
// Modeled after D.Bartocha and Baron, Influence of Tin Bronze Melting and
|
|
2665
|
+
// Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry
|
|
2666
|
+
// Engineering, 2016.
|
|
2667
|
+
//
|
|
2668
|
+
// Model height is 1 m.
|
|
2669
|
+
//
|
|
2670
|
+
// This model contains 7 excitation positions going linearly from the
|
|
2671
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
2672
|
+
// position could be regenerated using `mesh2faust`.
|
|
2673
|
+
//
|
|
2674
|
+
// This function also implement a virtual exciter to drive the model.
|
|
2675
|
+
//
|
|
2676
|
+
// #### Usage
|
|
2677
|
+
//
|
|
2678
|
+
// ```
|
|
2679
|
+
// excitation : englishBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) : _
|
|
2680
|
+
// ```
|
|
2681
|
+
//
|
|
2682
|
+
// Where:
|
|
2683
|
+
//
|
|
2684
|
+
// * `excitation`: the excitation signal
|
|
2685
|
+
// * `strikePosition`: strike position (0-6)
|
|
2686
|
+
// * `strikeCutoff`: cuttoff frequency of the strike genarator (recommended: ~7000Hz)
|
|
2687
|
+
// * `strikeSharpness`: sharpness of the strike (recommended: ~0.25)
|
|
2688
|
+
// * `gain`: gain of the strike (0-1)
|
|
2689
|
+
// * `trigger` signal (0: off, 1: on)
|
|
2690
|
+
//----------------------------------
|
|
2691
|
+
englishBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) =
|
|
2692
|
+
strikeModel(10,strikeCutoff,strikeSharpness,gain,trigger) :
|
|
2693
|
+
englishBellModel(50,strikePosition,30,1,3);
|
|
2694
|
+
|
|
2695
|
+
|
|
2696
|
+
//-------`(pm.)englishBell_ui`----------
|
|
2697
|
+
// English church bell physical model based on [`englishBell`](#englishbell) with
|
|
2698
|
+
// built-in UI.
|
|
2699
|
+
//
|
|
2700
|
+
// #### Usage
|
|
2701
|
+
//
|
|
2702
|
+
// ```
|
|
2703
|
+
// englishBell_ui : _
|
|
2704
|
+
// ```
|
|
2705
|
+
//----------------------------------
|
|
2706
|
+
englishBell_ui =
|
|
2707
|
+
englishBell(strikePosition,strikeCutoff,strikeSharpness,gain,gate)
|
|
2708
|
+
with{
|
|
2709
|
+
strikePosition = nentry("v:englishBell/[0]strikePosition",0,0,6,1);
|
|
2710
|
+
strikeCutoff = hslider("v:englishBell/[1]strikeCutOff",6500,20,20000,1);
|
|
2711
|
+
strikeSharpness = hslider("v:englishBell/[2]strikeSharpness",0.5,0.01,5,0.01);
|
|
2712
|
+
gain = hslider("v:englishBell/[3]gain",1,0,1,0.01);
|
|
2713
|
+
gate = button("v:englishBell/[4]gate");
|
|
2714
|
+
};
|
|
2715
|
+
|
|
2716
|
+
|
|
2717
|
+
//-------`(pm.)frenchBellModel`----------
|
|
2718
|
+
// French church bell modal model generated by `mesh2faust` from
|
|
2719
|
+
// `libraries/modalmodels/frenchBell`.
|
|
2720
|
+
//
|
|
2721
|
+
// Modeled after D.Bartocha and Baron, Influence of Tin Bronze Melting and
|
|
2722
|
+
// Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry
|
|
2723
|
+
// Engineering, 2016.
|
|
2724
|
+
//
|
|
2725
|
+
// Model height is 1 m.
|
|
2726
|
+
//
|
|
2727
|
+
// This model contains 7 excitation positions going linearly from the
|
|
2728
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
2729
|
+
// position could be regenerated using `mesh2faust`.
|
|
2730
|
+
//
|
|
2731
|
+
// #### Usage
|
|
2732
|
+
//
|
|
2733
|
+
// ```
|
|
2734
|
+
// excitation : frenchBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope)
|
|
2735
|
+
// ```
|
|
2736
|
+
//
|
|
2737
|
+
// Where:
|
|
2738
|
+
//
|
|
2739
|
+
// * `excitation`: the excitation signal
|
|
2740
|
+
// * `nModes`: number of synthesized modes (max: 50)
|
|
2741
|
+
// * `exPos`: excitation position (0-6)
|
|
2742
|
+
// * `t60`: T60 in seconds (recommended value: 0.1)
|
|
2743
|
+
// * `t60DecayRatio`: T60 decay ratio (recommended value: 1)
|
|
2744
|
+
// * `t60DecaySlope`: T60 decay slope (recommended value: 5)
|
|
2745
|
+
//----------------------------------
|
|
2746
|
+
frenchBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope) = _ <: par(i,nModes,modeFilter(modesFreqs(i),modesT60s(i),modesGains(int(exPos),i))) :> /(nModes)
|
|
2747
|
+
with{
|
|
2748
|
+
nExPos = 7;
|
|
2749
|
+
modesFreqs(n) = ba.take(n+1,(439.077,440.305,606.452,611.776,709.617,709.877,856.966,899.051,1064.37,1064.75,1073.03,1074.43,1076.58,1145.42,1148.9,1197.09,1199.91,1387.7,1400.16,1402.37,1512.06,1513.06,1592.47,1593.35,1663.45,1666.47,1691.32,1693.77,1804.83,1808.84,1820.07,1847.14,1910.73,1927.7,2035.07,2038.73,2054.66,2055.67,2078.69,2091.76,2115.78,2127.01,2209.86,2214.05,2296.15,2298.08,2298.97,2307.62,2404.44,2408.99));
|
|
2750
|
+
modesGains(p,n) = waveform{0.97289,0.542393,0.495832,0.897966,0.552367,0.557895,0.614213,0.353694,0.436039,0.441024,0.674913,0.566754,0.755008,0.69903,0.164398,0.91004,0.628373,0.201718,0.429517,0.503715,0.871174,0.106886,0.761173,0.673602,0.291937,0.58859,0.31528,0.413081,0.274464,0.494062,0.696121,0.61201,0.382757,0.995113,0.228806,0.198449,0.595847,0.306263,0.252397,0.0883567,0.236086,1,0.245278,0.379388,0.198824,0.548892,0.492764,0.420871,0.794637,0.605634,1,0.604159,0.399841,0.799347,0.507187,0.50981,0.477383,0.310226,0.426976,0.437623,0.735712,0.630728,0.625785,0.651168,0.277738,0.850858,0.578079,0.645354,0.3837,0.370598,0.782542,0.181325,0.614391,0.740684,0.342441,0.586186,0.286909,0.405197,0.259215,0.566983,0.748219,0.655898,0.36826,0.940814,0.336157,0.413702,0.561557,0.402176,0.117698,0.329369,0.254571,0.870706,0.260981,0.274122,0.206247,0.6453,0.400758,0.363622,0.636834,0.584566,0.975603,0.616937,0.295401,0.650447,0.464221,0.465057,0.312467,0.238358,0.383695,0.399674,0.753912,0.662012,0.504268,0.599248,0.378665,0.725363,0.493214,1,0.332836,0.265889,0.674073,0.320401,0.440018,0.769782,0.316419,0.529968,0.380509,0.578676,0.249013,0.591384,0.761717,0.687057,0.324437,0.818864,0.505369,0.672485,0.461783,0.426198,0.0678875,0.435329,0.347955,0.708394,0.293322,0.328986,0.258254,0.893512,0.320131,0.433554,0.459302,0.542213,0.817241,0.51623,0.205302,0.467354,0.388683,0.388216,0.171262,0.150865,0.29172,0.311414,0.658876,0.570647,0.383619,0.502455,0.364114,0.532313,0.352989,1,0.261984,0.219591,0.544031,0.337199,0.279173,0.668303,0.208439,0.39923,0.418674,0.648618,0.234133,0.504729,0.645347,0.572851,0.232828,0.614292,0.485272,0.666264,0.31657,0.320355,0.191421,0.340131,0.342069,0.538371,0.281131,0.393115,0.251394,0.890725,0.310644,0.5037,0.29909,0.442478,0.733128,0.455217,0.199322,0.315699,0.375856,0.37649,0.029145,0.0200283,0.279578,0.3168,0.655957,0.546843,0.349666,0.470249,0.353765,0.286794,0.180185,1,0.210831,0.280133,0.535853,0.376488,0.15367,0.634745,0.0510449,0.485575,0.593111,0.917884,0.380477,0.422925,0.599373,0.311421,0.135654,0.359954,0.295748,0.474439,0.353339,0.116743,0.454313,0.112858,0.35931,0.483897,0.301608,0.577342,0.262663,0.794986,0.54958,0.808086,0.152511,0.439591,0.535941,0.308018,0.419837,0.579191,0.250428,0.25212,0.10286,0.288332,0.599679,0.665108,0.636285,0.495234,0.251613,0.208527,0.0939072,0.458415,0.318952,0.23535,0.215189,0.313412,0.0472787,0.0386893,0.0863359,0.222346,0.361511,0.997037,0.238509,0.38214,1,0.203554,0.472087,0.509015,0.206371,0.441013,0.794008,0.971623,0.796384,0.55043,0.68778,0.554298,0.0436545,0.0595577,0.214685,0.58147,0.27732,0.368466,0.121382,0.152739,0.0782244,0.190497,0.316269,0.180456,0.405196,0.518716,0.159365,0.165808,0.194372,0.614764,0.553415,0.644794,0.44178,0.44149,0.221588,1,0.579371,0.606339,0.529167,0.0214475,0.417046,0.663152,0.894841,0.475752,0.168289,0.46859,0.304604,0.666369,0.308337,0.295091,0.768945,0.350911,0.49068,0.516584,0.400117,0.820687,0.545486,0.709357,0.509759,0.472006,0.152455,0.981265,0.459134,0.698666,0.247154,0.623253,0.255508,0.830815,0.088709,0.126082,0.0770623,0.263328},int(p*nModes+n) : rdtable;
|
|
2751
|
+
modesT60s(i) = t60*pow(1-(modesFreqs(i)/2555.3)*t60DecayRatio,t60DecaySlope);
|
|
2752
|
+
};
|
|
2753
|
+
|
|
2754
|
+
|
|
2755
|
+
//-------`(pm.)frenchBell`----------
|
|
2756
|
+
// French church bell modal model.
|
|
2757
|
+
//
|
|
2758
|
+
// Modeled after D.Bartocha and Baron, Influence of Tin Bronze Melting and
|
|
2759
|
+
// Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry
|
|
2760
|
+
// Engineering, 2016.
|
|
2761
|
+
//
|
|
2762
|
+
// Model height is 1 m.
|
|
2763
|
+
//
|
|
2764
|
+
// This model contains 7 excitation positions going linearly from the
|
|
2765
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
2766
|
+
// position could be regenerated using `mesh2faust`.
|
|
2767
|
+
//
|
|
2768
|
+
// This function also implement a virtual exciter to drive the model.
|
|
2769
|
+
//
|
|
2770
|
+
// #### Usage
|
|
2771
|
+
//
|
|
2772
|
+
// ```
|
|
2773
|
+
// excitation : frenchBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) : _
|
|
2774
|
+
// ```
|
|
2775
|
+
//
|
|
2776
|
+
// Where:
|
|
2777
|
+
//
|
|
2778
|
+
// * `excitation`: the excitation signal
|
|
2779
|
+
// * `strikePosition`: strike position (0-6)
|
|
2780
|
+
// * `strikeCutoff`: cuttoff frequency of the strike genarator (recommended: ~7000Hz)
|
|
2781
|
+
// * `strikeSharpness`: sharpness of the strike (recommended: ~0.25)
|
|
2782
|
+
// * `gain`: gain of the strike (0-1)
|
|
2783
|
+
// * `trigger` signal (0: off, 1: on)
|
|
2784
|
+
//----------------------------------
|
|
2785
|
+
frenchBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) =
|
|
2786
|
+
strikeModel(10,strikeCutoff,strikeSharpness,gain,trigger) :
|
|
2787
|
+
frenchBellModel(50,strikePosition,30,1,3);
|
|
2788
|
+
|
|
2789
|
+
|
|
2790
|
+
//-------`(pm.)frenchBell_ui`----------
|
|
2791
|
+
// French church bell physical model based on [`frenchBell`](#frenchbell) with
|
|
2792
|
+
// built-in UI.
|
|
2793
|
+
//
|
|
2794
|
+
// #### Usage
|
|
2795
|
+
//
|
|
2796
|
+
// ```
|
|
2797
|
+
// frenchBell_ui : _
|
|
2798
|
+
// ```
|
|
2799
|
+
//----------------------------------
|
|
2800
|
+
frenchBell_ui =
|
|
2801
|
+
frenchBell(strikePosition,strikeCutoff,strikeSharpness,gain,gate)
|
|
2802
|
+
with{
|
|
2803
|
+
strikePosition = nentry("v:frenchBell/[0]strikePosition",0,0,6,1);
|
|
2804
|
+
strikeCutoff = hslider("v:frenchBell/[1]strikeCutOff",6500,20,20000,1);
|
|
2805
|
+
strikeSharpness = hslider("v:frenchBell/[2]strikeSharpness",0.5,0.01,5,0.01);
|
|
2806
|
+
gain = hslider("v:frenchBell/[3]gain",1,0,1,0.01);
|
|
2807
|
+
gate = button("v:frenchBell/[4]gate");
|
|
2808
|
+
};
|
|
2809
|
+
|
|
2810
|
+
|
|
2811
|
+
//-------`(pm.)germanBellModel`----------
|
|
2812
|
+
// German church bell modal model generated by `mesh2faust` from
|
|
2813
|
+
// `libraries/modalmodels/germanBell`.
|
|
2814
|
+
//
|
|
2815
|
+
// Modeled after D.Bartocha and Baron, Influence of Tin Bronze Melting and
|
|
2816
|
+
// Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry
|
|
2817
|
+
// Engineering, 2016.
|
|
2818
|
+
//
|
|
2819
|
+
// Model height is 1 m.
|
|
2820
|
+
//
|
|
2821
|
+
// This model contains 7 excitation positions going linearly from the
|
|
2822
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
2823
|
+
// position could be regenerated using `mesh2faust`.
|
|
2824
|
+
//
|
|
2825
|
+
// #### Usage
|
|
2826
|
+
//
|
|
2827
|
+
// ```
|
|
2828
|
+
// excitation : germanBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope)
|
|
2829
|
+
// ```
|
|
2830
|
+
//
|
|
2831
|
+
// Where:
|
|
2832
|
+
//
|
|
2833
|
+
// * `excitation`: the excitation signal
|
|
2834
|
+
// * `nModes`: number of synthesized modes (max: 50)
|
|
2835
|
+
// * `exPos`: excitation position (0-6)
|
|
2836
|
+
// * `t60`: T60 in seconds (recommended value: 0.1)
|
|
2837
|
+
// * `t60DecayRatio`: T60 decay ratio (recommended value: 1)
|
|
2838
|
+
// * `t60DecaySlope`: T60 decay slope (recommended value: 5)
|
|
2839
|
+
//----------------------------------
|
|
2840
|
+
germanBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope) = _ <: par(i,nModes,modeFilter(modesFreqs(i),modesT60s(i),modesGains(int(exPos),i))) :> /(nModes)
|
|
2841
|
+
with{
|
|
2842
|
+
nExPos = 7;
|
|
2843
|
+
modesFreqs(n) = ba.take(n+1,(238.909,240.235,406.25,408.214,561.105,562.923,749.632,749.88,781.389,800.68,801.547,884.486,942.52,942.715,958.571,960.581,1016.87,1018.29,1022.29,1206.2,1206.87,1213.93,1222.77,1231.68,1345.65,1355.18,1356.55,1357.3,1389.29,1391.11,1420.17,1424.05,1424.31,1426.54,1582.3,1631.07,1638.15,1720.28,1726.7,1803.79,1827.08,1829.44,1922.87,1926.94,1940.96,1944.47,1948.2,1969.86,1992.24,2011.85));
|
|
2844
|
+
modesGains(p,n) = waveform{0.761411,0.797803,0.586057,0.225039,0.926354,0.813875,0.529871,0.158915,0.662516,0.30841,0.0454785,0.556082,0.784713,0.213035,0.956227,0.795165,0.313508,0.158531,0.301586,0.16832,0.281267,0.154237,0.217235,0.247239,0.522688,0.170303,0.320614,0.154857,0.414941,0.788364,0.713299,0.381592,0.707011,1,0.0106946,0.359763,0.0746156,0.431124,0.118053,0.52729,0.255303,0.646855,0.201145,0.919908,0.359389,0.253494,0.865695,0.0829263,0.222589,0.0415736,0.735774,0.769678,0.381416,0.197543,0.682389,0.614766,0.249525,0.289883,0.300319,0.443691,0.275272,0.370218,0.74879,0.161247,0.634353,0.498498,0.221988,0.350637,0.436817,0.436463,0.52508,0.842646,0.195324,0.224755,0.545681,0.353778,0.269044,0.327814,0.448952,0.852305,0.380503,1,0.458063,0.565058,0.354635,0.659529,0.449485,0.802014,0.283446,0.521563,0.374639,0.652112,0.181042,0.468394,0.430116,0.157207,0.414995,0.292737,0.487785,0.47768,0.481445,0.556988,0.561132,0.378265,0.291462,0.32325,0.482602,0.328248,0.196792,0.712254,0.389806,0.307751,0.792876,0.199098,0.288838,0.146811,0.0178444,0.394017,0.588212,0.489226,0.701486,0.940303,0.213191,0.0778845,0.474463,0.609972,0.16338,0.408376,0.330864,0.88999,0.0798101,1,0.167172,0.208727,0.227549,0.825903,0.531897,0.580946,0.215339,0.247319,0.268148,0.504088,0.160955,0.170316,0.230769,0.151191,0.0825031,0.141328,0.288079,0.499676,0.420355,0.487764,0.75371,0.492248,0.181364,0.20594,0.52497,0.325641,0.236827,0.931842,0.472981,0.312162,0.901032,0.270478,0.167112,0.0709698,0.166004,0.290745,0.425893,0.403633,0.581772,0.855694,0.0325587,0.0568359,0.241923,0.79931,0.181962,0.530283,0.41561,1,0.0291501,0.831155,0.119755,0.102188,0.132037,0.76603,0.442221,0.1749,0.142175,0.0140794,0.4375,0.85186,0.196836,0.0907522,0.551673,0.256528,0.0424377,0.490363,0.108178,0.503276,0.226584,0.312758,0.824079,0.48412,0.0347338,0.0619428,0.255097,0.145273,0.190359,0.995297,0.50342,0.217575,0.793975,0.357179,0.0409728,0.0187931,0.414458,0.15844,0.346233,0.0771673,0.175111,0.380567,0.497409,0.316164,0.488669,1,0.420657,0.442333,0.24706,0.796407,0.0104146,0.227079,0.10684,0.0289873,0.76757,0.0643122,0.0423098,0.715522,0.472117,0.392577,0.660433,0.803575,0.188653,0.0191653,0.873212,0.448719,0.0147128,0.618967,0.30718,0.345899,0.131394,0.193225,0.715283,0.40562,0.040637,0.0503336,0.0544331,0.0452023,0.152302,0.894549,0.443343,0.172071,0.647667,0.328993,0.0416014,0.0229488,0.551071,0.423544,0.862362,0.363526,0.769929,0.123452,0.710702,0.394895,0.556638,1,0.450925,0.422849,0.092187,0.413892,0.00995372,0.321146,0.160624,0.0300681,0.915385,0.4755,0.506951,0.387549,0.275591,0.468281,0.184776,0.186837,0.188195,0.0202785,0.697136,0.408862,0.0116935,0.349823,0.202301,0.461379,0.0559023,0.0582571,0.260608,0.181875,0.0271739,0.0249578,0.685089,0.470384,0.283194,0.33105,0.138349,0.338068,0.481992,0.178242,0.0155942,0.0110435,0.783771,0.442707,0.616478,0.381542,0.510892,0.045985,0.303119,0.0731909,0.547715,0.348941,0.149981,0.302158,0.284482,0.398177,0.00413049,0.180739,0.062839,0.0133459,0.347088,0.57637,0.240764,0.978481,0.452755,0.529742,0.340471,0.662282,0.444305,0.0429901,1,0.36194,0.0183372,0.626893,0.55285,0.384936},int(p*nModes+n) : rdtable;
|
|
2845
|
+
modesT60s(i) = t60*pow(1-(modesFreqs(i)/2016.94)*t60DecayRatio,t60DecaySlope);
|
|
2846
|
+
};
|
|
2847
|
+
|
|
2848
|
+
|
|
2849
|
+
//-------`(pm.)germanBell`----------
|
|
2850
|
+
// German church bell modal model.
|
|
2851
|
+
//
|
|
2852
|
+
// Modeled after D.Bartocha and Baron, Influence of Tin Bronze Melting and
|
|
2853
|
+
// Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry
|
|
2854
|
+
// Engineering, 2016.
|
|
2855
|
+
//
|
|
2856
|
+
// Model height is 1 m.
|
|
2857
|
+
//
|
|
2858
|
+
// This model contains 7 excitation positions going linearly from the
|
|
2859
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
2860
|
+
// position could be regenerated using `mesh2faust`.
|
|
2861
|
+
//
|
|
2862
|
+
// This function also implement a virtual exciter to drive the model.
|
|
2863
|
+
//
|
|
2864
|
+
// #### Usage
|
|
2865
|
+
//
|
|
2866
|
+
// ```
|
|
2867
|
+
// excitation : germanBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) : _
|
|
2868
|
+
// ```
|
|
2869
|
+
//
|
|
2870
|
+
// Where:
|
|
2871
|
+
//
|
|
2872
|
+
// * `excitation`: the excitation signal
|
|
2873
|
+
// * `strikePosition`: strike position (0-6)
|
|
2874
|
+
// * `strikeCutoff`: cuttoff frequency of the strike genarator (recommended: ~7000Hz)
|
|
2875
|
+
// * `strikeSharpness`: sharpness of the strike (recommended: ~0.25)
|
|
2876
|
+
// * `gain`: gain of the strike (0-1)
|
|
2877
|
+
// * `trigger` signal (0: off, 1: on)
|
|
2878
|
+
//----------------------------------
|
|
2879
|
+
germanBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) =
|
|
2880
|
+
strikeModel(10,strikeCutoff,strikeSharpness,gain,trigger) :
|
|
2881
|
+
germanBellModel(50,strikePosition,30,1,2.5);
|
|
2882
|
+
|
|
2883
|
+
|
|
2884
|
+
//-------`(pm.)germanBell_ui`----------
|
|
2885
|
+
// German church bell physical model based on [`germanBell`](#germanbell) with
|
|
2886
|
+
// built-in UI.
|
|
2887
|
+
//
|
|
2888
|
+
// #### Usage
|
|
2889
|
+
//
|
|
2890
|
+
// ```
|
|
2891
|
+
// germanBell_ui : _
|
|
2892
|
+
// ```
|
|
2893
|
+
//----------------------------------
|
|
2894
|
+
germanBell_ui =
|
|
2895
|
+
germanBell(strikePosition,strikeCutoff,strikeSharpness,gain,gate)
|
|
2896
|
+
with{
|
|
2897
|
+
strikePosition = nentry("v:germanBell/[0]strikePosition",0,0,6,1);
|
|
2898
|
+
strikeCutoff = hslider("v:germanBell/[1]strikeCutOff",6500,20,20000,1);
|
|
2899
|
+
strikeSharpness = hslider("v:germanBell/[2]strikeSharpness",0.5,0.01,5,0.01);
|
|
2900
|
+
gain = hslider("v:germanBell/[3]gain",1,0,1,0.01);
|
|
2901
|
+
gate = button("v:germanBell/[4]gate");
|
|
2902
|
+
};
|
|
2903
|
+
|
|
2904
|
+
|
|
2905
|
+
//-------`(pm.)russianBellModel`----------
|
|
2906
|
+
// Russian church bell modal model generated by `mesh2faust` from
|
|
2907
|
+
// `libraries/modalmodels/russianBell`.
|
|
2908
|
+
//
|
|
2909
|
+
// Modeled after D.Bartocha and Baron, Influence of Tin Bronze Melting and
|
|
2910
|
+
// Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry
|
|
2911
|
+
// Engineering, 2016.
|
|
2912
|
+
//
|
|
2913
|
+
// Model height is 2 m.
|
|
2914
|
+
//
|
|
2915
|
+
// This model contains 7 excitation positions going linearly from the
|
|
2916
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
2917
|
+
// position could be regenerated using `mesh2faust`.
|
|
2918
|
+
//
|
|
2919
|
+
// #### Usage
|
|
2920
|
+
//
|
|
2921
|
+
// ```
|
|
2922
|
+
// excitation : russianBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope)
|
|
2923
|
+
// ```
|
|
2924
|
+
//
|
|
2925
|
+
// Where:
|
|
2926
|
+
//
|
|
2927
|
+
// * `excitation`: the excitation signal
|
|
2928
|
+
// * `nModes`: number of synthesized modes (max: 50)
|
|
2929
|
+
// * `exPos`: excitation position (0-6)
|
|
2930
|
+
// * `t60`: T60 in seconds (recommended value: 0.1)
|
|
2931
|
+
// * `t60DecayRatio`: T60 decay ratio (recommended value: 1)
|
|
2932
|
+
// * `t60DecaySlope`: T60 decay slope (recommended value: 5)
|
|
2933
|
+
//----------------------------------
|
|
2934
|
+
russianBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope) = _ <: par(i,nModes,modeFilter(modesFreqs(i),modesT60s(i),modesGains(int(exPos),i))) :> /(nModes)
|
|
2935
|
+
with{
|
|
2936
|
+
nExPos = 7;
|
|
2937
|
+
modesFreqs(n) = ba.take(n+1,(136.491,136.992,258.958,260.419,316.489,318.411,393.852,393.949,454.677,467.493,503.594,503.637,530.46,531.046,541.16,546.158,578.335,579.863,660.026,708.34,716.915,717.23,775.839,776.066,783.356,783.464,788.826,789.463,800.348,806.758,876.788,880.414,887.297,888.222,916.815,919.711,937.686,984.606,1057.2,1058.45,1065.48,1082.27,1083.93,1086.55,1086.77,1108.2,1116.17,1149,1150.54,1199.54));
|
|
2938
|
+
modesGains(p,n) = waveform{0.925507,0.59752,0.0965671,0.45412,0.989773,0.593498,0.512541,0.124241,0.705411,0.292396,0.673399,0.302181,0.026234,0.286249,0.556267,1,0.250426,0.107711,0.427299,0.336295,0.616257,0.21442,0.0845294,0.231363,0.522724,0.559114,0.34847,0.854197,0.835576,0.735036,0.288494,0.117122,0.409686,0.363575,0.484943,0.170862,0.420531,0.164793,0.233847,0.861232,0.214037,0.283462,0.173153,0.876122,0.607809,0.294745,0.143142,0.332009,0.491878,0.626104,0.962027,0.584298,0.213653,0.420452,0.812329,0.545172,0.380744,0.331536,0.386801,0.248909,0.688756,0.313904,0.377894,0.595846,0.412274,0.739626,0.541148,0.393005,0.656637,0.847672,0.930653,0.288289,0.404938,0.657989,0.763949,0.574085,0.282241,1,0.429131,0.572049,0.734868,0.577477,0.520789,0.355593,0.890067,0.272391,0.448223,0.423969,0.392237,0.856091,0.0583794,0.784967,0.359527,0.576567,0.201513,0.642013,0.419308,0.340667,0.42319,0.860812,0.69402,0.423568,0.376987,0.568453,0.502302,0.280716,0.464041,0.395601,0.19985,0.0950398,0.64279,0.228326,0.484911,0.842353,0.161404,0.403432,0.655549,0.409098,0.699392,0.87605,1,0.185606,0.414255,0.695205,0.732612,0.478298,0.24947,0.927739,0.213135,0.227382,0.976352,0.642745,0.376311,0.260674,0.811034,0.264631,0.239979,0.261897,0.191642,0.78167,0.390679,0.382437,0.206714,0.22472,0.0676332,0.502611,0.301455,0.241029,0.224505,0.721193,0.436348,0.254062,0.480496,0.772371,0.210681,0.103415,0.485338,0.378334,0.228484,0.114877,0.68676,0.296942,0.50742,0.99747,0.0377103,0.132212,0.319547,0.192032,0.520574,0.585844,0.419362,0.0847317,0.134544,0.194762,0.616689,0.39736,0.298809,0.914746,0.0513371,0.0543569,0.989159,0.602892,0.145582,0.102149,0.129022,0.116485,0.279988,0.39427,0.290139,1,0.708655,0.780555,0.387526,0.0395217,0.00964067,0.24368,0.0740625,0.619315,0.447395,0.292497,0.295458,0.163748,0.521375,0.864533,0.0773408,0.0334231,0.345121,0.27886,0.223876,0.307756,0.763106,0.424707,0.487201,0.968962,0.00911747,0.0324653,0.334275,0.166787,0.312498,0.264262,0.35488,0.37559,0.261094,0.565006,0.474935,0.31352,0.251249,0.735352,0.0189072,0.0153634,0.786225,0.503299,0.369038,0.250765,0.673019,0.387573,0.742025,0.749056,0.261714,0.751868,0.771816,1,0.459484,0.0124402,0.0105394,0.964109,0.457052,0.532316,0.407128,0.697241,0.1522,0.0895893,0.406175,0.65104,0.0233951,0.010107,0.0722347,0.066634,0.195489,0.41674,0.654451,0.382782,0.305396,0.631501,0.00162802,0.0140906,0.762915,0.410245,0.189436,0.0604462,0.624941,0.439781,0.516273,0.896678,0.273298,0.202868,0.0996022,0.257657,0.0174508,0.0157859,0.429433,0.202184,0.443111,0.343811,0.447562,0.268694,0.753551,0.529426,0.0772973,0.097696,0.446414,0.261678,0.169035,0.0116219,0.0207399,1,0.488856,0.413029,0.252661,0.148369,0.0919644,0.0330634,0.268764,0.441849,0.0139873,0.0108584,0.657799,0.488248,0.375433,0.958179,0.761492,0.40949,0.151709,0.314931,0.0036118,0.013307,1,0.605343,0.550506,0.363516,0.255278,0.137537,0.448881,0.867615,0.483247,0.308622,0.348444,0.534835,0.0157716,0.0128965,0.147608,0.0762611,0.762224,0.511585,0.985863,0.540227,0.691691,0.905296,0.397521,0.69794,0.423289,0.924613,0.491559,0.00567911,0.0106002,0.647916,0.324182,0.579449,0.451936,0.877897},int(p*nModes+n) : rdtable;
|
|
2939
|
+
modesT60s(i) = t60*pow(1-(modesFreqs(i)/1201.01)*t60DecayRatio,t60DecaySlope);
|
|
2940
|
+
};
|
|
2941
|
+
|
|
2942
|
+
|
|
2943
|
+
//-------`(pm.)russianBell`----------
|
|
2944
|
+
// Russian church bell modal model.
|
|
2945
|
+
//
|
|
2946
|
+
// Modeled after D.Bartocha and Baron, Influence of Tin Bronze Melting and
|
|
2947
|
+
// Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry
|
|
2948
|
+
// Engineering, 2016.
|
|
2949
|
+
//
|
|
2950
|
+
// Model height is 2 m.
|
|
2951
|
+
//
|
|
2952
|
+
// This model contains 7 excitation positions going linearly from the
|
|
2953
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
2954
|
+
// position could be regenerated using `mesh2faust`.
|
|
2955
|
+
//
|
|
2956
|
+
// This function also implement a virtual exciter to drive the model.
|
|
2957
|
+
//
|
|
2958
|
+
// #### Usage
|
|
2959
|
+
//
|
|
2960
|
+
// ```
|
|
2961
|
+
// excitation : russianBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) : _
|
|
2962
|
+
// ```
|
|
2963
|
+
//
|
|
2964
|
+
// Where:
|
|
2965
|
+
//
|
|
2966
|
+
// * `excitation`: the excitation signal
|
|
2967
|
+
// * `strikePosition`: strike position (0-6)
|
|
2968
|
+
// * `strikeCutoff`: cuttoff frequency of the strike genarator (recommended: ~7000Hz)
|
|
2969
|
+
// * `strikeSharpness`: sharpness of the strike (recommended: ~0.25)
|
|
2970
|
+
// * `gain`: gain of the strike (0-1)
|
|
2971
|
+
// * `trigger` signal (0: off, 1: on)
|
|
2972
|
+
//----------------------------------
|
|
2973
|
+
russianBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) =
|
|
2974
|
+
strikeModel(10,strikeCutoff,strikeSharpness,gain,trigger) :
|
|
2975
|
+
russianBellModel(50,strikePosition,30,1,3);
|
|
2976
|
+
|
|
2977
|
+
|
|
2978
|
+
//-------`(pm.)russianBell_ui`----------
|
|
2979
|
+
// Russian church bell physical model based on [`russianBell`](#russianbell) with
|
|
2980
|
+
// built-in UI.
|
|
2981
|
+
//
|
|
2982
|
+
// #### Usage
|
|
2983
|
+
//
|
|
2984
|
+
// ```
|
|
2985
|
+
// russianBell_ui : _
|
|
2986
|
+
// ```
|
|
2987
|
+
//----------------------------------
|
|
2988
|
+
russianBell_ui =
|
|
2989
|
+
russianBell(strikePosition,strikeCutoff,strikeSharpness,gain,gate)
|
|
2990
|
+
with{
|
|
2991
|
+
strikePosition = nentry("v:russianBell/[0]strikePosition",0,0,6,1);
|
|
2992
|
+
strikeCutoff = hslider("v:russianBell/[1]strikeCutOff",6500,20,20000,1);
|
|
2993
|
+
strikeSharpness = hslider("v:russianBell/[2]strikeSharpness",0.5,0.01,5,0.01);
|
|
2994
|
+
gain = hslider("v:russianBell/[3]gain",1,0,1,0.01);
|
|
2995
|
+
gate = button("v:russianBell/[4]gate");
|
|
2996
|
+
};
|
|
2997
|
+
|
|
2998
|
+
//-------`(pm.)standardBellModel`----------
|
|
2999
|
+
// Standard church bell modal model generated by `mesh2faust` from
|
|
3000
|
+
// `libraries/modalmodels/standardBell`.
|
|
3001
|
+
//
|
|
3002
|
+
// Modeled after T. Rossing and R. Perrin, Vibrations of Bells, Applied
|
|
3003
|
+
// Acoustics 2, 1987.
|
|
3004
|
+
//
|
|
3005
|
+
// Model height is 1.8 m.
|
|
3006
|
+
//
|
|
3007
|
+
// This model contains 7 excitation positions going linearly from the
|
|
3008
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
3009
|
+
// position could be regenerated using `mesh2faust`.
|
|
3010
|
+
//
|
|
3011
|
+
// #### Usage
|
|
3012
|
+
//
|
|
3013
|
+
// ```
|
|
3014
|
+
// excitation : standardBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope)
|
|
3015
|
+
// ```
|
|
3016
|
+
//
|
|
3017
|
+
// Where:
|
|
3018
|
+
//
|
|
3019
|
+
// * `excitation`: the excitation signal
|
|
3020
|
+
// * `nModes`: number of synthesized modes (max: 50)
|
|
3021
|
+
// * `exPos`: excitation position (0-6)
|
|
3022
|
+
// * `t60`: T60 in seconds (recommended value: 0.1)
|
|
3023
|
+
// * `t60DecayRatio`: T60 decay ratio (recommended value: 1)
|
|
3024
|
+
// * `t60DecaySlope`: T60 decay slope (recommended value: 5)
|
|
3025
|
+
//----------------------------------
|
|
3026
|
+
standardBellModel(nModes,exPos,t60,t60DecayRatio,t60DecaySlope) = _ <: par(i,nModes,modeFilter(modesFreqs(i),modesT60s(i),modesGains(int(exPos),i))) :> /(nModes)
|
|
3027
|
+
with{
|
|
3028
|
+
nExPos = 7;
|
|
3029
|
+
modesFreqs(n) = ba.take(n+1,(490.25,493.646,924.838,927.779,1181.21,1186.94,1348.84,1349.5,1560.33,1635.97,1706.73,1712.89,1745.05,1745.25,2005.51,2025.47,2053.88,2142.37,2151.4,2408.16,2534.11,2536.42,2623.3,2628.4,2711.57,2712.46,2823.23,2827.22,2863.42,2874.19,2923,2925.69,3032.52,3042.15,3208.57,3392.52,3485.92,3493.65,3539.8,3550.56,3678.71,3719.04,3722.59,3786.28,3789.38,3993.59,3998.43,4123.41,4164.83,4187.98));
|
|
3030
|
+
modesGains(p,n) = waveform{0.691911,0.622333,0.548651,0.463306,0.826946,0.749513,0.2242,0.642678,0.760442,0.326054,0.276463,0.359344,0.18258,0.686765,0.457159,0.839015,0.845338,0.372377,0.306417,0.147381,0.359707,0.653537,0.27553,0.401233,0.435417,0.251481,0.190062,0.773372,0.315014,0.228812,0.521512,0.411542,0.720762,1,0.286502,0.338938,0.119995,0.432289,0.409677,0.156272,0.298871,0.250786,0.640776,0.209431,0.17001,0.390014,0.301698,0.799413,0.980581,0.385,0.82544,0.818894,0.349616,0.235396,0.783164,0.821914,0.28411,0.430286,0.507671,0.326254,0.260488,0.273364,0.20518,0.714852,0.47995,0.803637,0.683943,0.355371,0.406924,0.656257,0.423025,0.413515,0.38636,0.384787,0.389448,0.813367,0.234988,1,0.311268,0.350245,0.403856,0.646143,0.500485,0.833553,0.431768,0.467064,0.298979,0.487413,0.514907,0.369383,0.106197,0.494224,0.816079,0.535807,0.379873,0.380201,0.606306,0.516117,0.748449,0.556948,0.587066,0.584423,0.394866,0.341121,0.433458,0.455987,0.361237,0.42939,0.122969,0.133175,0.505176,0.513985,0.0554619,0.604942,0.372074,0.381126,0.314354,0.499636,0.518711,0.923792,0.259544,0.576517,0.553915,0.585444,0.245369,1,0.117757,0.977318,0.652862,0.509314,0.14855,0.506402,0.180059,0.356005,0.38681,0.279354,0.205792,0.551055,0.689107,0.445724,0.306857,0.324747,0.603621,0.394466,0.288613,0.264697,0.60612,0.20274,0.267271,0.925656,0.439228,0.425884,0.626633,0.547204,0.230022,0.225654,0.392697,0.493474,0.149857,0.0604048,0.693889,0.740271,0.175485,0.704998,0.329732,0.153026,0.125744,0.286995,0.278878,0.812372,0.0562174,0.241479,0.294525,0.358834,0.171047,0.847604,0.17228,0.97521,0.892073,0.613987,0.0659213,0.301583,0.0610847,0.125438,0.145151,0.180086,0.124231,0.260161,0.337573,0.203743,0.655798,0.425893,0.902347,0.500686,0.311173,0.215561,0.349591,0.0854218,0.0805062,1,0.338652,0.295396,0.698314,0.664972,0.118983,0.0881905,0.31158,0.391136,0.151915,0.239504,0.685742,0.884332,0.288516,0.768688,0.274851,0.0490311,0.0357865,0.293303,0.249461,0.493771,0.340984,0.467623,0.216631,0.255235,0.0988695,0.46198,0.147247,0.640196,1,0.551938,0.0453732,0.189907,0.0197542,0.0309217,0.769837,0.360418,0.384041,0.867434,0.398948,0.171848,0.748652,0.301957,0.860611,0.958674,0.54903,0.272753,0.372753,0.0180728,0.0292353,0.8502,0.224583,0.214805,0.670319,0.586433,0.0435142,0.0388574,0.144811,0.157061,0.155569,0.418334,0.673656,0.749573,0.337354,0.747254,0.255997,0.0239656,0.0310719,0.721087,0.700616,0.199051,0.511844,0.849485,0.700682,0.778658,0.171289,0.261973,0.129228,0.328597,0.781821,0.583813,0.0806713,0.416876,0.0118202,0.00868563,1,0.461884,0.186882,0.641364,0.994705,0.501902,0.566449,0.0678845,0.139737,0.462582,0.318656,0.233947,0.495941,0.0314028,0.0146478,0.70432,0.124953,0.132549,0.457126,0.378636,0.0169362,0.0195494,0.204155,0.294401,0.271367,0.730857,0.459322,0.433078,0.325171,0.734536,0.416205,0.012873,0.0388489,0.821567,0.863683,0.0920531,0.393972,0.539544,0.832052,0.842732,0.241144,0.479558,0.283092,0.477845,0.385473,0.436587,0.144308,0.642395,0.0215791,0.00779029,0.563714,0.838279,0.410004,0.829086,1,0.630598,0.0233729,0.496217,0.711042,0.914266,0.695042,0.331894,0.898442,0.028568,0.0174966,0.482846},int(p*nModes+n) : rdtable;
|
|
3031
|
+
modesT60s(i) = t60*pow(1-(modesFreqs(i)/4191.95)*t60DecayRatio,t60DecaySlope);
|
|
3032
|
+
};
|
|
3033
|
+
|
|
3034
|
+
|
|
3035
|
+
//-------`(pm.)standardBell`----------
|
|
3036
|
+
// Standard church bell modal model.
|
|
3037
|
+
//
|
|
3038
|
+
// Modeled after T. Rossing and R. Perrin, Vibrations of Bells, Applied
|
|
3039
|
+
// Acoustics 2, 1987.
|
|
3040
|
+
//
|
|
3041
|
+
// Model height is 1.8 m.
|
|
3042
|
+
//
|
|
3043
|
+
// This model contains 7 excitation positions going linearly from the
|
|
3044
|
+
// bottom to the top of the bell. Obviously, a model with more excitation
|
|
3045
|
+
// position could be regenerated using `mesh2faust`.
|
|
3046
|
+
//
|
|
3047
|
+
// This function also implement a virtual exciter to drive the model.
|
|
3048
|
+
//
|
|
3049
|
+
// #### Usage
|
|
3050
|
+
//
|
|
3051
|
+
// ```
|
|
3052
|
+
// excitation : standardBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) : _
|
|
3053
|
+
// ```
|
|
3054
|
+
//
|
|
3055
|
+
// Where:
|
|
3056
|
+
//
|
|
3057
|
+
// * `excitation`: the excitation signal
|
|
3058
|
+
// * `strikePosition`: strike position (0-6)
|
|
3059
|
+
// * `strikeCutoff`: cuttoff frequency of the strike genarator (recommended: ~7000Hz)
|
|
3060
|
+
// * `strikeSharpness`: sharpness of the strike (recommended: ~0.25)
|
|
3061
|
+
// * `gain`: gain of the strike (0-1)
|
|
3062
|
+
// * `trigger` signal (0: off, 1: on)
|
|
3063
|
+
//----------------------------------
|
|
3064
|
+
standardBell(strikePosition,strikeCutoff,strikeSharpness,gain,trigger) =
|
|
3065
|
+
strikeModel(10,strikeCutoff,strikeSharpness,gain,trigger) :
|
|
3066
|
+
standardBellModel(50,strikePosition,30,1,2.5);
|
|
3067
|
+
|
|
3068
|
+
|
|
3069
|
+
//-------`(pm.)standardBell_ui`----------
|
|
3070
|
+
// Standard church bell physical model based on [`standardBell`](#standardbell) with
|
|
3071
|
+
// built-in UI.
|
|
3072
|
+
//
|
|
3073
|
+
// #### Usage
|
|
3074
|
+
//
|
|
3075
|
+
// ```
|
|
3076
|
+
// standardBell_ui : _
|
|
3077
|
+
// ```
|
|
3078
|
+
//----------------------------------
|
|
3079
|
+
standardBell_ui =
|
|
3080
|
+
standardBell(strikePosition,strikeCutoff,strikeSharpness,gain,gate)
|
|
3081
|
+
with{
|
|
3082
|
+
strikePosition = nentry("v:standardBell/[0]strikePosition",0,0,6,1);
|
|
3083
|
+
strikeCutoff = hslider("v:standardBell/[1]strikeCutOff",6500,20,20000,1);
|
|
3084
|
+
strikeSharpness = hslider("v:standardBell/[2]strikeSharpness",0.5,0.01,5,0.01);
|
|
3085
|
+
gain = hslider("v:standardBell/[3]gain",1,0,1,0.01);
|
|
3086
|
+
gate = button("v:standardBell/[4]gate");
|
|
3087
|
+
};
|
|
3088
|
+
|
|
3089
|
+
|
|
3090
|
+
//==============================Vocal Synthesis===========================================
|
|
3091
|
+
// Vocal synthesizer functions (source/filter, fof, etc.).
|
|
3092
|
+
//========================================================================================
|
|
3093
|
+
|
|
3094
|
+
//-------`(pm.)formantValues`----------
|
|
3095
|
+
// Formant data values.
|
|
3096
|
+
//
|
|
3097
|
+
// The formant data used here come from the CSOUND manual
|
|
3098
|
+
// <http://www.csounds.com/manual/html/>.
|
|
3099
|
+
//
|
|
3100
|
+
// #### Usage
|
|
3101
|
+
//
|
|
3102
|
+
// ```
|
|
3103
|
+
// ba.take(j+1,formantValues.f(i)) : _
|
|
3104
|
+
// ba.take(j+1,formantValues.g(i)) : _
|
|
3105
|
+
// ba.take(j+1,formantValues.bw(i)) : _
|
|
3106
|
+
// ```
|
|
3107
|
+
//
|
|
3108
|
+
// Where:
|
|
3109
|
+
//
|
|
3110
|
+
// * `i`: formant number
|
|
3111
|
+
// * `j`: (voiceType*nFormants)+vowel
|
|
3112
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3:
|
|
3113
|
+
// soprano, 4: tenor)
|
|
3114
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u)
|
|
3115
|
+
//--------------------------------------
|
|
3116
|
+
formantValues = environment {
|
|
3117
|
+
f(0) = (800,400,350,450,325,600,400,250,400,350,660,440,270,430,370,800,
|
|
3118
|
+
350,270,450,325,650,400,290,400,350); // formant 0 freqs
|
|
3119
|
+
f(1) = (1150,1600,1700,800,700,1040,1620,1750,750,600,1120,1800,1850,820,630,
|
|
3120
|
+
1150,2000,2140,800,700,1080,1700,1870,800,600); // formant 1 freqs
|
|
3121
|
+
f(2) = (2800,2700,2700,2830,2530,2250,2400,2600,2400,2400,2750,2700,2900,2700,2750,
|
|
3122
|
+
2900,2800,2950,2830,2700,2650,2600,2800,2600,2700); // formant 2 freqs
|
|
3123
|
+
f(3) = (3500,3300,3700,3500,3500,2450,2800,3050,2600,2675,3000,3000,3350,3000,3000,
|
|
3124
|
+
3900,3600,3900,3800,3800,2900,3200,3250,2800,2900); // formant 3 freqs
|
|
3125
|
+
f(4) = (4950,4950,4950,4950,4950,2750,3100,3340,2900,2950,3350,3300,3590,3300,3400,
|
|
3126
|
+
4950,4950,4950,4950,4950,3250,3580,3540,3000,3300); // formant 4 freqs
|
|
3127
|
+
g(0) = (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); // formant 0 gains
|
|
3128
|
+
g(1) = (0.630957,0.063096,0.100000,0.354813,0.251189,0.446684,0.251189,0.031623,
|
|
3129
|
+
0.281838,0.100000,0.501187,0.199526,0.063096,0.316228,0.100000,
|
|
3130
|
+
0.501187,0.100000,0.251189,0.281838,0.158489,0.501187,0.199526,0.177828,
|
|
3131
|
+
0.316228,0.100000); // formant 1 gains
|
|
3132
|
+
g(2) = (0.100000,0.031623,0.031623,0.158489,0.031623,0.354813,0.354813,0.158489,
|
|
3133
|
+
0.089125,0.025119,0.070795,0.125893,0.063096,0.050119,0.070795,
|
|
3134
|
+
0.025119,0.177828,0.050119,0.079433,0.017783,0.446684,0.251189,0.125893,
|
|
3135
|
+
0.251189,0.141254); // formant 2 gains
|
|
3136
|
+
g(3) = (0.015849,0.017783,0.015849,0.039811,0.010000,0.354813,0.251189,0.079433,
|
|
3137
|
+
0.100000,0.039811,0.063096,0.100000,0.015849,0.079433,0.031623,
|
|
3138
|
+
0.100000,0.010000,0.050119,0.079433,0.010000,0.398107,0.199526,0.100000,
|
|
3139
|
+
0.251189,0.199526); // formant 3 gains
|
|
3140
|
+
g(4) = (0.001000,0.001000,0.001000,0.001778,0.000631,0.100000,0.125893,0.039811,
|
|
3141
|
+
0.010000,0.015849,0.012589,0.100000,0.015849,0.019953,0.019953,
|
|
3142
|
+
0.003162,0.001585,0.006310,0.003162,0.001000,0.079433,0.100000,0.031623,
|
|
3143
|
+
0.050119,0.050119); // formant 4 gains
|
|
3144
|
+
bw(0) = (80,60,50,70,50,60,40,60,40,40,80,70,40,40,40,80,60,60,40,50,
|
|
3145
|
+
50,70,40,70,40); // formant 0 bandwidths
|
|
3146
|
+
bw(1) = (90,80,100,80,60,70,80,90,80,80,90,80,90,80,60,90,100,90,80,60,
|
|
3147
|
+
90,80,90,80,60); // formant 1 bandwidths
|
|
3148
|
+
bw(2) = (120,120,120,100,170,110,100,100,100,100,120,100,100,100,100,
|
|
3149
|
+
120,120,100,100,170,120,100,100,100,100); // formant 2 bandwidths
|
|
3150
|
+
bw(3) = (130,150,150,130,180,120,120,120,120,120,130,120,120,120,120,
|
|
3151
|
+
130,150,120,120,180,130,120,120,130,120); // formant 3 bandwidths
|
|
3152
|
+
bw(4) = (140,200,200,135,200,130,120,120,120,120,140,120,120,120,120,
|
|
3153
|
+
140,200,120,120,200,140,120,120,135,120); // formant 4 bandwidths
|
|
3154
|
+
};
|
|
3155
|
+
|
|
3156
|
+
|
|
3157
|
+
// array of values used to multiply BWs by to get attack Bws for FOF version.
|
|
3158
|
+
// min/max values per vowel (AEIOU) and per gender (M/F). Index by:
|
|
3159
|
+
// gender*5 + vowel;
|
|
3160
|
+
// values were chosen based on informal listening tests
|
|
3161
|
+
bwMultMins = (1.0, 1.25, 1.25, 1.0, 1.5, 2.0, 3.0, 3.0, 2.0, 2.0);
|
|
3162
|
+
bwMultMaxes = (10.0, 2.5, 2.5, 10.0, 4.0, 15.0, 12.0, 12.0, 12.0, 12.0);
|
|
3163
|
+
|
|
3164
|
+
|
|
3165
|
+
// minimum/maximum frequency values per gender (M/F) used in the calculation
|
|
3166
|
+
// of the attack Bws from the release Bws in the FOF version
|
|
3167
|
+
// values are based on arbitrary maximum/minimum singing values
|
|
3168
|
+
// in Hz for male/female voices
|
|
3169
|
+
minGenderFreq = (82.41,174.61);
|
|
3170
|
+
maxGenderFreq = (523.25,1046.5);
|
|
3171
|
+
|
|
3172
|
+
|
|
3173
|
+
//--------------`(pm.)voiceGender`-----------------
|
|
3174
|
+
// Calculate the gender for the provided `voiceType` value. (0: male, 1: female)
|
|
3175
|
+
//
|
|
3176
|
+
// #### Usage
|
|
3177
|
+
//
|
|
3178
|
+
// ```
|
|
3179
|
+
// voiceGender(voiceType) : _
|
|
3180
|
+
// ```
|
|
3181
|
+
//
|
|
3182
|
+
// Where:
|
|
3183
|
+
//
|
|
3184
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3185
|
+
//---------------------------------------------
|
|
3186
|
+
declare voiceGender author "Mike Olsen";
|
|
3187
|
+
|
|
3188
|
+
voiceGender(voiceType) = ba.if(voiceType == 0,1,ba.if(voiceType == 3,1,0));
|
|
3189
|
+
|
|
3190
|
+
|
|
3191
|
+
//-----------`(pm.)skirtWidthMultiplier`------------
|
|
3192
|
+
// Calculates value to multiply bandwidth to obtain `skirtwidth`
|
|
3193
|
+
// for a Fof filter.
|
|
3194
|
+
//
|
|
3195
|
+
// #### Usage
|
|
3196
|
+
//
|
|
3197
|
+
// ```
|
|
3198
|
+
// skirtWidthMultiplier(vowel,freq,gender) : _
|
|
3199
|
+
// ```
|
|
3200
|
+
//
|
|
3201
|
+
// Where:
|
|
3202
|
+
//
|
|
3203
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u)
|
|
3204
|
+
// * `freq`: the fundamental frequency of the excitation signal
|
|
3205
|
+
// * `gender`: gender of the voice used in the fof filter (0: male, 1: female)
|
|
3206
|
+
//---------------------------------------------
|
|
3207
|
+
declare skirtWidthMultiplier author "Mike Olsen";
|
|
3208
|
+
|
|
3209
|
+
skirtWidthMultiplier(vowel,freq,gender) = (multMax-multMin)*skirtParam+multMin
|
|
3210
|
+
with {
|
|
3211
|
+
nVowels = 5;
|
|
3212
|
+
index = gender*nVowels + vowel;
|
|
3213
|
+
multMin = bwMultMins : ba.selectn(10,index);
|
|
3214
|
+
multMax = bwMultMaxes : ba.selectn(10,index);
|
|
3215
|
+
freqMin = minGenderFreq : ba.selectn(2,gender);
|
|
3216
|
+
freqMax = maxGenderFreq : ba.selectn(2,gender);
|
|
3217
|
+
skirtParam = ba.if(freq <= freqMin,0.0,ba.if(freq >= freqMax,1.0,
|
|
3218
|
+
(1.0/(freqMax-freqMin))*(freq-freqMin)));
|
|
3219
|
+
};
|
|
3220
|
+
|
|
3221
|
+
|
|
3222
|
+
//--------------`(pm.)autobendFreq`-----------------
|
|
3223
|
+
// Autobends the center frequencies of formants 1 and 2 based on
|
|
3224
|
+
// the fundamental frequency of the excitation signal and leaves
|
|
3225
|
+
// all other formant frequencies unchanged. Ported from `chant-lib`.
|
|
3226
|
+
//
|
|
3227
|
+
// #### Reference
|
|
3228
|
+
//
|
|
3229
|
+
// <https://ccrma.stanford.edu/~rmichon/chantLib/>.
|
|
3230
|
+
//
|
|
3231
|
+
// #### Usage
|
|
3232
|
+
//
|
|
3233
|
+
// ```
|
|
3234
|
+
// _ : autobendFreq(n,freq,voiceType) : _
|
|
3235
|
+
// ```
|
|
3236
|
+
//
|
|
3237
|
+
// Where:
|
|
3238
|
+
//
|
|
3239
|
+
// * `n`: formant index
|
|
3240
|
+
// * `freq`: the fundamental frequency of the excitation signal
|
|
3241
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3242
|
+
// * input is the center frequency of the corresponding formant
|
|
3243
|
+
//---------------------------------------------
|
|
3244
|
+
declare autobendFreq author "Mike Olsen";
|
|
3245
|
+
|
|
3246
|
+
autobendFreq(n,freq,voiceType) = autobend(n)
|
|
3247
|
+
with {
|
|
3248
|
+
autobend(0) = _ <: ba.if(_ <= freq,freq,_);
|
|
3249
|
+
autobend(1) = _ <: ba.if(voiceType != 2,
|
|
3250
|
+
_ <: ba.if((_ >= 1300)&(freq >= 200),
|
|
3251
|
+
_ -(freq-200)*(_-1300)/1050,
|
|
3252
|
+
ba.if(_ <= (30 + 2*freq),30 + 2*freq,_)), _);
|
|
3253
|
+
autobend(n) = _;
|
|
3254
|
+
};
|
|
3255
|
+
|
|
3256
|
+
|
|
3257
|
+
//--------------`(pm.)vocalEffort`-----------------
|
|
3258
|
+
// Changes the gains of the formants based on the fundamental
|
|
3259
|
+
// frequency of the excitation signal. Higher formants are
|
|
3260
|
+
// reinforced for higher fundamental frequencies.
|
|
3261
|
+
// Ported from `chant-lib`.
|
|
3262
|
+
//
|
|
3263
|
+
// #### Reference
|
|
3264
|
+
//
|
|
3265
|
+
// <https://ccrma.stanford.edu/~rmichon/chantLib/>.
|
|
3266
|
+
//
|
|
3267
|
+
// #### Usage
|
|
3268
|
+
//
|
|
3269
|
+
// ```
|
|
3270
|
+
// _ : vocalEffort(freq,gender) : _
|
|
3271
|
+
// ```
|
|
3272
|
+
//
|
|
3273
|
+
// Where:
|
|
3274
|
+
//
|
|
3275
|
+
// * `freq`: the fundamental frequency of the excitation signal
|
|
3276
|
+
// * `gender`: the gender of the voice type (0: male, 1: female)
|
|
3277
|
+
// * input is the linear amplitude of the formant
|
|
3278
|
+
//---------------------------------------------
|
|
3279
|
+
declare vocalEffort author "Mike Olsen";
|
|
3280
|
+
|
|
3281
|
+
vocalEffort(freq,gender) = _ <: ba.if(gender == 0,*(3+1.1*(400-freq)/300),*(0.8+1.05*(1000-freq)/1250));
|
|
3282
|
+
|
|
3283
|
+
|
|
3284
|
+
//-------------------------`(pm.)fof`--------------------------
|
|
3285
|
+
// Function to generate a single Formant-Wave-Function.
|
|
3286
|
+
//
|
|
3287
|
+
// #### Reference
|
|
3288
|
+
//
|
|
3289
|
+
// <https://ccrma.stanford.edu/~mjolsen/pdfs/smc2016_MOlsenFOF.pdf>.
|
|
3290
|
+
//
|
|
3291
|
+
// #### Usage
|
|
3292
|
+
//
|
|
3293
|
+
// ```
|
|
3294
|
+
// _ : fof(fc,bw,a,g) : _
|
|
3295
|
+
// ```
|
|
3296
|
+
//
|
|
3297
|
+
// Where:
|
|
3298
|
+
//
|
|
3299
|
+
// * `fc`: formant center frequency,
|
|
3300
|
+
// * `bw`: formant bandwidth (Hz),
|
|
3301
|
+
// * `sw`: formant skirtwidth (Hz)
|
|
3302
|
+
// * `g`: linear scale factor (g=1 gives 0dB amplitude response at fc)
|
|
3303
|
+
// * input is an impulse signal to excite filter
|
|
3304
|
+
//---------------------------------------------------------
|
|
3305
|
+
declare fof author "Mike Olsen";
|
|
3306
|
+
|
|
3307
|
+
fof(fc,bw,sw,g) = _ <: (_',_) : (f * s)
|
|
3308
|
+
with {
|
|
3309
|
+
T = 1/ma.SR; // sample period
|
|
3310
|
+
pi = ma.PI; // pi
|
|
3311
|
+
u1 = exp(-sw*pi*T); // exponential controlling rise
|
|
3312
|
+
u2 = exp(-bw*pi*T); // exponential controlling decay
|
|
3313
|
+
a1 = -1*(u1+u2); // a1 filter coefficient
|
|
3314
|
+
a2 = u1*u2; // a2 filter coefficient
|
|
3315
|
+
G0 = 1/(1+a1+a2); // magnitude at DC
|
|
3316
|
+
b0 = g/G0; // filter gain
|
|
3317
|
+
s = os.hs_oscsin(fc); // hardsyncing wavetable oscillator
|
|
3318
|
+
f = fi.tf2(b0,0,0,a1,a2); // biquad filter
|
|
3319
|
+
};
|
|
3320
|
+
|
|
3321
|
+
|
|
3322
|
+
//-------------------------`(pm.)fofSH`-------------------------
|
|
3323
|
+
// FOF with sample and hold used on `bw` and a parameter
|
|
3324
|
+
// used in the filter-cycling FOF function `fofCycle`.
|
|
3325
|
+
//
|
|
3326
|
+
// #### Reference
|
|
3327
|
+
//
|
|
3328
|
+
// <https://ccrma.stanford.edu/~mjolsen/pdfs/smc2016_MOlsenFOF.pdf>.
|
|
3329
|
+
//
|
|
3330
|
+
// #### Usage
|
|
3331
|
+
//
|
|
3332
|
+
// ```
|
|
3333
|
+
// _ : fofSH(fc,bw,a,g) : _
|
|
3334
|
+
// ```
|
|
3335
|
+
//
|
|
3336
|
+
// Where: all parameters same as for [`fof`](#fof)
|
|
3337
|
+
//---------------------------------------------------------
|
|
3338
|
+
declare fofSH author "Mike Olsen";
|
|
3339
|
+
|
|
3340
|
+
fofSH(fc,bw,a,g) = _ <: (((_,bw):ba.sAndH),((_,a):ba.sAndH),_) : (fc,_,_,g,_') : fof;
|
|
3341
|
+
|
|
3342
|
+
|
|
3343
|
+
//----------------------`(pm.)fofCycle`-------------------------
|
|
3344
|
+
// FOF implementation where time-varying filter parameter noise is
|
|
3345
|
+
// mitigated by using a cycle of `n` sample and hold FOF filters.
|
|
3346
|
+
//
|
|
3347
|
+
// #### Reference
|
|
3348
|
+
//
|
|
3349
|
+
// <https://ccrma.stanford.edu/~mjolsen/pdfs/smc2016_MOlsenFOF.pdf>.
|
|
3350
|
+
//
|
|
3351
|
+
// #### Usage
|
|
3352
|
+
//
|
|
3353
|
+
// ```
|
|
3354
|
+
// _ : fofCycle(fc,bw,a,g,n) : _
|
|
3355
|
+
// ```
|
|
3356
|
+
//
|
|
3357
|
+
// Where:
|
|
3358
|
+
//
|
|
3359
|
+
// * `n`: the number of FOF filters to cycle through
|
|
3360
|
+
// * all other parameters are same as for [`fof`](#fof)
|
|
3361
|
+
//---------------------------------------------------------
|
|
3362
|
+
declare fofCycle author "Mike Olsen";
|
|
3363
|
+
|
|
3364
|
+
fofCycle(fc,bw,a,g,n) = _ : ba.cycle(n) : par(i,n,fofSH(fc,bw,a,g)) :> _;
|
|
3365
|
+
|
|
3366
|
+
|
|
3367
|
+
//----------------------`(pm.)fofSmooth`-------------------------
|
|
3368
|
+
// FOF implementation where time-varying filter parameter
|
|
3369
|
+
// noise is mitigated by lowpass filtering the filter
|
|
3370
|
+
// parameters `bw` and `a` with [smooth](#smooth).
|
|
3371
|
+
//
|
|
3372
|
+
// #### Usage
|
|
3373
|
+
//
|
|
3374
|
+
// ```
|
|
3375
|
+
// _ : fofSmooth(fc,bw,sw,g,tau) : _
|
|
3376
|
+
// ```
|
|
3377
|
+
//
|
|
3378
|
+
// Where:
|
|
3379
|
+
//
|
|
3380
|
+
// * `tau`: the desired smoothing time constant in seconds
|
|
3381
|
+
// * all other parameters are same as for [`fof`](#fof)
|
|
3382
|
+
//---------------------------------------------------------
|
|
3383
|
+
declare fofSmooth author "Mike Olsen";
|
|
3384
|
+
|
|
3385
|
+
fofSmooth(fc,bw,sw,g,tau) = fof(fc,bw2,sw2,g)
|
|
3386
|
+
with{
|
|
3387
|
+
sw2 = sw : si.smooth(ba.tau2pole(tau));
|
|
3388
|
+
bw2 = bw : si.smooth(ba.tau2pole(tau));
|
|
3389
|
+
};
|
|
3390
|
+
|
|
3391
|
+
|
|
3392
|
+
//-------`(pm.)formantFilterFofCycle`--------------
|
|
3393
|
+
// Formant filter based on a single FOF filter.
|
|
3394
|
+
// Formant parameters are linearly interpolated allowing to go smoothly from
|
|
3395
|
+
// one vowel to another. A cycle of `n` fof filters with sample-and-hold is
|
|
3396
|
+
// used so that the fof filter parameters can be varied in realtime.
|
|
3397
|
+
// This technique is more robust but more computationally expensive than
|
|
3398
|
+
// [`formantFilterFofSmooth`](#formantFilterFofSmooth).Voice type can be
|
|
3399
|
+
// selected but must correspond to
|
|
3400
|
+
// the frequency range of the provided source to be realistic.
|
|
3401
|
+
//
|
|
3402
|
+
// #### Usage
|
|
3403
|
+
//
|
|
3404
|
+
// ```
|
|
3405
|
+
// _ : formantFilterFofCycle(voiceType,vowel,nFormants,i,freq) : _
|
|
3406
|
+
// ```
|
|
3407
|
+
//
|
|
3408
|
+
// Where:
|
|
3409
|
+
//
|
|
3410
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor,
|
|
3411
|
+
// 3: soprano, 4: tenor)
|
|
3412
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u)
|
|
3413
|
+
// * `nFormants`: number of formant regions in frequency domain, typically 5
|
|
3414
|
+
// * `i`: formant number (i.e. 0 - 4) used to index formant data value arrays
|
|
3415
|
+
// * `freq`: fundamental frequency of excitation signal. Used to calculate
|
|
3416
|
+
// rise time of envelope
|
|
3417
|
+
//--------------------------------------
|
|
3418
|
+
declare formantFilterFofCycle author "Mike Olsen";
|
|
3419
|
+
|
|
3420
|
+
formantFilterFofCycle(voiceType,vowel,nFormants,i,freq) =
|
|
3421
|
+
fofCycle(formantFreq(i),formantBw(i),formantSw(i),formantGain(i),n)
|
|
3422
|
+
with{
|
|
3423
|
+
n = 3; // number of fof filters to cycle between
|
|
3424
|
+
index = (voiceType*nFormants)+vowel; // index of formant values
|
|
3425
|
+
// formant center frequency using autobend correction
|
|
3426
|
+
formantFreq(i) = ba.listInterp(formantValues.f(i),index) : autobendFreq(i,freq,voiceType);
|
|
3427
|
+
// formant amplitude using vocal effort correction
|
|
3428
|
+
formantGain(i) = ba.listInterp(formantValues.g(i),index) : vocalEffort(freq,gender);
|
|
3429
|
+
formantBw(i) = ba.listInterp(formantValues.bw(i),index); // formant bandwidth
|
|
3430
|
+
// formant skirtwidth
|
|
3431
|
+
formantSw(i) = skirtWidthMultiplier(vowel,freq,gender)*formantBw(i);
|
|
3432
|
+
gender = voiceGender(voiceType); // gender of voice
|
|
3433
|
+
};
|
|
3434
|
+
|
|
3435
|
+
|
|
3436
|
+
//-------`(pm.)formantFilterFofSmooth`--------------
|
|
3437
|
+
// Formant filter based on a single FOF filter.
|
|
3438
|
+
// Formant parameters are linearly interpolated allowing to go smoothly from
|
|
3439
|
+
// one vowel to another. Fof filter parameters are lowpass filtered
|
|
3440
|
+
// to mitigate possible noise from varying them in realtime.
|
|
3441
|
+
// Voice type can be selected but must correspond to
|
|
3442
|
+
// the frequency range of the provided source to be realistic.
|
|
3443
|
+
//
|
|
3444
|
+
// #### Usage
|
|
3445
|
+
//
|
|
3446
|
+
// ```
|
|
3447
|
+
// _ : formantFilterFofSmooth(voiceType,vowel,nFormants,i,freq) : _
|
|
3448
|
+
// ```
|
|
3449
|
+
//
|
|
3450
|
+
// Where:
|
|
3451
|
+
//
|
|
3452
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor,
|
|
3453
|
+
// 3: soprano, 4: tenor)
|
|
3454
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u)
|
|
3455
|
+
// * `nFormants`: number of formant regions in frequency domain, typically 5
|
|
3456
|
+
// * `i`: formant number (i.e. 1 - 5) used to index formant data value arrays
|
|
3457
|
+
// * `freq`: fundamental frequency of excitation signal. Used to calculate
|
|
3458
|
+
// rise time of envelope
|
|
3459
|
+
//--------------------------------------
|
|
3460
|
+
declare formantFilterFofSmooth author "Mike Olsen";
|
|
3461
|
+
|
|
3462
|
+
formantFilterFofSmooth(voiceType,vowel,nFormants,i,freq) =
|
|
3463
|
+
fofSmooth(formantFreq(i),formantBw(i),formantSw(i),formantGain(i),tau)
|
|
3464
|
+
with{
|
|
3465
|
+
tau = 0.001;
|
|
3466
|
+
index = (voiceType*nFormants)+vowel; // index of formant values
|
|
3467
|
+
// formant center frequency using autobend correction
|
|
3468
|
+
formantFreq(i) = ba.listInterp(formantValues.f(i),index) : autobendFreq(i,freq,voiceType);
|
|
3469
|
+
// formant amplitude using vocal effort correction
|
|
3470
|
+
formantGain(i) = ba.listInterp(formantValues.g(i),index) : vocalEffort(freq,gender);
|
|
3471
|
+
formantBw(i) = ba.listInterp(formantValues.bw(i),index); // formant bandwidth
|
|
3472
|
+
// formant skirtwidth
|
|
3473
|
+
formantSw(i) = skirtWidthMultiplier(vowel,freq,gender)*formantBw(i);
|
|
3474
|
+
gender = voiceGender(voiceType); // gender of voice
|
|
3475
|
+
};
|
|
3476
|
+
|
|
3477
|
+
|
|
3478
|
+
//-------`(pm.)formantFilterBP`--------------
|
|
3479
|
+
// Formant filter based on a single resonant bandpass filter.
|
|
3480
|
+
// Formant parameters are linearly interpolated allowing to go smoothly from
|
|
3481
|
+
// one vowel to another. Voice type can be selected but must correspond to
|
|
3482
|
+
// the frequency range of the provided source to be realistic.
|
|
3483
|
+
//
|
|
3484
|
+
// #### Usage
|
|
3485
|
+
//
|
|
3486
|
+
// ```
|
|
3487
|
+
// _ : formantFilterBP(voiceType,vowel,nFormants,i,freq) : _
|
|
3488
|
+
// ```
|
|
3489
|
+
//
|
|
3490
|
+
// Where:
|
|
3491
|
+
//
|
|
3492
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3493
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u)
|
|
3494
|
+
// * `nFormants`: number of formant regions in frequency domain, typically 5
|
|
3495
|
+
// * `i`: formant index used to index formant data value arrays
|
|
3496
|
+
// * `freq`: fundamental frequency of excitation signal.
|
|
3497
|
+
//--------------------------------------
|
|
3498
|
+
formantFilterBP(voiceType,vowel,nFormants,i,freq) =
|
|
3499
|
+
fi.resonbp(formantFreq(i),formantFreq(i)/formantBw(i),
|
|
3500
|
+
formantGain(i))
|
|
3501
|
+
with{
|
|
3502
|
+
index = (voiceType*nFormants)+vowel; // index of formant values
|
|
3503
|
+
// formant center frequency using autobend correction
|
|
3504
|
+
formantFreq(i) = ba.listInterp(formantValues.f(i),index) : autobendFreq(i,freq,voiceType);
|
|
3505
|
+
// formant amplitude using vocal effort correction
|
|
3506
|
+
formantGain(i) = ba.listInterp(formantValues.g(i),index) : vocalEffort(freq,gender);
|
|
3507
|
+
formantBw(i) = ba.listInterp(formantValues.bw(i),index); // formant bandwidth
|
|
3508
|
+
gender = voiceGender(voiceType); // gender of voice
|
|
3509
|
+
};
|
|
3510
|
+
|
|
3511
|
+
|
|
3512
|
+
//-------`(pm.)formantFilterbank`--------------
|
|
3513
|
+
// Formant filterbank which can use different types of filterbank
|
|
3514
|
+
// functions and different excitation signals. Formant parameters are
|
|
3515
|
+
// linearly interpolated allowing to go smoothly from one vowel to another.
|
|
3516
|
+
// Voice type can be selected but must correspond to the frequency range
|
|
3517
|
+
// of the provided source to be realistic.
|
|
3518
|
+
//
|
|
3519
|
+
// #### Usage
|
|
3520
|
+
//
|
|
3521
|
+
// ```
|
|
3522
|
+
// _ : formantFilterbank(voiceType,vowel,formantGen,freq) : _
|
|
3523
|
+
// ```
|
|
3524
|
+
//
|
|
3525
|
+
// Where:
|
|
3526
|
+
//
|
|
3527
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3528
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u)
|
|
3529
|
+
// * `formantGen`: the specific formant filterbank function
|
|
3530
|
+
// (i.e. FormantFilterbankBP, FormantFilterbankFof,...)
|
|
3531
|
+
// * `freq`: fundamental frequency of excitation signal. Needed for FOF
|
|
3532
|
+
// version to calculate rise time of envelope
|
|
3533
|
+
//--------------------------------------
|
|
3534
|
+
declare formantFilterbank author "Mike Olsen";
|
|
3535
|
+
|
|
3536
|
+
formantFilterbank(voiceType,vowel,formantGen,freq) =
|
|
3537
|
+
_ <: par(i,nFormants,formantGen(voiceType,vowel,nFormants,i,freq)) :> _
|
|
3538
|
+
with{
|
|
3539
|
+
nFormants = 5;
|
|
3540
|
+
};
|
|
3541
|
+
|
|
3542
|
+
|
|
3543
|
+
//-----`(pm.)formantFilterbankFofCycle`-----
|
|
3544
|
+
// Formant filterbank based on a bank of fof filters.
|
|
3545
|
+
// Formant parameters are linearly interpolated allowing to go smoothly from
|
|
3546
|
+
// one vowel to another. Voice type can be selected but must correspond to
|
|
3547
|
+
// the frequency range of the provided source to be realistic.
|
|
3548
|
+
//
|
|
3549
|
+
// #### Usage
|
|
3550
|
+
//
|
|
3551
|
+
// ```
|
|
3552
|
+
// _ : formantFilterbankFofCycle(voiceType,vowel,freq) : _
|
|
3553
|
+
// ```
|
|
3554
|
+
//
|
|
3555
|
+
// Where:
|
|
3556
|
+
//
|
|
3557
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3558
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u)
|
|
3559
|
+
// * `freq`: the fundamental frequency of the excitation signal. Needed to calculate the skirtwidth
|
|
3560
|
+
// of the FOF envelopes and for the autobendFreq and vocalEffort functions
|
|
3561
|
+
//-------------------------------------
|
|
3562
|
+
declare formantFilterbankFofCycle author "Mike Olsen";
|
|
3563
|
+
|
|
3564
|
+
formantFilterbankFofCycle(voiceType,vowel,freq) =
|
|
3565
|
+
formantFilterbank(voiceType,vowel,formantFilterFofCycle,freq);
|
|
3566
|
+
|
|
3567
|
+
|
|
3568
|
+
//-----`(pm.)formantFilterbankFofSmooth`----
|
|
3569
|
+
// Formant filterbank based on a bank of fof filters.
|
|
3570
|
+
// Formant parameters are linearly interpolated allowing to go smoothly from
|
|
3571
|
+
// one vowel to another. Voice type can be selected but must correspond to
|
|
3572
|
+
// the frequency range of the provided source to be realistic.
|
|
3573
|
+
//
|
|
3574
|
+
// #### Usage
|
|
3575
|
+
//
|
|
3576
|
+
// ```
|
|
3577
|
+
// _ : formantFilterbankFofSmooth(voiceType,vowel,freq) : _
|
|
3578
|
+
// ```
|
|
3579
|
+
//
|
|
3580
|
+
// Where:
|
|
3581
|
+
//
|
|
3582
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3583
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u)
|
|
3584
|
+
// * `freq`: the fundamental frequency of the excitation signal. Needed to
|
|
3585
|
+
// calculate the skirtwidth of the FOF envelopes and for the
|
|
3586
|
+
// autobendFreq and vocalEffort functions
|
|
3587
|
+
//-------------------------------------
|
|
3588
|
+
declare formantFilterbankFofSmooth author "Mike Olsen";
|
|
3589
|
+
|
|
3590
|
+
formantFilterbankFofSmooth(voiceType,vowel,freq) =
|
|
3591
|
+
formantFilterbank(voiceType,vowel,formantFilterFofSmooth,freq);
|
|
3592
|
+
|
|
3593
|
+
|
|
3594
|
+
//-------`(pm.)formantFilterbankBP`--------------
|
|
3595
|
+
// Formant filterbank based on a bank of resonant bandpass filters.
|
|
3596
|
+
// Formant parameters are linearly interpolated allowing to go smoothly from
|
|
3597
|
+
// one vowel to another. Voice type can be selected but must correspond to
|
|
3598
|
+
// the frequency range of the provided source to be realistic.
|
|
3599
|
+
//
|
|
3600
|
+
// #### Usage
|
|
3601
|
+
//
|
|
3602
|
+
// ```
|
|
3603
|
+
// _ : formantFilterbankBP(voiceType,vowel,freq) : _
|
|
3604
|
+
// ```
|
|
3605
|
+
//
|
|
3606
|
+
// Where:
|
|
3607
|
+
//
|
|
3608
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3609
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u)
|
|
3610
|
+
// * `freq`: the fundamental frequency of the excitation signal. Needed for the autobendFreq and vocalEffort functions
|
|
3611
|
+
//--------------------------------------
|
|
3612
|
+
formantFilterbankBP(voiceType,vowel,freq) =
|
|
3613
|
+
formantFilterbank(voiceType,vowel,formantFilterBP,freq);
|
|
3614
|
+
|
|
3615
|
+
|
|
3616
|
+
//-------`(pm.)SFFormantModel`--------------
|
|
3617
|
+
// Simple formant/vocal synthesizer based on a source/filter model. The `source`
|
|
3618
|
+
// and `filterbank` must be specified by the user. `filterbank` must take the same
|
|
3619
|
+
// input parameters as [`formantFilterbank`](#formantFilterbank) (`BP`/`FofCycle`
|
|
3620
|
+
// /`FofSmooth`).
|
|
3621
|
+
// Formant parameters are linearly interpolated allowing to go smoothly from
|
|
3622
|
+
// one vowel to another. Voice type can be selected but must correspond to
|
|
3623
|
+
// the frequency range of the synthesized voice to be realistic.
|
|
3624
|
+
//
|
|
3625
|
+
// #### Usage
|
|
3626
|
+
//
|
|
3627
|
+
// ```
|
|
3628
|
+
// SFFormantModel(voiceType,vowel,exType,freq,gain,source,filterbank,isFof) : _
|
|
3629
|
+
// ```
|
|
3630
|
+
//
|
|
3631
|
+
// Where:
|
|
3632
|
+
//
|
|
3633
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3634
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u
|
|
3635
|
+
// * `exType`: voice vs. fricative sound ratio (0-1 where 1 is 100% fricative)
|
|
3636
|
+
// * `freq`: the fundamental frequency of the source signal
|
|
3637
|
+
// * `gain`: linear gain multiplier to multiply the source by
|
|
3638
|
+
// * `isFof`: whether model is FOF based (0: no, 1: yes)
|
|
3639
|
+
//--------------------------------------
|
|
3640
|
+
declare SFFormantModel author "Mike Olsen";
|
|
3641
|
+
|
|
3642
|
+
SFFormantModel(voiceType,vowel,exType,freq,gain,source,filterbank,isFof) =
|
|
3643
|
+
excitation : resonance
|
|
3644
|
+
with{
|
|
3645
|
+
breath = no.noise;
|
|
3646
|
+
excitation = ba.if(isFof,source,source*(1-exType) + breath*exType :
|
|
3647
|
+
*(gain));
|
|
3648
|
+
resonance = filterbank(voiceType,vowel,freq) <: ba.if(isFof,*(gain),_);
|
|
3649
|
+
};
|
|
3650
|
+
|
|
3651
|
+
|
|
3652
|
+
//-------`(pm.)SFFormantModelFofCycle`-------
|
|
3653
|
+
// Simple formant/vocal synthesizer based on a source/filter model. The source
|
|
3654
|
+
// is just a periodic impulse and the "filter" is a bank of FOF filters.
|
|
3655
|
+
// Formant parameters are linearly interpolated allowing to go smoothly from
|
|
3656
|
+
// one vowel to another. Voice type can be selected but must correspond to
|
|
3657
|
+
// the frequency range of the synthesized voice to be realistic. This model
|
|
3658
|
+
// does not work with noise in the source signal so exType has been removed
|
|
3659
|
+
// and model does not depend on SFFormantModel function.
|
|
3660
|
+
//
|
|
3661
|
+
// #### Usage
|
|
3662
|
+
//
|
|
3663
|
+
// ```
|
|
3664
|
+
// SFFormantModelFofCycle(voiceType,vowel,freq,gain) : _
|
|
3665
|
+
// ```
|
|
3666
|
+
//
|
|
3667
|
+
// Where:
|
|
3668
|
+
//
|
|
3669
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3670
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u
|
|
3671
|
+
// * `freq`: the fundamental frequency of the source signal
|
|
3672
|
+
// * `gain`: linear gain multiplier to multiply the source by
|
|
3673
|
+
//---------------------------------------
|
|
3674
|
+
declare SFFormantModelFofCycle author "Mike Olsen";
|
|
3675
|
+
|
|
3676
|
+
SFFormantModelFofCycle(voiceType,vowel,freq,gain) =
|
|
3677
|
+
SFFormantModel(voiceType,vowel,0,freq,gain,os.lf_imptrain(freq),
|
|
3678
|
+
formantFilterbankFofCycle,1);
|
|
3679
|
+
|
|
3680
|
+
|
|
3681
|
+
//-------`(pm.)SFFormantModelFofSmooth`-------
|
|
3682
|
+
// Simple formant/vocal synthesizer based on a source/filter model. The source
|
|
3683
|
+
// is just a periodic impulse and the "filter" is a bank of FOF filters.
|
|
3684
|
+
// Formant parameters are linearly interpolated allowing to go smoothly from
|
|
3685
|
+
// one vowel to another. Voice type can be selected but must correspond to
|
|
3686
|
+
// the frequency range of the synthesized voice to be realistic.
|
|
3687
|
+
//
|
|
3688
|
+
// #### Usage
|
|
3689
|
+
//
|
|
3690
|
+
// ```
|
|
3691
|
+
// SFFormantModelFofSmooth(voiceType,vowel,freq,gain) : _
|
|
3692
|
+
// ```
|
|
3693
|
+
//
|
|
3694
|
+
// Where:
|
|
3695
|
+
//
|
|
3696
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3697
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u
|
|
3698
|
+
// * `freq`: the fundamental frequency of the source signal
|
|
3699
|
+
// * `gain`: linear gain multiplier to multiply the source by
|
|
3700
|
+
//---------------------------------------
|
|
3701
|
+
declare SFFormantModelFofSmooth author "Mike Olsen";
|
|
3702
|
+
|
|
3703
|
+
SFFormantModelFofSmooth(voiceType,vowel,freq,gain) =
|
|
3704
|
+
SFFormantModel(voiceType,vowel,0,freq,gain,os.lf_imptrain(freq),
|
|
3705
|
+
formantFilterbankFofSmooth,1);
|
|
3706
|
+
|
|
3707
|
+
|
|
3708
|
+
//-------`(pm.)SFFormantModelBP`--------------
|
|
3709
|
+
// Simple formant/vocal synthesizer based on a source/filter model. The source
|
|
3710
|
+
// is just a sawtooth wave and the "filter" is a bank of resonant bandpass filters.
|
|
3711
|
+
// Formant parameters are linearly interpolated allowing to go smoothly from
|
|
3712
|
+
// one vowel to another. Voice type can be selected but must correspond to
|
|
3713
|
+
// the frequency range of the synthesized voice to be realistic.
|
|
3714
|
+
//
|
|
3715
|
+
// The formant data used here come from the CSOUND manual
|
|
3716
|
+
// <http://www.csounds.com/manual/html/>.
|
|
3717
|
+
//
|
|
3718
|
+
// #### Usage
|
|
3719
|
+
//
|
|
3720
|
+
// ```
|
|
3721
|
+
// SFFormantModelBP(voiceType,vowel,exType,freq,gain) : _
|
|
3722
|
+
// ```
|
|
3723
|
+
//
|
|
3724
|
+
// Where:
|
|
3725
|
+
//
|
|
3726
|
+
// * `voiceType`: the voice type (0: alto, 1: bass, 2: countertenor, 3: soprano, 4: tenor)
|
|
3727
|
+
// * `vowel`: the vowel (0: a, 1: e, 2: i, 3: o, 4: u
|
|
3728
|
+
// * `exType`: voice vs. fricative sound ratio (0-1 where 1 is 100% fricative)
|
|
3729
|
+
// * `freq`: the fundamental frequency of the source signal
|
|
3730
|
+
// * `gain`: linear gain multiplier to multiply the source by
|
|
3731
|
+
//---------------------------------------
|
|
3732
|
+
SFFormantModelBP(voiceType,vowel,exType,freq,gain) =
|
|
3733
|
+
SFFormantModel(voiceType,vowel,exType,freq,gain,os.sawtooth(freq),
|
|
3734
|
+
formantFilterbankBP,0);
|
|
3735
|
+
|
|
3736
|
+
|
|
3737
|
+
//-------`(pm.)SFFormantModelFofCycle_ui`----------
|
|
3738
|
+
// Ready-to-use source-filter vocal synthesizer with built-in user interface.
|
|
3739
|
+
//
|
|
3740
|
+
// #### Usage
|
|
3741
|
+
//
|
|
3742
|
+
// ```
|
|
3743
|
+
// SFFormantModelFofCycle_ui : _
|
|
3744
|
+
// ```
|
|
3745
|
+
//----------------------------------
|
|
3746
|
+
declare SFFormantModelFofCycle_ui author "Mike Olsen";
|
|
3747
|
+
|
|
3748
|
+
SFFormantModelFofCycle_ui = SFFormantModelFofCycle(voiceType,vowel,freq2,gain*corrFactor)
|
|
3749
|
+
with{
|
|
3750
|
+
freq1 = hslider("v:vocal/[0]freq",440,50,1000,0.01);
|
|
3751
|
+
gain = hslider("v:vocal/[1]gain",0.9,0,1,0.01);
|
|
3752
|
+
corrFactor = 75.0;
|
|
3753
|
+
voiceType = hslider("v:vocal/[2]voiceType",0,0,4,1);
|
|
3754
|
+
vowel = hslider("v:vocal/[3]vowel",0,0,4,0.01) : si.smoo;
|
|
3755
|
+
vibratoFreq = hslider("v:vocal/[5]vibratoFreq",6,1,10,0.01);
|
|
3756
|
+
vibratoGain = hslider("v:vocal/[6]vibratoGain",0.5,0,1,0.01)*0.1;
|
|
3757
|
+
freq2 = freq1*(os.osc(vibratoFreq)*vibratoGain+1);
|
|
3758
|
+
};
|
|
3759
|
+
|
|
3760
|
+
|
|
3761
|
+
//-------`(pm.)SFFormantModelFofSmooth_ui`----------
|
|
3762
|
+
// Ready-to-use source-filter vocal synthesizer with built-in user interface.
|
|
3763
|
+
//
|
|
3764
|
+
// #### Usage
|
|
3765
|
+
//
|
|
3766
|
+
// ```
|
|
3767
|
+
// SFFormantModelFofSmooth_ui : _
|
|
3768
|
+
// ```
|
|
3769
|
+
//----------------------------------
|
|
3770
|
+
declare SFFormantModelFofSmooth_ui author "Mike Olsen";
|
|
3771
|
+
|
|
3772
|
+
SFFormantModelFofSmooth_ui = SFFormantModelFofSmooth(voiceType,vowel,freq2,gain*corrFactor)
|
|
3773
|
+
with{
|
|
3774
|
+
freq1 = hslider("v:vocal/[0]freq",440,50,1000,0.01);
|
|
3775
|
+
gain = hslider("v:vocal/[1]gain",0.9,0,1,0.01);
|
|
3776
|
+
corrFactor = 25.0;
|
|
3777
|
+
voiceType = hslider("v:vocal/[2]voiceType",0,0,4,1);
|
|
3778
|
+
vowel = hslider("v:vocal/[3]vowel",0,0,4,0.01) : si.smoo;
|
|
3779
|
+
vibratoFreq = hslider("v:vocal/[5]vibratoFreq",6,1,10,0.01);
|
|
3780
|
+
vibratoGain = hslider("v:vocal/[6]vibratoGain",0.5,0,1,0.01)*0.1;
|
|
3781
|
+
freq2 = freq1*(os.osc(vibratoFreq)*vibratoGain+1);
|
|
3782
|
+
};
|
|
3783
|
+
|
|
3784
|
+
|
|
3785
|
+
//-------`(pm.)SFFormantModelBP_ui`----------
|
|
3786
|
+
// Ready-to-use source-filter vocal synthesizer with built-in user interface.
|
|
3787
|
+
//
|
|
3788
|
+
// #### Usage
|
|
3789
|
+
//
|
|
3790
|
+
// ```
|
|
3791
|
+
// SFFormantModelBP_ui : _
|
|
3792
|
+
// ```
|
|
3793
|
+
//----------------------------------
|
|
3794
|
+
SFFormantModelBP_ui = SFFormantModelBP(voiceType,vowel,fricative,freq2,gain)
|
|
3795
|
+
with{
|
|
3796
|
+
freq1 = hslider("v:vocal/[0]freq",440,50,1000,0.01);
|
|
3797
|
+
gain = hslider("v:vocal/[1]gain",0.9,0,1,0.01);
|
|
3798
|
+
voiceType = hslider("v:vocal/[2]voiceType",0,0,4,1);
|
|
3799
|
+
vowel = hslider("v:vocal/[3]vowel",0,0,4,0.01) : si.smoo;
|
|
3800
|
+
fricative = hslider("v:vocal/[4]fricative",0,0,1,0.01) : si.smoo;
|
|
3801
|
+
vibratoFreq = hslider("v:vocal/[5]vibratoFreq",6,1,10,0.01);
|
|
3802
|
+
vibratoGain = hslider("v:vocal/[6]vibratoGain",0.5,0,1,0.01)*0.1;
|
|
3803
|
+
freq2 = freq1*(os.osc(vibratoFreq)*vibratoGain+1);
|
|
3804
|
+
};
|
|
3805
|
+
|
|
3806
|
+
|
|
3807
|
+
//-------`(pm.)SFFormantModelFofCycle_ui_MIDI`----------
|
|
3808
|
+
// Ready-to-use MIDI-controllable source-filter vocal synthesizer.
|
|
3809
|
+
//
|
|
3810
|
+
// #### Usage
|
|
3811
|
+
//
|
|
3812
|
+
// ```
|
|
3813
|
+
// SFFormantModelFofCycle_ui_MIDI : _
|
|
3814
|
+
// ```
|
|
3815
|
+
//----------------------------------
|
|
3816
|
+
SFFormantModelFofCycle_ui_MIDI = SFFormantModelFofCycle(voiceType,vowel,freq2,envelope)*outGain
|
|
3817
|
+
with{
|
|
3818
|
+
freq1 = hslider("v:vocal/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
3819
|
+
bend = ba.semi2ratio(hslider("v:vocal/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel]
|
|
3820
|
+
[style:knob]",0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
3821
|
+
gain = hslider("v:vocal/h:[0]midi/[2]gain[style:knob]
|
|
3822
|
+
",0.9,0,1,0.01);
|
|
3823
|
+
corrFactor = 75.0;
|
|
3824
|
+
envAttack = hslider("v:vocal/h:[0]midi/[3]envAttack[style:knob]
|
|
3825
|
+
",10,0,30,0.01)*0.001;
|
|
3826
|
+
s = hslider("v:vocal/h:[0]midi/[4]sustain[hidden:1][midi:ctrl 64]
|
|
3827
|
+
[style:knob]",0,0,1,1);
|
|
3828
|
+
voiceType = hslider("v:vocal/h:[1]otherParams/[0]voiceType
|
|
3829
|
+
[style:knob]",0,0,4,1);
|
|
3830
|
+
vowel = hslider("v:vocal/h:[1]otherParams/[1]vowel
|
|
3831
|
+
[style:knob][midi:ctrl 1]",0,0,4,0.01) : si.smoo;
|
|
3832
|
+
vibratoFreq = hslider("v:vocal/h:[1]otherParams/[3]vibratoFreq[style:knob]
|
|
3833
|
+
",6,1,10,0.01);
|
|
3834
|
+
vibratoGain = hslider("v:vocal/h:[1]otherParams/[4]vibratoGain[style:knob]
|
|
3835
|
+
",0.5,0,1,0.01)*0.1;
|
|
3836
|
+
outGain = hslider("v:vocal/h:[1]otherParams/[5]outGain[style:knob]
|
|
3837
|
+
",0.5,0,1,0.01);
|
|
3838
|
+
t = button("v:vocal/[2]gate");
|
|
3839
|
+
|
|
3840
|
+
gate = t+s : min(1);
|
|
3841
|
+
freq2 = freq1*bend*(os.osc(vibratoFreq)*vibratoGain+1);
|
|
3842
|
+
envelope = gate*gain*corrFactor : si.smooth(ba.tau2pole(envAttack));
|
|
3843
|
+
};
|
|
3844
|
+
|
|
3845
|
+
|
|
3846
|
+
//-------`(pm.)SFFormantModelFofSmooth_ui_MIDI`----------
|
|
3847
|
+
// Ready-to-use MIDI-controllable source-filter vocal synthesizer.
|
|
3848
|
+
//
|
|
3849
|
+
// #### Usage
|
|
3850
|
+
//
|
|
3851
|
+
// ```
|
|
3852
|
+
// SFFormantModelFofSmooth_ui_MIDI : _
|
|
3853
|
+
// ```
|
|
3854
|
+
//----------------------------------
|
|
3855
|
+
SFFormantModelFofSmooth_ui_MIDI = SFFormantModelFofSmooth(voiceType,vowel,freq2,envelope)*outGain
|
|
3856
|
+
with{
|
|
3857
|
+
freq1 = hslider("v:vocal/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
3858
|
+
bend = ba.semi2ratio(hslider("v:vocal/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel]
|
|
3859
|
+
[style:knob]",0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
3860
|
+
gain = hslider("v:vocal/h:[0]midi/[2]gain[style:knob]
|
|
3861
|
+
",0.9,0,1,0.01);
|
|
3862
|
+
corrFactor = 25.0;
|
|
3863
|
+
envAttack = hslider("v:vocal/h:[0]midi/[3]envAttack[style:knob]
|
|
3864
|
+
",10,0,30,0.01)*0.001;
|
|
3865
|
+
s = hslider("v:vocal/h:[0]midi/[4]sustain[hidden:1][midi:ctrl 64]
|
|
3866
|
+
[style:knob]",0,0,1,1);
|
|
3867
|
+
voiceType = hslider("v:vocal/h:[1]otherParams/[0]voiceType
|
|
3868
|
+
[style:knob]",0,0,4,1);
|
|
3869
|
+
vowel = hslider("v:vocal/h:[1]otherParams/[1]vowel
|
|
3870
|
+
[style:knob][midi:ctrl 1]",0,0,4,0.01) : si.smoo;
|
|
3871
|
+
vibratoFreq = hslider("v:vocal/h:[1]otherParams/[3]vibratoFreq[style:knob]
|
|
3872
|
+
",6,1,10,0.01);
|
|
3873
|
+
vibratoGain = hslider("v:vocal/h:[1]otherParams/[4]vibratoGain[style:knob]
|
|
3874
|
+
",0.5,0,1,0.01)*0.1;
|
|
3875
|
+
outGain = hslider("v:vocal/h:[1]otherParams/[5]outGain[style:knob]
|
|
3876
|
+
",0.5,0,1,0.01);
|
|
3877
|
+
t = button("v:vocal/[2]gate");
|
|
3878
|
+
|
|
3879
|
+
gate = t+s : min(1);
|
|
3880
|
+
freq2 = freq1*bend*(os.osc(vibratoFreq)*vibratoGain+1);
|
|
3881
|
+
envelope = gate*gain*corrFactor : si.smooth(ba.tau2pole(envAttack));
|
|
3882
|
+
};
|
|
3883
|
+
|
|
3884
|
+
|
|
3885
|
+
//-------`(pm.)SFFormantModelBP_ui_MIDI`----------
|
|
3886
|
+
// Ready-to-use MIDI-controllable source-filter vocal synthesizer.
|
|
3887
|
+
//
|
|
3888
|
+
// #### Usage
|
|
3889
|
+
//
|
|
3890
|
+
// ```
|
|
3891
|
+
// SFFormantModelBP_ui_MIDI : _
|
|
3892
|
+
// ```
|
|
3893
|
+
//----------------------------------
|
|
3894
|
+
SFFormantModelBP_ui_MIDI = SFFormantModelBP(voiceType,vowel,fricative,freq2,envelope)*outGain
|
|
3895
|
+
with{
|
|
3896
|
+
freq1 = hslider("v:vocal/h:[0]midi/[0]freq[style:knob]",440,50,1000,0.01);
|
|
3897
|
+
bend = ba.semi2ratio(hslider("v:vocal/h:[0]midi/[1]bend[hidden:1][midi:pitchwheel]
|
|
3898
|
+
[style:knob]",0,-2,2,0.01)) : si.polySmooth(gate,0.999,1);
|
|
3899
|
+
gain = hslider("v:vocal/h:[0]midi/[2]gain[style:knob]
|
|
3900
|
+
",0.9,0,1,0.01);
|
|
3901
|
+
envAttack = hslider("v:vocal/h:[0]midi/[3]envAttack[style:knob]
|
|
3902
|
+
",10,0,30,0.01)*0.001;
|
|
3903
|
+
s = hslider("v:vocal/h:[0]midi/[4]sustain[hidden:1][midi:ctrl 64]
|
|
3904
|
+
[style:knob]",0,0,1,1);
|
|
3905
|
+
voiceType = hslider("v:vocal/h:[1]otherParams/[0]voiceType
|
|
3906
|
+
[style:knob]",0,0,4,1);
|
|
3907
|
+
vowel = hslider("v:vocal/h:[1]otherParams/[1]vowel
|
|
3908
|
+
[style:knob][midi:ctrl 1]",0,0,4,0.01) : si.smoo;
|
|
3909
|
+
fricative = hslider("v:vocal/h:[1]otherParams/[2]fricative
|
|
3910
|
+
[style:knob]",0,0,1,0.01) : si.smoo;
|
|
3911
|
+
vibratoFreq = hslider("v:vocal/h:[1]otherParams/[3]vibratoFreq[style:knob]
|
|
3912
|
+
",6,1,10,0.01);
|
|
3913
|
+
vibratoGain = hslider("v:vocal/h:[1]otherParams/[4]vibratoGain[style:knob]
|
|
3914
|
+
",0.5,0,1,0.01)*0.1;
|
|
3915
|
+
outGain = hslider("v:vocal/h:[1]otherParams/[5]outGain[style:knob]
|
|
3916
|
+
",0.5,0,1,0.01);
|
|
3917
|
+
t = button("v:vocal/[2]gate");
|
|
3918
|
+
|
|
3919
|
+
gate = t+s : min(1);
|
|
3920
|
+
freq2 = freq1*bend*(os.osc(vibratoFreq)*vibratoGain+1);
|
|
3921
|
+
envelope = gate*gain : si.smooth(ba.tau2pole(envAttack));
|
|
3922
|
+
};
|
|
3923
|
+
|
|
3924
|
+
|
|
3925
|
+
//=============================== Misc Functions =========================================
|
|
3926
|
+
// Various miscellaneous functions.
|
|
3927
|
+
//========================================================================================
|
|
3928
|
+
|
|
3929
|
+
//-------`(pm.)allpassNL`--------------
|
|
3930
|
+
// Bidirectional block adding nonlinearities in both directions in a chain.
|
|
3931
|
+
// Nonlinearities are created by modulating the coefficients of a passive
|
|
3932
|
+
// allpass filter by the signal it is processing.
|
|
3933
|
+
//
|
|
3934
|
+
// #### Usage
|
|
3935
|
+
//
|
|
3936
|
+
// ```
|
|
3937
|
+
// chain(... : allpassNL(nonlinearity) : ...)
|
|
3938
|
+
// ```
|
|
3939
|
+
//
|
|
3940
|
+
// Where:
|
|
3941
|
+
//
|
|
3942
|
+
// * `nonlinearity`: amount of nonlinearity to be added (0-1)
|
|
3943
|
+
//--------------------------------------
|
|
3944
|
+
allpassNL(nonlinearity) = par(i,2,nlf),_
|
|
3945
|
+
with{
|
|
3946
|
+
nlf = _ <: fi.allpassn(2,par(i,2,*(nonlinearity)*ma.PI));
|
|
3947
|
+
};
|
|
3948
|
+
|
|
3949
|
+
|
|
3950
|
+
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
3951
|
+
// UNCATEGORIZED FUNCTIONS (TODO)
|
|
3952
|
+
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
3953
|
+
|
|
3954
|
+
//-------`(pm).modalModel`--------------
|
|
3955
|
+
//
|
|
3956
|
+
// Implement multiple resonance modes using resonant bandpass filters.
|
|
3957
|
+
//
|
|
3958
|
+
// #### Usage
|
|
3959
|
+
//
|
|
3960
|
+
// ```
|
|
3961
|
+
// _ : modalModel(n, freqs, t60s, gains) : _
|
|
3962
|
+
// ```
|
|
3963
|
+
//
|
|
3964
|
+
// Where:
|
|
3965
|
+
//
|
|
3966
|
+
// * `n`: number of given modes
|
|
3967
|
+
// * `freqs` : list of filter center freqencies
|
|
3968
|
+
// * `t60s` : list of mode resonance durations (in seconds)
|
|
3969
|
+
// * `gains` : list of mode gains (0-1)
|
|
3970
|
+
//
|
|
3971
|
+
// For example, to generate a model with 2 modes (440 Hz and 660 Hz, a
|
|
3972
|
+
// fifth) where the higher one decays faster and is attenuated:
|
|
3973
|
+
//
|
|
3974
|
+
// ```
|
|
3975
|
+
// os.impulse : modalModel(2, (440, 660),
|
|
3976
|
+
// (0.5, 0.25),
|
|
3977
|
+
// (ba.db2linear(-1), ba.db2linear(-6)) : _
|
|
3978
|
+
// ```
|
|
3979
|
+
//
|
|
3980
|
+
// Further reading: [Grumiaux et. al., 2017:
|
|
3981
|
+
// Impulse-Response and CAD-Model-Based Physical Modeling in
|
|
3982
|
+
// Faust](https://raw.githubusercontent.com/grame-cncm/faust/master-dev/tools/physicalModeling/ir2dsp/lacPaper2017.pdf)
|
|
3983
|
+
//
|
|
3984
|
+
//--------------------------------------
|
|
3985
|
+
modalModel(n,modeFreqs,modeRes,modeGains) = _ <: par(i,n,modeFilter(freqs(i),res(i),gain(i))) :> _
|
|
3986
|
+
with{
|
|
3987
|
+
freqs(i) = ba.take(i+1,modeFreqs);
|
|
3988
|
+
res(i) = ba.take(i+1,modeRes);
|
|
3989
|
+
gain(i) = ba.take(i+1,modeGains);
|
|
3990
|
+
};
|