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