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,1710 @@
|
|
|
1
|
+
//////////////////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// WARNING: Deprecated Library!!
|
|
3
|
+
// Read the README file in /libraries for more information
|
|
4
|
+
//////////////////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
|
|
6
|
+
// filter.lib - digital filters of various types useful in audio and beyond
|
|
7
|
+
|
|
8
|
+
declare name "Faust Filter Library";
|
|
9
|
+
declare author "Julius O. Smith (jos at ccrma.stanford.edu)";
|
|
10
|
+
declare copyright "Julius O. Smith III";
|
|
11
|
+
declare version "1.29";
|
|
12
|
+
declare license "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license)
|
|
13
|
+
declare reference "https://ccrma.stanford.edu/~jos/filters/";
|
|
14
|
+
declare deprecated "This library is deprecated and is not maintained anymore. It will be removed in August 2017.";
|
|
15
|
+
|
|
16
|
+
import("music.lib"); // delay, frac and, from math.lib, SR and PI
|
|
17
|
+
|
|
18
|
+
//---------------------- zero(z) --------------------------
|
|
19
|
+
// z = location of zero along real axis in z-plane
|
|
20
|
+
// Difference equation: y(n) = x(n) - z * x(n-1)
|
|
21
|
+
// Reference: https://ccrma.stanford.edu/~jos/filters/One_Zero.html
|
|
22
|
+
|
|
23
|
+
zero(z) = _ <: _,mem : _,*(z) : -;
|
|
24
|
+
|
|
25
|
+
//------------------------ pole(p) ---------------------------
|
|
26
|
+
// p = pole location = feedback coefficient
|
|
27
|
+
// Could also be called a "leaky integrator".
|
|
28
|
+
// Difference equation: y(n) = x(n) + p * y(n-1)
|
|
29
|
+
// Reference: https://ccrma.stanford.edu/~jos/filters/One_Pole.html
|
|
30
|
+
|
|
31
|
+
pole(p) = + ~ *(p);
|
|
32
|
+
|
|
33
|
+
//---------------------- integrator --------------------------
|
|
34
|
+
// pole(1) [implemented separately for block-diagram clarity]
|
|
35
|
+
|
|
36
|
+
integrator = + ~ _ ;
|
|
37
|
+
|
|
38
|
+
//------------------ tau2pole, pole2tau ----------------------
|
|
39
|
+
// tau2pole(tau) returns a real pole giving exponential decay with
|
|
40
|
+
// tau = time-constant in seconds
|
|
41
|
+
// Note that t60 (time to decay 60 dB) is ~6.91 time constants.
|
|
42
|
+
// pole2tau(pole) returns the time-constant, in seconds,
|
|
43
|
+
// corresponding to the given real, positive pole in (0,1).
|
|
44
|
+
|
|
45
|
+
tau2pole(tau) = if(tau>0, exp(-1.0/(tau*SR)), 0.0);
|
|
46
|
+
pole2tau(pole) = if(pole<1.0, -1.0/(log(pole)*SR), 1.0e10);
|
|
47
|
+
|
|
48
|
+
//---------------------- smooth(s) --------------------------
|
|
49
|
+
// Exponential smoothing by a unity-dc-gain one-pole lowpass
|
|
50
|
+
//
|
|
51
|
+
// USAGE: smooth(tau2pole(tau)), where
|
|
52
|
+
// tau = desired smoothing time constant in seconds,
|
|
53
|
+
// or
|
|
54
|
+
// smooth(s), where s = smoothness between 0 and 1.
|
|
55
|
+
// s=0 for no smoothing
|
|
56
|
+
// s=0.999 is "very smooth"
|
|
57
|
+
// s>1 is unstable, and s=1 yields the zero signal for all inputs.
|
|
58
|
+
// The exponential time-constant is approximately
|
|
59
|
+
// 1/(1-s) samples, when s is close to (but less than) 1.
|
|
60
|
+
// Reference:
|
|
61
|
+
// https://ccrma.stanford.edu/~jos/mdft/Convolution_Example_2_ADSR.html
|
|
62
|
+
|
|
63
|
+
smooth(s) = *(1.0 - s) : + ~ *(s);
|
|
64
|
+
|
|
65
|
+
//------------------- dcblockerat(fb) -----------------------
|
|
66
|
+
// fb = "break frequency" in Hz, i.e., -3 dB gain frequency.
|
|
67
|
+
// The amplitude response is substantially flat above fb,
|
|
68
|
+
// and sloped at about +6 dB/octave below fb.
|
|
69
|
+
// Derived from the analog transfer function
|
|
70
|
+
// H(s) = s / (s + 2*PI*fb)
|
|
71
|
+
// by the low-frequency-matching bilinear transform method
|
|
72
|
+
// (i.e., the standard frequency-scaling constant 2*SR).
|
|
73
|
+
// Reference:
|
|
74
|
+
// https://ccrma.stanford.edu/~jos/pasp/Bilinear_Transformation.html
|
|
75
|
+
|
|
76
|
+
dcblockerat(fb) = *(b0) : zero(1) : pole(p)
|
|
77
|
+
with {
|
|
78
|
+
wn = PI*fb/SR;
|
|
79
|
+
b0 = 1.0 / (1 + wn);
|
|
80
|
+
p = (1 - wn) * b0;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
//---------------------- dcblocker --------------------------
|
|
84
|
+
// Default dc blocker has -3dB point near 35 Hz (at 44.1 kHz)
|
|
85
|
+
// and high-frequency gain near 1.0025 (due to no scaling)
|
|
86
|
+
//
|
|
87
|
+
dcblocker = zero(1) : pole(0.995);
|
|
88
|
+
|
|
89
|
+
//------------ notchw(width,freq), notch(freq) --------------
|
|
90
|
+
// width = "notch width" in Hz (approximate)
|
|
91
|
+
// freq = "notch frequency" in Hz
|
|
92
|
+
// Reference:
|
|
93
|
+
// https://ccrma.stanford.edu/~jos/pasp/Phasing_2nd_Order_Allpass_Filters.html
|
|
94
|
+
|
|
95
|
+
notchw(width,freq) = tf2(b0,b1,b2,a1,a2)
|
|
96
|
+
with {
|
|
97
|
+
fb = 0.5*width; // First design a dcblockerat(width/2)
|
|
98
|
+
wn = PI*fb/SR;
|
|
99
|
+
b0db = 1.0 / (1 + wn);
|
|
100
|
+
p = (1 - wn) * b0db; // This is our pole radius.
|
|
101
|
+
// Now place unit-circle zeros at desired angles:
|
|
102
|
+
tn = 2*PI*freq/SR;
|
|
103
|
+
a2 = p * p;
|
|
104
|
+
a2p1 = 1+a2;
|
|
105
|
+
a1 = -a2p1*cos(tn);
|
|
106
|
+
b1 = a1;
|
|
107
|
+
b0 = 0.5*a2p1;
|
|
108
|
+
b2 = b0;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
//---------------------------- latch(c) --------------------------------
|
|
112
|
+
// Latch input on positive-going transition of "clock" ("sample-and-hold")
|
|
113
|
+
//
|
|
114
|
+
// USAGE:
|
|
115
|
+
// _ : latch(clocksig) : _
|
|
116
|
+
|
|
117
|
+
latch(c,x) = x * s : + ~ *(1-s) with { s = ((c'<=0)&(c>0)); };
|
|
118
|
+
|
|
119
|
+
//========================= Comb Filters ===============================
|
|
120
|
+
|
|
121
|
+
//----------------------- ff_comb, ff_fcomb ----------------------------
|
|
122
|
+
// Feed-Forward Comb Filter
|
|
123
|
+
//
|
|
124
|
+
// USAGE:
|
|
125
|
+
// _ : ff_comb(maxdel,intdel,b0,bM) : _
|
|
126
|
+
// _ : ff_fcomb(maxdel,del,b0,bM) : _
|
|
127
|
+
// where
|
|
128
|
+
// maxdel = maximum delay (a power of 2)
|
|
129
|
+
// intdel = current (integer) comb-filter delay between 0 and maxdel
|
|
130
|
+
// del = current (float) comb-filter delay between 0 and maxdel
|
|
131
|
+
// b0 = gain applied to delay-line input
|
|
132
|
+
// bM = gain applied to delay-line output and then summed with input
|
|
133
|
+
//
|
|
134
|
+
// Note that ff_comb requires integer delays (uses delay() internally)
|
|
135
|
+
// while ff_fcomb takes floating-point delays (uses fdelay() internally).
|
|
136
|
+
//
|
|
137
|
+
// REFERENCE:
|
|
138
|
+
// https://ccrma.stanford.edu/~jos/pasp/Feedforward_Comb_Filters.html
|
|
139
|
+
|
|
140
|
+
ff_comb (maxdel,M,b0,bM) = _ <: *(b0), bM * delay(maxdel,M) : + ;
|
|
141
|
+
ff_fcomb(maxdel,M,b0,bM) = _ <: *(b0), bM * fdelay(maxdel,M) : + ;
|
|
142
|
+
|
|
143
|
+
// Typical special case:
|
|
144
|
+
ffcombfilter(maxdel,del,g) = ff_comb(maxdel,del,1,g);
|
|
145
|
+
|
|
146
|
+
//----------------------- fb_comb, fb_fcomb, rev1 -----------------------
|
|
147
|
+
// Feed-Back Comb Filter
|
|
148
|
+
//
|
|
149
|
+
// USAGE:
|
|
150
|
+
// _ : fb_comb(maxdel,intdel,b0,aN) : _
|
|
151
|
+
// _ : fb_fcomb(maxdel,del,b0,aN) : _
|
|
152
|
+
// _ : rev1(maxdel,del,-aN) : _
|
|
153
|
+
// where
|
|
154
|
+
// maxdel = maximum delay (a power of 2)
|
|
155
|
+
// intdel = current (integer) comb-filter delay between 0 and maxdel
|
|
156
|
+
// del = current (float) comb-filter delay between 0 and maxdel
|
|
157
|
+
// b0 = gain applied to delay-line input and forwarded to output
|
|
158
|
+
// aN = minus the gain applied to delay-line output before
|
|
159
|
+
// summing with the input and feeding to the delay line
|
|
160
|
+
//
|
|
161
|
+
// Reference:
|
|
162
|
+
// https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html
|
|
163
|
+
|
|
164
|
+
fb_comb (maxdel,N,b0,aN) = (+ <: delay(maxdel,N-1),_) ~ *(-aN) : !,*(b0):mem;
|
|
165
|
+
fb_fcomb(maxdel,N,b0,aN) = (+ <: fdelay(maxdel,float(N)-1.0),_) ~ *(-aN) : !,*(b0):mem;
|
|
166
|
+
|
|
167
|
+
// The "rev1 section" dates back to the 1960s in computer-music reverberation.
|
|
168
|
+
// See the jcrev and brassrev in effect.lib for usage examples.
|
|
169
|
+
rev1(maxdel,N,g) = fb_comb (maxdel,N,1,-g);
|
|
170
|
+
|
|
171
|
+
// Typical special case:
|
|
172
|
+
fbcombfilter(maxdel,intdel,g) = (+ : delay(maxdel,intdel)) ~ *(g);
|
|
173
|
+
ffbcombfilter(maxdel,del,g) = (+ : fdelay(maxdel,del)) ~ *(g);
|
|
174
|
+
|
|
175
|
+
//------------------- allpass_comb, allpass_fcomb, rev2 -----------------
|
|
176
|
+
// Schroeder Allpass Comb Filter
|
|
177
|
+
//
|
|
178
|
+
// USAGE:
|
|
179
|
+
// _ : allpass_comb (maxdel,intdel,aN) : _
|
|
180
|
+
// _ : allpass_fcomb(maxdel,del,aN) : _
|
|
181
|
+
// _ : rev2(maxdel,del,-aN) : _
|
|
182
|
+
// where
|
|
183
|
+
// maxdel = maximum delay (a power of 2)
|
|
184
|
+
// intdel = current (integer) comb-filter delay between 0 and maxdel
|
|
185
|
+
// del = current (float) comb-filter delay between 0 and maxdel
|
|
186
|
+
// aN = minus the feedback gain
|
|
187
|
+
//
|
|
188
|
+
// Note that allpass_comb(maxlen,len,aN) =
|
|
189
|
+
// ff_comb(maxlen,len,aN,1) :
|
|
190
|
+
// fb_comb(maxlen,len-1,1,aN);
|
|
191
|
+
// which is a direct-form-1 implementation, requiring two delay lines.
|
|
192
|
+
// The implementation here is direct-form-2 requiring only one delay line.
|
|
193
|
+
//
|
|
194
|
+
// REFERENCES:
|
|
195
|
+
// https://ccrma.stanford.edu/~jos/pasp/Allpass_Two_Combs.html
|
|
196
|
+
// https://ccrma.stanford.edu/~jos/pasp/Schroeder_Allpass_Sections.html
|
|
197
|
+
// https://ccrma.stanford.edu/~jos/filters/Four_Direct_Forms.html
|
|
198
|
+
|
|
199
|
+
allpass_comb(maxdel,N,aN) = (+ <:
|
|
200
|
+
delay(maxdel,N-1),*(aN)) ~ *(-aN)
|
|
201
|
+
: mem,_ : + ;
|
|
202
|
+
|
|
203
|
+
allpass_fcomb(maxdel,N,aN) = (+ <: fdelay(maxdel,N-1),*(aN)) ~ *(-aN) : mem,_ : + ;
|
|
204
|
+
allpass_fcomb5(maxdel,N,aN) = (+ <: fdelay5(maxdel,N-1),*(aN)) ~ *(-aN) : mem,_ : + ;
|
|
205
|
+
allpass_fcomb1a(maxdel,N,aN) = (+ <: fdelay1a(maxdel,N-1),*(aN)) ~ *(-aN) : mem,_ : + ;
|
|
206
|
+
// Interpolation helps - look at an fft of faust2octave on
|
|
207
|
+
// 1-1' <: allpass_fcomb(1024,10.5,0.95), allpass_fcomb5(1024,10.5,0.95);
|
|
208
|
+
|
|
209
|
+
// The "rev2 section" dates back to the 1960s in computer-music reverberation:
|
|
210
|
+
rev2(maxlen,len,g) = allpass_comb(maxlen,len,-g);
|
|
211
|
+
|
|
212
|
+
//================ Direct-Form Digital Filter Sections ================
|
|
213
|
+
|
|
214
|
+
// Specified by transfer-function polynomials B(z)/A(z) as in matlab
|
|
215
|
+
|
|
216
|
+
//---------------------------- iir (tfN) -------------------------------
|
|
217
|
+
// Nth-order Infinite-Impulse-Response (IIR) digital filter,
|
|
218
|
+
// implemented in terms of the Transfer-Function (TF) coefficients.
|
|
219
|
+
// Such filter structures are termed "direct form".
|
|
220
|
+
//
|
|
221
|
+
// USAGE:
|
|
222
|
+
// _ : iir(bcoeffs,acoeffs) : _
|
|
223
|
+
// where
|
|
224
|
+
// order = filter order (int) = max(#poles,#zeros)
|
|
225
|
+
// bcoeffs = (b0,b1,...,b_order) = TF numerator coefficients
|
|
226
|
+
// acoeffs = (a1,...,a_order) = TF denominator coeffs (a0=1)
|
|
227
|
+
//
|
|
228
|
+
// REFERENCE:
|
|
229
|
+
// https://ccrma.stanford.edu/~jos/filters/Four_Direct_Forms.html
|
|
230
|
+
|
|
231
|
+
iir(bv,av) = sub ~ fir(av) : fir(bv);
|
|
232
|
+
|
|
233
|
+
//----------------------------- sub ---------------------------------
|
|
234
|
+
sub(x,y) = y-x; // move to math.lib?
|
|
235
|
+
|
|
236
|
+
//----------------------------- fir ---------------------------------
|
|
237
|
+
// FIR filter (convolution of FIR filter coefficients with a signal)
|
|
238
|
+
//
|
|
239
|
+
// USAGE:
|
|
240
|
+
// _ : fir(bv) : _
|
|
241
|
+
// where bv = b0,b1,...,bn is a parallel bank of coefficient signals.
|
|
242
|
+
// NOTE: bv is processed using pattern-matching at compile time,
|
|
243
|
+
// so it must have this normal form (parallel signals).
|
|
244
|
+
// EXAMPLE: Smoothing white noise with a five-point moving average:
|
|
245
|
+
// bv = .2,.2,.2,.2,.2;
|
|
246
|
+
// process = noise : fir(bv);
|
|
247
|
+
// EQUIVALENT (note double parens):
|
|
248
|
+
// process = noise : fir((.2,.2,.2,.2,.2));
|
|
249
|
+
|
|
250
|
+
//fir(bv) = conv(bv);
|
|
251
|
+
fir((b0,bv)) = _ <: *(b0), R(1,bv) :> _ with {
|
|
252
|
+
R(n,(bn,bv)) = (@(n):*(bn)), R(n+1,bv);
|
|
253
|
+
R(n, bn) = (@(n):*(bn)); };
|
|
254
|
+
fir(b0) = *(b0);
|
|
255
|
+
|
|
256
|
+
//--------------------------- conv, convN -------------------------------
|
|
257
|
+
// Convolution of input signal with given coefficients
|
|
258
|
+
//
|
|
259
|
+
// USAGE:
|
|
260
|
+
// _ : conv((k1,k2,k3,...,kN)) : _; // Argument = one signal bank
|
|
261
|
+
// _ : convN(N,(k1,k2,k3,...)) : _; // Useful when N < count((k1,...))
|
|
262
|
+
|
|
263
|
+
//convN(N,kv,x) = sum(i,N,take(i+1,kv) * x@i); // take() defined in math.lib
|
|
264
|
+
convN(N,kv) = sum(i,N, @(i)*take(i+1,kv)); // take() defined in math.lib
|
|
265
|
+
|
|
266
|
+
//conv(kv,x) = sum(i,count(kv),take(i+1,kv) * x@i); // count() from math.lib
|
|
267
|
+
conv(kv) = fir(kv);
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
// Named special cases:
|
|
271
|
+
//----------------------------- tf1, tf2 ---------------------------------
|
|
272
|
+
// tfN = N'th-order direct-form digital filter
|
|
273
|
+
tf1(b0,b1,a1) = _ <: *(b0), (mem : *(b1)) :> + ~ *(0-a1);
|
|
274
|
+
tf2(b0,b1,b2,a1,a2) = iir((b0,b1,b2),(a1,a2)); // cf. TF2 in music.lib)
|
|
275
|
+
// tf2 is a variant of tf22 below with duplicated mems
|
|
276
|
+
tf3(b0,b1,b2,b3,a1,a2,a3) = iir((b0,b1,b2,b3),(a1,a2,a3));
|
|
277
|
+
|
|
278
|
+
//=============== Direct-Form second-order biquad sections ================
|
|
279
|
+
// REFERENCE: https://ccrma.stanford.edu/~jos/filters/Four_Direct_Forms.html
|
|
280
|
+
|
|
281
|
+
//---------------------- tf21, tf21t, tf22, tf22t ------------------------
|
|
282
|
+
tf21(b0,b1,b2,a1,a2) = // tf2, direct-form 1:
|
|
283
|
+
_ <:(mem<:((mem:*(b2)),*(b1))),*(b0) :>_
|
|
284
|
+
: ((_,_,_:>_) ~(_<:*(-a1),(mem:*(-a2))));
|
|
285
|
+
tf22(b0,b1,b2,a1,a2) = // tf2, direct-form 2:
|
|
286
|
+
_ : (((_,_,_:>_)~*(-a1)<:mem,*(b0))~*(-a2))
|
|
287
|
+
: (_<:mem,*(b1)),_ : *(b2),_,_ :> _;
|
|
288
|
+
tf22t(b0,b1,b2,a1,a2) = // tf2, direct-form 2 transposed:
|
|
289
|
+
_ : (_,_,(_ <: *(b2)',*(b1)',*(b0))
|
|
290
|
+
: _,+',_,_ :> _)~*(-a1)~*(-a2) : _;
|
|
291
|
+
tf21t(b0,b1,b2,a1,a2) = // tf2, direct-form 1 transposed:
|
|
292
|
+
tf22t(1,0,0,a1,a2) : tf22t(b0,b1,b2,0,0); // or write it out if you want
|
|
293
|
+
|
|
294
|
+
//===================== Ladder/Lattice Digital Filters ======================
|
|
295
|
+
// Ladder and lattice digital filters generally have superior numerical
|
|
296
|
+
// properties relative to direct-form digital filters. They can be derived
|
|
297
|
+
// from digital waveguide filters, which gives them a physical interpretation.
|
|
298
|
+
|
|
299
|
+
// REFERENCES:
|
|
300
|
+
// F. Itakura and S. Saito: "Digital Filtering Techniques for Speech Analysis and Synthesis",
|
|
301
|
+
// 7th Int. Cong. Acoustics, Budapest, 25 C 1, 1971.
|
|
302
|
+
// J. D. Markel and A. H. Gray: Linear Prediction of Speech, New York: Springer Verlag, 1976.
|
|
303
|
+
// https://ccrma.stanford.edu/~jos/pasp/Conventional_Ladder_Filters.html
|
|
304
|
+
|
|
305
|
+
//------------------------- block, crossn,crossn1 -----------------------------
|
|
306
|
+
// signal block/crossing utilities
|
|
307
|
+
// (move to math.lib?)
|
|
308
|
+
|
|
309
|
+
// block - terminate n signals (goes with bus(n) in math.lib)
|
|
310
|
+
block(n) = par(i,n,!);
|
|
311
|
+
|
|
312
|
+
// crossnn - cross two bus(n)s:
|
|
313
|
+
crossnn(n) = bus(n),bus(n) <: block(n),bus(n),bus(n),block(n);
|
|
314
|
+
|
|
315
|
+
// crossn1 - cross bus(n) and bus(1):
|
|
316
|
+
crossn1(n) = bus(n),(bus(1)<:bus(n)) <: block(n),bus(n),bus(n),block(n):bus(1),block(n-1),bus(n);
|
|
317
|
+
|
|
318
|
+
//------------------------------- av2sv -----------------------------------
|
|
319
|
+
// Compute reflection coefficients sv from transfer-function denominator av
|
|
320
|
+
//
|
|
321
|
+
// USAGE:
|
|
322
|
+
// sv = av2sv(av)
|
|
323
|
+
// where
|
|
324
|
+
// av = parallel signal bank a1,...,aN
|
|
325
|
+
// sv = parallel signal bank s1,...,sN
|
|
326
|
+
// where si = ith reflection coefficient, and
|
|
327
|
+
// ai = coefficient of z^(-i) in the filter
|
|
328
|
+
// transfer-function denominator A(z).
|
|
329
|
+
//
|
|
330
|
+
// REFERENCE:
|
|
331
|
+
// https://ccrma.stanford.edu/~jos/filters/Step_Down_Procedure.html
|
|
332
|
+
// (where reflection coefficients are denoted by k rather than s).
|
|
333
|
+
|
|
334
|
+
av2sv(av) = par(i,M,s(i+1)) with {
|
|
335
|
+
M = count(av);
|
|
336
|
+
s(m) = sr(M-m+1); // m=1..M
|
|
337
|
+
sr(m) = Ari(m,M-m+1); // s_{M-1-m}
|
|
338
|
+
Ari(m,i) = take(i+1,Ar(m-1));
|
|
339
|
+
//step-down recursion for lattice/ladder digital filters:
|
|
340
|
+
Ar(0) = (1,av); // Ar(m) is order M-m (i.e. "reverse-indexed")
|
|
341
|
+
Ar(m) = 1,par(i,M-m, (Ari(m,i+1) - sr(m)*Ari(m,M-m-i))/(1-sr(m)*sr(m)));
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
//---------------------------- bvav2nuv --------------------------------
|
|
345
|
+
// Compute lattice tap coefficients from transfer-function coefficients
|
|
346
|
+
//
|
|
347
|
+
// USAGE:
|
|
348
|
+
// nuv = bvav2nuv(bv,av)
|
|
349
|
+
// where
|
|
350
|
+
// av = parallel signal bank a1,...,aN
|
|
351
|
+
// bv = parallel signal bank b0,b1,...,aN
|
|
352
|
+
// nuv = parallel signal bank nu1,...,nuN
|
|
353
|
+
// where nui is the i'th tap coefficient,
|
|
354
|
+
// bi is the coefficient of z^(-i) in the filter numerator,
|
|
355
|
+
// ai is the coefficient of z^(-i) in the filter denominator
|
|
356
|
+
|
|
357
|
+
bvav2nuv(bv,av) = par(m,M+1,nu(m)) with {
|
|
358
|
+
M = count(av);
|
|
359
|
+
nu(m) = take(m+1,Pr(M-m)); // m=0..M
|
|
360
|
+
// lattice/ladder tap parameters:
|
|
361
|
+
Pr(0) = bv; // Pr(m) is order M-m, 'r' means "reversed"
|
|
362
|
+
Pr(m) = par(i,M-m+1, (Pri(m,i) - nu(M-m+1)*Ari(m,M-m-i+1)));
|
|
363
|
+
Pri(m,i) = take(i+1,Pr(m-1));
|
|
364
|
+
Ari(m,i) = take(i+1,Ar(m-1));
|
|
365
|
+
//step-down recursion for lattice/ladder digital filters:
|
|
366
|
+
Ar(0) = (1,av); // Ar(m) is order M-m (recursion index must start at constant)
|
|
367
|
+
Ar(m) = 1,par(i,M-m, (Ari(m,i+1) - sr(m)*Ari(m,M-m-i))/(1-sr(m)*sr(m)));
|
|
368
|
+
sr(m) = Ari(m,M-m+1); // s_{M-1-m}
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
//--------------------------- iir_lat2, allpassnt -----------------------
|
|
372
|
+
|
|
373
|
+
iir_lat2(bv,av) = allpassnt(M,sv) : sum(i,M+1,*(take(M-i+1,tg)))
|
|
374
|
+
with {
|
|
375
|
+
M = count(av);
|
|
376
|
+
sv = av2sv(av); // sv = vector of sin(theta) reflection coefficients
|
|
377
|
+
tg = bvav2nuv(bv,av); // tg = vector of tap gains
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
// two-multiply lattice allpass (nested order-1 direct-form-ii allpasses):
|
|
381
|
+
allpassnt(0,sv) = _;
|
|
382
|
+
allpassnt(n,sv) =
|
|
383
|
+
//0: x <: ((+ <: (allpassnt(n-1,sv)),*(s))~(*(-s))) : _',_ :+
|
|
384
|
+
_ : ((+ <: (allpassnt(n-1,sv),*(s)))~*(-s)) : fsec(n)
|
|
385
|
+
with {
|
|
386
|
+
fsec(1) = crossnn(1) : _, (_<:mem,_) : +,_;
|
|
387
|
+
fsec(n) = crossn1(n) : _, (_<:mem,_),par(i,n-1,_) : +, par(i,n,_);
|
|
388
|
+
innertaps(n) = par(i,n,_);
|
|
389
|
+
s = take(n,sv); // reflection coefficient s = sin(theta)
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
//------------------------------- iir_kl, allpassnklt -------------------------
|
|
393
|
+
iir_kl(bv,av) = allpassnklt(M,sv) : sum(i,M+1,*(tghr(i)))
|
|
394
|
+
with {
|
|
395
|
+
M = count(av);
|
|
396
|
+
sv = av2sv(av); // sv = vector of sin(theta) reflection coefficients
|
|
397
|
+
tg = bvav2nuv(bv,av); // tg = vector of tap gains for 2mul case
|
|
398
|
+
tgr(i) = take(M+1-i,tg);
|
|
399
|
+
tghr(n) = tgr(n)/pi(n);
|
|
400
|
+
pi(0) = 1;
|
|
401
|
+
pi(n) = pi(n-1)*(1+take(M-n+1,sv)); // all sign parameters '+'
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
// Kelly-Lochbaum ladder allpass with tap lines:
|
|
405
|
+
allpassnklt(0,sv) = _;
|
|
406
|
+
allpassnklt(n,sv) = _ <: *(s),(*(1+s) : (+
|
|
407
|
+
: allpassnklt(n-1,sv))~(*(-s))) : fsec(n)
|
|
408
|
+
with {
|
|
409
|
+
fsec(1) = _, (_<:mem*(1-s),_) : sumandtaps(n);
|
|
410
|
+
fsec(n) = _, (_<:mem*(1-s),_), par(i,n-1,_) : sumandtaps(n);
|
|
411
|
+
s = take(n,sv);
|
|
412
|
+
sumandtaps(n) = +,par(i,n,_);
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
//------------------------------- iir_lat1, allpassn1mt -------------------------
|
|
417
|
+
iir_lat1(bv,av) = allpassn1mt(M,sv) : sum(i,M+1,*(tghr(i+1)))
|
|
418
|
+
with {
|
|
419
|
+
M = count(av);
|
|
420
|
+
sv = av2sv(av); // sv = vector of sin(theta) reflection coefficients
|
|
421
|
+
tg = bvav2nuv(bv,av); // tg = vector of tap gains
|
|
422
|
+
tgr(i) = take(M+2-i,tg); // i=1..M+1 (for "takability")
|
|
423
|
+
tghr(n)=tgr(n)/pi(n);
|
|
424
|
+
pi(1) = 1;
|
|
425
|
+
pi(n) = pi(n-1)*(1+take(M-n+2,sv)); // all sign parameters '+'
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
// one-multiply lattice allpass with tap lines:
|
|
429
|
+
allpassn1mt(0,sv) = _;
|
|
430
|
+
allpassn1mt(n,sv)= _ <: _,_ : ((+:*(s) <: _,_),_ : _,+ : crossnn(1)
|
|
431
|
+
: allpassn1mt(n-1,sv),_)~(*(-1)) : fsec(n)
|
|
432
|
+
with {
|
|
433
|
+
//0: fsec(n) = _',_ : +
|
|
434
|
+
fsec(1) = crossnn(1) : _, (_<:mem,_) : +,_;
|
|
435
|
+
fsec(n) = crossn1(n) : _, (_<:mem,_),par(i,n-1,_) : +, par(i,n,_);
|
|
436
|
+
innertaps(n) = par(i,n,_);
|
|
437
|
+
s = take(n,sv); // reflection coefficient s = sin(theta)
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
//------------------------------- iir_nl, allpassnnlt -------------------------
|
|
441
|
+
// Normalized ladder filter
|
|
442
|
+
//
|
|
443
|
+
// REFERENCES:
|
|
444
|
+
// J. D. Markel and A. H. Gray, Linear Prediction of Speech, New York: Springer Verlag, 1976.
|
|
445
|
+
// https://ccrma.stanford.edu/~jos/pasp/Normalized_Scattering_Junctions.html
|
|
446
|
+
|
|
447
|
+
iir_nl(bv,av) = allpassnnlt(M,sv) : sum(i,M+1,*(tghr(i)))
|
|
448
|
+
with {
|
|
449
|
+
M = count(av);
|
|
450
|
+
sv = av2sv(av); // sv = vector of sin(theta) reflection coefficients
|
|
451
|
+
tg = bvav2nuv(bv,av); // tg = vector of tap gains for 2mul case
|
|
452
|
+
tgr(i) = take(M+1-i,tg);
|
|
453
|
+
tghr(n) = tgr(n)/pi(n);
|
|
454
|
+
pi(0) = 1;
|
|
455
|
+
s(n) = take(M-n+1,sv); // reflection coefficient = sin(theta)
|
|
456
|
+
c(n) = sqrt(max(0,1-s(n)*s(n))); // compiler crashes on sqrt(-)
|
|
457
|
+
pi(n) = pi(n-1)*c(n);
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
// Normalized ladder allpass with tap lines:
|
|
461
|
+
allpassnnlt(0,sv) = _;
|
|
462
|
+
allpassnnlt(n,scl*(sv)) = allpassnnlt(n,par(i,count(sv),scl*(sv(i))));
|
|
463
|
+
allpassnnlt(n,sv) = _ <: *(s),(*(c) : (+
|
|
464
|
+
: allpassnnlt(n-1,sv))~(*(-s))) : fsec(n)
|
|
465
|
+
with {
|
|
466
|
+
fsec(1) = _, (_<:mem*(c),_) : sumandtaps(n);
|
|
467
|
+
fsec(n) = _, (_<:mem*(c),_), par(i,n-1,_) : sumandtaps(n);
|
|
468
|
+
s = take(n,sv);
|
|
469
|
+
c = sqrt(max(0,1-s*s));
|
|
470
|
+
sumandtaps(n) = +,par(i,n,_);
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
//========================= Useful special cases ============================
|
|
474
|
+
|
|
475
|
+
//-------------------------------- tf2np ------------------------------------
|
|
476
|
+
// tf2np - biquad based on a stable second-order Normalized Ladder Filter
|
|
477
|
+
// (more robust to modulation than tf2 and protected against instability)
|
|
478
|
+
tf2np(b0,b1,b2,a1,a2) = allpassnnlt(M,sv) : sum(i,M+1,*(tghr(i)))
|
|
479
|
+
with {
|
|
480
|
+
smax = 0.9999; // maximum reflection-coefficient magnitude allowed
|
|
481
|
+
s2 = max(-smax, min(smax,a2)); // Project both reflection-coefficients
|
|
482
|
+
s1 = max(-smax, min(smax,a1/(1+a2))); // into the defined stability-region.
|
|
483
|
+
sv = (s1,s2); // vector of sin(theta) reflection coefficients
|
|
484
|
+
M = 2;
|
|
485
|
+
nu(2) = b2;
|
|
486
|
+
nu(1) = b1 - b2*a1;
|
|
487
|
+
nu(0) = (b0-b2*a2) - nu(1)*s1;
|
|
488
|
+
tg = (nu(0),nu(1),nu(2));
|
|
489
|
+
tgr(i) = take(M+1-i,tg); // vector of tap gains for 2mul case
|
|
490
|
+
tghr(n) = tgr(n)/pi(n); // apply pi parameters for NLF case
|
|
491
|
+
pi(0) = 1;
|
|
492
|
+
s(n) = take(M-n+1,sv);
|
|
493
|
+
c(n) = sqrt(1-s(n)*s(n));
|
|
494
|
+
pi(n) = pi(n-1)*c(n);
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
//----------------------------- wgr ---------------------------------
|
|
498
|
+
// Second-order transformer-normalized digital waveguide resonator
|
|
499
|
+
// USAGE:
|
|
500
|
+
// _ : wgr(f,r) : _
|
|
501
|
+
// where
|
|
502
|
+
// f = resonance frequency (Hz)
|
|
503
|
+
// r = loss factor for exponential decay
|
|
504
|
+
// (set to 1 to make a numerically stable oscillator)
|
|
505
|
+
//
|
|
506
|
+
// REFERENCES:
|
|
507
|
+
// https://ccrma.stanford.edu/~jos/pasp/Power_Normalized_Waveguide_Filters.html
|
|
508
|
+
// https://ccrma.stanford.edu/~jos/pasp/Digital_Waveguide_Oscillator.html
|
|
509
|
+
//
|
|
510
|
+
wgr(f,r,x) = (*(G),_<:_,((+:*(C))<:_,_),_:+,_,_:+(x),-) ~ cross : _,*(0-gi)
|
|
511
|
+
with {
|
|
512
|
+
C = cos(2*PI*f/SR);
|
|
513
|
+
gi = sqrt(max(0,(1+C)/(1-C))); // compensate amplitude (only needed when
|
|
514
|
+
G = r*(1-1' + gi')/gi; // frequency changes substantially)
|
|
515
|
+
cross = _,_ <: !,_,_,!;
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
//----------------------------- nlf2 --------------------------------
|
|
519
|
+
// Second order normalized digital waveguide resonator
|
|
520
|
+
// USAGE:
|
|
521
|
+
// _ : nlf2(f,r) : _
|
|
522
|
+
// where
|
|
523
|
+
// f = resonance frequency (Hz)
|
|
524
|
+
// r = loss factor for exponential decay
|
|
525
|
+
// (set to 1 to make a sinusoidal oscillator)
|
|
526
|
+
//
|
|
527
|
+
// REFERENCE:
|
|
528
|
+
// https://ccrma.stanford.edu/~jos/pasp/Power_Normalized_Waveguide_Filters.html
|
|
529
|
+
//
|
|
530
|
+
nlf2(f,r,x) = ((_<:_,_),(_<:_,_) : (*(s),*(c),*(c),*(0-s)) :>
|
|
531
|
+
(*(r),+(x))) ~ cross
|
|
532
|
+
with {
|
|
533
|
+
th = 2*PI*f/SR;
|
|
534
|
+
c = cos(th);
|
|
535
|
+
s = sin(th);
|
|
536
|
+
cross = _,_ <: !,_,_,!;
|
|
537
|
+
};
|
|
538
|
+
|
|
539
|
+
//===================== Ladder/Lattice Allpass Filters ======================
|
|
540
|
+
// An allpass filter has gain 1 at every frequency, but variable phase.
|
|
541
|
+
// Ladder/lattice allpass filters are specified by reflection coefficients.
|
|
542
|
+
// They are defined here as nested allpass filters, hence the names allpassn*.
|
|
543
|
+
//
|
|
544
|
+
// REFERENCES
|
|
545
|
+
// 1. https://ccrma.stanford.edu/~jos/pasp/Conventional_Ladder_Filters.html
|
|
546
|
+
// https://ccrma.stanford.edu/~jos/pasp/Nested_Allpass_Filters.html
|
|
547
|
+
// 2. Linear Prediction of Speech, Markel and Gray, Springer Verlag, 1976
|
|
548
|
+
//
|
|
549
|
+
// QUICK GUIDE
|
|
550
|
+
// allpassn - two-multiply lattice - each section is two multiply-adds
|
|
551
|
+
// allpassnn - normalized form - four multiplies and two adds per section,
|
|
552
|
+
// but coefficients can be time varying and nonlinear without
|
|
553
|
+
// "parametric amplification" (modulation of signal energy).
|
|
554
|
+
// allpassnkl - Kelly-Lochbaum form - four multiplies and two adds per
|
|
555
|
+
// section, but all signals have an immediate physical
|
|
556
|
+
// interpretation as traveling pressure waves, etc.
|
|
557
|
+
// allpassn1m - One-multiply form - one multiply and three adds per section.
|
|
558
|
+
// Normally the most efficient in special-purpose hardware.
|
|
559
|
+
//
|
|
560
|
+
// TYPICAL USAGE
|
|
561
|
+
// _ : allpassn(N,sv) : _
|
|
562
|
+
// where
|
|
563
|
+
// N = allpass order (number of ladder or lattice sections)
|
|
564
|
+
// sv = (s1,s2,...,sN) = reflection coefficients (between -1 and 1).
|
|
565
|
+
// For allpassnn only, sv is replaced by tv, where sv(i) = sin(tv(i)),
|
|
566
|
+
// where tv(i) may range between -PI and PI.
|
|
567
|
+
//
|
|
568
|
+
// two-multiply:
|
|
569
|
+
allpassn(0,sv) = _;
|
|
570
|
+
allpassn(n,sv) = _ <: ((+ <: (allpassn(n-1,sv)),*(s))~(*(-s))) : _',_ :+
|
|
571
|
+
with { s = take(n,sv); };
|
|
572
|
+
|
|
573
|
+
// power-normalized (reflection coefficients s = sin(t)):
|
|
574
|
+
allpassnn(0,tv) = _;
|
|
575
|
+
allpassnn(n,tv) = _ <: *(s), (*(c) : (+
|
|
576
|
+
: allpassnn(n-1,tv))~(*(-s))) : _, mem*c : +
|
|
577
|
+
with { c=cos(take(n,tv)); s=sin(take(n,tv)); };
|
|
578
|
+
|
|
579
|
+
// power-normalized with sparse delays dv(n)>1:
|
|
580
|
+
allpassnns(0,tv,dmax,dv) = _;
|
|
581
|
+
allpassnns(n,tv,dmax,dv) = _ <: *(s), (*(c) : (+ : dl
|
|
582
|
+
: allpassnns(n-1,tv,dmax,dv))~(*(-s))) : _, mem*c : +
|
|
583
|
+
with { c=cos(take(n,tv)); s=sin(take(n,tv));
|
|
584
|
+
dl=delay(dmax,(take(n,dv)-1)); };
|
|
585
|
+
|
|
586
|
+
// Kelly-Lochbaum:
|
|
587
|
+
allpassnkl(0,sv) = _;
|
|
588
|
+
allpassnkl(n,sv) = _ <: *(s),(*(1+s) : (+
|
|
589
|
+
: allpassnkl(n-1,sv))~(*(-s))) : _, mem*(1-s) : +
|
|
590
|
+
with { s = take(n,sv); };
|
|
591
|
+
|
|
592
|
+
// one-multiply:
|
|
593
|
+
allpassn1m(0,sv) = _;
|
|
594
|
+
allpassn1m(n,sv)= _ <: _,_ : ((+:*(s) <: _,_),_ : _,+ : cross
|
|
595
|
+
: allpassn1m(n-1,sv),_)~(*(-1)) : _',_ : +
|
|
596
|
+
with {s = take(n,sv); cross = _,_ <: !,_,_,!; };
|
|
597
|
+
|
|
598
|
+
//===== Digital Filter Sections Specified as Analog Filter Sections =====
|
|
599
|
+
//
|
|
600
|
+
//------------------------- tf2s, tf2snp --------------------------------
|
|
601
|
+
// Second-order direct-form digital filter,
|
|
602
|
+
// specified by ANALOG transfer-function polynomials B(s)/A(s),
|
|
603
|
+
// and a frequency-scaling parameter. Digitization via the
|
|
604
|
+
// bilinear transform is built in.
|
|
605
|
+
//
|
|
606
|
+
// USAGE: tf2s(b2,b1,b0,a1,a0,w1), where
|
|
607
|
+
//
|
|
608
|
+
// b2 s^2 + b1 s + b0
|
|
609
|
+
// H(s) = --------------------
|
|
610
|
+
// s^2 + a1 s + a0
|
|
611
|
+
//
|
|
612
|
+
// and w1 is the desired digital frequency (in radians/second)
|
|
613
|
+
// corresponding to analog frequency 1 rad/sec (i.e., s = j).
|
|
614
|
+
//
|
|
615
|
+
// EXAMPLE: A second-order ANALOG Butterworth lowpass filter,
|
|
616
|
+
// normalized to have cutoff frequency at 1 rad/sec,
|
|
617
|
+
// has transfer function
|
|
618
|
+
//
|
|
619
|
+
// 1
|
|
620
|
+
// H(s) = -----------------
|
|
621
|
+
// s^2 + a1 s + 1
|
|
622
|
+
//
|
|
623
|
+
// where a1 = sqrt(2). Therefore, a DIGITAL Butterworth lowpass
|
|
624
|
+
// cutting off at SR/4 is specified as tf2s(0,0,1,sqrt(2),1,PI*SR/2);
|
|
625
|
+
//
|
|
626
|
+
// METHOD: Bilinear transform scaled for exact mapping of w1.
|
|
627
|
+
// REFERENCE:
|
|
628
|
+
// https://ccrma.stanford.edu/~jos/pasp/Bilinear_Transformation.html
|
|
629
|
+
//
|
|
630
|
+
tf2s(b2,b1,b0,a1,a0,w1) = tf2(b0d,b1d,b2d,a1d,a2d)
|
|
631
|
+
with {
|
|
632
|
+
c = 1/tan(w1*0.5/SR); // bilinear-transform scale-factor
|
|
633
|
+
csq = c*c;
|
|
634
|
+
d = a0 + a1 * c + csq;
|
|
635
|
+
b0d = (b0 + b1 * c + b2 * csq)/d;
|
|
636
|
+
b1d = 2 * (b0 - b2 * csq)/d;
|
|
637
|
+
b2d = (b0 - b1 * c + b2 * csq)/d;
|
|
638
|
+
a1d = 2 * (a0 - csq)/d;
|
|
639
|
+
a2d = (a0 - a1*c + csq)/d;
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
// tf2snp = tf2s but using a protected normalized ladder filter for tf2:
|
|
643
|
+
tf2snp(b2,b1,b0,a1,a0,w1) = tf2np(b0d,b1d,b2d,a1d,a2d)
|
|
644
|
+
with {
|
|
645
|
+
c = 1/tan(w1*0.5/SR); // bilinear-transform scale-factor
|
|
646
|
+
csq = c*c;
|
|
647
|
+
d = a0 + a1 * c + csq;
|
|
648
|
+
b0d = (b0 + b1 * c + b2 * csq)/d;
|
|
649
|
+
b1d = 2 * (b0 - b2 * csq)/d;
|
|
650
|
+
b2d = (b0 - b1 * c + b2 * csq)/d;
|
|
651
|
+
a1d = 2 * (a0 - csq)/d;
|
|
652
|
+
a2d = (a0 - a1*c + csq)/d;
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
//----------------------------- tf3slf -------------------------------
|
|
656
|
+
// Analogous to tf2s above, but third order, and using the typical
|
|
657
|
+
// low-frequency-matching bilinear-transform constant 2/T ("lf" series)
|
|
658
|
+
// instead of the specific-frequency-matching value used in tf2s and tf1s.
|
|
659
|
+
// Note the lack of a "w1" argument.
|
|
660
|
+
//
|
|
661
|
+
tf3slf(b3,b2,b1,b0,a3,a2,a1,a0) = tf3(b0d,b1d,b2d,b3d,a1d,a2d,a3d) with {
|
|
662
|
+
c = 2.0 * SR; // bilinear-transform scale-factor ("lf" case)
|
|
663
|
+
csq = c*c;
|
|
664
|
+
cc = csq*c;
|
|
665
|
+
// Thank you maxima:
|
|
666
|
+
b3d = (b3*c^3-b2*c^2+b1*c-b0)/d;
|
|
667
|
+
b2d = (-3*b3*c^3+b2*c^2+b1*c-3*b0)/d;
|
|
668
|
+
b1d = (3*b3*c^3+b2*c^2-b1*c-3*b0)/d;
|
|
669
|
+
b0d = (-b3*c^3-b2*c^2-b1*c-b0)/d;
|
|
670
|
+
a3d = (a3*c^3-a2*c^2+a1*c-a0)/d;
|
|
671
|
+
a2d = (-3*a3*c^3+a2*c^2+a1*c-3*a0)/d;
|
|
672
|
+
a1d = (3*a3*c^3+a2*c^2-a1*c-3*a0)/d;
|
|
673
|
+
d = (-a3*c^3-a2*c^2-a1*c-a0);
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
//----------------------------- tf1s --------------------------------
|
|
677
|
+
// First-order direct-form digital filter,
|
|
678
|
+
// specified by ANALOG transfer-function polynomials B(s)/A(s),
|
|
679
|
+
// and a frequency-scaling parameter.
|
|
680
|
+
//
|
|
681
|
+
// USAGE: tf1s(b1,b0,a0,w1), where
|
|
682
|
+
//
|
|
683
|
+
// b1 s + b0
|
|
684
|
+
// H(s) = ----------
|
|
685
|
+
// s + a0
|
|
686
|
+
//
|
|
687
|
+
// and w1 is the desired digital frequency (in radians/second)
|
|
688
|
+
// corresponding to analog frequency 1 rad/sec (i.e., s = j).
|
|
689
|
+
//
|
|
690
|
+
// EXAMPLE: A first-order ANALOG Butterworth lowpass filter,
|
|
691
|
+
// normalized to have cutoff frequency at 1 rad/sec,
|
|
692
|
+
// has transfer function
|
|
693
|
+
//
|
|
694
|
+
// 1
|
|
695
|
+
// H(s) = -------
|
|
696
|
+
// s + 1
|
|
697
|
+
//
|
|
698
|
+
// so b0 = a0 = 1 and b1 = 0. Therefore, a DIGITAL first-order
|
|
699
|
+
// Butterworth lowpass with gain -3dB at SR/4 is specified as
|
|
700
|
+
//
|
|
701
|
+
// tf1s(0,1,1,PI*SR/2); // digital half-band order 1 Butterworth
|
|
702
|
+
//
|
|
703
|
+
// METHOD: Bilinear transform scaled for exact mapping of w1.
|
|
704
|
+
// REFERENCE:
|
|
705
|
+
// https://ccrma.stanford.edu/~jos/pasp/Bilinear_Transformation.html
|
|
706
|
+
//
|
|
707
|
+
tf1s(b1,b0,a0,w1) = tf1(b0d,b1d,a1d)
|
|
708
|
+
with {
|
|
709
|
+
c = 1/tan(w1*0.5/SR); // bilinear-transform scale-factor
|
|
710
|
+
d = a0 + c;
|
|
711
|
+
b1d = (b0 - b1*c) / d;
|
|
712
|
+
b0d = (b0 + b1*c) / d;
|
|
713
|
+
a1d = (a0 - c) / d;
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
//----------------------------- tf2sb --------------------------------
|
|
717
|
+
// Bandpass mapping of tf2s: In addition to a frequency-scaling parameter
|
|
718
|
+
// w1 (set to HALF the desired passband width in rad/sec),
|
|
719
|
+
// there is a desired center-frequency parameter wc (also in rad/s).
|
|
720
|
+
// Thus, tf2sb implements a fourth-order digital bandpass filter section
|
|
721
|
+
// specified by the coefficients of a second-order analog lowpass prototpe
|
|
722
|
+
// section. Such sections can be combined in series for higher orders.
|
|
723
|
+
// The order of mappings is (1) frequency scaling (to set lowpass cutoff w1),
|
|
724
|
+
// (2) bandpass mapping to wc, then (3) the bilinear transform, with the
|
|
725
|
+
// usual scale parameter 2*SR. Algebra carried out in maxima and pasted here.
|
|
726
|
+
//
|
|
727
|
+
tf2sb(b2,b1,b0,a1,a0,w1,wc) =
|
|
728
|
+
iir((b0d/a0d,b1d/a0d,b2d/a0d,b3d/a0d,b4d/a0d),(a1d/a0d,a2d/a0d,a3d/a0d,a4d/a0d)) with {
|
|
729
|
+
T = 1.0/float(SR);
|
|
730
|
+
b0d = (4*b0*w1^2+8*b2*wc^2)*T^2+8*b1*w1*T+16*b2;
|
|
731
|
+
b1d = 4*b2*wc^4*T^4+4*b1*wc^2*w1*T^3-16*b1*w1*T-64*b2;
|
|
732
|
+
b2d = 6*b2*wc^4*T^4+(-8*b0*w1^2-16*b2*wc^2)*T^2+96*b2;
|
|
733
|
+
b3d = 4*b2*wc^4*T^4-4*b1*wc^2*w1*T^3+16*b1*w1*T-64*b2;
|
|
734
|
+
b4d = (b2*wc^4*T^4-2*b1*wc^2*w1*T^3+(4*b0*w1^2+8*b2*wc^2)*T^2-8*b1*w1*T +16*b2)
|
|
735
|
+
+ b2*wc^4*T^4+2*b1*wc^2*w1*T^3;
|
|
736
|
+
a0d = wc^4*T^4+2*a1*wc^2*w1*T^3+(4*a0*w1^2+8*wc^2)*T^2+8*a1*w1*T+16;
|
|
737
|
+
a1d = 4*wc^4*T^4+4*a1*wc^2*w1*T^3-16*a1*w1*T-64;
|
|
738
|
+
a2d = 6*wc^4*T^4+(-8*a0*w1^2-16*wc^2)*T^2+96;
|
|
739
|
+
a3d = 4*wc^4*T^4-4*a1*wc^2*w1*T^3+16*a1*w1*T-64;
|
|
740
|
+
a4d = wc^4*T^4-2*a1*wc^2*w1*T^3+(4*a0*w1^2+8*wc^2)*T^2-8*a1*w1*T+16;
|
|
741
|
+
};
|
|
742
|
+
|
|
743
|
+
//----------------------------- tf1sb --------------------------------
|
|
744
|
+
// First-to-second-order lowpass-to-bandpass section mapping,
|
|
745
|
+
// analogous to tf2sb above.
|
|
746
|
+
//
|
|
747
|
+
tf1sb(b1,b0,a0,w1,wc) = tf2(b0d/a0d,b1d/a0d,b2d/a0d,a1d/a0d,a2d/a0d) with {
|
|
748
|
+
T = 1.0/float(SR);
|
|
749
|
+
a0d = wc^2*T^2+2*a0*w1*T+4;
|
|
750
|
+
b0d = b1*wc^2*T^2 +2*b0*w1*T+4*b1;
|
|
751
|
+
b1d = 2*b1*wc^2*T^2-8*b1;
|
|
752
|
+
b2d = b1*wc^2*T^2-2*b0*w1*T+4*b1;
|
|
753
|
+
a1d = 2*wc^2*T^2-8;
|
|
754
|
+
a2d = wc^2*T^2-2*a0*w1*T+4;
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
//====================== Simple Resonator Filters ======================
|
|
758
|
+
|
|
759
|
+
// resonlp = 2nd-order lowpass with corner resonance:
|
|
760
|
+
resonlp(fc,Q,gain) = tf2s(b2,b1,b0,a1,a0,wc)
|
|
761
|
+
with {
|
|
762
|
+
wc = 2*PI*fc;
|
|
763
|
+
a1 = 1/Q;
|
|
764
|
+
a0 = 1;
|
|
765
|
+
b2 = 0;
|
|
766
|
+
b1 = 0;
|
|
767
|
+
b0 = gain;
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
// resonhp = 2nd-order highpass with corner resonance:
|
|
771
|
+
resonhp(fc,Q,gain,x) = gain*x-resonlp(fc,Q,gain,x);
|
|
772
|
+
|
|
773
|
+
// resonbp = 2nd-order bandpass
|
|
774
|
+
resonbp(fc,Q,gain) = tf2s(b2,b1,b0,a1,a0,wc)
|
|
775
|
+
with {
|
|
776
|
+
wc = 2*PI*fc;
|
|
777
|
+
a1 = 1/Q;
|
|
778
|
+
a0 = 1;
|
|
779
|
+
b2 = 0;
|
|
780
|
+
b1 = gain;
|
|
781
|
+
b0 = 0;
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
//================ Butterworth Lowpass/Highpass Filters ======================
|
|
785
|
+
// Nth-order Butterworth lowpass or highpass filters
|
|
786
|
+
//
|
|
787
|
+
// USAGE:
|
|
788
|
+
// _ : lowpass(N,fc) : _
|
|
789
|
+
// _ : highpass(N,fc) : _
|
|
790
|
+
// where
|
|
791
|
+
// N = filter order (number of poles) [nonnegative constant integer]
|
|
792
|
+
// fc = desired cut-off frequency (-3dB frequency) in Hz
|
|
793
|
+
// REFERENCE:
|
|
794
|
+
// https://ccrma.stanford.edu/~jos/filters/Butterworth_Lowpass_Design.html
|
|
795
|
+
// 'butter' function in Octave ("[z,p,g] = butter(N,1,'s');")
|
|
796
|
+
// ACKNOWLEDGMENT
|
|
797
|
+
// Generalized recursive formulation initiated by Yann Orlarey.
|
|
798
|
+
|
|
799
|
+
lowpass(N,fc) = lowpass0_highpass1(0,N,fc);
|
|
800
|
+
highpass(N,fc) = lowpass0_highpass1(1,N,fc);
|
|
801
|
+
lowpass0_highpass1(s,N,fc) = lphpr(s,N,N,fc)
|
|
802
|
+
with {
|
|
803
|
+
lphpr(s,0,N,fc) = _;
|
|
804
|
+
lphpr(s,1,N,fc) = tf1s(s,1-s,1,2*PI*fc);
|
|
805
|
+
lphpr(s,O,N,fc) = lphpr(s,(O-2),N,fc) : tf2s(s,0,1-s,a1s,1,w1) with {
|
|
806
|
+
parity = N % 2;
|
|
807
|
+
S = (O-parity)/2; // current section number
|
|
808
|
+
a1s = -2*cos(-PI + (1-parity)*PI/(2*N) + (S-1+parity)*PI/N);
|
|
809
|
+
w1 = 2*PI*fc;
|
|
810
|
+
};
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
//========== Special Filter-Bank Delay-Equalizing Allpass Filters ===========
|
|
814
|
+
//
|
|
815
|
+
// These special allpass filters are needed by filterbank et al. below.
|
|
816
|
+
// They are equivalent to (lowpass(N,fc) +|- highpass(N,fc))/2, but with
|
|
817
|
+
// canceling pole-zero pairs removed (which occurs for odd N).
|
|
818
|
+
|
|
819
|
+
//-------------------- lowpass_plus|minus_highpass ------------------
|
|
820
|
+
|
|
821
|
+
highpass_plus_lowpass(1,fc) = _;
|
|
822
|
+
highpass_plus_lowpass(3,fc) = tf2s(1,-1,1,1,1,w1) with { w1 = 2*PI*fc; };
|
|
823
|
+
highpass_minus_lowpass(3,fc) = tf1s(-1,1,1,w1) with { w1 = 2*PI*fc; };
|
|
824
|
+
highpass_plus_lowpass(5,fc) = tf2s(1,-a11,1,a11,1,w1)
|
|
825
|
+
with {
|
|
826
|
+
a11 = 1.618033988749895;
|
|
827
|
+
w1 = 2*PI*fc;
|
|
828
|
+
};
|
|
829
|
+
highpass_minus_lowpass(5,fc) = tf1s(1,-1,1,w1) : tf2s(1,-a12,1,a12,1,w1)
|
|
830
|
+
with {
|
|
831
|
+
a12 = 0.618033988749895;
|
|
832
|
+
w1 = 2*PI*fc;
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
// Catch-all definitions for generality - even order is done:
|
|
836
|
+
|
|
837
|
+
highpass_plus_lowpass(N,fc) = _ <: switch_odd_even(N%2,N,fc) with {
|
|
838
|
+
switch_odd_even(0,N,fc) = highpass_plus_lowpass_even(N,fc);
|
|
839
|
+
switch_odd_even(1,N,fc) = highpass_plus_lowpass_odd(N,fc);
|
|
840
|
+
};
|
|
841
|
+
|
|
842
|
+
highpass_minus_lowpass(N,fc) = _ <: switch_odd_even(N%2,N,fc) with {
|
|
843
|
+
switch_odd_even(0,N,fc) = highpass_minus_lowpass_even(N,fc);
|
|
844
|
+
switch_odd_even(1,N,fc) = highpass_minus_lowpass_odd(N,fc);
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
highpass_plus_lowpass_even(N,fc) = highpass(N,fc) + lowpass(N,fc);
|
|
848
|
+
highpass_minus_lowpass_even(N,fc) = highpass(N,fc) - lowpass(N,fc);
|
|
849
|
+
|
|
850
|
+
// FIXME: Rewrite the following, as for orders 3 and 5 above,
|
|
851
|
+
// to eliminate pole-zero cancellations:
|
|
852
|
+
highpass_plus_lowpass_odd(N,fc) = highpass(N,fc) + lowpass(N,fc);
|
|
853
|
+
highpass_minus_lowpass_odd(N,fc) = highpass(N,fc) - lowpass(N,fc);
|
|
854
|
+
|
|
855
|
+
//===================== Elliptic (Cauer) Lowpass Filters ===================
|
|
856
|
+
// USAGE:
|
|
857
|
+
// _ : lowpass3e(fc) : _
|
|
858
|
+
// _ : lowpass6e(fc) : _
|
|
859
|
+
// where fc = -3dB frequency in Hz
|
|
860
|
+
//
|
|
861
|
+
// REFERENCES:
|
|
862
|
+
// http://en.wikipedia.org/wiki/Elliptic_filter
|
|
863
|
+
// functions 'ncauer' and 'ellip' in Octave
|
|
864
|
+
|
|
865
|
+
//----------------------------- lowpass3e -----------------------------
|
|
866
|
+
// Third-order Elliptic (Cauer) lowpass filter
|
|
867
|
+
// DESIGN: For spectral band-slice level display (see octave_analyzer3e):
|
|
868
|
+
// [z,p,g] = ncauer(Rp,Rs,3); % analog zeros, poles, and gain, where
|
|
869
|
+
// Rp = 60 % dB ripple in stopband
|
|
870
|
+
// Rs = 0.2 % dB ripple in passband
|
|
871
|
+
//
|
|
872
|
+
lowpass3e(fc) = tf2s(b21,b11,b01,a11,a01,w1) : tf1s(0,1,a02,w1)
|
|
873
|
+
with {
|
|
874
|
+
a11 = 0.802636764161030; // format long; poly(p(1:2)) % in octave
|
|
875
|
+
a01 = 1.412270893774204;
|
|
876
|
+
a02 = 0.822445908998816; // poly(p(3)) % in octave
|
|
877
|
+
b21 = 0.019809144837789; // poly(z)
|
|
878
|
+
b11 = 0;
|
|
879
|
+
b01 = 1.161516418982696;
|
|
880
|
+
w1 = 2*PI*fc;
|
|
881
|
+
};
|
|
882
|
+
|
|
883
|
+
//----------------------------- lowpass6e -----------------------------
|
|
884
|
+
// Sixth-order Elliptic/Cauer lowpass filter
|
|
885
|
+
// DESIGN: For spectral band-slice level display (see octave_analyzer6e):
|
|
886
|
+
// [z,p,g] = ncauer(Rp,Rs,6); % analog zeros, poles, and gain, where
|
|
887
|
+
// Rp = 80 % dB ripple in stopband
|
|
888
|
+
// Rs = 0.2 % dB ripple in passband
|
|
889
|
+
//
|
|
890
|
+
lowpass6e(fc) =
|
|
891
|
+
tf2s(b21,b11,b01,a11,a01,w1) :
|
|
892
|
+
tf2s(b22,b12,b02,a12,a02,w1) :
|
|
893
|
+
tf2s(b23,b13,b03,a13,a03,w1)
|
|
894
|
+
with {
|
|
895
|
+
b21 = 0.000099999997055;
|
|
896
|
+
a21 = 1;
|
|
897
|
+
b11 = 0;
|
|
898
|
+
a11 = 0.782413046821645;
|
|
899
|
+
b01 = 0.000433227200555;
|
|
900
|
+
a01 = 0.245291508706160;
|
|
901
|
+
b22 = 1;
|
|
902
|
+
a22 = 1;
|
|
903
|
+
b12 = 0;
|
|
904
|
+
a12 = 0.512478641889141;
|
|
905
|
+
b02 = 7.621731298870603;
|
|
906
|
+
a02 = 0.689621364484675;
|
|
907
|
+
b23 = 1;
|
|
908
|
+
a23 = 1;
|
|
909
|
+
b13 = 0;
|
|
910
|
+
a13 = 0.168404871113589;
|
|
911
|
+
b03 = 53.536152954556727;
|
|
912
|
+
a03 = 1.069358407707312;
|
|
913
|
+
w1 = 2*PI*fc;
|
|
914
|
+
};
|
|
915
|
+
|
|
916
|
+
//===================== Elliptic Highpass Filters =====================
|
|
917
|
+
// USAGE:
|
|
918
|
+
// _ : highpass3e(fc) : _
|
|
919
|
+
// _ : highpass6e(fc) : _
|
|
920
|
+
// where fc = -3dB frequency in Hz
|
|
921
|
+
|
|
922
|
+
//----------------------------- highpass3e -----------------------------
|
|
923
|
+
// Third-order Elliptic (Cauer) highpass filter
|
|
924
|
+
// DESIGN: Inversion of lowpass3e wrt unit circle in s plane (s <- 1/s)
|
|
925
|
+
//
|
|
926
|
+
highpass3e(fc) = tf2s(b01/a01,b11/a01,b21/a01,a11/a01,1/a01,w1) :
|
|
927
|
+
tf1s(1/a02,0,1/a02,w1)
|
|
928
|
+
with {
|
|
929
|
+
a11 = 0.802636764161030;
|
|
930
|
+
a01 = 1.412270893774204;
|
|
931
|
+
a02 = 0.822445908998816;
|
|
932
|
+
b21 = 0.019809144837789;
|
|
933
|
+
b11 = 0;
|
|
934
|
+
b01 = 1.161516418982696;
|
|
935
|
+
w1 = 2*PI*fc;
|
|
936
|
+
};
|
|
937
|
+
|
|
938
|
+
//----------------------------- highpass6e -----------------------------
|
|
939
|
+
// Sixth-order Elliptic/Cauer highpass filter
|
|
940
|
+
// METHOD: Inversion of lowpass3e wrt unit circle in s plane (s <- 1/s)
|
|
941
|
+
//
|
|
942
|
+
highpass6e(fc) =
|
|
943
|
+
tf2s(b01/a01,b11/a01,b21/a01,a11/a01,1/a01,w1) :
|
|
944
|
+
tf2s(b02/a02,b12/a02,b22/a02,a12/a02,1/a02,w1) :
|
|
945
|
+
tf2s(b03/a03,b13/a03,b23/a03,a13/a03,1/a03,w1)
|
|
946
|
+
with {
|
|
947
|
+
b21 = 0.000099999997055;
|
|
948
|
+
a21 = 1;
|
|
949
|
+
b11 = 0;
|
|
950
|
+
a11 = 0.782413046821645;
|
|
951
|
+
b01 = 0.000433227200555;
|
|
952
|
+
a01 = 0.245291508706160;
|
|
953
|
+
b22 = 1;
|
|
954
|
+
a22 = 1;
|
|
955
|
+
b12 = 0;
|
|
956
|
+
a12 = 0.512478641889141;
|
|
957
|
+
b02 = 7.621731298870603;
|
|
958
|
+
a02 = 0.689621364484675;
|
|
959
|
+
b23 = 1;
|
|
960
|
+
a23 = 1;
|
|
961
|
+
b13 = 0;
|
|
962
|
+
a13 = 0.168404871113589;
|
|
963
|
+
b03 = 53.536152954556727;
|
|
964
|
+
a03 = 1.069358407707312;
|
|
965
|
+
w1 = 2*PI*fc;
|
|
966
|
+
};
|
|
967
|
+
|
|
968
|
+
//================== Butterworth Bandpass/Bandstop Filters =====================
|
|
969
|
+
// Order 2*Nh Butterworth bandpass filter made using the transformation
|
|
970
|
+
// s <- s + wc^2/s on lowpass(Nh), where wc is the desired bandpass center
|
|
971
|
+
// frequency. The lowpass(Nh) cutoff w1 is half the desired bandpass width.
|
|
972
|
+
// A notch-like "bandstop" filter is similarly made from highpass(Nh).
|
|
973
|
+
//
|
|
974
|
+
// USAGE:
|
|
975
|
+
// _ : bandpass(Nh,fl,fu) : _
|
|
976
|
+
// _ : bandstop(Nh,fl,fu) : _
|
|
977
|
+
// where
|
|
978
|
+
// Nh = HALF the desired bandpass/bandstop order (which is therefore even)
|
|
979
|
+
// fl = lower -3dB frequency in Hz
|
|
980
|
+
// fu = upper -3dB frequency in Hz
|
|
981
|
+
// Thus, the passband (stopband) width is fu-fl,
|
|
982
|
+
// and its center frequency is (fl+fu)/2.
|
|
983
|
+
//
|
|
984
|
+
// REFERENCE:
|
|
985
|
+
// http://cnx.org/content/m16913/latest/
|
|
986
|
+
//
|
|
987
|
+
bandpass(Nh,fl,fu) = bandpass0_bandstop1(0,Nh,fl,fu);
|
|
988
|
+
bandstop(Nh,fl,fu) = bandpass0_bandstop1(1,Nh,fl,fu);
|
|
989
|
+
bandpass0_bandstop1(s,Nh,fl,fu) = bpbsr(s,Nh,Nh,fl,fu)
|
|
990
|
+
with {
|
|
991
|
+
wl = 2*PI*fl; // digital (z-plane) lower passband edge
|
|
992
|
+
wu = 2*PI*fu; // digital (z-plane) upper passband edge
|
|
993
|
+
|
|
994
|
+
c = 2.0*SR; // bilinear transform scaling used in tf2sb, tf1sb
|
|
995
|
+
wla = c*tan(wl/c); // analog (s-splane) lower cutoff
|
|
996
|
+
wua = c*tan(wu/c); // analog (s-splane) upper cutoff
|
|
997
|
+
|
|
998
|
+
wc = sqrt(wla*wua); // s-plane center frequency
|
|
999
|
+
w1 = wua - wc^2/wua; // s-plane lowpass prototype cutoff
|
|
1000
|
+
|
|
1001
|
+
bpbsr(s,0,Nh,fl,fu) = _;
|
|
1002
|
+
bpbsr(s,1,Nh,fl,fu) = tf1sb(s,1-s,1,w1,wc);
|
|
1003
|
+
bpbsr(s,O,Nh,fl,fu) = bpbsr(s,O-2,Nh,fl,fu) : tf2sb(s,0,(1-s),a1s,1,w1,wc)
|
|
1004
|
+
with {
|
|
1005
|
+
parity = Nh % 2;
|
|
1006
|
+
S = (O-parity)/2; // current section number
|
|
1007
|
+
a1s = -2*cos(-PI + (1-parity)*PI/(2*Nh) + (S-1+parity)*PI/Nh);
|
|
1008
|
+
};
|
|
1009
|
+
};
|
|
1010
|
+
|
|
1011
|
+
//======================= Elliptic Bandpass Filters ============================
|
|
1012
|
+
|
|
1013
|
+
//----------------------------- bandpass6e -----------------------------
|
|
1014
|
+
// Order 12 elliptic bandpass filter analogous to bandpass(6) above.
|
|
1015
|
+
//
|
|
1016
|
+
bandpass6e(fl,fu) = tf2sb(b21,b11,b01,a11,a01,w1,wc) : tf1sb(0,1,a02,w1,wc)
|
|
1017
|
+
with {
|
|
1018
|
+
a11 = 0.802636764161030; // In octave: format long; poly(p(1:2))
|
|
1019
|
+
a01 = 1.412270893774204;
|
|
1020
|
+
a02 = 0.822445908998816; // poly(p(3))
|
|
1021
|
+
b21 = 0.019809144837789; // poly(z)
|
|
1022
|
+
b11 = 0;
|
|
1023
|
+
b01 = 1.161516418982696;
|
|
1024
|
+
|
|
1025
|
+
wl = 2*PI*fl; // digital (z-plane) lower passband edge
|
|
1026
|
+
wu = 2*PI*fu; // digital (z-plane) upper passband edge
|
|
1027
|
+
|
|
1028
|
+
c = 2.0*SR; // bilinear transform scaling used in tf2sb, tf1sb
|
|
1029
|
+
wla = c*tan(wl/c); // analog (s-splane) lower cutoff
|
|
1030
|
+
wua = c*tan(wu/c); // analog (s-splane) upper cutoff
|
|
1031
|
+
|
|
1032
|
+
wc = sqrt(wla*wua); // s-plane center frequency
|
|
1033
|
+
w1 = wua - wc^2/wua; // s-plane lowpass cutoff
|
|
1034
|
+
};
|
|
1035
|
+
|
|
1036
|
+
//----------------------------- bandpass12e -----------------------------
|
|
1037
|
+
|
|
1038
|
+
bandpass12e(fl,fu) =
|
|
1039
|
+
tf2sb(b21,b11,b01,a11,a01,w1,wc) :
|
|
1040
|
+
tf2sb(b22,b12,b02,a12,a02,w1,wc) :
|
|
1041
|
+
tf2sb(b23,b13,b03,a13,a03,w1,wc)
|
|
1042
|
+
with { // octave script output:
|
|
1043
|
+
b21 = 0.000099999997055;
|
|
1044
|
+
a21 = 1;
|
|
1045
|
+
b11 = 0;
|
|
1046
|
+
a11 = 0.782413046821645;
|
|
1047
|
+
b01 = 0.000433227200555;
|
|
1048
|
+
a01 = 0.245291508706160;
|
|
1049
|
+
b22 = 1;
|
|
1050
|
+
a22 = 1;
|
|
1051
|
+
b12 = 0;
|
|
1052
|
+
a12 = 0.512478641889141;
|
|
1053
|
+
b02 = 7.621731298870603;
|
|
1054
|
+
a02 = 0.689621364484675;
|
|
1055
|
+
b23 = 1;
|
|
1056
|
+
a23 = 1;
|
|
1057
|
+
b13 = 0;
|
|
1058
|
+
a13 = 0.168404871113589;
|
|
1059
|
+
b03 = 53.536152954556727;
|
|
1060
|
+
a03 = 1.069358407707312;
|
|
1061
|
+
|
|
1062
|
+
wl = 2*PI*fl; // digital (z-plane) lower passband edge
|
|
1063
|
+
wu = 2*PI*fu; // digital (z-plane) upper passband edge
|
|
1064
|
+
|
|
1065
|
+
c = 2.0*SR; // bilinear transform scaling used in tf2sb, tf1sb
|
|
1066
|
+
wla = c*tan(wl/c); // analog (s-splane) lower cutoff
|
|
1067
|
+
wua = c*tan(wu/c); // analog (s-splane) upper cutoff
|
|
1068
|
+
|
|
1069
|
+
wc = sqrt(wla*wua); // s-plane center frequency
|
|
1070
|
+
w1 = wua - wc^2/wua; // s-plane lowpass cutoff
|
|
1071
|
+
};
|
|
1072
|
+
|
|
1073
|
+
//================= Parametric Equalizers (Shelf, Peaking) ==================
|
|
1074
|
+
// REFERENCES
|
|
1075
|
+
// - http://en.wikipedia.org/wiki/Equalization
|
|
1076
|
+
// - filterbank (below, here in filter.lib)
|
|
1077
|
+
// - http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
|
|
1078
|
+
// - Digital Audio Signal Processing, Udo Zolzer, Wiley, 1999, p. 124
|
|
1079
|
+
// - https://ccrma.stanford.edu/~jos/filters/Low_High_Shelving_Filters.html
|
|
1080
|
+
// - https://ccrma.stanford.edu/~jos/filters/Peaking_Equalizers.html
|
|
1081
|
+
// - maxmsp.lib in the Faust distribution
|
|
1082
|
+
// - bandfilter.dsp in the faust2pd distribution
|
|
1083
|
+
|
|
1084
|
+
//------------------------------ low_shelf -------------------------------------
|
|
1085
|
+
// First-order "low shelf" filter (gain boost|cut between dc and some frequency)
|
|
1086
|
+
//
|
|
1087
|
+
// USAGE:
|
|
1088
|
+
// _ : lowshelf(N,L0,fx) : _
|
|
1089
|
+
// where
|
|
1090
|
+
// N = filter order 1, 3, 5, ... (odd only).
|
|
1091
|
+
// L0 = desired level (dB) between dc and fx (boost L0>0 or cut L0<0)
|
|
1092
|
+
// fx = -3dB frequency of lowpass band (L0>0) or upper band (L0<0)
|
|
1093
|
+
// (see "SHELF SHAPE" below).
|
|
1094
|
+
//
|
|
1095
|
+
// The gain at SR/2 is constrained to be 1.
|
|
1096
|
+
// The generalization to arbitrary odd orders is based on the well known
|
|
1097
|
+
// fact that odd-order Butterworth band-splits are allpass-complementary
|
|
1098
|
+
// (see filterbank documentation below for references).
|
|
1099
|
+
//
|
|
1100
|
+
// SHELF SHAPE
|
|
1101
|
+
// The magnitude frequency response is approximately piecewise-linear
|
|
1102
|
+
// on a log-log plot ("BODE PLOT"). The Bode "stick diagram" approximation
|
|
1103
|
+
// L(lf) is easy to state in dB versus dB-frequency lf = dB(f):
|
|
1104
|
+
// L0 > 0:
|
|
1105
|
+
// L(lf) = L0, f between 0 and fx = 1st corner frequency;
|
|
1106
|
+
// L(lf) = L0 - N * (lf - lfx), f between fx and f2 = 2nd corner frequency;
|
|
1107
|
+
// L(lf) = 0, lf > lf2.
|
|
1108
|
+
// lf2 = lfx + L0/N = dB-frequency at which level gets back to 0 dB.
|
|
1109
|
+
// See lowshelf_other_freq() below.
|
|
1110
|
+
// L0 < 0:
|
|
1111
|
+
// L(lf) = L0, f between 0 and f1 = 1st corner frequency;
|
|
1112
|
+
// L(lf) = - N * (lfx - lf), f between f1 and lfx = 2nd corner frequency;
|
|
1113
|
+
// L(lf) = 0, lf > lfx.
|
|
1114
|
+
// lf1 = lfx + L0/N = dB-frequency at which level goes up from L0.
|
|
1115
|
+
// See lowshelf_other_freq() below.
|
|
1116
|
+
|
|
1117
|
+
lowshelf(N,L0,fx) = filterbank(N,(fx)) : _, *(db2linear(L0)) :> _;
|
|
1118
|
+
// Special cases and optimization:
|
|
1119
|
+
low_shelf = lowshelf(3); // default = 3rd order Butterworth
|
|
1120
|
+
low_shelf1(L0,fx,x) = x + (db2linear(L0)-1)*lowpass(1,fx,x); // optimized
|
|
1121
|
+
low_shelf1_l(G0,fx,x) = x + (G0-1)*lowpass(1,fx,x); // optimized
|
|
1122
|
+
|
|
1123
|
+
lowshelf_other_freq(N, L0, fx) = db2linear(linear2db(fx) + L0/N); // convenience
|
|
1124
|
+
|
|
1125
|
+
//------------------------------ high_shelf ------------------------------------
|
|
1126
|
+
// First-order "high shelf" filter (gain boost|cut above some frequency)
|
|
1127
|
+
//
|
|
1128
|
+
// USAGE:
|
|
1129
|
+
// _ : highshelf(N,Lpi,fx) : _
|
|
1130
|
+
// where
|
|
1131
|
+
// N = filter order 1, 3, 5, ... (odd only).
|
|
1132
|
+
// Lpi = desired level (dB) between fx and SR/2 (boost Lpi>0 or cut Lpi<0)
|
|
1133
|
+
// fx = -3dB frequency of highpass band (L0>0) or lower band (L0<0)
|
|
1134
|
+
// (Use highshelf_other_freq() below to find the other one.)
|
|
1135
|
+
//
|
|
1136
|
+
// The gain at dc is constrained to be 1.
|
|
1137
|
+
// See lowshelf documentation above regarding SHELF SHAPE.
|
|
1138
|
+
|
|
1139
|
+
highshelf(N,Lpi,fx) = filterbank(N,(fx)) : *(db2linear(Lpi)), _ :> _;
|
|
1140
|
+
// Special cases and optimization:
|
|
1141
|
+
high_shelf = highshelf(3); // default = 3rd order Butterworth
|
|
1142
|
+
high_shelf1(Lpi,fx,x) = x + (db2linear(Lpi)-1)*highpass(1,fx,x); // optimized
|
|
1143
|
+
high_shelf1_l(Gpi,fx,x) = x + (Gpi-1)*highpass(1,fx,x); //optimized
|
|
1144
|
+
|
|
1145
|
+
// shelf transitions between frequency fx and this one:
|
|
1146
|
+
highshelf_other_freq(N, Lpi, fx) = db2linear(linear2db(fx) - Lpi/N);
|
|
1147
|
+
|
|
1148
|
+
//-------------------------------- peak_eq -----------------------------------
|
|
1149
|
+
// Second order "peaking equalizer" section
|
|
1150
|
+
// (gain boost or cut near some frequency)
|
|
1151
|
+
// Also called a "parametric equalizer" section
|
|
1152
|
+
// USAGE: _ : peak_eq(Lfx,fx,B) : _;
|
|
1153
|
+
// where
|
|
1154
|
+
// Lfx = level (dB) at fx (boost Lfx>0 or cut Lfx<0)
|
|
1155
|
+
// fx = peak frequency (Hz)
|
|
1156
|
+
// B = bandwidth (B) of peak in Hz
|
|
1157
|
+
//
|
|
1158
|
+
peak_eq(Lfx,fx,B) = tf2s(1,b1s,1,a1s,1,wx) with {
|
|
1159
|
+
T = float(1.0/SR);
|
|
1160
|
+
Bw = B*T/sin(wx*T); // prewarp s-bandwidth for more accuracy in z-plane
|
|
1161
|
+
a1 = PI*Bw;
|
|
1162
|
+
b1 = g*a1;
|
|
1163
|
+
g = db2linear(abs(Lfx));
|
|
1164
|
+
b1s = select2(Lfx>0,a1,b1); // When Lfx>0, pole dominates bandwidth
|
|
1165
|
+
a1s = select2(Lfx>0,b1,a1); // When Lfx<0, zero dominates
|
|
1166
|
+
wx = 2*PI*fx;
|
|
1167
|
+
};
|
|
1168
|
+
|
|
1169
|
+
//------------------------------- peak_eq_cq ---------------------------------
|
|
1170
|
+
// Constant-Q second order peaking equalizer section
|
|
1171
|
+
// USAGE: _ : peak_eq_cq(Lfx,fx,Q) : _;
|
|
1172
|
+
// where
|
|
1173
|
+
// Lfx = level (dB) at fx
|
|
1174
|
+
// fx = boost or cut frequency (Hz)
|
|
1175
|
+
// Q = "Quality factor" = fx/B where B = bandwidth of peak in Hz
|
|
1176
|
+
//
|
|
1177
|
+
peak_eq_cq(Lfx,fx,Q) = peak_eq(Lfx,fx,fx/Q);
|
|
1178
|
+
|
|
1179
|
+
//------------------------------- peak_eq_rm ---------------------------------
|
|
1180
|
+
// Regalia-Mitra second order peaking equalizer section
|
|
1181
|
+
// USAGE: _ : peak_eq_rm(Lfx,fx,tanPiBT) : _;
|
|
1182
|
+
// where
|
|
1183
|
+
// Lfx = level (dB) at fx
|
|
1184
|
+
// fx = boost or cut frequency (Hz)
|
|
1185
|
+
// tanPiBT = tan(PI*B/SR), where B = -3dB bandwidth (Hz) when 10^(Lfx/20) = 0
|
|
1186
|
+
// ~ PI*B/SR for narrow bandwidths B
|
|
1187
|
+
//
|
|
1188
|
+
// REFERENCE:
|
|
1189
|
+
// P.A. Regalia, S.K. Mitra, and P.P. Vaidyanathan,
|
|
1190
|
+
// "The Digital All-Pass Filter: A Versatile Signal Processing Building Block"
|
|
1191
|
+
// Proceedings of the IEEE, 76(1):19-37, Jan. 1988. (See pp. 29-30.)
|
|
1192
|
+
//
|
|
1193
|
+
peak_eq_rm(Lfx,fx,tanPiBT) = _ <: _,A,_ : +,- : *(0.5),*(K/2.0) : + with {
|
|
1194
|
+
A = tf2(k2, k1*(1+k2), 1, k1*(1+k2), k2) <: _,_; // allpass
|
|
1195
|
+
k1 = 0.0 - cos(2.0*PI*fx/SR);
|
|
1196
|
+
k2 = (1.0 - tanPiBT)/(1.0 + tanPiBT);
|
|
1197
|
+
K = db2linear(Lfx);
|
|
1198
|
+
};
|
|
1199
|
+
|
|
1200
|
+
//-------------------------- parametric_eq_demo ------------------------------
|
|
1201
|
+
// USAGE:
|
|
1202
|
+
// _ : parametric_eq_demo: _ ;
|
|
1203
|
+
parametric_eq_demo = // input_signal :
|
|
1204
|
+
low_shelf(LL,FL) :
|
|
1205
|
+
peak_eq(LP,FP,BP) :
|
|
1206
|
+
high_shelf(LH,FH)
|
|
1207
|
+
// Recommended:
|
|
1208
|
+
// : mth_octave_spectral_level_demo(2) // half-octave spectrum analyzer
|
|
1209
|
+
with {
|
|
1210
|
+
eq_group(x) = hgroup("[0] PARAMETRIC EQ SECTIONS
|
|
1211
|
+
[tooltip: See Faust's filter.lib for info and pointers]",x);
|
|
1212
|
+
|
|
1213
|
+
ls_group(x) = eq_group(vgroup("[1] Low Shelf",x));
|
|
1214
|
+
LL = ls_group(hslider("[0] Low Boost|Cut [unit:dB] [style:knob]
|
|
1215
|
+
[tooltip: Amount of low-frequency boost or cut in decibels]",
|
|
1216
|
+
0,-40,40,0.1));
|
|
1217
|
+
FL = ls_group(hslider("[1] Transition Frequency [unit:Hz] [style:knob] [scale:log]
|
|
1218
|
+
[tooltip: Transition-frequency from boost (cut) to unity gain]",
|
|
1219
|
+
200,1,5000,1));
|
|
1220
|
+
|
|
1221
|
+
pq_group(x) = eq_group(vgroup("[2] Peaking Equalizer
|
|
1222
|
+
[tooltip: Parametric Equalizer sections from filter.lib]",x));
|
|
1223
|
+
LP = pq_group(hslider("[0] Peak Boost|Cut [unit:dB] [style:knob]
|
|
1224
|
+
[tooltip: Amount of local boost or cut in decibels]",
|
|
1225
|
+
0,-40,40,0.1));
|
|
1226
|
+
FP = pq_group(hslider("[1] Peak Frequency [unit:PK] [style:knob]
|
|
1227
|
+
[tooltip: Peak Frequency in Piano Key (PK) units (A440 = 49PK)]",
|
|
1228
|
+
49,1,100,1)) : smooth(0.999) : pianokey2hz
|
|
1229
|
+
with { pianokey2hz(x) = 440.0*pow(2.0, (x-49.0)/12); };
|
|
1230
|
+
|
|
1231
|
+
Q = pq_group(hslider("[2] Peak Q [style:knob] [scale:log]
|
|
1232
|
+
[tooltip: Quality factor (Q) of the peak = center-frequency/bandwidth]",
|
|
1233
|
+
40,1,1000,0.1));
|
|
1234
|
+
|
|
1235
|
+
BP = FP/Q;
|
|
1236
|
+
|
|
1237
|
+
hs_group(x) = eq_group(vgroup("[3] High Shelf
|
|
1238
|
+
[tooltip: A high shelf provides a boost or cut
|
|
1239
|
+
above some frequency]",x));
|
|
1240
|
+
LH = hs_group(hslider("[0] High Boost|Cut [unit:dB] [style:knob]
|
|
1241
|
+
[tooltip: Amount of high-frequency boost or cut in decibels]",
|
|
1242
|
+
0,-40,40,.1));
|
|
1243
|
+
FH = hs_group(hslider("[1] Transition Frequency [unit:Hz] [style:knob] [scale:log]
|
|
1244
|
+
[tooltip: Transition-frequency from boost (cut) to unity gain]",
|
|
1245
|
+
8000,20,10000,1));
|
|
1246
|
+
};
|
|
1247
|
+
|
|
1248
|
+
//------------------------- spectral_tilt --------------------------------
|
|
1249
|
+
// Spectral tilt filter, providing an arbitrary spectral rolloff factor
|
|
1250
|
+
// alpha in (-1,1), where
|
|
1251
|
+
// -1 corresponds to one pole (-6 dB per octave), and
|
|
1252
|
+
// +1 corresponds to one zero (+6 dB per octave).
|
|
1253
|
+
// In other words, alpha is the slope of the ln magnitude versus ln frequency.
|
|
1254
|
+
// For a "pinking filter" (e.g., to generate 1/f noise from white noise),
|
|
1255
|
+
// set alpha to -1/2.
|
|
1256
|
+
//
|
|
1257
|
+
// USAGE:
|
|
1258
|
+
// _ : spectral_tilt(N,f0,bw,alpha) : _
|
|
1259
|
+
// where
|
|
1260
|
+
// N = desired integer filter order (fixed at compile time)
|
|
1261
|
+
// f0 = lower frequency limit for desired roll-off band
|
|
1262
|
+
// bw = bandwidth of desired roll-off band
|
|
1263
|
+
// alpha = slope of roll-off desired in nepers per neper
|
|
1264
|
+
// (ln mag / ln radian freq)
|
|
1265
|
+
//
|
|
1266
|
+
// EXAMPLE:
|
|
1267
|
+
// spectral_tilt_demo below
|
|
1268
|
+
//
|
|
1269
|
+
// REFERENCE:
|
|
1270
|
+
// http://arxiv.org/abs/1606.06154
|
|
1271
|
+
//
|
|
1272
|
+
spectral_tilt(N,f0,bw,alpha) = seq(i,N,sec(i)) with {
|
|
1273
|
+
sec(i) = g * tf1s(b1,b0,a0,1) with {
|
|
1274
|
+
g = a0/b0; // unity dc-gain scaling
|
|
1275
|
+
b1 = 1.0;
|
|
1276
|
+
b0 = mzh(i);
|
|
1277
|
+
a0 = mph(i);
|
|
1278
|
+
mzh(i) = prewarp(mz(i),SR,w0); // prewarping for bilinear transform
|
|
1279
|
+
mph(i) = prewarp(mp(i),SR,w0);
|
|
1280
|
+
prewarp(w,SR,wp) = wp * tan(w*T/2) / tan(wp*T/2) with { T = 1/SR; };
|
|
1281
|
+
mz(i) = w0 * r ^ (-alpha+i); // minus zero i in s plane
|
|
1282
|
+
mp(i) = w0 * r ^ i; // minus pole i in s plane
|
|
1283
|
+
w0 = 2 * PI * f0; // radian frequency of first pole
|
|
1284
|
+
f1 = f0 + bw; // upper band limit
|
|
1285
|
+
r = (f1/f0)^(1.0/float(N-1)); // pole ratio (2 => octave spacing)
|
|
1286
|
+
};
|
|
1287
|
+
};
|
|
1288
|
+
|
|
1289
|
+
//-------------------------- spectral_tilt_demo ------------------------------
|
|
1290
|
+
// USAGE:
|
|
1291
|
+
// _ : spectral_tilt_demo(N) : _ ;
|
|
1292
|
+
// where
|
|
1293
|
+
// N = filter order (integer)
|
|
1294
|
+
// All other parameters interactive
|
|
1295
|
+
//
|
|
1296
|
+
spectral_tilt_demo(N) = spectral_tilt(N,f0,bw,alpha) with {
|
|
1297
|
+
alpha = hslider("[1] Slope of Spectral Tilt across Band",-1/2,-1,1,0.001);
|
|
1298
|
+
f0 = hslider("[2] Band Start Frequency [unit:Hz]",100,20,10000,1);
|
|
1299
|
+
bw = hslider("[3] Band Width [unit:Hz]",5000,100,10000,1);
|
|
1300
|
+
};
|
|
1301
|
+
|
|
1302
|
+
//========================= Lagrange Interpolation ========================
|
|
1303
|
+
|
|
1304
|
+
//-------------------------- fdelaylti, fdelayltv -------------------------
|
|
1305
|
+
// Fractional delay line using Lagrange interpolation
|
|
1306
|
+
// USAGE: _ : fdelaylt[i|v](order, maxdelay, delay, inputsignal) : _
|
|
1307
|
+
// where order=1,2,3,... is the order of the Lagrange interpolation polynomial.
|
|
1308
|
+
// fdelaylti is most efficient, but designed for constant/slowly-varying delay.
|
|
1309
|
+
// fdelayltv is more expensive and more robust when the delay varies rapidly.
|
|
1310
|
+
//
|
|
1311
|
+
// NOTE: The requested delay should not be less than (N-1)/2.
|
|
1312
|
+
//
|
|
1313
|
+
// The first-order case (linear interpolation) is equivalent to
|
|
1314
|
+
// fdelay in music.lib (delay d in [0,1])
|
|
1315
|
+
//
|
|
1316
|
+
// REFERENCES:
|
|
1317
|
+
//
|
|
1318
|
+
// https://ccrma.stanford.edu/~jos/pasp/Lagrange_Interpolation.html
|
|
1319
|
+
//
|
|
1320
|
+
// Timo I. Laakso et al., "Splitting the Unit Delay - Tools for Fractional
|
|
1321
|
+
// Delay Filter Design", IEEE Signal Processing Magazine,
|
|
1322
|
+
// vol. 13, no. 1, pp. 30-60, Jan 1996.
|
|
1323
|
+
//
|
|
1324
|
+
// Philippe Depalle and Stephan Tassart, "Fractional Delay Lines using
|
|
1325
|
+
// Lagrange Interpolators", ICMC Proceedings, pp. 341-343, 1996.
|
|
1326
|
+
|
|
1327
|
+
fdelaylti(N,n,d,x) = delay(n,id,x) <: seq(i,N,section(i)) : !,_
|
|
1328
|
+
with {
|
|
1329
|
+
o = (N-1.00001)/2; // offset to ~center FIR interpolator
|
|
1330
|
+
dmo = d - o; // assumed nonnegative [d > (N-1)/2]
|
|
1331
|
+
id = int(dmo);
|
|
1332
|
+
fd = o + frac(dmo);
|
|
1333
|
+
section(i,x,y) = (x-x') * c(i) <: _,+(y);
|
|
1334
|
+
c(i) = (i - fd)/(i+1);
|
|
1335
|
+
};
|
|
1336
|
+
|
|
1337
|
+
fdelayltv(N,n,d,x) = sum(i, N+1, delay(n,id+i,x) * h(N,fd,i))
|
|
1338
|
+
with {
|
|
1339
|
+
o = (N-1.00001)/2; // ~center FIR interpolator
|
|
1340
|
+
dmo = d - o; // assumed >=0 [d > (N-1)/2]
|
|
1341
|
+
id = int(dmo);
|
|
1342
|
+
fd = o + frac(dmo);
|
|
1343
|
+
h(N,d,n) = facs1(N,d,n) * facs2(N,d,n);
|
|
1344
|
+
facs1(N,d,n) = select2(n,1,prod(k,max(1,n),select2(k<n,1,fac(d,n,k))));
|
|
1345
|
+
facs2(N,d,n) = select2(n<N,1,prod(l,max(1,N-n),fac(d,n,l+n+1)));
|
|
1346
|
+
fac(d,n,k) = (d-k)/((n-k)+(n==k));
|
|
1347
|
+
// Explicit formula for Lagrange interpolation coefficients:
|
|
1348
|
+
// h_d(n) = \prod_{\stackrel{k=0}{k\neq n}}^N \frac{d-k}{n-k}, n=0:N
|
|
1349
|
+
};
|
|
1350
|
+
|
|
1351
|
+
// Backward compatibility:
|
|
1352
|
+
fdelay1 = fdelayltv(1);
|
|
1353
|
+
fdelay2 = fdelayltv(2);
|
|
1354
|
+
fdelay3 = fdelayltv(3);
|
|
1355
|
+
fdelay4 = fdelayltv(4);
|
|
1356
|
+
fdelay5 = fdelayltv(5);
|
|
1357
|
+
|
|
1358
|
+
//====================== Thiran Allpass Interpolation =====================
|
|
1359
|
+
// Reference:
|
|
1360
|
+
// https://ccrma.stanford.edu/~jos/pasp/Thiran_Allpass_Interpolators.html
|
|
1361
|
+
//
|
|
1362
|
+
//---------------- fdelay1a, fdelay2a, fdelay3a, fdelay4a -------------
|
|
1363
|
+
// Delay lines interpolated using Thiran allpass interpolation
|
|
1364
|
+
// USAGE: fdelayNa(maxdelay, delay, inputsignal)
|
|
1365
|
+
// (exactly like fdelay in music.lib)
|
|
1366
|
+
// where N=1,2,3, or 4 is the order of the Thiran interpolation filter,
|
|
1367
|
+
// and the delay argument is at least N - 1/2.
|
|
1368
|
+
//
|
|
1369
|
+
// (Move the following and similar notes above to filter-lib-doc.txt?)
|
|
1370
|
+
//
|
|
1371
|
+
// NOTE: The interpolated delay should not be less than N - 1/2.
|
|
1372
|
+
// (The allpass delay ranges from N - 1/2 to N + 1/2.)
|
|
1373
|
+
// This constraint can be alleviated by altering the code,
|
|
1374
|
+
// but be aware that allpass filters approach zero delay
|
|
1375
|
+
// by means of pole-zero cancellations.
|
|
1376
|
+
// The delay range [N-1/2,N+1/2] is not optimal. What is?
|
|
1377
|
+
//
|
|
1378
|
+
// NOTE: Delay arguments too small will produce an UNSTABLE allpass!
|
|
1379
|
+
//
|
|
1380
|
+
// NOTE: Because allpass interpolation is recursive, it is not as robust
|
|
1381
|
+
// as Lagrange interpolation under time-varying conditions.
|
|
1382
|
+
// (You may hear clicks when changing the delay rapidly.)
|
|
1383
|
+
//
|
|
1384
|
+
// first-order allpass interpolation, delay d in [0.5,1.5]
|
|
1385
|
+
fdelay1a(n,d,x) = delay(n,id,x) : tf1(eta,1,eta)
|
|
1386
|
+
with {
|
|
1387
|
+
o = 0.49999; // offset to make life easy for allpass
|
|
1388
|
+
dmo = d - o; // assumed nonnegative
|
|
1389
|
+
id = int(dmo);
|
|
1390
|
+
fd = o + frac(dmo);
|
|
1391
|
+
eta = (1-fd)/(1+fd); // allpass coefficient
|
|
1392
|
+
};
|
|
1393
|
+
|
|
1394
|
+
// second-order allpass delay in [1.5,2.5]
|
|
1395
|
+
fdelay2a(n,d,x) = delay(n,id,x) : tf2(a2,a1,1,a1,a2)
|
|
1396
|
+
with {
|
|
1397
|
+
o = 1.49999;
|
|
1398
|
+
dmo = d - o; // delay range is [order-1/2, order+1/2]
|
|
1399
|
+
id = int(dmo);
|
|
1400
|
+
fd = o + frac(dmo);
|
|
1401
|
+
a1o2 = (2-fd)/(1+fd); // share some terms (the compiler does this anyway)
|
|
1402
|
+
a1 = 2*a1o2;
|
|
1403
|
+
a2 = a1o2*(1-fd)/(2+fd);
|
|
1404
|
+
};
|
|
1405
|
+
|
|
1406
|
+
// third-order allpass delay in [2.5,3.5]
|
|
1407
|
+
// delay d should be at least 2.5
|
|
1408
|
+
fdelay3a(n,d,x) = delay(n,id,x) : iir((a3,a2,a1,1),(a1,a2,a3))
|
|
1409
|
+
with {
|
|
1410
|
+
o = 2.49999;
|
|
1411
|
+
dmo = d - o;
|
|
1412
|
+
id = int(dmo);
|
|
1413
|
+
fd = o + frac(dmo);
|
|
1414
|
+
a1o3 = (3-fd)/(1+fd);
|
|
1415
|
+
a2o3 = a1o3*(2-fd)/(2+fd);
|
|
1416
|
+
a1 = 3*a1o3;
|
|
1417
|
+
a2 = 3*a2o3;
|
|
1418
|
+
a3 = a2o3*(1-fd)/(3+fd);
|
|
1419
|
+
};
|
|
1420
|
+
|
|
1421
|
+
// fourth-order allpass delay in [3.5,4.5]
|
|
1422
|
+
// delay d should be at least 3.5
|
|
1423
|
+
fdelay4a(n,d,x) = delay(n,id,x) : iir((a4,a3,a2,a1,1),(a1,a2,a3,a4))
|
|
1424
|
+
with {
|
|
1425
|
+
o = 3.49999;
|
|
1426
|
+
dmo = d - o;
|
|
1427
|
+
id = int(dmo);
|
|
1428
|
+
fd = o + frac(dmo);
|
|
1429
|
+
a1o4 = (4-fd)/(1+fd);
|
|
1430
|
+
a2o6 = a1o4*(3-fd)/(2+fd);
|
|
1431
|
+
a3o4 = a2o6*(2-fd)/(3+fd);
|
|
1432
|
+
a1 = 4*a1o4;
|
|
1433
|
+
a2 = 6*a2o6;
|
|
1434
|
+
a3 = 4*a3o4;
|
|
1435
|
+
a4 = a3o4*(1-fd)/(4+fd);
|
|
1436
|
+
};
|
|
1437
|
+
|
|
1438
|
+
//================ Mth-Octave Filter-Banks and Spectrum-Analyzers ============
|
|
1439
|
+
// Mth-octave filter-banks and spectrum-analyzers split the input signal into a
|
|
1440
|
+
// bank of parallel signals, one for each spectral band. The parameters are
|
|
1441
|
+
//
|
|
1442
|
+
// M = number of band-slices per octave (>1)
|
|
1443
|
+
// N = total number of bands (>2)
|
|
1444
|
+
// ftop = upper bandlimit of the Mth-octave bands (<SR/2)
|
|
1445
|
+
//
|
|
1446
|
+
// In addition to the Mth-octave output signals, there is a highpass signal
|
|
1447
|
+
// containing frequencies from ftop to SR/2, and a "dc band" lowpass signal
|
|
1448
|
+
// containing frequencies from 0 (dc) up to the start of the Mth-octave bands.
|
|
1449
|
+
// Thus, the N output signals are
|
|
1450
|
+
//
|
|
1451
|
+
// highpass(ftop), MthOctaveBands(M,N-2,ftop), dcBand(ftop*2^(-M*(N-1)))
|
|
1452
|
+
//
|
|
1453
|
+
// A FILTER-BANK is defined here as a signal bandsplitter having the
|
|
1454
|
+
// property that summing its output signals gives an allpass-filtered
|
|
1455
|
+
// version of the filter-bank input signal. A more conventional term for
|
|
1456
|
+
// this is an "allpass-complementary filter bank". If the allpass filter
|
|
1457
|
+
// is a pure delay (and possible scaling), the filter bank is said to be
|
|
1458
|
+
// a "perfect-reconstruction filter bank" (see Vaidyanathan-1993 cited
|
|
1459
|
+
// below for details). A "graphic equalizer", in which band signals
|
|
1460
|
+
// are scaled by gains and summed, should be based on a filter bank.
|
|
1461
|
+
//
|
|
1462
|
+
// A SPECTRUM-ANALYZER is defined here as any band-split whose bands span
|
|
1463
|
+
// the relevant spectrum, but whose band-signals do not
|
|
1464
|
+
// necessarily sum to the original signal, either exactly or to within an
|
|
1465
|
+
// allpass filtering. Spectrum analyzer outputs are normally at least nearly
|
|
1466
|
+
// "power complementary", i.e., the power spectra of the individual bands
|
|
1467
|
+
// sum to the original power spectrum (to within some negligible tolerance).
|
|
1468
|
+
//
|
|
1469
|
+
// The filter-banks below are implemented as Butterworth or Elliptic
|
|
1470
|
+
// spectrum-analyzers followed by delay equalizers that make them
|
|
1471
|
+
// allpass-complementary.
|
|
1472
|
+
//
|
|
1473
|
+
// INCREASING CHANNEL ISOLATION
|
|
1474
|
+
// Go to higher filter orders - see Regalia et al. or Vaidyanathan (cited
|
|
1475
|
+
// below) regarding the construction of more aggressive recursive
|
|
1476
|
+
// filter-banks using elliptic or Chebyshev prototype filters.
|
|
1477
|
+
//
|
|
1478
|
+
// REFERENCES
|
|
1479
|
+
// - "Tree-structured complementary filter banks using all-pass sections",
|
|
1480
|
+
// Regalia et al., IEEE Trans. Circuits & Systems, CAS-34:1470-1484, Dec. 1987
|
|
1481
|
+
// - "Multirate Systems and Filter Banks", P. Vaidyanathan, Prentice-Hall, 1993
|
|
1482
|
+
// - Elementary filter theory: https://ccrma.stanford.edu/~jos/filters/
|
|
1483
|
+
//
|
|
1484
|
+
//------------------------- mth_octave_analyzer ----------------------------
|
|
1485
|
+
//
|
|
1486
|
+
// USAGE
|
|
1487
|
+
// _ : mth_octave_analyzer(O,M,ftop,N) : par(i,N,_); // Oth-order Butterworth
|
|
1488
|
+
// _ : mth_octave_analyzer6e(M,ftop,N) : par(i,N,_); // 6th-order elliptic
|
|
1489
|
+
//
|
|
1490
|
+
// where
|
|
1491
|
+
// O = order of filter used to split each frequency band into two
|
|
1492
|
+
// M = number of band-slices per octave
|
|
1493
|
+
// ftop = highest band-split crossover frequency (e.g., 20 kHz)
|
|
1494
|
+
// N = total number of bands (including dc and Nyquist)
|
|
1495
|
+
//
|
|
1496
|
+
// ACKNOWLEDGMENT
|
|
1497
|
+
// Recursive band-splitting formulation improved by Yann Orlarey.
|
|
1498
|
+
|
|
1499
|
+
mth_octave_analyzer6e(M,ftop,N) = _ <: bsplit(N-1) with {
|
|
1500
|
+
fc(n) = ftop * 2^(float(n-N+1)/float(M)); // -3dB crossover frequencies
|
|
1501
|
+
lp(n) = lowpass6e(fc(n)); // 6th-order elliptic - see other choices above
|
|
1502
|
+
hp(n) = highpass6e(fc(n)); // (search for lowpass* and highpass*)
|
|
1503
|
+
bsplit(0) = _;
|
|
1504
|
+
bsplit(i) = hp(i), (lp(i) <: bsplit(i-1));
|
|
1505
|
+
};
|
|
1506
|
+
|
|
1507
|
+
// Butterworth analyzers may be cascaded with allpass
|
|
1508
|
+
// delay-equalizers to make (allpass-complementary) filter banks:
|
|
1509
|
+
|
|
1510
|
+
mth_octave_analyzer(O,M,ftop,N) = _ <: bsplit(N-1) with {
|
|
1511
|
+
fc(n) = ftop * 2^(float(n-N+1)/float(M));
|
|
1512
|
+
lp(n) = lowpass(O,fc(n)); // Order O Butterworth
|
|
1513
|
+
hp(n) = highpass(O,fc(n));
|
|
1514
|
+
bsplit(0) = _;
|
|
1515
|
+
bsplit(i) = hp(i), (lp(i) <: bsplit(i-1));
|
|
1516
|
+
};
|
|
1517
|
+
|
|
1518
|
+
mth_octave_analyzer3(M,ftop,N) = mth_octave_analyzer(3,M,ftop,N);
|
|
1519
|
+
mth_octave_analyzer5(M,ftop,N) = mth_octave_analyzer(5,M,ftop,N);
|
|
1520
|
+
mth_octave_analyzer_default = mth_octave_analyzer6e; // default analyzer
|
|
1521
|
+
|
|
1522
|
+
//------------------------ mth_octave_filterbank -------------------------
|
|
1523
|
+
// Allpass-complementary filter banks based on Butterworth band-splitting.
|
|
1524
|
+
// For Butterworth band-splits, the needed delay equalizer is easily found.
|
|
1525
|
+
|
|
1526
|
+
mth_octave_filterbank(O,M,ftop,N) =
|
|
1527
|
+
mth_octave_analyzer(O,M,ftop,N) :
|
|
1528
|
+
delayeq(N) with {
|
|
1529
|
+
fc(n) = ftop * 2^(float(n-N+1)/float(M)); // -3dB crossover frequencies
|
|
1530
|
+
ap(n) = highpass_plus_lowpass(O,fc(n)); // delay-equalizing allpass
|
|
1531
|
+
delayeq(N) = par(i,N-2,apchain(i+1)), _, _;
|
|
1532
|
+
apchain(i) = seq(j,N-1-i,ap(j+1));
|
|
1533
|
+
};
|
|
1534
|
+
|
|
1535
|
+
// dc-inverted version. This reduces the delay-equalizer order for odd O.
|
|
1536
|
+
// Negating the input signal makes the dc band noninverting
|
|
1537
|
+
// and all higher bands sign-inverted (if preferred).
|
|
1538
|
+
mth_octave_filterbank_alt(O,M,ftop,N) =
|
|
1539
|
+
mth_octave_analyzer(O,M,ftop,N) : delayeqi(O,N) with {
|
|
1540
|
+
fc(n) = ftop * 2^(float(n-N+1)/float(M)); // -3dB crossover frequencies
|
|
1541
|
+
ap(n) = highpass_minus_lowpass(O,fc(n)); // half the order of 'plus' case
|
|
1542
|
+
delayeqi(N) = par(i,N-2,apchain(i+1)), _, *(-1.0);
|
|
1543
|
+
apchain(i) = seq(j,N-1-i,ap(j+1));
|
|
1544
|
+
};
|
|
1545
|
+
|
|
1546
|
+
// Note that even-order cases require complex coefficients.
|
|
1547
|
+
// See Vaidyanathan 1993 and papers cited there for more info.
|
|
1548
|
+
|
|
1549
|
+
mth_octave_filterbank3(M,ftop,N) = mth_octave_filterbank_alt(3,M,ftop,N);
|
|
1550
|
+
mth_octave_filterbank5(M,ftop,N) = mth_octave_filterbank(5,M,ftop,N);
|
|
1551
|
+
|
|
1552
|
+
mth_octave_filterbank_default = mth_octave_filterbank5;
|
|
1553
|
+
|
|
1554
|
+
//======================= Mth-Octave Spectral Level =========================
|
|
1555
|
+
// Spectral Level: Display (in bar graphs) the average signal level in each
|
|
1556
|
+
// spectral band.
|
|
1557
|
+
//
|
|
1558
|
+
//------------------------ mth_octave_spectral_level -------------------------
|
|
1559
|
+
// USAGE: _ : mth_octave_spectral_level(M,ftop,NBands,tau,dB_offset);
|
|
1560
|
+
// where
|
|
1561
|
+
// M = bands per octave
|
|
1562
|
+
// ftop = lower edge frequency of top band
|
|
1563
|
+
// NBands = number of passbands (including highpass and dc bands),
|
|
1564
|
+
// tau = spectral display averaging-time (time constant) in seconds,
|
|
1565
|
+
// dB_offset = constant dB offset in all band level meters.
|
|
1566
|
+
//
|
|
1567
|
+
mth_octave_spectral_level6e(M,ftop,N,tau,dB_offset) = _<:
|
|
1568
|
+
_,mth_octave_analyzer6e(M,ftop,N) :
|
|
1569
|
+
_,(display:>_):attach with {
|
|
1570
|
+
display = par(i,N,dbmeter(i));
|
|
1571
|
+
dbmeter(i) = abs : smooth(tau2pole(tau)) : linear2db : +(dB_offset) :
|
|
1572
|
+
meter(N-i-1);
|
|
1573
|
+
meter(i) = speclevel_group(vbargraph("[%2i] [unit:dB]
|
|
1574
|
+
[tooltip: Spectral Band Level in dB]", -50, 10));
|
|
1575
|
+
O = int(((N-2)/M)+0.4999);
|
|
1576
|
+
speclevel_group(x) = hgroup("[0] CONSTANT-Q SPECTRUM ANALYZER (6E), %N bands spanning LP, %O octaves below %ftop Hz, HP
|
|
1577
|
+
[tooltip: See Faust's filter.lib for documentation and references]", x);
|
|
1578
|
+
};
|
|
1579
|
+
|
|
1580
|
+
mth_octave_spectral_level_default = mth_octave_spectral_level6e;
|
|
1581
|
+
spectral_level = mth_octave_spectral_level(2,10000,20); // simple default
|
|
1582
|
+
|
|
1583
|
+
//---------------------- mth_octave_spectral_level_demo ----------------------
|
|
1584
|
+
// Demonstrate mth_octave_spectral_level in a standalone GUI.
|
|
1585
|
+
//
|
|
1586
|
+
// USAGE: _ : mth_octave_spectral_level_demo(BandsPerOctave);
|
|
1587
|
+
|
|
1588
|
+
mth_octave_spectral_level_demo(M) =
|
|
1589
|
+
mth_octave_spectral_level_default(M,ftop,N,tau,dB_offset)
|
|
1590
|
+
with {
|
|
1591
|
+
ftop = 16000;
|
|
1592
|
+
Noct = 10; // number of octaves down from ftop
|
|
1593
|
+
// Lowest band-edge is at ftop*2^(-Noct+2) = 62.5 Hz when ftop=16 kHz:
|
|
1594
|
+
N = int(Noct*M); // without 'int()', segmentation fault observed for M=1.67
|
|
1595
|
+
ctl_group(x) = hgroup("[1] SPECTRUM ANALYZER CONTROLS", x);
|
|
1596
|
+
tau = ctl_group(hslider("[0] Level Averaging Time [unit:ms] [scale:log]
|
|
1597
|
+
[tooltip: band-level averaging time in milliseconds]",
|
|
1598
|
+
100,1,10000,1)) * 0.001;
|
|
1599
|
+
dB_offset = ctl_group(hslider("[1] Level dB Offset [unit:dB]
|
|
1600
|
+
[tooltip: Level offset in decibels]",
|
|
1601
|
+
50,0,100,1));
|
|
1602
|
+
};
|
|
1603
|
+
|
|
1604
|
+
spectral_level_demo = mth_octave_spectral_level_demo(1.5); // 2/3 octave
|
|
1605
|
+
|
|
1606
|
+
//---------------- (third|half)_octave_(analyzer|filterbank) -----------------
|
|
1607
|
+
|
|
1608
|
+
// Named special cases of mth_octave_* with defaults filled in:
|
|
1609
|
+
|
|
1610
|
+
third_octave_analyzer(N) = mth_octave_analyzer_default(3,10000,N);
|
|
1611
|
+
third_octave_filterbank(N) = mth_octave_filterbank_default(3,10000,N);
|
|
1612
|
+
// Third-Octave Filter-Banks have been used in audio for over a century.
|
|
1613
|
+
// See, e.g.,
|
|
1614
|
+
// Acoustics [the book], by L. L. Beranek
|
|
1615
|
+
// Amer. Inst. Physics for the Acoustical Soc. America,
|
|
1616
|
+
// http://asa.aip.org/publications.html, 1986 (1st ed.1954)
|
|
1617
|
+
|
|
1618
|
+
// Third-octave bands across the audio spectrum are too wide for current
|
|
1619
|
+
// typical computer screens, so half-octave bands are the default:
|
|
1620
|
+
half_octave_analyzer(N) = mth_octave_analyzer_default(2,10000,N);
|
|
1621
|
+
half_octave_filterbank(N) = mth_octave_filterbank_default(2,10000,N);
|
|
1622
|
+
|
|
1623
|
+
octave_filterbank(N) = mth_octave_filterbank_default(1,10000,N);
|
|
1624
|
+
octave_analyzer(N) = mth_octave_analyzer_default(1,10000,N);
|
|
1625
|
+
|
|
1626
|
+
//=========================== Filter-Bank Demos ==============================
|
|
1627
|
+
// Graphic Equalizer: Each filter-bank output signal routes through a fader.
|
|
1628
|
+
//
|
|
1629
|
+
// USAGE: _ : mth_octave_filterbank_demo(M) : _
|
|
1630
|
+
// where
|
|
1631
|
+
// M = number of bands per octave
|
|
1632
|
+
|
|
1633
|
+
mth_octave_filterbank_demo(M) = bp1(bp,mthoctavefilterbankdemo) with {
|
|
1634
|
+
bp1 = component("effect.lib").bypass1;
|
|
1635
|
+
mofb_group(x) = vgroup("CONSTANT-Q FILTER BANK (Butterworth dyadic tree)
|
|
1636
|
+
[tooltip: See Faust's filter.lib for documentation and references]", x);
|
|
1637
|
+
bypass_group(x) = mofb_group(hgroup("[0]", x));
|
|
1638
|
+
slider_group(x) = mofb_group(hgroup("[1]", x));
|
|
1639
|
+
N = 10*M; // total number of bands (highpass band, octave-bands, dc band)
|
|
1640
|
+
ftop = 10000;
|
|
1641
|
+
mthoctavefilterbankdemo = chan;
|
|
1642
|
+
chan = mth_octave_filterbank_default(M,ftop,N) :
|
|
1643
|
+
sum(i,N,(*(db2linear(fader(N-i)))));
|
|
1644
|
+
fader(i) = slider_group(vslider("[%2i] [unit:dB]
|
|
1645
|
+
[tooltip: Bandpass filter gain in dB]", -10, -70, 10, 0.1)) :
|
|
1646
|
+
smooth(0.999);
|
|
1647
|
+
bp = bypass_group(checkbox("[0] Bypass
|
|
1648
|
+
[tooltip: When this is checked, the filter-bank has no effect]"));
|
|
1649
|
+
};
|
|
1650
|
+
|
|
1651
|
+
filterbank_demo = mth_octave_filterbank_demo(1); // octave-bands = default
|
|
1652
|
+
|
|
1653
|
+
//=========== Arbritary-Crossover Filter-Banks and Spectrum Analyzers ========
|
|
1654
|
+
// These are similar to the Mth-octave filter-banks above, except that the
|
|
1655
|
+
// band-split frequencies are passed explicitly as arguments.
|
|
1656
|
+
//
|
|
1657
|
+
// USAGE:
|
|
1658
|
+
// _ : filterbank (O,freqs) : par(i,N,_); // Butterworth band-splits
|
|
1659
|
+
// _ : filterbanki(O,freqs) : par(i,N,_); // Inverted-dc version
|
|
1660
|
+
// _ : analyzer (O,freqs) : par(i,N,_); // No delay equalizer
|
|
1661
|
+
//
|
|
1662
|
+
// where
|
|
1663
|
+
// O = band-split filter order (ODD integer required for filterbank[i])
|
|
1664
|
+
// freqs = (fc1,fc2,...,fcNs) [in numerically ascending order], where
|
|
1665
|
+
// Ns=N-1 is the number of octave band-splits
|
|
1666
|
+
// (total number of bands N=Ns+1).
|
|
1667
|
+
//
|
|
1668
|
+
// If frequencies are listed explicitly as arguments, enclose them in parens:
|
|
1669
|
+
//
|
|
1670
|
+
// _ : filterbank(3,(fc1,fc2)) : _,_,_
|
|
1671
|
+
//
|
|
1672
|
+
// ACKNOWLEDGMENT
|
|
1673
|
+
// Technique for processing a variable number of signal arguments due
|
|
1674
|
+
// to Yann Orlarey (as is the entire Faust framework!)
|
|
1675
|
+
//
|
|
1676
|
+
//------------------------------ analyzer --------------------------------------
|
|
1677
|
+
analyzer(O,lfreqs) = _ <: bsplit(nb) with
|
|
1678
|
+
{
|
|
1679
|
+
nb = count(lfreqs);
|
|
1680
|
+
fc(n) = take(n, lfreqs);
|
|
1681
|
+
lp(n) = lowpass(O,fc(n));
|
|
1682
|
+
hp(n) = highpass(O,fc(n));
|
|
1683
|
+
bsplit(0) = _;
|
|
1684
|
+
bsplit(i) = hp(i), (lp(i) <: bsplit(i-1));
|
|
1685
|
+
};
|
|
1686
|
+
|
|
1687
|
+
//----------------------------- filterbank -------------------------------------
|
|
1688
|
+
filterbank(O,lfreqs) = analyzer(O,lfreqs) : delayeq(nb) with
|
|
1689
|
+
{
|
|
1690
|
+
nb = count(lfreqs);
|
|
1691
|
+
fc(n) = take(n, lfreqs);
|
|
1692
|
+
ap(n) = highpass_plus_lowpass(O,fc(n));
|
|
1693
|
+
delayeq(1) = _,_; // par(i,0,...) does not fly
|
|
1694
|
+
delayeq(nb) = par(i,nb-1,apchain(nb-1-i)),_,_;
|
|
1695
|
+
apchain(0) = _;
|
|
1696
|
+
apchain(i) = ap(i) : apchain(i-1);
|
|
1697
|
+
};
|
|
1698
|
+
|
|
1699
|
+
//----------------------------- filterbanki ------------------------------------
|
|
1700
|
+
filterbanki(O,lfreqs) = _ <: bsplit(nb) with
|
|
1701
|
+
{
|
|
1702
|
+
fc(n) = take(n, lfreqs);
|
|
1703
|
+
lp(n) = lowpass(O,fc(n));
|
|
1704
|
+
hp(n) = highpass(O,fc(n));
|
|
1705
|
+
ap(n) = highpass_minus_lowpass(O,fc(n));
|
|
1706
|
+
bsplit(0) = *(-1.0);
|
|
1707
|
+
bsplit(i) = (hp(i) : delayeq(i-1)), (lp(i) <: bsplit(i-1));
|
|
1708
|
+
delayeq(0) = _; // moving the *(-1) here inverts all outputs BUT dc
|
|
1709
|
+
delayeq(i) = ap(i) : delayeq(i-1);
|
|
1710
|
+
};
|