├── .clang-format ├── .dockerignore ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bugreport.yaml │ └── feature_request.md ├── .gitignore ├── .gitmodules ├── .vscode ├── c_cpp_properties.json ├── launch.json ├── settings.save.json ├── tasks.json └── vscode.h ├── AUTHORS.md ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSES └── GPL3.txt ├── README.md ├── data ├── acknowledgements.txt ├── developers.txt ├── fonts │ ├── Roboto-LICENSE.txt │ ├── Roboto-Regular.ttf │ └── meson.build ├── images │ ├── element-icon-v1.svg │ ├── icon-template.png │ ├── icon.png │ ├── meson.build │ └── power_48x48.png ├── meson.build ├── screenshot.png └── sessions │ ├── atomports.els │ ├── datadial.els │ ├── embeds.els │ ├── musicbox.els │ └── pluginstack.els ├── deploy ├── au │ ├── component.js │ ├── meson.build │ └── package.xml ├── config.xml ├── control.js ├── element │ ├── component.js │ ├── meson.build │ └── package.xml ├── installer-linux.sh.in ├── installer-macos.sh.in ├── installer.bat.in ├── linux │ ├── appimage-docker.sh │ ├── appimage.sh │ ├── element.desktop.in │ ├── entrypoint.sh │ ├── icon_256x256.png │ └── meson.build ├── meson.build ├── osx │ ├── Icon.icns │ ├── Info.plist.in │ ├── app.entitlements │ ├── bundle.sh │ ├── meson.build │ ├── plugin.entitlements │ └── run.sh ├── updater │ ├── component.js │ ├── meson.build │ └── package.xml ├── vst │ ├── component.js │ ├── meson.build │ └── package.xml ├── vst3 │ ├── component.js │ ├── meson.build │ └── package.xml └── windows │ └── jenkins.sh ├── docs ├── building.md ├── config.ld ├── cppstyle.md ├── luastyle.md └── meson.build ├── include └── element │ ├── aligneddata.hpp │ ├── arc.hpp │ ├── atombuffer.hpp │ ├── atomic.hpp │ ├── audioengine.hpp │ ├── context.hpp │ ├── controller.hpp │ ├── datapath.hpp │ ├── datapipe.hpp │ ├── devices.hpp │ ├── element.h │ ├── element.hpp │ ├── engine.hpp │ ├── filesystem.hpp │ ├── graph.hpp │ ├── gzip.hpp │ ├── juce.hpp │ ├── juce │ ├── audio_basics.hpp │ ├── audio_devices.hpp │ ├── audio_formats.hpp │ ├── audio_processors.hpp │ ├── core.hpp │ ├── data_structures.hpp │ ├── dsp.hpp │ ├── events.hpp │ ├── graphics.hpp │ ├── gui_basics.hpp │ ├── gui_extra.hpp │ ├── meson.build │ └── osc.hpp │ ├── linkedlist.hpp │ ├── lua.hpp │ ├── lv2.hpp │ ├── meson.build │ ├── midichannels.hpp │ ├── midiiomonitor.hpp │ ├── midipipe.hpp │ ├── model.hpp │ ├── node.h │ ├── node.hpp │ ├── nodefactory.hpp │ ├── nodeproxy.hpp │ ├── oversampler.hpp │ ├── parameter.hpp │ ├── plugins.hpp │ ├── portcount.hpp │ ├── porttype.hpp │ ├── presets.hpp │ ├── processor.hpp │ ├── runmode.hpp │ ├── script.hpp │ ├── services.hpp │ ├── session.hpp │ ├── settings.hpp │ ├── shuttle.hpp │ ├── signals.hpp │ ├── symbolmap.hpp │ ├── tags.hpp │ ├── timescale.hpp │ ├── transport.hpp │ ├── ui.hpp │ ├── ui │ ├── about.hpp │ ├── commands.hpp │ ├── content.hpp │ ├── decibelscale.hpp │ ├── designer.hpp │ ├── grapheditor.hpp │ ├── mainwindow.hpp │ ├── menumodels.hpp │ ├── meterbridge.hpp │ ├── navigation.hpp │ ├── nodeeditor.hpp │ ├── popups.hpp │ ├── preferences.hpp │ ├── simplemeter.hpp │ ├── standard.hpp │ ├── style.hpp │ ├── updater.hpp │ └── view.hpp │ └── version.hpp ├── meson.build ├── meson ├── appimage.ini ├── deploy.ini ├── deps │ └── meson.build ├── juce │ └── meson.build ├── linux.ini ├── msvc.ini ├── osx-intel.ini ├── osx.ini ├── subs.ini └── x86_64-w64-mingw32.ini ├── meson_options.txt ├── plugins ├── auclient.mm ├── audiounit.plist.in ├── auwrapper.mm ├── effect │ ├── au │ │ └── meson.build │ ├── plugin.cpp │ ├── pluginconfig.h │ ├── vst2 │ │ └── meson.build │ └── vst3 │ │ ├── bundle │ │ └── meson.build │ │ └── meson.build ├── instrument │ ├── au │ │ └── meson.build │ ├── plugin.cpp │ ├── pluginconfig.h │ ├── vst2 │ │ └── meson.build │ └── vst3 │ │ ├── bundle │ │ └── meson.build │ │ └── meson.build ├── macvstutils.mm ├── meson.build ├── midieffect │ ├── au │ │ └── meson.build │ ├── plugin.cpp │ └── pluginconfig.h ├── plugin.plist.in ├── utilities.cpp ├── vst2client.cpp ├── vst2client.mm ├── vst3client.cpp └── vst3client.mm ├── scripts ├── amp.lua ├── ampui.lua ├── channelize.lua ├── commands.lua ├── component.js ├── console.lua ├── content.lua ├── meson.build ├── package.xml └── view.lua ├── src ├── .clang-format ├── ElementApp.h ├── appinfo.hpp ├── arc.cpp ├── atombuffer.cpp ├── bindings.cpp ├── commands.cpp ├── common.hpp ├── context.cpp ├── controller.cpp ├── datapath.cpp ├── datapath.hpp ├── delaylockedloop.hpp ├── devicemanager.cpp ├── dlfcn-win32.c ├── dlfcn-win32.h ├── dynlib.h ├── el │ ├── AudioBuffer.lua │ ├── AudioBuffer32.cpp │ ├── AudioBuffer64.cpp │ ├── AudioBufferImpl.ipp │ ├── Bounds.cpp │ ├── Commands.cpp │ ├── Content.cpp │ ├── Context.cpp │ ├── Desktop.cpp │ ├── Graph.cpp │ ├── GraphEditor.cpp │ ├── Graphics.cpp │ ├── MidiBuffer.cpp │ ├── MidiMessage.cpp │ ├── MouseEvent.cpp │ ├── Node.cpp │ ├── Parameter.cpp │ ├── Point.cpp │ ├── Range.cpp │ ├── Rectangle.cpp │ ├── Session.cpp │ ├── Slider.cpp │ ├── TextButton.cpp │ ├── View.cpp │ ├── Widget.cpp │ ├── audio.c │ ├── bytes.c │ ├── bytes.h │ ├── color.lua │ ├── command.lua │ ├── factories.hpp │ ├── midi.c │ ├── midi_buffer.hpp │ ├── nodetype.hpp │ ├── object.hpp │ ├── object.lua │ ├── packed.h │ ├── rectangle.hpp │ ├── round.c │ ├── script.lua │ ├── session.lua │ ├── sol_helpers.hpp │ ├── strings.lua │ ├── util.h │ ├── vector.c │ └── widget.hpp ├── engine │ ├── audioengine.cpp │ ├── audioprocessorfactory.hpp │ ├── clapprovider.cpp │ ├── clapprovider.hpp │ ├── graphbuilder.cpp │ ├── graphbuilder.hpp │ ├── graphmanager.cpp │ ├── graphmanager.hpp │ ├── graphnode.cpp │ ├── graphnode.hpp │ ├── internalformat.cpp │ ├── internalformat.hpp │ ├── ionode.cpp │ ├── ionode.hpp │ ├── jack.cpp │ ├── jack.hpp │ ├── linearfade.hpp │ ├── mappingengine.cpp │ ├── mappingengine.hpp │ ├── midichannelmap.hpp │ ├── midiclock.cpp │ ├── midiclock.hpp │ ├── midiengine.cpp │ ├── midiengine.hpp │ ├── midipanic.hpp │ ├── midipipe.cpp │ ├── miditranspose.hpp │ ├── nodefactory.cpp │ ├── oversampler.cpp │ ├── parameter.cpp │ ├── portbuffer.cpp │ ├── portbuffer.hpp │ ├── processor.cpp │ ├── rootgraph.cpp │ ├── rootgraph.hpp │ ├── shuttle.cpp │ ├── togglegrid.hpp │ ├── trace.hpp │ ├── transport.cpp │ └── velocitycurve.hpp ├── experimental │ └── el │ │ ├── DocumentWindow.cpp │ │ └── File.cpp ├── feature_store.hpp ├── filesystemwatcher.cpp ├── filesystemwatcher.hpp ├── filesystemwatcher.mm ├── graph.cpp ├── gzip.cpp ├── juce │ ├── .clang-format │ ├── AppConfig.h │ ├── JuceHeader.h │ ├── JucePluginDefines.h │ ├── include_juce_audio_basics.cpp │ ├── include_juce_audio_basics.mm │ ├── include_juce_audio_devices.cpp │ ├── include_juce_audio_devices.mm │ ├── include_juce_audio_formats.cpp │ ├── include_juce_audio_formats.mm │ ├── include_juce_audio_plugin_client_AU.r │ ├── include_juce_audio_plugin_client_AU_1.mm │ ├── include_juce_audio_plugin_client_AU_2.mm │ ├── include_juce_audio_plugin_client_VST2.cpp │ ├── include_juce_audio_plugin_client_VST3.cpp │ ├── include_juce_audio_plugin_client_utils.cpp │ ├── include_juce_audio_processors.cpp │ ├── include_juce_audio_processors.mm │ ├── include_juce_audio_processors_lv2_libs.cpp │ ├── include_juce_audio_utils.cpp │ ├── include_juce_audio_utils.mm │ ├── include_juce_core.cpp │ ├── include_juce_core.mm │ ├── include_juce_cryptography.cpp │ ├── include_juce_cryptography.mm │ ├── include_juce_data_structures.cpp │ ├── include_juce_data_structures.mm │ ├── include_juce_dsp.cpp │ ├── include_juce_dsp.mm │ ├── include_juce_events.cpp │ ├── include_juce_events.mm │ ├── include_juce_graphics.cpp │ ├── include_juce_graphics.mm │ ├── include_juce_gui_basics.cpp │ ├── include_juce_gui_basics.mm │ ├── include_juce_gui_extra.cpp │ ├── include_juce_gui_extra.mm │ ├── include_juce_osc.cpp │ ├── include_kv_core.cpp │ ├── include_kv_core.mm │ ├── include_kv_engines.cpp │ ├── include_kv_engines.mm │ ├── include_kv_gui.cpp │ ├── include_kv_gui.mm │ ├── include_kv_models.cpp │ ├── include_kv_models.mm │ ├── jbridge.cpp │ └── meson.build ├── log.hpp ├── lua │ ├── .clang-format │ ├── .gitignore │ ├── meson.build │ ├── sol │ │ └── sol │ │ │ ├── config.hpp │ │ │ ├── forward.hpp │ │ │ └── sol.hpp │ └── src │ │ ├── Makefile │ │ ├── lapi.c │ │ ├── lapi.h │ │ ├── lauxlib.c │ │ ├── lauxlib.h │ │ ├── lbaselib.c │ │ ├── lcode.c │ │ ├── lcode.h │ │ ├── lcorolib.c │ │ ├── lctype.c │ │ ├── lctype.h │ │ ├── ldblib.c │ │ ├── ldebug.c │ │ ├── ldebug.h │ │ ├── ldo.c │ │ ├── ldo.h │ │ ├── ldump.c │ │ ├── lfunc.c │ │ ├── lfunc.h │ │ ├── lgc.c │ │ ├── lgc.h │ │ ├── linit.c │ │ ├── liolib.c │ │ ├── ljumptab.h │ │ ├── llex.c │ │ ├── llex.h │ │ ├── llimits.h │ │ ├── lmathlib.c │ │ ├── lmem.c │ │ ├── lmem.h │ │ ├── loadlib.c │ │ ├── lobject.c │ │ ├── lobject.h │ │ ├── lopcodes.c │ │ ├── lopcodes.h │ │ ├── lopnames.h │ │ ├── loslib.c │ │ ├── lparser.c │ │ ├── lparser.h │ │ ├── lprefix.h │ │ ├── lstate.c │ │ ├── lstate.h │ │ ├── lstring.c │ │ ├── lstring.h │ │ ├── lstrlib.c │ │ ├── ltable.c │ │ ├── ltable.h │ │ ├── ltablib.c │ │ ├── ltm.c │ │ ├── ltm.h │ │ ├── lua.c │ │ ├── lua.h │ │ ├── lua.hpp │ │ ├── luac.c │ │ ├── luaconf.h │ │ ├── lualib.h │ │ ├── lundump.c │ │ ├── lundump.h │ │ ├── lutf8lib.c │ │ ├── lvm.c │ │ ├── lvm.h │ │ ├── lzio.c │ │ └── lzio.h ├── lv2.cpp ├── lv2 │ ├── logfeature.cpp │ ├── logfeature.hpp │ ├── lv2features.hpp │ ├── messages.cpp │ ├── messages.hpp │ ├── module.cpp │ ├── module.hpp │ ├── native.cpp │ ├── native.hpp │ ├── platform.cpp │ ├── platform.mm │ ├── portevent.hpp │ ├── workerfeature.cpp │ ├── workerfeature.hpp │ ├── workthread.cpp │ ├── workthread.hpp │ ├── world.cpp │ └── world.hpp ├── main.cpp ├── manifest.hpp ├── matrixstate.cpp ├── matrixstate.hpp ├── meson.build ├── messages.cpp ├── messages.hpp ├── model.cpp ├── module.cpp ├── module.hpp ├── native_unix.cpp ├── node.cpp ├── nodes │ ├── allpassfilter.hpp │ ├── audiofileplayer.cpp │ ├── audiofileplayer.hpp │ ├── audiomixer.cpp │ ├── audiomixer.hpp │ ├── audioprocessor.hpp │ ├── audioprocessornode.cpp │ ├── audiorouter.cpp │ ├── audiorouter.hpp │ ├── audioroutereditor.cpp │ ├── audioroutereditor.hpp │ ├── baseprocessor.hpp │ ├── channelize.hpp │ ├── colorbars.hpp │ ├── combfilter.hpp │ ├── compressor.cpp │ ├── compressor.hpp │ ├── compressoreditor.cpp │ ├── compressoreditor.hpp │ ├── eqfilter.cpp │ ├── eqfilter.hpp │ ├── eqfiltereditor.cpp │ ├── eqfiltereditor.hpp │ ├── everb.hpp │ ├── freqsplitter.hpp │ ├── genericeditor.cpp │ ├── genericeditor.hpp │ ├── ionodeeditor.hpp │ ├── knobs.cpp │ ├── knobs.hpp │ ├── mcu.hpp │ ├── mediaplayer.cpp │ ├── mediaplayer.hpp │ ├── midichannelmap.hpp │ ├── midichannelsplitter.cpp │ ├── midichannelsplitter.hpp │ ├── mididevice.cpp │ ├── mididevice.hpp │ ├── midideviceeditor.hpp │ ├── midifilter.cpp │ ├── midifilter.hpp │ ├── midimonitor.cpp │ ├── midimonitor.hpp │ ├── midimonitoreditor.cpp │ ├── midimonitoredtor.hpp │ ├── midiprogrammap.cpp │ ├── midiprogrammap.hpp │ ├── midiprogrammapeditor.cpp │ ├── midiprogrammapeditor.hpp │ ├── midirouter.cpp │ ├── midirouter.hpp │ ├── midiroutereditor.cpp │ ├── midiroutereditor.hpp │ ├── midisetlist.cpp │ ├── midisetlist.hpp │ ├── midisetlisteditor.cpp │ ├── midisetlisteditor.hpp │ ├── nodetypes.hpp │ ├── oscreceiver.cpp │ ├── oscreceiver.hpp │ ├── oscreceivereditor.cpp │ ├── oscreceivereditor.hpp │ ├── oscsender.cpp │ ├── oscsender.hpp │ ├── oscsendereditor.cpp │ ├── oscsendereditor.hpp │ ├── placeholder.hpp │ ├── scriptnode.cpp │ ├── scriptnode.hpp │ ├── scriptnodeeditor.cpp │ ├── scriptnodeeditor.hpp │ ├── videomonitor.hpp │ ├── volume.hpp │ ├── volumeeditor.cpp │ ├── volumeeditor.hpp │ └── wetdry.hpp ├── plugineditor.cpp ├── plugineditor.hpp ├── pluginmanager.cpp ├── pluginprocessor.cpp ├── pluginprocessor.hpp ├── presetmanager.hpp ├── res │ ├── icon.ico │ └── resources.rc ├── ringbuffer.cpp ├── ringbuffer.hpp ├── scopedcallback.hpp ├── scopedflag.hpp ├── script.cpp ├── scripting.cpp ├── scripting.hpp ├── scripting │ ├── bindings.cpp │ ├── bindings.hpp │ ├── dspscript.cpp │ ├── dspscript.hpp │ ├── dspuiscript.cpp │ ├── dspuiscript.hpp │ ├── scriptinstance.hpp │ ├── scriptloader.cpp │ ├── scriptloader.hpp │ ├── scriptmanager.cpp │ ├── scriptmanager.hpp │ └── scriptsource.hpp ├── search_path.hpp ├── semaphore.cpp ├── semaphore.hpp ├── services.cpp ├── services │ ├── deviceservice.cpp │ ├── deviceservice.hpp │ ├── engineservice.cpp │ ├── guiservice.cpp │ ├── mappingservice.cpp │ ├── mappingservice.hpp │ ├── oscservice.cpp │ ├── oscservice.hpp │ ├── presetservice.cpp │ ├── presetservice.hpp │ ├── sessionservice.cpp │ └── sessionservice.hpp ├── session.cpp ├── settings.cpp ├── strings.cpp ├── tempo.hpp ├── timescale.cpp ├── ui │ ├── aboutscreen.cpp │ ├── aboutscreen.hpp │ ├── audiodeviceselector.cpp │ ├── audiodeviceselector.hpp │ ├── audioiopanelview.cpp │ ├── audioiopanelview.hpp │ ├── block.cpp │ ├── block.hpp │ ├── blockutils.hpp │ ├── breadcrumb.hpp │ ├── buttons.cpp │ ├── buttons.hpp │ ├── capslock.cpp │ ├── capslock.hpp │ ├── channelstrip.cpp │ ├── channelstrip.hpp │ ├── connectiongrid.cpp │ ├── connectiongrid.hpp │ ├── console.cpp │ ├── console.hpp │ ├── content.cpp │ ├── contextmenus.cpp │ ├── contextmenus.hpp │ ├── controllermapsview.cpp │ ├── controllermapsview.hpp │ ├── controllersview.cpp │ ├── controllersview.hpp │ ├── datapathbrowser.hpp │ ├── decibelscale.cpp │ ├── designer.cpp │ ├── emptyview.hpp │ ├── filecombobox.cpp │ ├── filecombobox.hpp │ ├── filetreeview.cpp │ ├── filetreeview.hpp │ ├── graphdisplayview.hpp │ ├── grapheditorcomponent.cpp │ ├── grapheditorcomponent.hpp │ ├── grapheditorview.cpp │ ├── grapheditorview.hpp │ ├── graphmixerview.cpp │ ├── graphmixerview.hpp │ ├── graphnodeeditor.cpp │ ├── graphsettingsview.cpp │ ├── graphsettingsview.hpp │ ├── guicommon.hpp │ ├── horizontallistbox.cpp │ ├── horizontallistbox.hpp │ ├── icons.cpp │ ├── icons.hpp │ ├── ioconfigurationwindow.cpp │ ├── ioconfigurationwindow.hpp │ ├── keymapeditorview.cpp │ ├── keymapeditorview.hpp │ ├── loglistbox.hpp │ ├── luaconsole.cpp │ ├── luaconsole.hpp │ ├── luaconsoleview.cpp │ ├── luaconsoleview.hpp │ ├── luatokenizer.cpp │ ├── luatokenizer.hpp │ ├── mainmenu.cpp │ ├── mainmenu.hpp │ ├── mainwindow.cpp │ ├── meterbridge.cpp │ ├── midiblinker.cpp │ ├── midiblinker.hpp │ ├── midichannelselectcomponent.hpp │ ├── midimultichannelproperty.hpp │ ├── navigation.cpp │ ├── navigationview.cpp │ ├── navigationview.hpp │ ├── nodechannelstrip.hpp │ ├── nodechannelstripview.cpp │ ├── nodechannelstripview.hpp │ ├── nodeeditor.cpp │ ├── nodeeditorfactory.cpp │ ├── nodeeditorfactory.hpp │ ├── nodeeditorview.cpp │ ├── nodeeditorview.hpp │ ├── nodeioconfiguration.cpp │ ├── nodeioconfiguration.hpp │ ├── nodelistcombobox.hpp │ ├── nodemidiprogramcomponent.cpp │ ├── nodemidiprogramcomponent.hpp │ ├── nodeportstable.cpp │ ├── nodeportstable.hpp │ ├── nodeproperties.cpp │ ├── nodeproperties.hpp │ ├── nodepropertiesview.cpp │ ├── nodepropertiesview.hpp │ ├── nodepropertypanel.cpp │ ├── nodepropertypanel.hpp │ ├── nsviewwithparent.hpp │ ├── nsviewwithparent.mm │ ├── patchmatrix.cpp │ ├── patchmatrix.hpp │ ├── pluginmanagercomponent.cpp │ ├── pluginmanagercomponent.hpp │ ├── pluginspanelview.cpp │ ├── pluginspanelview.hpp │ ├── pluginwindow.cpp │ ├── pluginwindow.hpp │ ├── preferences.cpp │ ├── rackview.cpp │ ├── rackview.hpp │ ├── res.hpp │ ├── resizelistener.hpp │ ├── scripteditorview.cpp │ ├── scripteditorview.hpp │ ├── scriptview.cpp │ ├── scriptview.hpp │ ├── sessiondocument.cpp │ ├── sessiondocument.hpp │ ├── sessionimportwizard.cpp │ ├── sessionimportwizard.hpp │ ├── sessionsettingsview.cpp │ ├── sessionsettingsview.hpp │ ├── sessiontreepanel.cpp │ ├── sessiontreepanel.hpp │ ├── sessiontreeview.cpp │ ├── sessiontreeview.hpp │ ├── simplemeter.cpp │ ├── standard.cpp │ ├── style_v1.cpp │ ├── systemtray.cpp │ ├── systemtray.hpp │ ├── tempoandmeterbar.hpp │ ├── transportbar.cpp │ ├── transportbar.hpp │ ├── treeviewbase.cpp │ ├── treeviewbase.hpp │ ├── updater.cpp │ ├── viewhelpers.cpp │ ├── viewhelpers.hpp │ ├── virtualkeyboardview.cpp │ ├── virtualkeyboardview.hpp │ ├── window.cpp │ ├── window.hpp │ ├── windowmanager.cpp │ └── windowmanager.hpp ├── urls.hpp ├── utils.cpp └── utils.hpp ├── subprojects ├── .gitignore ├── .ignore ├── clap-helpers.wrap ├── clap.wrap ├── juce.wrap ├── lilv.wrap ├── lv2.wrap ├── lvtk-host.wrap ├── lvtk.wrap ├── pugl.wrap ├── serd.wrap ├── sord.wrap ├── sratom.wrap ├── suil.wrap └── zix.wrap ├── test ├── GraphNodeTests.cpp ├── IONodeTests.cpp ├── MidiProgramMapTests.cpp ├── NodeFactoryTests.cpp ├── NodeObjectTests.cpp ├── NodeTests.cpp ├── OversamplerTests.cpp ├── PluginManagerTests.cpp ├── PortListTests.cpp ├── RootGraphTests.cpp ├── TestMain.cpp ├── atomtests.cpp ├── datapathtests.cpp ├── engine │ ├── LinearFadeTest.cpp │ ├── MidiChannelMapTest.cpp │ ├── VelocityCurveTest.cpp │ └── togglegridtest.cpp ├── fixture │ ├── PreparedGraph.h │ ├── TestNode.h │ └── context.hpp ├── integration │ └── SessionChangedTest.cpp ├── meson.build ├── osc │ └── node-client │ │ ├── README.md │ │ ├── index.js │ │ └── package.json ├── porttypetests.cpp ├── scripting │ ├── bytestest.cpp │ ├── dspscripttest.cpp │ ├── luatest.hpp │ ├── scriptinfotest.cpp │ ├── scriptloadertest.cpp │ ├── scriptmanagertest.cpp │ └── scriptplayground.cpp ├── shuttletests.cpp ├── snippets │ ├── sol3_parent.lua │ ├── stream_from_c.lua │ ├── test_bytes.lua │ └── test_dsp_script_01.lua ├── testutil.hpp └── updatetests.cpp └── util ├── bin2c.cpp ├── bundle.py ├── date.py ├── docker.sh ├── getcode.py ├── img2ico.sh ├── macos-install-user-plugins.sh ├── macos-uninstall-user-plugins.sh ├── meson.build └── version.py /.dockerignore: -------------------------------------------------------------------------------- 1 | 2 | *.pch 3 | 4 | data/*.ai 5 | 6 | dst 7 | waf-* 8 | waf3-* 9 | .waf-* 10 | .waf3-* 11 | .lock* 12 | build/ 13 | *.pyc 14 | .DS_Store 15 | *.autosave 16 | node_modules 17 | 18 | /.vscode/**/*.* 19 | !/.vscode/tasks.json 20 | !/.vscode/launch.json 21 | !/.vscode/c_cpp_properties.json 22 | !/.vscode/vscode.h 23 | 24 | /libs/ASIOSDK/ 25 | /libs/vstsdk2.4/ 26 | 27 | /delete.txt 28 | /deploy/ 29 | /tools/deploy/ 30 | /tools/installers/ 31 | /plugins 32 | /pro/ 33 | 34 | /*.gz 35 | /*.bz2 36 | /*.zip 37 | /element-0.* 38 | /*.AppImage 39 | 40 | /tools/contrib/contrib 41 | /tools/contrib/*.exe 42 | /tools/linuxdeploy.sh 43 | /data/Info.plist 44 | /dist/ 45 | 46 | /*.lua 47 | 48 | docs/_build/ 49 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: [ 2 | "https://kushview.net/donate", 3 | "https://kushview.gumroad.com" 4 | ] 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for Element 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pch 2 | 3 | data/*.ai 4 | 5 | data/**/*.ttf 6 | !data/fonts/Roboto-Regular.ttf 7 | 8 | dst 9 | waf-* 10 | waf3-* 11 | .waf-* 12 | .waf3-* 13 | .lock* 14 | build/ 15 | *.pyc 16 | .DS_Store 17 | *.autosave 18 | node_modules 19 | *.dmg 20 | 21 | /.vscode/**/*.* 22 | .vscode/settings.json 23 | !/.vscode/tasks.json 24 | !/.vscode/launch.json 25 | !/.vscode/c_cpp_properties.json 26 | !/.vscode/vscode.h 27 | !/.vscode/settings.save.json 28 | 29 | /libs/vstsdk2.4/ 30 | /libs/ASIOSDK/ 31 | /libs/eldb/*.dylib 32 | /libs/eldb/*.dll 33 | /libs/eldb/*.so 34 | /libs/eldb/*.db 35 | /libs/eldb/eldb 36 | 37 | /delete.txt 38 | /tools/deploy/ 39 | /tools/installers/ 40 | /pro/ 41 | 42 | /*.gz 43 | /*.bz2 44 | /*.zip 45 | /element-0.* 46 | /*.AppImage 47 | 48 | /tools/contrib/contrib 49 | /tools/contrib/*.exe 50 | /tools/linuxdeploy.sh 51 | /data/Info.plist 52 | /dist/ 53 | /stage/ 54 | 55 | /*.lua 56 | 57 | docs/_build/ 58 | /reconfig.sh 59 | /stage/ 60 | /sign.sh 61 | /configure 62 | 63 | Cardinal 64 | .meson-subproject*.txt 65 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kushview/element/2159d748c3a48385a838cab31ba12c11e6d114a2/.gitmodules -------------------------------------------------------------------------------- /.vscode/vscode.h: -------------------------------------------------------------------------------- 1 | #define JUCE_PLUGINHOST_LV2 1 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "ElementApp.h" 9 | 10 | using namespace juce; 11 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Element Authors 2 | 3 | ## Lead Developer 4 | Michael Fisher (mfisher31) 5 | 6 | ## Contributors 7 | Chris Ryan (digitalelements) 8 | David Runge (dvzrv) 9 | Eliot Akira (eliot-akira) 10 | Max Hunter (nippoo) 11 | Michael Forrest (michaelforrest) 12 | Steve Schow (steveschow) 13 | Trevor Parscal (trevorparscal) 14 | iamvs2002 15 | jatinchowdhury18 16 | mmoole. (mmoole) 17 | schnitzeltony 18 | splisp 19 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Element 2 | This document is currently incomplete. More details coming soon! 3 | 4 | ### Static Data, Global Variables, and Singletons 5 | Because Element is designed to run as a plugin in other software, usage of these types is strictly forbidden. Certain cases might be ok such as embedding binary data (e.g. fonts, images), but should still be avoided. 6 | 7 | ### Changing the Audio/Rendering Engine 8 | If you change things in the Engine layer, please thoroughly test before submitting pull requests. The slightest changes may work fine on your system but cause nasty crashes or unexpected behavior elsewhere. 9 | 10 | ### Adding Features to or New Nodes 11 | When adding properties to Nodes or making new ones, Please make sure that the state can be saved or restored. There's no point in adding new functions to Nodes if they can't restore state when a session is saved then opened later. 12 | 13 | ### Adding New Files 14 | Please use Copyright 20xx. Kushview, LLC. and below this Author Your Name 15 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM kushview/depends 2 | WORKDIR "/project" 3 | -------------------------------------------------------------------------------- /data/developers.txt: -------------------------------------------------------------------------------- 1 | Chris Ryan (digitalelements) 2 | David Runge (dvzrv) 3 | Eliot Akira (eliot-akira) 4 | Max Hunter (nippoo) 5 | Michael Forrest (michaelforrest) 6 | Steve Schow (steveschow) 7 | Trevor Parscal (trevorparscal) 8 | iamvs2002 9 | jatinchowdhury18 10 | mmoole. (mmoole) 11 | schnitzeltony 12 | splisp 13 | -------------------------------------------------------------------------------- /data/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kushview/element/2159d748c3a48385a838cab31ba12c11e6d114a2/data/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /data/fonts/meson.build: -------------------------------------------------------------------------------- 1 | res_sources = [res_sources, res_gen.process ( 2 | 'Roboto-Regular.ttf' 3 | )] 4 | -------------------------------------------------------------------------------- /data/images/icon-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kushview/element/2159d748c3a48385a838cab31ba12c11e6d114a2/data/images/icon-template.png -------------------------------------------------------------------------------- /data/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kushview/element/2159d748c3a48385a838cab31ba12c11e6d114a2/data/images/icon.png -------------------------------------------------------------------------------- /data/images/meson.build: -------------------------------------------------------------------------------- 1 | res_sources = [res_sources, res_gen.process ( 2 | 'icon.png', 3 | 'icon-template.png' 4 | )] 5 | -------------------------------------------------------------------------------- /data/images/power_48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kushview/element/2159d748c3a48385a838cab31ba12c11e6d114a2/data/images/power_48x48.png -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | res_gen = generator (bin2c, 2 | output : [ '@PLAINNAME@.cpp', '@PLAINNAME@.h'], 3 | arguments : [ '@INPUT@', '@BUILD_DIR@', 'res' ]) 4 | res_includes = include_directories ('.') 5 | res_sources = res_gen.process ( 6 | 'acknowledgements.txt', 7 | 'developers.txt' 8 | ) 9 | 10 | subdir ('fonts') 11 | subdir ('images') 12 | -------------------------------------------------------------------------------- /data/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kushview/element/2159d748c3a48385a838cab31ba12c11e6d114a2/data/screenshot.png -------------------------------------------------------------------------------- /deploy/au/component.js: -------------------------------------------------------------------------------- 1 | function extractDir() { 2 | var dir = ""; 3 | if (systemInfo.kernelType === "darwin") { 4 | dir = "/Library/Audio/Plug-Ins/Components"; 5 | } else if (systemInfo.kernelType === "winnt") { 6 | dir = "@ApplicationsDirX64@/Kushview/Element"; 7 | } 8 | return dir; 9 | } 10 | 11 | function Component() {} 12 | 13 | Component.prototype.createOperations = function () { 14 | for (var i = 0; i < component.archives.length; ++i) { 15 | let a = component.archives [i] 16 | if (! a.endsWith ('7z')) 17 | continue; 18 | let target = extractDir(); 19 | if (target.length <= 0) 20 | continue; 21 | component.addElevatedOperation ("Extract", a, target) 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /deploy/au/meson.build: -------------------------------------------------------------------------------- 1 | foreach f : 'package.xml component.js'.split() 2 | configure_file (input :f, 3 | install: true, install_dir: packagedir_element + '.au' / 'meta', 4 | output: f, configuration: { 5 | 'VERSION': version_with_build, 6 | 'RELEASEDATE': element_release_date, 7 | }) 8 | endforeach 9 | -------------------------------------------------------------------------------- /deploy/au/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | AudioUnit Plugins 4 | Element AudioUnit plugins. Instrument, Effect, and MIDI Effect 5 | 6 | @VERSION@ 7 | @RELEASEDATE@ 8 | 9 | true 10 | false 11 | false 12 | true 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /deploy/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Element 4 | Element 5 | @VERSION@ 6 | Kushview, LLC 7 | https://kushview.net/element/ 8 | 9 | Kushview 10 | @TARGETDIR@ 11 | control.js 12 | updater 13 | 14 | @APPICON@ 15 | logo.png 16 | 17 | 18 | true 19 | 20 | @RUNPROGRAM@ 21 | 782 22 | 512 23 | 24 | false 25 | 26 | 27 | @RELEASEREPO@ 28 | 1 29 | Public 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /deploy/control.js: -------------------------------------------------------------------------------- 1 | function Controller() 2 | { 3 | installer.setDefaultPageVisible (QInstaller.TargetDirectory, false); 4 | } 5 | 6 | //============================================================================= 7 | Controller.prototype.IntroductionPageCallback = function() {} 8 | 9 | Controller.prototype.TargetDirectoryPageCallback = function() {} 10 | 11 | Controller.prototype.ComponentSelectionPageCallback = function() { 12 | installer.recalculateAllComponents(); 13 | installer.calculateComponentsToInstall(); 14 | installer.coreNetworkSettingsChanged(); 15 | } 16 | -------------------------------------------------------------------------------- /deploy/element/meson.build: -------------------------------------------------------------------------------- 1 | install_data ('component.js', install_dir : packagedir_element / 'meta') 2 | 3 | element_operations = '' 4 | if host_machine.system() == 'windows' 5 | element_operations = '' 6 | elif host_machine.system() == 'darwin' 7 | element_operations = '' 8 | endif 9 | 10 | configure_file (input : 'package.xml', 11 | install: true, install_dir: packagedir_element / 'meta', 12 | output: 'package.xml', configuration: { 13 | 'VERSION': version_with_build, 14 | 'RELEASEDATE': element_release_date, 15 | 'OPERATIONS': element_operations 16 | }) 17 | -------------------------------------------------------------------------------- /deploy/element/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Element Application 4 | Element modular streaming engine, plugin, host, and Audio Interface controller. 5 | 6 | @VERSION@ 7 | @RELEASEDATE@ 8 | 9 | true 10 | false 11 | true 12 | true 13 | 14 | 15 | 16 | 17 | 18 | 19 | net.kushview.element.app 20 | 100 21 | 22 | -------------------------------------------------------------------------------- /deploy/installer-linux.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | rm -rf *.gz *.app *.dmg 5 | 6 | @BINARYCREATOR@ -v -c "@CONFIGFILE@" -p "@PACKAGES@" @INSTALLERBASE@.run 7 | 8 | rm -rf archives && mkdir archives 9 | cd packages && @ARCHIVEGEN@ -f tar.gz -c 9 \ 10 | ../archives/element-linux.tar.gz \ 11 | net.kushview.element \ 12 | net.kushview.element.lua 13 | 14 | if [ -d "net.kushview.element.vst3" ]; then 15 | @ARCHIVEGEN@ -f tar.gz -c 9 \ 16 | ../archives/element-plugins-linux.tar.gz \ 17 | net.kushview.element.vst \ 18 | net.kushview.element.vst3 19 | fi 20 | 21 | cd ../archives 22 | -------------------------------------------------------------------------------- /deploy/installer-macos.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | rm -rf *.gz *.app *.dmg 6 | 7 | # Create a signed updater app. 8 | updaterdir="packages/net.kushview.element.updater" 9 | if [ -f "${updaterdir}/meta/package.xml" ]; then 10 | mkdir -p "${updaterdir}/data" 11 | rm -rf "${updaterdir}/data/updater.app" 12 | 13 | @BINARYCREATOR@ -v -c "config/config.xml" @SIGNOPT@ \ 14 | --mt -p "packages" 15 | rsync -var updater.app/ "${updaterdir}/data/manage.app/" 16 | fi 17 | 18 | @BINARYCREATOR@ -v -c "@CONFIGFILE@" -p "@PACKAGES@" \ 19 | -t "/opt/SDKs/bin/installerbase-element" @INSTALLERBASE@ 20 | 21 | sed -i '' 's/com.yourcompany.installerbase/net.kushview.element.installer/' "@INSTALLERBASE@.app/Contents/Info.plist" 22 | 23 | @MACDEPLOYQT@ @INSTALLERBASE@.app \ 24 | -no-plugins -dmg -always-overwrite -verbose=3 \ 25 | @MACDEPLOYQT_ARGS@ 26 | 27 | @NOTARYSCRIPT@ 28 | 29 | rm -rf archives && mkdir archives 30 | cd packages && @ARCHIVEGEN@ -f tar.gz -c 9 \ 31 | ../archives/element-osx.tar.gz \ 32 | net.kushview.element \ 33 | net.kushview.element.lua \ 34 | net.kushview.element.updater 35 | 36 | if [ -d "net.kushview.element.vst3" ]; then 37 | @ARCHIVEGEN@ -f tar.gz -c 9 \ 38 | ../archives/element-plugins-osx.tar.gz \ 39 | net.kushview.element.au \ 40 | net.kushview.element.vst \ 41 | net.kushview.element.vst3 42 | fi 43 | 44 | cd ../archives 45 | md5 *.* > md5.sum 46 | -------------------------------------------------------------------------------- /deploy/installer.bat.in: -------------------------------------------------------------------------------- 1 | 2 | @BINARYCREATOR@ -v -c "@CONFIGFILE@" -p "@PACKAGES@"^ 3 | -t "c:\SDKs\bin\installerbase-element.exe" @INSTALLERBASE@ || exit 4 | 5 | rmdir archives /s /q 6 | mkdir archives 7 | 8 | cd packages 9 | @ARCHIVEGEN@ -c 9 -f tar.gz ../archives/element-win64.tar.gz^ 10 | net.kushview.element^ 11 | net.kushview.element.lua || exit 12 | 13 | if exist net.kushview.element.vst\ ( 14 | @ARCHIVEGEN@ -c 9 -f tar.gz ../archives/element-plugins-win64.tar.gz^ 15 | net.kushview.element.vst^ 16 | net.kushview.element.vst3 || exit 17 | ) 18 | 19 | cd .. 20 | 21 | call "C:\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\Auxiliary\\Build\\vcvars64.bat" 22 | @SIGNTOOL@ 23 | -------------------------------------------------------------------------------- /deploy/linux/appimage-docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | docker build -t kushview/element . 5 | docker run -i --rm \ 6 | -e WAF_BUILD_OPTIONS="-j4" \ 7 | --entrypoint "deploy/linux/entrypoint.sh" \ 8 | --volume `pwd`/stage:/dist \ 9 | --volume `pwd`:/project \ 10 | --volume /opt/SDKs:/SDKs:ro \ 11 | --workdir /project \ 12 | -u $(id -u ${USER}):$(id -g ${USER}) \ 13 | kushview/element 14 | -------------------------------------------------------------------------------- /deploy/linux/appimage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # generates a linux AppImage and moves to the build directory. 3 | 4 | set -ex 5 | builddir="$1" 6 | appdir="AppDir" 7 | rm -rf "$builddir/$appdir" 8 | mkdir -p "$builddir/$appdir" 9 | meson install --destdir="${appdir}" -C "$builddir" --quiet --skip-subprojects 10 | 11 | if [ -z "${VERSION}" ]; then 12 | export VERSION="$(python util/version.py --build)" 13 | fi 14 | 15 | cd "$builddir" 16 | export LD_LIBRARY_PATH="${builddir}/${appdir}/usr/lib:${LD_LIBRARY_PATH}" 17 | linuxdeploy --appimage-extract-and-run \ 18 | --appdir ${appdir} --output appimage \ 19 | --desktop-file="`find "$appdir" -name "net.kushview.element.desktop"`" \ 20 | --icon-file="../deploy/linux/icon_256x256.png" \ 21 | --icon-filename="net.kushview.element" \ 22 | --executable="./element" 23 | rm -rf "${appdir}" 24 | -------------------------------------------------------------------------------- /deploy/linux/element.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Encoding=UTF-8 3 | Name=Element 4 | Comment=Element modular plugin host 5 | Exec=@ELEMENT_EXE@ 6 | Icon=@ELEMENT_ICON@ 7 | Terminal=false 8 | Type=Application 9 | Categories=Application;AudioVideo;Audio; 10 | -------------------------------------------------------------------------------- /deploy/linux/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Builds a Linux AppImage 3 | 4 | export CC=clang 5 | export CFLAGS="-DEL_APPIMAGE=1" 6 | export CXX=clang++ 7 | export CXXFLAGS="-DEL_APPIMAGE=1" 8 | export LD_LIBRARY_PATH="/depends/x86_64-pc-linux-gnu/lib" 9 | 10 | export BOOST_ROOT="/depends/x86_64-pc-linux-gnu/include" 11 | 12 | nativefiles="--native-file=meson/subs.ini --native-file=meson/linux.ini --native-file=meson/appimage.ini" 13 | builddir="build-docker" 14 | 15 | rm -rf build-docker 16 | meson subprojects download 17 | meson subprojects update --reset 18 | 19 | set -e 20 | meson setup -Dbuildtype=release $nativefiles $builddir 21 | meson compile -C $builddir -j3 22 | meson test -C $builddir 23 | sh deploy/linux/appimage.sh "$builddir" 24 | -------------------------------------------------------------------------------- /deploy/linux/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kushview/element/2159d748c3a48385a838cab31ba12c11e6d114a2/deploy/linux/icon_256x256.png -------------------------------------------------------------------------------- /deploy/linux/meson.build: -------------------------------------------------------------------------------- 1 | custom_target ('desktop icon', 2 | command : [ 'cp', '-f', '@INPUT@', '@OUTPUT@' ], 3 | input : 'icon_256x256.png', 4 | output : 'net.kushview.element.png', 5 | install : true, 6 | install_dir : get_option('datadir') / 'icons/hicolor/256x256/apps') 7 | configure_file ( 8 | input: 'element.desktop.in', 9 | output: 'net.kushview.element.desktop', 10 | configuration : { 11 | 'ELEMENT_ICON' : 'net.kushview.element', 12 | 'ELEMENT_EXE' : 'element' 13 | }, 14 | install : true, 15 | install_dir : get_option('datadir') / 'applications') 16 | -------------------------------------------------------------------------------- /deploy/osx/Icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kushview/element/2159d748c3a48385a838cab31ba12c11e6d114a2/deploy/osx/Icon.icns -------------------------------------------------------------------------------- /deploy/osx/app.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-jit 6 | 7 | com.apple.security.cs.disable-library-validation 8 | 9 | com.apple.security.device.audio-input 10 | 11 | com.apple.security.get-task-allow 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /deploy/osx/bundle.sh: -------------------------------------------------------------------------------- 1 | 2 | rootdir="$(pwd)" # root build directory 3 | blddir="${rootdir}/deploy/osx" # dest dir within build dir 4 | srcdir="$(dirname "$rootdir")/deploy/osx" # src dir in code base 5 | Element_exe="${rootdir}/Element" 6 | Element_app="${blddir}/Element.app" 7 | 8 | # echo $rootdir 9 | # echo $srcdir 10 | # echo $blddir 11 | # echo $Element_exe 12 | # echo $Element_app 13 | # exit 0 14 | 15 | set -e 16 | rm -rf "$Element_app" 17 | mkdir -p "${Element_app}/Contents/MacOS" 18 | mkdir -p "${Element_app}/Contents/Resources" 19 | mkdir -p "${Element_app}/Contents/Frameworks" 20 | mkdir -p "${Element_app}/Contents/PlugIns" 21 | 22 | cp "${Element_exe}" "${Element_app}/Contents/MacOS/Element" 23 | cp "${srcdir}/Info.plist" "${Element_app}/Contents/Info.plist" 24 | cp "${srcdir}/PkgInfo" "${Element_app}/Contents/PkgInfo" 25 | cp "${srcdir}/Icon.icns" "${Element_app}/Contents/Resources/Icon.icns" 26 | exit 0 27 | -------------------------------------------------------------------------------- /deploy/osx/meson.build: -------------------------------------------------------------------------------- 1 | 2 | app_info_plist = configure_file ( 3 | input : files ('Info.plist.in'), 4 | output: 'Info.plist', 5 | install : false, 6 | configuration: { 7 | 'VERSION': meson.project_version() 8 | }) 9 | 10 | element_bundles += custom_target ( 11 | 'Element.app', 12 | build_by_default: true, 13 | command: [ python3, bundle_py, '--binary', '@INPUT@', 14 | '--output', '@OUTPUT@', 15 | '--plist', app_info_plist, 16 | '--resource', files ('Icon.icns') ], 17 | input: element_app, 18 | output: 'Element.app', 19 | install: get_option ('deploy'), 20 | install_dir: packagedir_element / 'data' 21 | ) 22 | -------------------------------------------------------------------------------- /deploy/osx/plugin.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-jit 6 | 7 | com.apple.security.cs.disable-library-validation 8 | 9 | com.apple.security.device.audio-input 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /deploy/osx/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | DYLD_LIBRARY_PATH="" $(find deploy/osx -name "Element") 3 | -------------------------------------------------------------------------------- /deploy/updater/component.js: -------------------------------------------------------------------------------- 1 | function Component() {} 2 | 3 | Component.prototype.createOperationsForArchive = function (archive) { 4 | let target = installer.value ('TargetDir'); 5 | component.addElevatedOperation ("Extract", archive, target, 'UNDOOPERATION', ''); 6 | }; 7 | -------------------------------------------------------------------------------- /deploy/updater/meson.build: -------------------------------------------------------------------------------- 1 | packgedir_updater = packagesdir / net_kushview + '.element.updater' 2 | install_data ('component.js', install_dir : packgedir_updater / 'meta') 3 | 4 | configure_file (input : 'package.xml', 5 | install: true, install_dir: packgedir_updater / 'meta', 6 | output: 'package.xml', configuration: { 7 | 'VERSION': version_with_build, 8 | 'RELEASEDATE': element_release_date, 9 | 'TargetDir': '@TargetDir@' 10 | }) 11 | -------------------------------------------------------------------------------- /deploy/updater/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Element Updater 4 | Application used to update and uninstall packages. 5 | 6 | @VERSION@ 7 | @RELEASEDATE@ 8 | 9 | false 10 | true 11 | true 12 | true 13 | 14 | 15 | 16 | 100 17 | 22 | 23 | -------------------------------------------------------------------------------- /deploy/vst/component.js: -------------------------------------------------------------------------------- 1 | function extractDir() { 2 | var dir = "/usr/local/lib/vst"; 3 | if (systemInfo.kernelType === "darwin") { 4 | dir = "/Library/Audio/Plug-Ins/VST"; 5 | } else if (systemInfo.kernelType === "winnt") { 6 | dir = installer.value ("ApplicationsDirX64") + "/Steinberg/VstPlugins"; 7 | } 8 | return dir; 9 | } 10 | 11 | function Component() {} 12 | 13 | Component.prototype.createOperations = function () { 14 | for (var i = 0; i < component.archives.length; ++i) { 15 | let a = component.archives [i] 16 | if (! a.endsWith ('7z')) 17 | continue; 18 | let target = extractDir(); 19 | if (target.length <= 0) 20 | continue; 21 | component.addElevatedOperation ("Extract", a, target) 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /deploy/vst/meson.build: -------------------------------------------------------------------------------- 1 | foreach f : 'package.xml component.js'.split() 2 | configure_file (input :f, 3 | install: true, install_dir: packagedir_element + '.vst' / 'meta', 4 | output: f, configuration: { 5 | 'VERSION': version_with_build, 6 | 'RELEASEDATE': element_release_date, 7 | }) 8 | endforeach 9 | -------------------------------------------------------------------------------- /deploy/vst/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | VST Plugins 4 | Element VST2 plugins. Instrument and Effect 5 | 6 | @VERSION@ 7 | @RELEASEDATE@ 8 | 9 | false 10 | false 11 | false 12 | true 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /deploy/vst3/component.js: -------------------------------------------------------------------------------- 1 | function extractDir() { 2 | var dir = "/usr/local/lib/vst3"; 3 | if (systemInfo.kernelType === "darwin") { 4 | dir = "/Library/Audio/Plug-Ins/VST3"; 5 | } else if (systemInfo.kernelType === "winnt") { 6 | dir =installer.value ("ApplicationsDirX64") + "/Common Files/VST3"; 7 | } 8 | return dir; 9 | } 10 | 11 | function Component() {} 12 | 13 | Component.prototype.createOperations = function () { 14 | for (var i = 0; i < component.archives.length; ++i) { 15 | let a = component.archives [i] 16 | if (! a.endsWith ('7z')) 17 | continue; 18 | let target = extractDir(); 19 | if (target.length <= 0) 20 | continue; 21 | component.addElevatedOperation ("Extract", a, target) 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /deploy/vst3/meson.build: -------------------------------------------------------------------------------- 1 | foreach f : 'package.xml component.js'.split() 2 | configure_file (input :f, 3 | install: true, install_dir: packagedir_element + '.vst3' / 'meta', 4 | output: f, configuration: { 5 | 'VERSION': version_with_build, 6 | 'RELEASEDATE': element_release_date, 7 | }) 8 | endforeach 9 | -------------------------------------------------------------------------------- /deploy/vst3/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | VST3 Plugins 4 | Element VST3 plugins. Instrument and Effect 5 | 6 | @VERSION@ 7 | @RELEASEDATE@ 8 | 9 | false 10 | false 11 | false 12 | true 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /deploy/windows/jenkins.sh: -------------------------------------------------------------------------------- 1 | echo "Building branch $GIT_BRANCH" 2 | 3 | setup_args="${SETUP_ARGS}" 4 | set -e 5 | 6 | if [ "$CLEAN" = "true" ] || [ ! -d "build" ]; then 7 | echo "Setting up for clean build" 8 | rm -rf build 9 | setup_args="" 10 | fi 11 | 12 | mkdir -p ~/agent/tmp 13 | meson subprojects update --reset 14 | meson setup $setup_args \ 15 | --native-file=meson/subs.ini \ 16 | --native-file=meson/msvc.ini \ 17 | -Dbuildtype=release \ 18 | -Delement-plugins=enabled \ 19 | -Ddefault_library=static \ 20 | build 21 | meson compile -C build -j4 22 | meson test -C build 23 | -------------------------------------------------------------------------------- /docs/config.ld: -------------------------------------------------------------------------------- 1 | project = 'Element' 2 | title = 'Element Lua API' 3 | description = "API reference to Element's scripting engine" 4 | file = { 5 | '../src/el', 6 | '../src/engine/midipipe.cpp', 7 | exclude = { 8 | '../src/el/midi_buffer.hpp', 9 | '../src/el/sol_helpers.hpp', 10 | '../src/el/vector.c', 11 | '../src/el/color.lua', 12 | '../src/el/session.lua', 13 | '../src/el/Parameter.cpp' 14 | } 15 | } 16 | 17 | examples = { 18 | -- '../docs/examples/helloworld.lua', 19 | -- '../docs/examples/sysex.lua', 20 | -- '../docs/examples/sysexui.lua', 21 | '../scripts/amp.lua', 22 | '../scripts/ampui.lua', 23 | '../scripts/channelize.lua' 24 | } 25 | output = 'index' 26 | merge = true 27 | all = false 28 | 29 | add_language_extension ('.hpp', 'c') 30 | add_language_extension ('.ipp', 'c') 31 | 32 | ---[[ 33 | custom_tags = { 34 | { 35 | "property", 36 | title = "Properties", 37 | hidden = false, 38 | format = function (data) 39 | return data .. "" 40 | end 41 | } 42 | } 43 | 44 | custom_display_name_handler = function (item, default_handler) 45 | if item.tags.kind then 46 | return item.name 47 | end 48 | return default_handler (item) 49 | end 50 | --]] 51 | -------------------------------------------------------------------------------- /docs/meson.build: -------------------------------------------------------------------------------- 1 | if not get_option('ldoc').disabled() 2 | ldoc = find_program ('ldoc', version : '>= 1.5.0', required: false) 3 | ldoc_install_dir = get_option ('datadir') / 'doc' / 'element-0' / 'lua' 4 | 5 | if ldoc.found() and not meson.is_subproject() 6 | custom_target ( 7 | 'Lua API Docs', 8 | build_always_stale: true, 9 | command: [ ldoc, '-f', 'markdown', '-q', 10 | '-c', '@INPUT@', 11 | '-d', meson.current_build_dir() / '..' / '@OUTPUT@', 12 | meson.project_source_root()], 13 | input: files('config.ld'), 14 | output: 'lua', 15 | install: true, 16 | install_dir: ldoc_install_dir 17 | ) 18 | endif 19 | endif 20 | -------------------------------------------------------------------------------- /include/element/devices.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | class DeviceManager : public juce::AudioDeviceManager { 12 | public: 13 | typedef juce::AudioDeviceManager::AudioDeviceSetup AudioSettings; 14 | static const int maxAudioChannels; 15 | 16 | DeviceManager(); 17 | ~DeviceManager(); 18 | 19 | void getAudioDrivers (juce::StringArray& drivers); 20 | void selectAudioDriver (const juce::String& name); 21 | void attach (AudioEnginePtr engine); 22 | 23 | #if KV_JACK_AUDIO 24 | kv::JackClient& getJackClient(); 25 | #endif 26 | 27 | void createAudioDeviceTypes (juce::OwnedArray& list) override; 28 | 29 | private: 30 | friend class World; 31 | class Private; 32 | std::unique_ptr impl; 33 | }; 34 | 35 | } // namespace element 36 | -------------------------------------------------------------------------------- /include/element/element.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | 7 | #define EL_DISABLE_COPY(ClassName) \ 8 | ClassName (const ClassName&) = delete; \ 9 | ClassName& operator= (const ClassName&) = delete; 10 | #define EL_DISABLE_MOVE(ClassName) \ 11 | ClassName (const ClassName&&) = delete; \ 12 | ClassName& operator= (const ClassName&&) = delete; 13 | 14 | namespace element { 15 | 16 | /** Ignore a set of variables... */ 17 | template 18 | inline void ignore (Args&&...) noexcept 19 | { 20 | } 21 | 22 | } // namespace element 23 | -------------------------------------------------------------------------------- /include/element/gzip.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | namespace gzip { 10 | 11 | juce::String encode (const juce::String& input); 12 | juce::String decode (const juce::String& input); 13 | 14 | } // namespace gzip 15 | } // namespace element 16 | -------------------------------------------------------------------------------- /include/element/juce.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace juce; // FIXME: 25 | namespace element { 26 | } 27 | -------------------------------------------------------------------------------- /include/element/juce/audio_basics.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | 8 | namespace element { 9 | } 10 | -------------------------------------------------------------------------------- /include/element/juce/audio_devices.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /include/element/juce/audio_formats.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | namespace element { 8 | } 9 | -------------------------------------------------------------------------------- /include/element/juce/audio_processors.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /include/element/juce/core.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | 8 | namespace element { 9 | // FIXME: juce aliases 10 | using int32 = juce::int32; 11 | using uint8 = juce::uint8; 12 | using uint16 = juce::uint16; 13 | using uint32 = juce::uint32; 14 | 15 | using juce::Array; 16 | using juce::File; 17 | using juce::Identifier; 18 | using juce::String; 19 | using juce::StringArray; 20 | 21 | template 22 | using HeapBlock = juce::HeapBlock; 23 | } // namespace element 24 | -------------------------------------------------------------------------------- /include/element/juce/data_structures.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /include/element/juce/dsp.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /include/element/juce/events.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /include/element/juce/graphics.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /include/element/juce/gui_basics.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /include/element/juce/gui_extra.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /include/element/juce/meson.build: -------------------------------------------------------------------------------- 1 | configure_file (output : 'config.h', 2 | configuration : juce_conf_data, 3 | install: true, 4 | install_dir: element_include_dir / 'juce') 5 | -------------------------------------------------------------------------------- /include/element/juce/osc.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /include/element/lua.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | extern "C" { 7 | #include "lauxlib.h" 8 | #include "lua.h" 9 | #include "lualib.h" 10 | } 11 | 12 | #include 13 | #include 14 | 15 | namespace element { 16 | namespace lua { 17 | 18 | using CFunction = lua_CFunction; 19 | using PackageLoaderMap = std::map; 20 | 21 | } // namespace lua 22 | } // namespace element 23 | -------------------------------------------------------------------------------- /include/element/lv2.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class SymbolMap; 11 | class Processor; 12 | 13 | //============================================================================== 14 | class LV2NodeProvider : public NodeProvider { 15 | public: 16 | LV2NodeProvider(); 17 | LV2NodeProvider (SymbolMap&); 18 | ~LV2NodeProvider(); 19 | juce::String format() const override { return "LV2"; } 20 | Processor* create (const juce::String&) override; 21 | FileSearchPath defaultSearchPath() override; 22 | juce::StringArray findTypes (const juce::FileSearchPath&, bool, bool) override; 23 | String nameForURI (const String& uri) const noexcept; 24 | void scan (const String& URI, OwnedArray& out) override; 25 | 26 | private: 27 | class LV2; 28 | std::unique_ptr lv2; 29 | }; 30 | 31 | } // namespace element 32 | -------------------------------------------------------------------------------- /include/element/meson.build: -------------------------------------------------------------------------------- 1 | 2 | version_data = configuration_data() 3 | version_data.set_quoted ('EL_VERSION_STRING', meson.project_version()) 4 | version_data.set ('EL_BUILD_NUMBER', build_number.to_int()) 5 | version_data.set_quoted ('EL_GIT_HASH', git_hash) 6 | version_data.set_quoted ('EL_GIT_SHORT_HASH', git_short_hash) 7 | configure_file (output: 'version.h', 8 | configuration: version_data, 9 | install: true, 10 | install_dir: element_include_dir ) 11 | 12 | install_headers ('element.h', subdir: element_include_subdir) 13 | install_headers ('node.h', subdir: element_include_subdir) 14 | -------------------------------------------------------------------------------- /include/element/nodeproxy.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class NodeProxy { 11 | public: 12 | NodeProxy() = delete; 13 | virtual ~NodeProxy() = default; 14 | 15 | private: 16 | EL_DISABLE_COPY (NodeProxy) 17 | }; 18 | 19 | } // namespace element 20 | -------------------------------------------------------------------------------- /include/element/oversampler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | template 12 | class Oversampler final { 13 | public: 14 | using ProcessorType = juce::dsp::Oversampling; 15 | 16 | Oversampler() = default; 17 | ~Oversampler(); 18 | 19 | int getNumProcessors() const noexcept { return processors.size(); } 20 | ProcessorType* getProcessor (int index) const { return processors[index]; } 21 | 22 | float getLatencySamples (int index) const; 23 | int getFactor (int index) const; 24 | void prepare (int numChannels, int blockSize); 25 | void reset(); 26 | 27 | private: 28 | enum { 29 | maxProc = 3 30 | }; 31 | int channels = 0, 32 | buffer = 0; 33 | juce::OwnedArray processors; 34 | }; 35 | 36 | } // namespace element 37 | -------------------------------------------------------------------------------- /include/element/presets.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | struct PresetInfo { 11 | std::string ID; 12 | std::string name; 13 | std::string format; 14 | std::string file; 15 | }; 16 | 17 | } // namespace element 18 | -------------------------------------------------------------------------------- /include/element/runmode.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | namespace element { 7 | 8 | /** The runtime mode of Element */ 9 | enum struct RunMode : int { 10 | /** Running as standalone application */ 11 | Standalone = 0, 12 | /** Running as an audio plugin */ 13 | Plugin = 1 14 | }; 15 | 16 | } // namespace element 17 | -------------------------------------------------------------------------------- /include/element/signals.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-laters 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | template 10 | using Signal = boost::signals2::signal; 11 | using SignalConnection = boost::signals2::connection; 12 | using SharedConnectionBlock = boost::signals2::shared_connection_block; 13 | } // namespace element 14 | -------------------------------------------------------------------------------- /include/element/symbolmap.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | 10 | namespace element { 11 | 12 | class SymbolMap final { 13 | public: 14 | SymbolMap() noexcept {} 15 | ~SymbolMap() {} 16 | 17 | const uint32_t map (const char* str) noexcept { return _sym.map (str); } 18 | const char* unmap (uint32_t urid) noexcept { return _sym.unmap (urid); } 19 | 20 | inline auto mapPtr() const noexcept { return (LV2_URID_Map*) _sym.map_feature()->data; } 21 | inline auto mapFeature() const noexcept { return _sym.map_feature(); } 22 | inline auto unmapPtr() const noexcept { return (LV2_URID_Unmap*) _sym.unmap_feature()->data; } 23 | inline auto unmapFeature() const noexcept { return _sym.unmap_feature(); } 24 | 25 | inline operator LV2_URID_Map*() const noexcept { return mapPtr(); } 26 | 27 | private: 28 | lvtk::Symbols _sym; 29 | }; 30 | 31 | } // namespace element 32 | -------------------------------------------------------------------------------- /include/element/ui/about.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | /** Information used in the About screen. */ 12 | struct AboutInfo { 13 | /** The application's title. */ 14 | juce::String title; 15 | /** The application's version. */ 16 | juce::String version; 17 | /** Copyright notice. */ 18 | juce::String copyright; 19 | /** EULA text. */ 20 | juce::String licenseText; 21 | /** Link to show. */ 22 | juce::URL link; 23 | /** Text of link button. */ 24 | juce::String linkText; 25 | /** App icon or logo. */ 26 | juce::Image logo; 27 | }; 28 | 29 | } // namespace element 30 | -------------------------------------------------------------------------------- /include/element/ui/decibelscale.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | //============================================================================== 10 | /** 11 | Creates a decibel scale using iec lin 2 db scale 12 | */ 13 | class DecibelScale : public juce::Component { 14 | public: 15 | enum DecibelLevels { 16 | LevelOver = 0, 17 | Level0dB = 1, 18 | Level3dB = 2, 19 | Level6dB = 3, 20 | Level10dB = 4, 21 | LevelCount = 5 22 | }; 23 | 24 | enum ColourIds { 25 | markerColourId = 0x11112222 26 | }; 27 | 28 | DecibelScale(); 29 | ~DecibelScale(); 30 | 31 | int iecScale (const float dB) const; 32 | int iecLevel (const int index) const; 33 | 34 | /** @internal */ 35 | void paint (juce::Graphics& g); 36 | /** @internal */ 37 | void resized(); 38 | 39 | protected: 40 | void drawLabel (juce::Graphics& g, const int y, const juce::String& label); 41 | 42 | private: 43 | juce::Font font; 44 | float scale; 45 | int lastY; 46 | int levels[LevelCount]; 47 | }; 48 | 49 | } // namespace element 50 | -------------------------------------------------------------------------------- /include/element/ui/designer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class Context; 11 | class Designer : public juce::Component { 12 | public: 13 | Designer (Context& c); 14 | ~Designer(); 15 | 16 | void resized() override; 17 | void paint (juce::Graphics&) override; 18 | void refresh(); 19 | 20 | private: 21 | class Content; 22 | std::unique_ptr content; 23 | }; 24 | 25 | } // namespace element 26 | -------------------------------------------------------------------------------- /include/element/ui/grapheditor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | 6 | namespace element { 7 | 8 | class GraphNodeEditor : public NodeEditor { 9 | public: 10 | GraphNodeEditor (const Node& graph); 11 | ~GraphNodeEditor(); 12 | void resized() override; 13 | void paint (juce::Graphics& g) override; 14 | 15 | private: 16 | class Graph; 17 | std::unique_ptr graph; 18 | }; 19 | 20 | } // namespace element 21 | -------------------------------------------------------------------------------- /include/element/ui/mainwindow.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | class Services; 12 | class Context; 13 | class MainMenu; 14 | class MainMenuBarModel; 15 | 16 | class MainWindow : public juce::DocumentWindow, 17 | public juce::ChangeListener { 18 | public: 19 | MainWindow (Context&); 20 | virtual ~MainWindow(); 21 | virtual void closeButtonPressed() override; 22 | void minimiseButtonPressed() override; 23 | 24 | void refreshMenu(); 25 | Context& context() { return world; } 26 | Services& services(); 27 | 28 | void changeListenerCallback (juce::ChangeBroadcaster* source) override; 29 | void activeWindowStatusChanged() override; 30 | void refreshName(); 31 | 32 | private: 33 | friend class GuiService; 34 | 35 | Context& world; 36 | std::function windowTitleFunction; 37 | std::unique_ptr mainMenu; 38 | void setMainMenuModel (std::unique_ptr model); 39 | 40 | void nameChanged(); 41 | void nameChangedSession(); 42 | }; 43 | 44 | } // namespace element 45 | -------------------------------------------------------------------------------- /include/element/ui/menumodels.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class MainMenuBarModel : public juce::MenuBarModel { 11 | public: 12 | virtual ~MainMenuBarModel() = default; 13 | virtual juce::PopupMenu* getMacAppMenu() { return nullptr; } 14 | }; 15 | } // namespace element 16 | -------------------------------------------------------------------------------- /include/element/ui/nodeeditor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #define EL_NODE_EDITOR_DEFAULT_ID "el.DefaultNodeEditor" 11 | 12 | namespace element { 13 | 14 | //============================================================================== 15 | class Editor : public juce::Component { 16 | public: 17 | Editor(); 18 | virtual ~Editor(); 19 | bool resizable() const noexcept { return _resizable; } 20 | 21 | protected: 22 | void setResizable (bool canResize); 23 | 24 | private: 25 | bool _resizable { false }; 26 | }; 27 | 28 | //============================================================================== 29 | class NodeEditor : public Editor { 30 | protected: 31 | NodeEditor (const Node&) noexcept; 32 | 33 | public: 34 | NodeEditor() = delete; 35 | virtual ~NodeEditor() override; 36 | inline Node getNode() const { return node; } 37 | bool isRunningInPluginWindow() const; 38 | 39 | protected: 40 | inline Processor* getNodeObject() const { return node.getObject(); } 41 | template 42 | inline T* getNodeObjectOfType() const 43 | { 44 | return dynamic_cast (getNodeObject()); 45 | } 46 | 47 | private: 48 | Node node; 49 | }; 50 | 51 | } // namespace element 52 | -------------------------------------------------------------------------------- /include/element/ui/popups.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | inline static void addMidiDevicesToMenu (juce::PopupMenu& menu, const bool isInput, const int offset = 80000) 12 | { 13 | jassert (offset > 0); 14 | const auto devices = isInput ? juce::MidiInput::getAvailableDevices() 15 | : juce::MidiOutput::getAvailableDevices(); 16 | for (int i = 0; i < devices.size(); ++i) 17 | menu.addItem (i + offset, devices[i].name, true, false); 18 | } 19 | 20 | inline static juce::MidiDeviceInfo getMidiDeviceForMenuResult (const int result, const bool isInput, const int offset = 80000) 21 | { 22 | const int index = result - offset; 23 | const auto devices = isInput ? juce::MidiInput::getAvailableDevices() 24 | : juce::MidiOutput::getAvailableDevices(); 25 | return juce::isPositiveAndBelow (index, devices.size()) ? devices.getUnchecked (index) 26 | : juce::MidiDeviceInfo(); 27 | } 28 | 29 | } // namespace element -------------------------------------------------------------------------------- /include/element/ui/view.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | class EL_API View : public juce::Component { 12 | public: 13 | View() = default; 14 | virtual ~View() = default; 15 | }; 16 | 17 | } // namespace element 18 | -------------------------------------------------------------------------------- /meson/appimage.ini: -------------------------------------------------------------------------------- 1 | [binaries] 2 | c = '/usr/bin/clang' 3 | cpp = '/usr/bin/clang++' 4 | 5 | [built-in options] 6 | buildtype = 'release' 7 | debug = false 8 | prefix = '/usr' 9 | cpp_args = [ '-DEL_APPIMAGE=1', 10 | '-Wno-unused-const-variable', 11 | '-Wno-deprecated-declarations', 12 | '-Wno-sign-compare', 13 | '-Wno-non-virtual-dtor', 14 | '-Wno-unused-private-field' ] 15 | 16 | [project options] 17 | ldoc = 'disabled' 18 | 19 | [lvtk:project options] 20 | test = 'disabled' 21 | -------------------------------------------------------------------------------- /meson/deploy.ini: -------------------------------------------------------------------------------- 1 | [built-in options] 2 | default_library = 'static' 3 | buildtype = 'release' 4 | 5 | [project options] 6 | updater = true 7 | deploy = true 8 | jack = 'enabled' 9 | -------------------------------------------------------------------------------- /meson/juce/meson.build: -------------------------------------------------------------------------------- 1 | juce_proj = subproject ('juce') 2 | juce_dep = juce_proj.get_variable ('juce_dep') 3 | -------------------------------------------------------------------------------- /meson/linux.ini: -------------------------------------------------------------------------------- 1 | [built-in options] 2 | cpp_args = [ 3 | '-Wno-deprecated-declarations', 4 | '-Wno-sign-compare', 5 | '-Wno-non-virtual-dtor'] 6 | 7 | [lvtk:project options] 8 | doc = 'disabled' 9 | -------------------------------------------------------------------------------- /meson/msvc.ini: -------------------------------------------------------------------------------- 1 | [target_machine] 2 | system = 'windows' 3 | cpu_family = 'x86_64' 4 | cpu = 'x86_64' 5 | endian = 'little' 6 | 7 | [properties] 8 | boost_root = 'C:/SDKs/boost_1_81_0' 9 | 10 | [built-in options] 11 | default_library = 'static' 12 | cpp_args = [ '/bigobj', '/wd4244', '/IC:/Program Files/JACK2/include' ] 13 | 14 | [project options] 15 | vst2sdk = 'C:/SDKs/vstsdk2.4' 16 | asiosdk = 'C:/SDKs/ASIOSDK2.3' 17 | -------------------------------------------------------------------------------- /meson/osx-intel.ini: -------------------------------------------------------------------------------- 1 | [constants] 2 | common_args = [ '-arch', 'x86_64', '-mmacosx-version-min=10.15' ] 3 | 4 | [properties] 5 | boost_root = '/usr/local/include' 6 | -------------------------------------------------------------------------------- /meson/osx.ini: -------------------------------------------------------------------------------- 1 | [constants] 2 | common_args = [ '-arch', 'arm64', '-arch', 'x86_64', '-mmacosx-version-min=10.15' ] 3 | 4 | [binaries] 5 | strip = '/usr/bin/strip' 6 | 7 | [properties] 8 | boost_root = '/opt/SDKs/include' 9 | 10 | [built-in options] 11 | default_library = 'static' 12 | c_args = common_args 13 | c_link_args = common_args 14 | objc_args = c_args 15 | objc_link_args = c_link_args 16 | 17 | cpp_args = c_args + [ 18 | '-Wno-sign-compare', #FIXME 19 | '-Wno-non-virtual-dtor', #VST3 SDK 20 | '-Wno-unused-private-field' ] #FIXME 21 | cpp_link_args = c_link_args 22 | objcpp_args = cpp_args 23 | objcpp_link_args = cpp_link_args 24 | 25 | [project options] 26 | vst2sdk = '/opt/SDKs/vstsdk2.4' 27 | -------------------------------------------------------------------------------- /meson/subs.ini: -------------------------------------------------------------------------------- 1 | 2 | [lvtk:project options] 3 | test = 'disabled' 4 | doc = 'disabled' 5 | 6 | [lv2:project options] 7 | plugins = 'disabled' 8 | tests = 'disabled' 9 | docs = 'disabled' 10 | 11 | [serd:project options] 12 | tools = 'disabled' 13 | tests = 'disabled' 14 | docs = 'disabled' 15 | 16 | [sord:project options] 17 | tests = 'disabled' 18 | docs = 'disabled' 19 | tools = 'disabled' 20 | 21 | [sratom:project options] 22 | tests = 'disabled' 23 | docs = 'disabled' 24 | 25 | [lilv:project options] 26 | tools = 'disabled' 27 | tests = 'disabled' 28 | docs = 'disabled' 29 | c_args = [ '/wd4090' ] 30 | 31 | [suil:project options] 32 | tests = 'disabled' 33 | docs = 'disabled' 34 | cocoa = 'enabled' 35 | gtk2 = 'disabled' 36 | gtk3 = 'disabled' 37 | qt5 = 'disabled' 38 | qt6 = 'disabled' 39 | x11 = 'disabled' 40 | 41 | [pugl:project options] 42 | examples = 'disabled' 43 | tests = 'disabled' 44 | docs = 'disabled' 45 | 46 | [zix:project options] 47 | benchmarks = 'disabled' 48 | tests = 'disabled' 49 | docs = 'disabled' 50 | -------------------------------------------------------------------------------- /meson/x86_64-w64-mingw32.ini: -------------------------------------------------------------------------------- 1 | [binaries] 2 | c = 'x86_64-w64-mingw32-gcc' 3 | cpp = 'x86_64-w64-mingw32-g++' 4 | ar = 'x86_64-w64-mingw32-ar' 5 | strip = 'x86_64-w64-mingw32-strip' 6 | exe_wrapper = 'wine64' 7 | windres = 'x86_64-w64-mingw32-windres' 8 | 9 | [host_machine] 10 | system = 'windows' 11 | cpu_family = 'x86_64' 12 | cpu = 'x86_64' 13 | endian = 'little' 14 | 15 | [built-in options] 16 | default_library = 'static' 17 | cpp_args = [ 18 | '-Wa,-mbig-obj', 19 | '-Wno-unused-but-set-variable', 20 | '-Wno-deprecated-declarations', 21 | '-Wno-sign-compare', 22 | '-Wno-non-virtual-dtor' ] 23 | 24 | [properties] 25 | boost_root = '/opt/SDKs/boost' 26 | 27 | [project options] 28 | vst2sdk = '/opt/SDKs/vstsdk2.4' 29 | vst3sdk = '/opt/SDKs/vst3sdk' -------------------------------------------------------------------------------- /plugins/auclient.mm: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pluginconfig.h" 3 | #include 4 | -------------------------------------------------------------------------------- /plugins/auwrapper.mm: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pluginconfig.h" 3 | #include 4 | -------------------------------------------------------------------------------- /plugins/effect/plugin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "./pluginconfig.h" 5 | #include "pluginprocessor.hpp" 6 | 7 | juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() 8 | { 9 | return new element::PluginProcessor ( 10 | element::PluginProcessor::Effect, 16); 11 | } 12 | -------------------------------------------------------------------------------- /plugins/effect/vst3/bundle/meson.build: -------------------------------------------------------------------------------- 1 | element_bundles += custom_target ( 2 | 'KV-Element-FX.vst3', 3 | build_by_default: true, 4 | command: element_fx_vst3_bundle_py, 5 | input: element_fx_vst3, 6 | output: 'KV-Element-FX.vst3', 7 | install: get_option ('deploy'), 8 | install_dir: element_vst3_install_dir 9 | ) 10 | -------------------------------------------------------------------------------- /plugins/instrument/plugin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "./pluginconfig.h" 5 | #include "pluginprocessor.hpp" 6 | 7 | juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() 8 | { 9 | return new element::PluginProcessor ( 10 | element::PluginProcessor::Instrument, 16); 11 | } 12 | -------------------------------------------------------------------------------- /plugins/instrument/vst3/bundle/meson.build: -------------------------------------------------------------------------------- 1 | element_bundles += custom_target ( 2 | 'KV-Element.vst3', 3 | build_by_default: true, 4 | command: element_vst3_bundle_py, 5 | input: element_vst3, 6 | output: 'KV-Element.vst3', 7 | install: get_option ('deploy'), 8 | install_dir: element_vst3_install_dir 9 | ) 10 | -------------------------------------------------------------------------------- /plugins/macvstutils.mm: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pluginconfig.h" 3 | // #include 4 | -------------------------------------------------------------------------------- /plugins/midieffect/plugin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "./pluginconfig.h" 5 | #include "pluginprocessor.hpp" 6 | 7 | juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() 8 | { 9 | return new element::PluginProcessor ( 10 | element::PluginProcessor::MidiEffect, 0); 11 | } 12 | -------------------------------------------------------------------------------- /plugins/plugin.plist.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CFBundleExecutable 7 | @BUNDLE_EXECUTABLE@ 8 | CFBundleIconFile 9 | 10 | CFBundleIdentifier 11 | @BUNDLE_ID@ 12 | CFBundleName 13 | @BUNDLE_NAME@ 14 | CFBundleDisplayName 15 | @BUNDLE_DISPLAY_NAME@ 16 | CFBundlePackageType 17 | BNDL 18 | CFBundleSignature 19 | ???? 20 | CFBundleShortVersionString 21 | @BUNDLE_VERSION@ 22 | CFBundleVersion 23 | @BUNDLE_VERSION@ 24 | NSHumanReadableCopyright 25 | Copyright (c) 2017-2023 Kushview, LLC 26 | NSHighResolutionCapable 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /plugins/utilities.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pluginconfig.h" 3 | // #include 4 | -------------------------------------------------------------------------------- /plugins/vst2client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pluginconfig.h" 3 | 4 | #if __APPLE__ 5 | #include 6 | #endif 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /plugins/vst2client.mm: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pluginconfig.h" 3 | #include 4 | #include -------------------------------------------------------------------------------- /plugins/vst3client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pluginconfig.h" 3 | #include 4 | -------------------------------------------------------------------------------- /plugins/vst3client.mm: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pluginconfig.h" 3 | #include 4 | #include 5 | -------------------------------------------------------------------------------- /scripts/commands.lua: -------------------------------------------------------------------------------- 1 | --- List commands registered in the command manager. 2 | -- @script commands 3 | -- @type anonymous 4 | -- @license GPLv3 5 | -- @author Michael Fisher 6 | -- @usage 7 | -- > script.exec ('commands') 8 | -- SHOW_ABOUT = 256 9 | -- SHOW_ALL_PLUGIN_WINDOWS = 265 10 | -- SHOW_SESSION_CONFIG = 260 11 | -- RECENTS_CLEAR = 4096 12 | -- GRAPH_OPEN = 1793 13 | -- GRAPH_SAVE_AS = 1795 14 | -- UNDO = 4104 15 | -- ... 16 | 17 | local CMD = require ('el.CommandManager') 18 | local strings = require ('el.strings') 19 | local format = select (1, ...) or 'constants' 20 | 21 | if not strings.isslug (format) then 22 | error ("Invalid format: " .. tostring (format)) 23 | end 24 | 25 | local list = { 26 | -- List as constants used with the el.command module 27 | constants = function (cmds) 28 | for k,v in pairs (cmds) do 29 | local out = string.upper (strings.tosnake (k)) 30 | out = out .. " = " .. tostring(v) 31 | print (out) 32 | end 33 | end 34 | } 35 | 36 | local cmds = {} 37 | 38 | -- add standard commands 39 | for _, cmd in ipairs (CMD.standard()) do 40 | local str = CMD.tostring (cmd) 41 | if string.len(str) > 0 then 42 | cmds[str] = cmd 43 | end 44 | end 45 | 46 | if type(list[format]) == 'function' then 47 | list[format] (cmds) 48 | end 49 | -------------------------------------------------------------------------------- /scripts/component.js: -------------------------------------------------------------------------------- 1 | function extractDir() { 2 | var dir = ""; 3 | if (systemInfo.kernelType === "darwin") { 4 | dir = "/Library/Application Support/Kushview/Element"; 5 | } else if (systemInfo.kernelType === "winnt") { 6 | dir = installer.value ("ApplicationsDirX64") + "/Kushview/Element"; 7 | } 8 | return dir; 9 | } 10 | 11 | function Component() {} 12 | 13 | Component.prototype.createOperations = function () { 14 | for (var i = 0; i < component.archives.length; ++i) { 15 | let a = component.archives [i] 16 | if (! a.endsWith ('7z')) 17 | continue; 18 | let target = extractDir(); 19 | if (target.length <= 0) 20 | continue; 21 | component.addElevatedOperation ("Extract", a, target) 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /scripts/console.lua: -------------------------------------------------------------------------------- 1 | --- Console init. 2 | -- Runs when the console is loaded in the GUI. This anonymous script sets global 3 | -- variables, so be careful if you use it directly. 4 | -- @script console 5 | -- @pragma nostrip 6 | -- @type Anonymous 7 | 8 | io = require ('io') 9 | object = require ('el.object') 10 | command = require ('el.command') 11 | script = require ('el.script') 12 | 13 | console = { 14 | --- Log to stdout. 15 | -- Calls `tostring` on each argument then prints the combined result to 16 | -- stdout 17 | -- @function console.log 18 | -- @param ... Things to log 19 | log = function (...) 20 | local out = "" 21 | for i = 1, select ('#', ...) do 22 | out = out .. tostring (select (i, ...)) .. "\t" 23 | end 24 | if string.len(out) > 0 then 25 | io.stdout:write (out .. "\n") 26 | end 27 | end 28 | } 29 | -------------------------------------------------------------------------------- /scripts/content.lua: -------------------------------------------------------------------------------- 1 | --- SysEx MIDI Example. 2 | -- 3 | -- @script UI.Content 4 | -- @type Content 5 | -- @license GPL v3 6 | -- @author Michael Fisher 7 | 8 | local function instantiate (ctx) 9 | end 10 | 11 | return { 12 | type = "Content", 13 | instantiate = instantiate 14 | } 15 | -------------------------------------------------------------------------------- /scripts/meson.build: -------------------------------------------------------------------------------- 1 | 2 | scripts_gen = generator (bin2c, 3 | output : [ '@PLAINNAME@.cpp', '@PLAINNAME@.h'], 4 | arguments : [ '@INPUT@', '@BUILD_DIR@', 'scripts' ]) 5 | scripts_includes = include_directories ('.', '../scripts') 6 | scripts_sources = scripts_gen.process ( 7 | 'ampui.lua', 'channelize.lua', 'amp.lua', 'console.lua') 8 | 9 | if not meson.is_subproject() 10 | 11 | scripts_install_dir = get_option('datadir') / 'element/scripts' 12 | 13 | if get_option ('deploy') 14 | if host_machine.system() == 'windows' 15 | scripts_install_dir = packagedir_element + '.lua' / 'data' / 'lua' / 'scripts' 16 | elif host_machine.system() == 'darwin' 17 | scripts_install_dir = packagedir_element + '.lua' / 'data' / 'lua' / 'scripts' 18 | endif 19 | endif 20 | 21 | install_data (sources : [ 22 | 'amp.lua', 23 | 'ampui.lua', 24 | 'channelize.lua', 25 | 'console.lua', 26 | 'view.lua' 27 | ], 28 | install_dir : scripts_install_dir 29 | ) 30 | 31 | if get_option ('deploy') 32 | foreach f : 'package.xml component.js'.split() 33 | configure_file (input: f, output: f, 34 | install: true, install_dir: packagedir_element + '.lua' / 'meta', 35 | configuration: { 'VERSION': version_with_build, 36 | 'RELEASEDATE': element_release_date}) 37 | endforeach 38 | endif 39 | 40 | endif 41 | -------------------------------------------------------------------------------- /scripts/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Scripts 4 | Scripts 5 | @VERSION@ 6 | @RELEASEDATE@ 7 | 8 | 9 | false 10 | true 11 | true 12 | true 13 | 14 | -------------------------------------------------------------------------------- /scripts/view.lua: -------------------------------------------------------------------------------- 1 | --- A new View script (experimental) 2 | -- 3 | -- Script description. 4 | -- 5 | -- @type View 6 | -- @license GPL3-or-later 7 | -- @author Your Name 8 | 9 | local object = require ('el.object') 10 | local new = object.new 11 | 12 | local function instantiate() 13 | local w = new ('el.View') 14 | w.paint = function (_, g) 15 | g:fillAll(0xff00ff00) 16 | g:setColor (0xffffffff) 17 | g:drawText ("Hello World", w:localBounds()) 18 | end 19 | return w 20 | end 21 | 22 | local function handleGraphChange(_, graph) 23 | end 24 | 25 | return { 26 | type = "View", 27 | instantiate = instantiate, 28 | graph_changed = handleGraphChange 29 | } 30 | -------------------------------------------------------------------------------- /src/ElementApp.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "datapath.hpp" 13 | 14 | namespace element { 15 | using namespace juce; 16 | 17 | inline static bool canConnectToWebsite (const juce::URL& url, const int timeout = 2000) 18 | { 19 | int status = -1; 20 | auto options = juce::URL::InputStreamOptions (URL::ParameterHandling::inAddress) 21 | .withHttpRequestCmd ("GET") 22 | .withStatusCode (&status) 23 | .withConnectionTimeoutMs (timeout); 24 | std::unique_ptr in (url.createInputStream (options)); 25 | return in != nullptr; 26 | } 27 | 28 | inline static bool areMajorWebsitesAvailable() 29 | { 30 | const char* urlsToTry[] = { 31 | "http://google.com", "http://bing.com", "http://amazon.com", "https://google.com", "https://bing.com", "https://amazon.com", nullptr 32 | }; 33 | 34 | for (const char** url = urlsToTry; *url != nullptr; ++url) 35 | if (canConnectToWebsite (juce::URL (*url))) 36 | return true; 37 | 38 | return false; 39 | } 40 | 41 | } // namespace element 42 | -------------------------------------------------------------------------------- /src/appinfo.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | /** Settings in this file can only be configured with the CPP preprocessor. 7 | Modify them to change things like app name. 8 | */ 9 | 10 | // clang-format off 11 | #ifndef EL_APP_AUTHOR 12 | #define EL_APP_AUTHOR "Kushview" 13 | #endif 14 | 15 | #ifndef EL_APP_NAME 16 | #define EL_APP_NAME "Element" 17 | #endif 18 | 19 | #ifndef EL_APP_URL 20 | #define EL_APP_URL "https://kushview.net/element" 21 | #endif 22 | 23 | #define EL_APP_DATA_SUBDIR EL_APP_AUTHOR "/" EL_APP_NAME 24 | // clang-format on 25 | 26 | namespace element { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/arc.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | 6 | namespace element { 7 | 8 | Arc::Arc (uint32_t sn, uint32_t sp, uint32_t dn, uint32_t dp) noexcept 9 | : sourceNode (sn), sourcePort (sp), destNode (dn), destPort (dp) 10 | { 11 | } 12 | 13 | } // namespace element 14 | -------------------------------------------------------------------------------- /src/bindings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | 6 | #include "element/element.hpp" 7 | #include "element/lua.hpp" 8 | #include "sol/sol.hpp" 9 | 10 | #define EL_USE_LIBRARY_BUILT_INS 0 11 | 12 | #if EL_USE_LIBRARY_BUILT_INS 13 | extern "C" { 14 | extern int luaopen_el_audio (lua_State*); 15 | extern int luaopen_el_midi (lua_State*); 16 | extern int luaopen_el_bytes (lua_State*); 17 | extern int luaopen_el_round (lua_State*); 18 | } 19 | #endif 20 | 21 | namespace element { 22 | namespace lua { 23 | 24 | void fill_builtins (PackageLoaderMap& pkgs) 25 | { 26 | #if EL_USE_LIBRARY_BUILT_INS 27 | if (pkgs.find ("el.audio") != pkgs.end()) 28 | return; 29 | pkgs.insert ( 30 | { { "el.audio", luaopen_el_audio }, 31 | { "el.bytes", luaopen_el_bytes }, 32 | { "el.midi", luaopen_el_midi }, 33 | { "el.round", luaopen_el_round } }); 34 | #else 35 | element::ignore (pkgs); 36 | #endif 37 | } 38 | 39 | } // namespace lua 40 | } // namespace element 41 | -------------------------------------------------------------------------------- /src/commands.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | -------------------------------------------------------------------------------- /src/common.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | // !!!! DO NOT INCLUDE THIS IN OTHER HEADERS !!!! // 7 | 8 | #include "ElementApp.h" 9 | 10 | #include 11 | #include "services/deviceservice.hpp" 12 | #include 13 | #include 14 | #include "services/mappingservice.hpp" 15 | #include "services/sessionservice.hpp" 16 | #include "services/presetservice.hpp" 17 | 18 | #include "nodes/nodetypes.hpp" 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | #include "messages.hpp" 25 | #include 26 | #include 27 | #include "utils.hpp" 28 | -------------------------------------------------------------------------------- /src/controller.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | 6 | namespace element { 7 | using namespace juce; 8 | 9 | Controller::Controller (const ValueTree& data) 10 | : Model (data) 11 | { 12 | if (data.isValid()) 13 | { 14 | jassert (data.hasType (types::Controller)); 15 | jassert (data.hasProperty (tags::uuid)); 16 | setMissingProperties(); 17 | } 18 | } 19 | 20 | Controller::Controller (const String& name) 21 | : Model (types::Controller, EL_CONTROLLER_VERSION) 22 | { 23 | setName (name); 24 | setMissingProperties(); 25 | } 26 | 27 | void Controller::setMissingProperties() 28 | { 29 | stabilizePropertyString (tags::uuid, Uuid().toString()); 30 | stabilizePropertyString (tags::name, "New Device"); 31 | stabilizePropertyString (tags::inputDevice, ""); 32 | } 33 | 34 | Controller Control::controller() const 35 | { 36 | const Controller device (objectData.getParent()); 37 | return device; 38 | } 39 | 40 | } // namespace element 41 | -------------------------------------------------------------------------------- /src/datapath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | -------------------------------------------------------------------------------- /src/dynlib.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #ifndef EL_DYNLIB_H 5 | #define EL_DYNLIB_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef _WIN32 12 | #include "dlfcn-win32.h" 13 | #else 14 | #include 15 | #endif 16 | 17 | inline static void* element_openlib (const char* path) 18 | { 19 | return dlopen (path, RTLD_LOCAL | RTLD_LAZY); 20 | } 21 | 22 | inline static void element_closelib (void* handle) 23 | { 24 | dlclose (handle); 25 | } 26 | 27 | inline static void* element_getsym (void* handle, const char* f) 28 | { 29 | return dlsym (handle, f); 30 | } 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/el/AudioBuffer.lua: -------------------------------------------------------------------------------- 1 | --- An audio buffer 2 | -- @classmod el.AudioBuffer 3 | -- @pragma nostrip 4 | 5 | local AudioBuffer32 = require ('el.AudioBuffer32') 6 | local AudioBuffer64 = require ('el.AudioBuffer64') 7 | 8 | local M = {} 9 | 10 | function M.new32 (...) 11 | return AudioBuffer32.new (...) 12 | end 13 | 14 | function M.new64 (...) 15 | return AudioBuffer64.new (...) 16 | end 17 | 18 | M.new = M.new32 19 | 20 | return M 21 | -------------------------------------------------------------------------------- /src/el/AudioBuffer32.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #define EL_LUA_AUDIO_BUFFER_32 1 5 | #define EL_LUA_AUDIO_BUFFER_COMPILE 1 6 | #include "./AudioBufferImpl.ipp" 7 | -------------------------------------------------------------------------------- /src/el/AudioBuffer64.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #define EL_LUA_AUDIO_BUFFER_32 0 5 | #define EL_LUA_AUDIO_BUFFER_COMPILE 1 6 | #include "./AudioBufferImpl.ipp" 7 | -------------------------------------------------------------------------------- /src/el/Bounds.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | /// Bounding box 5 | // The value type for this is a 32bit integer and Backed by a juce::Rectangle. 6 | // API is identical to @{el.Rectangle}. 7 | // @classmod el.Bounds 8 | // @pragma nostrip 9 | 10 | #include 11 | #include "rectangle.hpp" 12 | 13 | #define EL_TYPE_NAME_BOUNDS "Bounds" 14 | 15 | using namespace juce; 16 | 17 | // clang-format off 18 | EL_PLUGIN_EXPORT 19 | int luaopen_el_Bounds (lua_State* L) 20 | { 21 | using B = Rectangle; 22 | 23 | auto M = element::lua::defineRectangle (L, EL_TYPE_NAME_BOUNDS, sol::meta_method::to_string, [] (B& self) { 24 | return element::lua::to_string (self, EL_TYPE_NAME_BOUNDS); 25 | }); 26 | 27 | sol::stack::push (L, M); 28 | return 1; 29 | } 30 | -------------------------------------------------------------------------------- /src/el/Desktop.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | /// Desktop controls. 5 | // Describes and controls aspects of the computer's desktop. 6 | // @classmod el.Desktop 7 | // @pragma nostrip 8 | 9 | #include 10 | #include 11 | 12 | #include "sol_helpers.hpp" 13 | 14 | #define EL_TYPE_NAME_DESKTOP "Desktop" 15 | 16 | using namespace juce; 17 | 18 | // clang-format off 19 | EL_PLUGIN_EXPORT 20 | int luaopen_el_Desktop (lua_State* L) 21 | { 22 | sol::state_view lua (L); 23 | auto M = lua.create_table(); 24 | M.new_usertype (EL_TYPE_NAME_DESKTOP, sol::no_constructor, 25 | /// Desktop single instance. 26 | // @function Desktop.instance 27 | // @within Class Methods 28 | "instance", Desktop::getInstance, 29 | 30 | /// Global scale factor (number) 31 | // Sets a global scale factor to be used for all desktop windows. 32 | // Setting this will also scale display sizes. 33 | // @tfield number Desktop.scale 34 | // @within Attributes 35 | "scale", sol::property (&Desktop::getGlobalScaleFactor, &Desktop::setGlobalScaleFactor)); 36 | 37 | sol::stack::push (L, element::lua::removeAndClear (M, EL_TYPE_NAME_DESKTOP)); 38 | return 1; 39 | } 40 | -------------------------------------------------------------------------------- /src/el/Graph.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | /// The Graph Model. 5 | // Representation of a Graph. Is a @{el.Node} 6 | // @classmod el.Graph 7 | // @pragma nostrip 8 | 9 | #include 10 | #include 11 | #include "./nodetype.hpp" 12 | 13 | // clang-format off 14 | EL_PLUGIN_EXPORT int luaopen_el_Graph (lua_State* L) 15 | { 16 | using namespace element; 17 | using namespace sol; 18 | 19 | auto M = element::lua::new_nodetype (L, "Graph", 20 | sol::meta_function::to_string, [](Graph& self) { return lua::to_string (self, "Graph"); }, 21 | 22 | /// Methods. 23 | // @section methods 24 | 25 | /// Returns true if this graph has a view script. 26 | // @function Graph:hasViewScript 27 | // @return bool True if yes 28 | "hasViewScript", &Graph::hasViewScript, 29 | 30 | /// Returns the view script if available. 31 | // @function Graph:viewScript 32 | // @treturn el.Script True if yes 33 | "viewScript", &Graph::findViewScript 34 | ); 35 | 36 | sol::stack::push (L, element::lua::removeAndClear (M, "Graph")); 37 | return 1; 38 | } 39 | -------------------------------------------------------------------------------- /src/el/Node.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | /// The Node Model. 5 | // Representation of a Node. Is an el.Model 6 | // @classmod el.Node 7 | // @pragma nostrip 8 | 9 | #include 10 | #include 11 | #include "./nodetype.hpp" 12 | 13 | // clang-format off 14 | EL_PLUGIN_EXPORT int luaopen_el_Node (lua_State* L) 15 | { 16 | using namespace element; 17 | using namespace sol; 18 | 19 | auto M = element::lua::new_nodetype (L, "Node", 20 | sol::meta_method::to_string, [](Node& self) { return lua::to_string (self, "Node"); }, 21 | 22 | /// Returns true if this node has an editor. 23 | // @function Node:hasEditor 24 | // @within Methods 25 | // @return bool True if yes. 26 | "hasEditor", &Node::hasEditor 27 | ); 28 | 29 | sol::stack::push (L, M); 30 | return 1; 31 | } 32 | -------------------------------------------------------------------------------- /src/el/Parameter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | /// A Parameter. 5 | // A variable property of a Node. 6 | // @classmod el.Parameter 7 | // @pragma nostrip 8 | 9 | /// Handlers. 10 | // @section handlers 11 | 12 | /// Value changed handler. 13 | // Implement this to handle when the value changes. If you call Parameter:set 14 | // from inside this callback, be careful to not create an infinte callback loop. 15 | // @function Parameter:changed 16 | // @within Handlers 17 | // @usage 18 | // param.changed = function() 19 | // local value = param:get() 20 | // print (value) 21 | // end 22 | 23 | /// Methods. 24 | // @section methods 25 | 26 | /// Get the current value. 27 | // @function Parameter:get 28 | // @treturn number The currrent value 29 | 30 | /// Set the current value. 31 | // @function Parameter:set 32 | // @number value The new value to set 33 | -------------------------------------------------------------------------------- /src/el/Rectangle.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | /// A rectangle. 5 | // The value type for this is a 64 bit float. 6 | // @classmod el.Rectangle 7 | // @pragma nostrip 8 | 9 | #include 10 | #include "rectangle.hpp" 11 | #define EL_TYPE_NAME_RECTANGLE "Rectangle" 12 | 13 | namespace lua = element::lua; 14 | 15 | // clang-format off 16 | EL_PLUGIN_EXPORT 17 | int luaopen_el_Rectangle (lua_State* L) 18 | { 19 | using R = juce::Rectangle; 20 | auto M = lua::defineRectangle (L, EL_TYPE_NAME_RECTANGLE, 21 | sol::meta_method::to_string, [] (R& self) { 22 | return lua::to_string (self, EL_TYPE_NAME_RECTANGLE); 23 | } 24 | ); 25 | 26 | sol::stack::push (L, M); 27 | return 1; 28 | } 29 | -------------------------------------------------------------------------------- /src/el/audio.c: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "element/element.h" 5 | #include 6 | #include 7 | 8 | #define MINUS_INFINITY_DB -100.0 9 | #define UNITY_GAIN 1.0 10 | 11 | static int f_todb (lua_State* L) 12 | { 13 | int isnum = 0; 14 | lua_Number gain = lua_tonumberx (L, 1, &isnum); 15 | if (isnum == 0) 16 | gain = UNITY_GAIN; 17 | lua_Number infinity = lua_tonumberx (L, 2, &isnum); 18 | if (isnum == 0) 19 | infinity = MINUS_INFINITY_DB; 20 | lua_pushnumber (L, gain > 0.0 ? fmax (infinity, log10 (gain) * 20.0) : infinity); 21 | return 1; 22 | } 23 | 24 | static int f_togain (lua_State* L) 25 | { 26 | int isnum = 0; 27 | lua_Number db = lua_tonumberx (L, 1, &isnum); 28 | if (isnum == 0) 29 | db = 1.0; 30 | lua_Number infinity = lua_tonumberx (L, 2, &isnum); 31 | if (isnum == 0) 32 | infinity = MINUS_INFINITY_DB; 33 | lua_pushnumber (L, db > infinity ? pow (10.f, db * 0.05) : 0.0); 34 | return 1; 35 | } 36 | 37 | static luaL_Reg audio_f[] = { 38 | { "togain", f_togain }, 39 | { "todb", f_todb }, 40 | { NULL, NULL } 41 | }; 42 | 43 | EL_PLUGIN_EXPORT 44 | int luaopen_el_audio (lua_State* L) 45 | { 46 | luaL_newlib (L, audio_f); 47 | return 1; 48 | } 49 | -------------------------------------------------------------------------------- /src/el/bytes.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #ifndef EL_LUA_BYTES_H 5 | #define EL_LUA_BYTES_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct _EL_Bytes 12 | { 13 | size_t size; 14 | uint8_t* data; 15 | } EL_Bytes; 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/el/color.lua: -------------------------------------------------------------------------------- 1 | --- Color operations and utilities. 2 | -- Utility library for manipulating colors. 3 | -- @module el.color 4 | local M = {} 5 | 6 | return M 7 | -------------------------------------------------------------------------------- /src/el/factories.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "element/element.h" 7 | #include "sol_helpers.hpp" 8 | #include 9 | 10 | namespace element { 11 | namespace lua { 12 | 13 | template 14 | T** new_userdata (lua_State* L, const char* metatable) 15 | { 16 | T** data = (T**) lua_newuserdata (L, sizeof (T**)); 17 | if (strlen (metatable) > 0) 18 | luaL_setmetatable (L, metatable); 19 | *data = new T(); 20 | return data; 21 | } 22 | 23 | template 24 | T** new_userdata (lua_State* L, const char* metatable, Args&&... args) 25 | { 26 | T** data = (T**) lua_newuserdata (L, sizeof (T**)); 27 | if (strlen (metatable) > 0) 28 | luaL_setmetatable (L, metatable); 29 | *data = new T (std::forward (args)...); 30 | return data; 31 | } 32 | 33 | } // namespace lua 34 | } // namespace element 35 | -------------------------------------------------------------------------------- /src/el/packed.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include 11 | 12 | typedef union _kv_packed_t 13 | { 14 | int64_t packed; 15 | uint8_t data[4]; 16 | } kv_packed_t; 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /src/el/script.lua: -------------------------------------------------------------------------------- 1 | --- Script module. 2 | -- @module el.script 3 | local M = {} 4 | 5 | M.DSP = 'DSP' 6 | M.DSPUI = 'DSPUI' 7 | M.VIEW = 'View' 8 | M.GRAPH_VIEW = 'GraphView' 9 | M.ANONYMOUS = 'Anonymous' 10 | 11 | --- Load a known script. 12 | -- @function load 13 | -- @string path The script to run 14 | -- @tparam table env The environment to use or _ENV 15 | -- @treturn table The script's descriptor table 16 | -- @usage script.load ('scriptname') 17 | function M.load (path, env) 18 | local src, e = package.searchpath (path, package.spath) 19 | if src then return loadfile (src, 'bt', env or _ENV) end 20 | return nil, e 21 | end 22 | 23 | --- Run a known script. 24 | -- @function exec 25 | -- @string path The script to run 26 | -- @tparam table env The environment to use or _ENV 27 | -- @tparam any ... Arguments passed to script 28 | -- @treturn any Return value from script or no value 29 | -- @usage script.exec ('scriptname') 30 | function M.exec (path, env, ...) 31 | local invoke, err = M.load (path, env) 32 | if err then return err end 33 | return invoke (...) 34 | end 35 | 36 | return M 37 | -------------------------------------------------------------------------------- /src/el/session.lua: -------------------------------------------------------------------------------- 1 | --- Session. 2 | -- High level session dealings in Lua. This module wraps el.Session class 3 | -- in an simplified API. 4 | -- @module el.session 5 | 6 | local Context = require ('el.Context') 7 | local Session = require ('el.Session') 8 | local Node = require ('el.Node') 9 | local Graph = require ('el.Graph') 10 | 11 | local M = {} 12 | local session = Context.instance():session() 13 | 14 | function M.toxmlstring() return session:toXmlString() end 15 | function M.name() return session.name end 16 | 17 | return M 18 | -------------------------------------------------------------------------------- /src/el/util.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #ifndef EL_LUA_UTIL_H 5 | #define EL_LUA_UTIL_H 6 | 7 | #ifdef MIN 8 | #undef MIN 9 | #endif 10 | 11 | #ifdef MAX 12 | #undef MAX 13 | #endif 14 | 15 | #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 16 | #define MAX(x, y) (((x) > (y)) ? (x) : (y)) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/engine/audioprocessorfactory.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class Context; 11 | 12 | // implemented in nodefactory.cpp 13 | class AudioProcessorFactory : public NodeProvider 14 | { 15 | public: 16 | AudioProcessorFactory (Context&); 17 | ~AudioProcessorFactory(); 18 | String format() const override { return EL_NODE_FORMAT_NAME; } 19 | /** Create the instance by ID string. */ 20 | Processor* create (const String&) override; 21 | /** return a list of types contained in this provider. */ 22 | StringArray findTypes (const juce::FileSearchPath&, bool, bool) override; 23 | 24 | private: 25 | class Format; 26 | std::unique_ptr _format; 27 | }; 28 | 29 | } // namespace element 30 | -------------------------------------------------------------------------------- /src/engine/clapprovider.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace element { 7 | 8 | class Processor; 9 | 10 | /** A provider of CLAP plugins. */ 11 | class CLAPProvider final : public NodeProvider 12 | { 13 | public: 14 | CLAPProvider(); 15 | ~CLAPProvider(); 16 | juce::String format() const override; 17 | Processor* create (const juce::String&) override; 18 | juce::FileSearchPath defaultSearchPath() override; 19 | juce::StringArray findTypes (const FileSearchPath& path, 20 | bool recursive, 21 | bool allowAsync) override; 22 | StringArray getHiddenTypes() override { return {}; } 23 | void scan (const String& fileOrID, OwnedArray& out) override; 24 | 25 | private: 26 | class Host; 27 | std::unique_ptr _host; 28 | }; 29 | } // namespace element 30 | -------------------------------------------------------------------------------- /src/engine/rootgraph.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "engine/rootgraph.hpp" 5 | 6 | namespace element { 7 | 8 | RootGraph::RootGraph (Context& c) 9 | : GraphNode (c) {} 10 | 11 | void RootGraph::refreshPorts() 12 | { 13 | GraphNode::refreshPorts(); 14 | } 15 | 16 | void RootGraph::setPlayConfigFor (DeviceManager& devices) 17 | { 18 | if (auto* const device = devices.getCurrentAudioDevice()) 19 | setPlayConfigFor (device); 20 | } 21 | 22 | void RootGraph::setPlayConfigFor (AudioIODevice* device) 23 | { 24 | jassert (device != nullptr); 25 | setRenderDetails (device->getCurrentBufferSizeSamples(), 26 | device->getCurrentSampleRate()); 27 | } 28 | 29 | void RootGraph::setPlayConfigFor (const DeviceManager::AudioDeviceSetup& setup) 30 | { 31 | setRenderDetails (setup.sampleRate, setup.bufferSize); 32 | } 33 | 34 | } // namespace element 35 | -------------------------------------------------------------------------------- /src/engine/trace.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | inline static void traceMidi (const juce::MidiMessage& msg, const int frame = -1) 11 | { 12 | if (msg.isMidiClock()) 13 | { 14 | DBG ("clock:"); 15 | } 16 | if (msg.isNoteOn()) 17 | { 18 | std::clog << "NOTE ON: " << msg.getMidiNoteName (msg.getNoteNumber(), true, false, 4).toStdString() << std::endl; 19 | } 20 | if (msg.isNoteOff()) 21 | { 22 | std::clog << "NOTE OFF: " << msg.getMidiNoteName (msg.getNoteNumber(), true, false, 4).toStdString() << std::endl; 23 | } 24 | 25 | if (msg.isController()) 26 | { 27 | msg.isControllerOfType (0); 28 | DBG ("MIDI CC: " << msg.getControllerNumber() << ":" << msg.getControllerValue()); 29 | } 30 | 31 | if (msg.isProgramChange()) 32 | { 33 | DBG ("program change: " << msg.getProgramChangeNumber() << " ch: " << msg.getChannel()); 34 | } 35 | 36 | if (frame >= 0 && (msg.isAllNotesOff() || msg.isAllSoundOff())) 37 | { 38 | DBG ("got it: " << frame); 39 | } 40 | } 41 | 42 | inline static void traceMidi (juce::MidiBuffer& buf) 43 | { 44 | for (const auto i : buf) 45 | traceMidi (i.getMessage(), i.samplePosition); 46 | } 47 | } // namespace element 48 | -------------------------------------------------------------------------------- /src/filesystemwatcher.mm: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "filesystemwatcher.cpp" 4 | -------------------------------------------------------------------------------- /src/graph.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | 6 | using namespace juce; 7 | 8 | namespace element { 9 | 10 | Graph Graph::create (const juce::String& name, int numAudioIns, int numAudioOuts, bool midiIn, bool midiOut) 11 | { 12 | Node graph (types::Graph); 13 | graph.setProperty (tags::name, name); 14 | ValueTree gports = graph.getPortsValueTree(); 15 | 16 | int portIdx = 0; 17 | for (int c = 0; c < numAudioIns; c++) 18 | { 19 | Port port (String ("Audio In XX").replace ("XX", String (c + 1)), 20 | tags::audio, 21 | tags::input, 22 | portIdx++); 23 | gports.addChild (port.data(), -1, nullptr); 24 | } 25 | 26 | if (midiIn) 27 | gports.addChild (Port ("MIDI In", tags::midi, tags::input, portIdx++).data(), -1, 0); 28 | 29 | for (int c = 0; c < numAudioOuts; c++) 30 | { 31 | Port port (String ("Audio Out XX").replace ("XX", String (c + 1)), 32 | tags::audio, 33 | tags::output, 34 | portIdx++); 35 | gports.addChild (port.data(), -1, nullptr); 36 | } 37 | 38 | if (midiOut) 39 | gports.addChild (Port ("MIDI Out", tags::midi, tags::output, portIdx++).data(), -1, 0); 40 | 41 | return graph; 42 | } 43 | 44 | } // namespace element -------------------------------------------------------------------------------- /src/gzip.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | 6 | namespace element { 7 | namespace gzip { 8 | using InputStream = juce::GZIPDecompressorInputStream; 9 | using OutputStream = juce::GZIPCompressorOutputStream; 10 | 11 | juce::String encode (const juce::String& input) 12 | { 13 | juce::MemoryOutputStream out; 14 | { 15 | juce::MemoryOutputStream mo; 16 | { 17 | OutputStream gz (mo); 18 | gz.writeString (input); 19 | } 20 | juce::Base64::convertToBase64 (out, mo.getData(), mo.getDataSize()); 21 | } 22 | // NOTE: "data:application/gzip;base64, "; 23 | return out.toString(); 24 | } 25 | 26 | juce::String decode (const juce::String& input) 27 | { 28 | juce::MemoryOutputStream mo; 29 | juce::Base64::convertFromBase64 (mo, input); 30 | auto block = mo.getMemoryBlock(); 31 | juce::MemoryInputStream mi (block, false); 32 | InputStream dc (new juce::MemoryInputStream (block, false), 33 | true, 34 | InputStream::zlibFormat, 35 | mo.getDataSize()); 36 | return dc.readString(); 37 | } 38 | 39 | } // namespace gzip 40 | } // namespace element 41 | -------------------------------------------------------------------------------- /src/juce/.clang-format: -------------------------------------------------------------------------------- 1 | DisableFormat: true 2 | SortIncludes: false 3 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_basics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_basics.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_devices.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_devices.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_formats.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_formats.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_plugin_client_AU.r: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "juce_config.hsss" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_plugin_client_AU_1.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "juce_config.h" 9 | #include "pluginconfig.h" 10 | #include 11 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_plugin_client_AU_2.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_plugin_client_VST2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "juce_config.h" 3 | #include "./JucePluginDefines.h" 4 | #include -------------------------------------------------------------------------------- /src/juce/include_juce_audio_plugin_client_VST3.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "juce_config.h" 3 | #include "./JucePluginDefines.h" 4 | #include 5 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_plugin_client_utils.cpp: -------------------------------------------------------------------------------- 1 | #include "juce_config.h" 2 | #include "pluginconfig.h" 3 | #include 4 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_processors.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include "jbridge.cpp" 10 | #include 11 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_processors.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_processors_lv2_libs.cpp: -------------------------------------------------------------------------------- 1 | #include "AppConfig.h" 2 | #include 3 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_audio_utils.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_core.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_core.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_cryptography.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_cryptography.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_data_structures.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_data_structures.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_dsp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_dsp.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_events.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_events.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_graphics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_graphics.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_gui_basics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_gui_basics.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_gui_extra.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_gui_extra.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_juce_osc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_kv_core.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_kv_core.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_kv_engines.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_kv_engines.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_kv_gui.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_kv_gui.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_kv_models.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/juce/include_kv_models.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /src/lua/.clang-format: -------------------------------------------------------------------------------- 1 | DisableFormat: true 2 | SortIncludes: false 3 | -------------------------------------------------------------------------------- /src/lua/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | /src/lua 4 | /src/luac 5 | -------------------------------------------------------------------------------- /src/lua/meson.build: -------------------------------------------------------------------------------- 1 | 2 | lua_includes = include_directories ('.', 'src') 3 | lua_c_args = [] 4 | if host_machine.system() == 'linux' 5 | lua_c_args += '-DLUA_USE_LINUX' 6 | elif host_machine.system() == 'darwin' 7 | lua_c_args += '-DLUA_USE_MACOSX' 8 | elif host_machine.system() == 'windows' 9 | # not actually needed 10 | # lua_c_args += '-DLUA_USE_WINDOWS' 11 | endif 12 | 13 | libelement_lua = static_library ('element_lua', ''' 14 | src/lauxlib.c 15 | src/liolib.c 16 | src/lopcodes.c 17 | src/lstate.c 18 | src/lobject.c 19 | src/lmathlib.c 20 | src/loadlib.c 21 | src/lvm.c 22 | src/lfunc.c 23 | src/lstrlib.c 24 | src/linit.c 25 | src/lstring.c 26 | src/lundump.c 27 | src/lctype.c 28 | src/ltable.c 29 | src/ldump.c 30 | src/loslib.c 31 | src/lgc.c 32 | src/lzio.c 33 | src/ldblib.c 34 | src/lutf8lib.c 35 | src/lmem.c 36 | src/lcorolib.c 37 | src/lcode.c 38 | src/ltablib.c 39 | src/lapi.c 40 | src/lbaselib.c 41 | src/ldebug.c 42 | src/lparser.c 43 | src/llex.c 44 | src/ltm.c 45 | src/ldo.c'''.split(), 46 | include_directories : lua_includes, 47 | install : false, 48 | gnu_symbol_visibility : 'default', 49 | c_args : lua_c_args 50 | ) 51 | -------------------------------------------------------------------------------- /src/lua/src/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /src/lua/src/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /src/lua/src/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* version suffix for environment variable names */ 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 16 | 17 | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_COLIBNAME "coroutine" 21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 22 | 23 | #define LUA_TABLIBNAME "table" 24 | LUAMOD_API int (luaopen_table) (lua_State *L); 25 | 26 | #define LUA_IOLIBNAME "io" 27 | LUAMOD_API int (luaopen_io) (lua_State *L); 28 | 29 | #define LUA_OSLIBNAME "os" 30 | LUAMOD_API int (luaopen_os) (lua_State *L); 31 | 32 | #define LUA_STRLIBNAME "string" 33 | LUAMOD_API int (luaopen_string) (lua_State *L); 34 | 35 | #define LUA_UTF8LIBNAME "utf8" 36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | 48 | /* open all previous libraries */ 49 | LUALIB_API void (luaL_openlibs) (lua_State *L); 50 | 51 | 52 | 53 | #if !defined(lua_assert) 54 | #define lua_assert(x) ((void)0) 55 | #endif 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/lua/src/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | /* 22 | ** Encode major-minor version in one byte, one nibble for each 23 | */ 24 | #define MYINT(s) (s[0]-'0') /* assume one-digit numerals */ 25 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 26 | 27 | #define LUAC_FORMAT 0 /* this is the official format */ 28 | 29 | /* load one chunk; from lundump.c */ 30 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 31 | 32 | /* dump one chunk; from ldump.c */ 33 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 34 | void* data, int strip); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/lv2/logfeature.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "lv2/logfeature.hpp" 5 | 6 | using namespace juce; 7 | 8 | namespace element { 9 | namespace LV2Callbacks { 10 | 11 | int vprintf (LV2_Log_Handle handle, LV2_URID type, const char* fmt, va_list ap) 12 | { 13 | // TODO: Lock 14 | return std::vfprintf (stderr, fmt, ap); 15 | } 16 | 17 | int printf (LV2_Log_Handle handle, LV2_URID type, const char* fmt, ...) 18 | { 19 | va_list args; 20 | va_start (args, fmt); 21 | const int ret = LV2Callbacks::vprintf (handle, type, fmt, args); 22 | va_end (args); 23 | return ret; 24 | } 25 | } // namespace LV2Callbacks 26 | 27 | LogFeature::LogFeature() 28 | { 29 | uri = LV2_LOG__log; 30 | feat.URI = uri.toRawUTF8(); 31 | log.handle = this; 32 | log.printf = &LV2Callbacks::printf; 33 | log.vprintf = &LV2Callbacks::vprintf; 34 | feat.data = (void*) &log; 35 | } 36 | 37 | LogFeature::~LogFeature() 38 | { 39 | } 40 | 41 | } // namespace element 42 | -------------------------------------------------------------------------------- /src/lv2/logfeature.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include "lv2/lv2features.hpp" 11 | 12 | namespace element { 13 | 14 | class LogFeature : public LV2Feature 15 | { 16 | public: 17 | LogFeature(); 18 | ~LogFeature(); 19 | 20 | inline const juce::String& getURI() const { return uri; } 21 | inline const LV2_Feature* getFeature() const { return &feat; } 22 | 23 | private: 24 | juce::String uri; 25 | LV2_Feature feat; 26 | LV2_Log_Log log; 27 | }; 28 | 29 | } // namespace element 30 | -------------------------------------------------------------------------------- /src/lv2/messages.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Michael Fisher 2 | // SPDX-License-Identifier: ISC 3 | 4 | #include "lv2/messages.hpp" 5 | #include 6 | -------------------------------------------------------------------------------- /src/lv2/native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "./native.hpp" 5 | 6 | // #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 7 | // #define JUCE_CORE_INCLUDE_OBJC_HELPERS 1 8 | #define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1 9 | // #define JUCE_GUI_BASICS_INCLUDE_SCOPED_THREAD_DPI_AWARENESS_SETTER 1 10 | // #define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1 11 | #include 12 | 13 | using namespace juce; 14 | 15 | namespace element { 16 | 17 | #if JUCE_LINUX 18 | inline static Display* display() 19 | { 20 | return XWindowSystem::getInstance()->getDisplay(); 21 | } 22 | void reparentWindow (intptr_t child, intptr_t parent, int x, int y) 23 | { 24 | XWindowSystemUtilities::ScopedXLock xLock; 25 | // X11Symbols::getInstance()->xUnmapWindow (display(), child); 26 | X11Symbols::getInstance()->xReparentWindow (display(), 27 | (::Window) child, 28 | (::Window) parent, 29 | x, 30 | y); 31 | } 32 | #else 33 | void reparentWindow (intptr_t child, intptr_t parent, int x, int y) 34 | { 35 | juce::ignoreUnused (child, parent, x, y); 36 | } 37 | #endif 38 | 39 | } // namespace element 40 | -------------------------------------------------------------------------------- /src/lv2/native.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | void reparentWindow (intptr_t child, intptr_t parent, int x, int y); 10 | } 11 | -------------------------------------------------------------------------------- /src/lv2/platform.mm: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #import 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | bool getNativeWindowSize (void* v, int& width, int& height) 11 | { 12 | NSView* view = (NSView*) v; 13 | width = static_cast (view.frame.size.width); 14 | height = static_cast (view.frame.size.height); 15 | return true; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/lv2/portevent.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | /** A function which writes to a port 11 | @param port Port Index 12 | @param size Data size 13 | @param protocol Data protocol 14 | @param data The Data 15 | */ 16 | using PortWriteFunction = std::function; 17 | 18 | /** Same as PortWriteFunction except is indended to trigger when 19 | events come from the plugin instance. */ 20 | using PortNotificationFunction = PortWriteFunction; 21 | 22 | /** A simple type for writing/reading port values/messages through a ringbuffer */ 23 | struct PortEvent 24 | { 25 | uint32_t index; ///< The port index 26 | uint32_t protocol; ///< The port protocol 27 | union 28 | { 29 | double decimal; ///< Timestamp as a decimal, units depends on context 30 | int64_t frames; ///< Timestamp in audio frames 31 | } time; 32 | uint32_t size; ///< The size of data 33 | }; 34 | 35 | } // namespace element 36 | -------------------------------------------------------------------------------- /src/lv2/workerfeature.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "lv2/lv2features.hpp" 9 | #include "lv2/workthread.hpp" 10 | 11 | namespace element { 12 | 13 | class WorkerFeature final : public LV2Feature, 14 | public WorkerBase 15 | { 16 | public: 17 | WorkerFeature (WorkThread& thread, uint32_t bufsize, LV2_Handle handle = nullptr, LV2_Worker_Interface* iface = nullptr); 18 | 19 | ~WorkerFeature(); 20 | 21 | void setInterface (LV2_Handle handle, LV2_Worker_Interface* iface); 22 | 23 | const String& getURI() const; 24 | const LV2_Feature* getFeature() const; 25 | 26 | void endRun(); 27 | void processRequest (uint32_t size, const void* data); 28 | void processResponse (uint32_t size, const void* data); 29 | 30 | private: 31 | juce::String uri; 32 | LV2_Worker_Interface* worker; 33 | LV2_Handle plugin; 34 | LV2_Worker_Schedule data; 35 | LV2_Feature feat; 36 | }; 37 | 38 | } // namespace element 39 | -------------------------------------------------------------------------------- /src/matrixstate.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "matrixstate.hpp" 5 | 6 | namespace element { 7 | using namespace juce; 8 | 9 | void MatrixState::setFrom (const MatrixState& o) 10 | { 11 | for (int row = jmin (getNumRows(), o.getNumRows()); --row >= 0;) 12 | for (int col = jmin (getNumColumns(), o.getNumColumns()); --col >= 0;) 13 | set (row, col, o.connected (row, col)); 14 | } 15 | 16 | void MatrixState::resize (int r, int c, bool retain) 17 | { 18 | if (r < 0) 19 | r = 0; 20 | if (c < 0) 21 | c = 0; 22 | 23 | BigInteger bits; 24 | bits.setRange (0, r * c, false); 25 | 26 | // TODO: retain set bits 27 | if (retain) 28 | { 29 | const auto old = *this; 30 | numRows = r; 31 | numColumns = c; 32 | toggled.swapWith (bits); 33 | setFrom (old); 34 | } 35 | else 36 | { 37 | numRows = r; 38 | numColumns = c; 39 | toggled.swapWith (bits); 40 | } 41 | } 42 | 43 | } // namespace element 44 | -------------------------------------------------------------------------------- /src/native_unix.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #if ! defined(_WIN32) 5 | 6 | #include 7 | #include 8 | 9 | uint64_t element_time_ns() 10 | { 11 | struct timespec ts; 12 | clock_gettime (CLOCK_MONOTONIC, &ts); 13 | return ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec); 14 | } 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/nodes/audioroutereditor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include "matrixstate.hpp" 8 | 9 | namespace element { 10 | 11 | class AudioRouterEditor : public NodeEditor, 12 | public ChangeListener 13 | { 14 | public: 15 | AudioRouterEditor (const Node& node); 16 | ~AudioRouterEditor(); 17 | 18 | void resized() override; 19 | void paint (Graphics& g) override; 20 | 21 | void adjustBoundsToMatrixSize (int cellSize = 0); 22 | String getSizeString() const; 23 | MatrixState& getMatrixState() { return matrix; } 24 | void applyMatrix(); 25 | void setFadeLength (double length); 26 | void changeListenerCallback (ChangeBroadcaster*) override; 27 | 28 | void setAutoResize (bool yn) { autoResize = yn; } 29 | 30 | private: 31 | MatrixState matrix; 32 | bool autoResize = false; 33 | class Content; 34 | std::unique_ptr content; 35 | }; 36 | 37 | } // namespace element 38 | -------------------------------------------------------------------------------- /src/nodes/eqfiltereditor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Kushview, LLC 2 | // Author: Jatin Chowdhury (jatin@ccrma.stanford.edu) 3 | // SPDX-License-Identifier: GPL3-or-later 4 | 5 | #pragma once 6 | 7 | #include "nodes/eqfiltereditor.hpp" 8 | #include "nodes/knobs.hpp" 9 | 10 | namespace element { 11 | 12 | class EQFilterNodeEditor : public AudioProcessorEditor 13 | { 14 | public: 15 | EQFilterNodeEditor (EQFilterProcessor& proc); 16 | ~EQFilterNodeEditor(); 17 | 18 | void paint (Graphics& g) override; 19 | void resized() override; 20 | 21 | private: 22 | [[maybe_unused]] EQFilterProcessor& proc; // reference to processor for this editor 23 | KnobsComponent knobs; 24 | 25 | class FreqViz : public Component 26 | { 27 | public: 28 | FreqViz (EQFilterProcessor& proc); 29 | ~FreqViz() {} 30 | 31 | void updateCurve(); 32 | float getFreqForX (float xPos); 33 | float getXForFreq (float freq); 34 | 35 | void paint (Graphics& g) override; 36 | void resized() override; 37 | 38 | private: 39 | EQFilterProcessor& proc; 40 | Path curvePath; // path for frequency response curve 41 | 42 | const float lowFreq = 10.0f; 43 | const float highFreq = 22000.0f; 44 | const float dashLengths[2] = { 4, 1 }; 45 | }; 46 | FreqViz viz; 47 | }; 48 | 49 | } // namespace element 50 | -------------------------------------------------------------------------------- /src/nodes/genericeditor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class GenericNodeEditor : public NodeEditor 11 | { 12 | public: 13 | GenericNodeEditor (const Node&); 14 | ~GenericNodeEditor() override; 15 | void resized() override; 16 | void paint (Graphics&) override; 17 | 18 | private: 19 | struct Pimpl; 20 | std::unique_ptr pimpl; 21 | }; 22 | 23 | } // namespace element 24 | -------------------------------------------------------------------------------- /src/nodes/knobs.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Kushview, LLC 2 | // Author: Jatin Chowdhury (jatin@ccrma.stanford.edu) 3 | // SPDX-License-Identifier: GPL3-or-later 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | namespace element { 11 | 12 | class KnobsComponent : public juce::Component 13 | { 14 | public: 15 | KnobsComponent (juce::AudioProcessor& proc, std::function paramLambda = {}); 16 | ~KnobsComponent() {} 17 | 18 | void paint (juce::Graphics& g) override; 19 | void resized() override; 20 | 21 | private: 22 | juce::OwnedArray sliders; 23 | juce::OwnedArray boxes; 24 | 25 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (KnobsComponent) 26 | }; 27 | 28 | } // namespace element 29 | -------------------------------------------------------------------------------- /src/nodes/midichannelsplitter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "nodes/midichannelsplitter.hpp" 5 | -------------------------------------------------------------------------------- /src/nodes/midifilter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "nodes/midifilter.hpp" 5 | 6 | namespace element { 7 | 8 | MidiFilterNode::MidiFilterNode (uint32 nodeId) 9 | : Processor (nodeId) {} 10 | MidiFilterNode::~MidiFilterNode() {} 11 | 12 | } // namespace element 13 | -------------------------------------------------------------------------------- /src/nodes/midifilter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class MidiFilterNode : public Processor 11 | { 12 | public: 13 | virtual ~MidiFilterNode(); 14 | 15 | protected: 16 | MidiFilterNode (uint32 nodeId); 17 | inline bool wantsContext() const noexcept override { return true; } 18 | }; 19 | 20 | } // namespace element 21 | -------------------------------------------------------------------------------- /src/nodes/midimonitoredtor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | // Author: Eliot Akira 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | namespace element { 10 | 11 | class MidiMonitorNodeEditor : public NodeEditor 12 | { 13 | public: 14 | MidiMonitorNodeEditor (const Node& node); 15 | virtual ~MidiMonitorNodeEditor(); 16 | void paint (Graphics& g) override { g.fillAll (findColour (TextEditor::backgroundColourId).darker()); } 17 | void resized() override; 18 | 19 | private: 20 | class Logger; 21 | std::unique_ptr logger; 22 | TextButton clearButton; 23 | }; 24 | 25 | } // namespace element 26 | -------------------------------------------------------------------------------- /src/nodes/nodetypes.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /src/nodes/volumeeditor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class Node; 11 | class GuiService; 12 | 13 | class VolumeNodeEditor : public NodeEditor 14 | { 15 | public: 16 | VolumeNodeEditor (const Node&, GuiService&); 17 | ~VolumeNodeEditor(); 18 | 19 | void paint (Graphics& g) override; 20 | void resized() override; 21 | 22 | private: 23 | class ChannelStrip; 24 | friend class ChannelStrip; 25 | std::unique_ptr strip; 26 | }; 27 | 28 | } // namespace element 29 | -------------------------------------------------------------------------------- /src/res/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kushview/element/2159d748c3a48385a838cab31ba12c11e6d114a2/src/res/icon.ico -------------------------------------------------------------------------------- /src/res/resources.rc: -------------------------------------------------------------------------------- 1 | #pragma code_page(65001) 2 | #undef WIN32_LEAN_AND_MEAN 3 | #define WIN32_LEAN_AND_MEAN 4 | 5 | #include 6 | 7 | VS_VERSION_INFO VERSIONINFO 8 | FILEVERSION 1,0,0,190 9 | BEGIN 10 | BLOCK "StringFileInfo" 11 | BEGIN 12 | BLOCK "040904E4" 13 | BEGIN 14 | VALUE "CompanyName", "Kushview\0" 15 | VALUE "LegalCopyright", "Copyright (c) 2014-2024 Kushview, LLC\0" 16 | VALUE "FileDescription", "Element\0" 17 | VALUE "FileVersion", "1.0.0\0" 18 | VALUE "ProductName", "Element\0" 19 | VALUE "ProductVersion", "1.0.0\0" 20 | END 21 | END 22 | 23 | BLOCK "VarFileInfo" 24 | BEGIN 25 | VALUE "Translation", 0x409, 1252 26 | END 27 | END 28 | 29 | IDI_ICON1 ICON DISCARDABLE "icon.ico" 30 | IDI_ICON2 ICON DISCARDABLE "icon.ico" -------------------------------------------------------------------------------- /src/ringbuffer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "ringbuffer.hpp" 5 | 6 | namespace element { 7 | 8 | RingBuffer::RingBuffer (int32 capacity) 9 | : fifo (1), buffer (nullptr) 10 | { 11 | setCapacity (capacity); 12 | } 13 | 14 | RingBuffer::~RingBuffer() 15 | { 16 | fifo.reset(); 17 | fifo.setTotalSize (1); 18 | buffer = nullptr; 19 | block.free(); 20 | } 21 | 22 | void RingBuffer::setCapacity (int32 newCapacity) 23 | { 24 | newCapacity = juce::nextPowerOfTwo (newCapacity); 25 | 26 | if (fifo.getTotalSize() != newCapacity) 27 | { 28 | juce::HeapBlock newBlock; 29 | newBlock.allocate (newCapacity, true); 30 | { 31 | block.swapWith (newBlock); 32 | buffer = block.getData(); 33 | fifo.setTotalSize (newCapacity); 34 | } 35 | } 36 | 37 | fifo.reset(); 38 | } 39 | 40 | } // namespace element 41 | -------------------------------------------------------------------------------- /src/scopedcallback.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | namespace element { 7 | 8 | /** A scoped function callback. Similar to goto, this calls a function when it goes out of scope. 9 | 10 | You should not perform complex operations with this. It is meant to ensure a callback when 11 | the calling function returns. 12 | */ 13 | class ScopedCallback 14 | { 15 | public: 16 | /** Create a new ScopedCallback. 17 | @param f The function to call 18 | */ 19 | explicit ScopedCallback (std::function f) 20 | : callback (f) {} 21 | 22 | ~ScopedCallback() 23 | { 24 | if (callback) 25 | callback(); 26 | } 27 | 28 | private: 29 | std::function callback; 30 | }; 31 | 32 | } // namespace element 33 | -------------------------------------------------------------------------------- /src/scopedflag.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | namespace element { 7 | 8 | /** Utility class that will set a boolean to a a new value, then 9 | reset it back when this class goes out of scope 10 | */ 11 | class ScopedFlag final 12 | { 13 | public: 14 | ScopedFlag() = delete; 15 | explicit ScopedFlag (bool& value, bool newValue) noexcept 16 | : valueToSet (value) 17 | { 18 | previousValue = value; 19 | valueToSet = newValue; 20 | } 21 | 22 | ~ScopedFlag() noexcept 23 | { 24 | valueToSet = previousValue; 25 | } 26 | 27 | private: 28 | bool& valueToSet; 29 | bool previousValue; 30 | }; 31 | 32 | } // namespace element 33 | -------------------------------------------------------------------------------- /src/scripting.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "element/lua.hpp" 9 | #include "sol/sol.hpp" 10 | 11 | namespace element { 12 | 13 | class Context; 14 | class ScriptManager; 15 | 16 | class ScriptingEngine 17 | { 18 | public: 19 | ScriptingEngine(); 20 | ~ScriptingEngine(); 21 | 22 | ScriptManager& getScriptManager(); 23 | 24 | //========================================================================== 25 | lua_State* getLuaState() const; 26 | 27 | //========================================================================== 28 | juce::Result execute (const String& code); 29 | 30 | std::vector getPackageNames() const noexcept; 31 | void addPackage (const std::string& name, lua::CFunction loader); 32 | 33 | void logError (const String&); 34 | 35 | private: 36 | friend Context; 37 | class Impl; 38 | std::unique_ptr impl; 39 | Context* world = nullptr; 40 | lua_State* L = nullptr; 41 | class State; 42 | std::unique_ptr state; 43 | 44 | ScriptingEngine (const ScriptingEngine&) = delete; 45 | void initialize (Context&); 46 | }; 47 | 48 | using Scripting = ScriptingEngine; 49 | 50 | } // namespace element 51 | -------------------------------------------------------------------------------- /src/scripting/bindings.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "sol/forward.hpp" 7 | 8 | namespace element { 9 | 10 | class Context; 11 | 12 | namespace Lua { 13 | extern void initializeState (sol::state_view&); 14 | extern void initializeState (sol::state_view&, Context&); 15 | extern void setGlobals (sol::state_view&, Context&); 16 | extern void clearGlobals (sol::state_view&); 17 | } // namespace Lua 18 | 19 | } // namespace element 20 | -------------------------------------------------------------------------------- /src/scripting/dspuiscript.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "scripting/dspuiscript.hpp" 5 | 6 | namespace element { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/scripting/dspuiscript.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "scripting/scriptinstance.hpp" 7 | 8 | namespace element { 9 | 10 | class DSPUIScript : public ScriptInstance 11 | { 12 | }; 13 | 14 | } // namespace element 15 | -------------------------------------------------------------------------------- /src/scripting/scriptinstance.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "sol/sol.hpp" 7 | 8 | namespace element { 9 | 10 | class ScriptInstance 11 | { 12 | public: 13 | ScriptInstance() = default; 14 | virtual ~ScriptInstance() = default; 15 | 16 | void cleanup() 17 | { 18 | if (! object.valid()) 19 | return; 20 | 21 | switch (object.get_type()) 22 | { 23 | case sol::type::table: { 24 | auto tbl = object.as(); 25 | if (sol::function f = tbl["cleanup"]) 26 | f (object); 27 | break; 28 | } 29 | default: 30 | break; 31 | } 32 | } 33 | 34 | private: 35 | sol::object object; 36 | }; 37 | 38 | } // namespace element 39 | -------------------------------------------------------------------------------- /src/scripting/scriptmanager.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | using ScriptArray = juce::Array; 11 | 12 | class ScriptManager final 13 | { 14 | public: 15 | ScriptManager(); 16 | ~ScriptManager(); 17 | 18 | void scanDefaultLocation(); 19 | void scanDirectory (const juce::File&); 20 | 21 | int getNumScripts() const; 22 | ScriptInfo getScript (int) const; 23 | 24 | const ScriptArray& getScriptsDSP() const; 25 | 26 | /** Returns the application's script directory. 27 | Scripts in the app data dir 28 | */ 29 | static juce::File getApplicationScriptsDir(); 30 | 31 | /** Returns the system scripts directory. 32 | The location where scripts were installed or packaged 33 | */ 34 | static juce::File getSystemScriptsDir(); 35 | 36 | /** Scripts in the users home dir. e.g. ~/.local/share */ 37 | static juce::File getHomeScriptsDir(); 38 | 39 | /** User scripts location. e.g. $HOME/Music/Element/Scripts */ 40 | static juce::File getUserScriptsDir(); 41 | 42 | private: 43 | class Registry; 44 | std::unique_ptr registry; 45 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScriptManager) 46 | }; 47 | 48 | } // namespace element 49 | -------------------------------------------------------------------------------- /src/services/deviceservice.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | class DeviceService : public Service 12 | { 13 | public: 14 | DeviceService(); 15 | ~DeviceService(); 16 | 17 | void activate() override; 18 | void deactivate() override; 19 | 20 | void add (const Controller&); 21 | void add (const Controller&, const Control&); 22 | void add (const File& file); 23 | void remove (const Controller&); 24 | void remove (const Controller&, const Control&); 25 | void refresh (const Controller&); 26 | void refresh(); 27 | 28 | private: 29 | class Impl; 30 | friend class Impl; 31 | std::unique_ptr impl; 32 | }; 33 | 34 | } // namespace element 35 | -------------------------------------------------------------------------------- /src/services/mappingservice.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | class Node; 12 | 13 | class MappingService : public Service 14 | { 15 | public: 16 | MappingService(); 17 | ~MappingService(); 18 | 19 | void activate() override; 20 | void deactivate() override; 21 | void learn (const bool shouldLearn = true); 22 | bool isLearning() const; 23 | void remove (const ControllerMap&); 24 | 25 | private: 26 | class Impl; 27 | friend class Impl; 28 | std::unique_ptr impl; 29 | SignalConnection capturedConnection; 30 | SignalConnection capturedParamConnection; 31 | void onControlCaptured(); 32 | void onParameterCaptured (const Node&, int); 33 | }; 34 | 35 | } // namespace element 36 | -------------------------------------------------------------------------------- /src/services/oscservice.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class OSCService : public Service 11 | { 12 | public: 13 | OSCService(); 14 | ~OSCService(); 15 | 16 | /** Sets the port and starts/stops the host accoding to Settings 17 | 18 | @param alertOnFail If true, show an alert if the host could not start 19 | */ 20 | void refreshWithSettings (bool alertOnFail = false); 21 | 22 | void activate() override; 23 | void deactivate() override; 24 | 25 | private: 26 | class Impl; 27 | std::unique_ptr impl; 28 | }; 29 | 30 | } // namespace element 31 | -------------------------------------------------------------------------------- /src/services/presetservice.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class Node; 11 | 12 | class PresetService : public Service 13 | { 14 | public: 15 | PresetService(); 16 | ~PresetService(); 17 | void activate() override; 18 | void deactivate() override; 19 | 20 | void refresh(); 21 | void add (const Node& Node, const juce::String& presetName = juce::String()); 22 | 23 | private: 24 | friend struct Impl; 25 | struct Impl; 26 | std::unique_ptr impl; 27 | }; 28 | 29 | } // namespace element 30 | -------------------------------------------------------------------------------- /src/strings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | 6 | namespace element { 7 | static void escape_regex (std::string& input) 8 | { 9 | boost::replace_all (input, "\\", "\\\\"); 10 | boost::replace_all (input, "^", "\\^"); 11 | boost::replace_all (input, ".", "\\."); 12 | boost::replace_all (input, "$", "\\$"); 13 | boost::replace_all (input, "|", "\\|"); 14 | boost::replace_all (input, "(", "\\("); 15 | boost::replace_all (input, ")", "\\)"); 16 | boost::replace_all (input, "{", "\\{"); 17 | boost::replace_all (input, "{", "\\}"); 18 | boost::replace_all (input, "[", "\\["); 19 | boost::replace_all (input, "]", "\\]"); 20 | boost::replace_all (input, "*", "\\*"); 21 | boost::replace_all (input, "+", "\\+"); 22 | boost::replace_all (input, "?", "\\?"); 23 | boost::replace_all (input, "/", "\\/"); 24 | } 25 | 26 | static void transform_wildcard (std::string& input) 27 | { 28 | boost::replace_all (input, "\\?", "."); 29 | boost::replace_all (input, "\\*", ".*"); 30 | } 31 | 32 | std::string wildcard_to_regex (const std::string& wildcard) 33 | { 34 | auto input = wildcard; 35 | escape_regex (input); 36 | transform_wildcard (input); 37 | return input; 38 | } 39 | 40 | } // namespace element -------------------------------------------------------------------------------- /src/ui/capslock.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #if defined(__MINGW32__) || defined(_MSC_VER) 5 | #include 6 | #elif defined(__APPLE__) 7 | #include 8 | #else 9 | #warning "Caps lock detection not yet implemented on Linux" 10 | #endif 11 | 12 | #include "ui/capslock.hpp" 13 | 14 | namespace element { 15 | 16 | bool isCapsLockOn() 17 | { 18 | bool result = false; 19 | #if defined(__MINGW32__) || defined(_MSC_VER) 20 | result = (GetKeyState (VK_CAPITAL) & 0x0001) != 0; 21 | #elif defined(__APPLE__) 22 | CGEventFlags flags = CGEventSourceFlagsState (kCGEventSourceStateHIDSystemState); 23 | result = (kCGEventFlagMaskAlphaShift & flags) != 0; 24 | #else 25 | // linux 26 | #endif 27 | return result; 28 | } 29 | 30 | } // namespace element 31 | -------------------------------------------------------------------------------- /src/ui/capslock.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | namespace element { 7 | 8 | /** Returns true if caps lock is currently down */ 9 | bool isCapsLockOn(); 10 | 11 | } // namespace element 12 | -------------------------------------------------------------------------------- /src/ui/contextmenus.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "ui/guicommon.hpp" 5 | #include "ui/contextmenus.hpp" 6 | -------------------------------------------------------------------------------- /src/ui/controllermapsview.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "ui/controllermapsview.hpp" 5 | 6 | namespace element { 7 | 8 | ControllerMapsView::ControllerMapsView() {} 9 | ControllerMapsView::~ControllerMapsView() {} 10 | 11 | } // namespace element 12 | -------------------------------------------------------------------------------- /src/ui/controllermapsview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class ControllerMapsView : public ContentView 11 | { 12 | public: 13 | ControllerMapsView(); 14 | virtual ~ControllerMapsView(); 15 | }; 16 | 17 | } // namespace element -------------------------------------------------------------------------------- /src/ui/controllersview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #define EL_VIEW_CONTROLLERS "ControllersView" 9 | 10 | namespace element { 11 | 12 | class ControllersView : public ContentView 13 | { 14 | public: 15 | ControllersView(); 16 | virtual ~ControllersView(); 17 | 18 | void resized() override; 19 | void stabilizeContent() override; 20 | void initializeView (Services&) override; 21 | 22 | private: 23 | class Content; 24 | std::unique_ptr content; 25 | }; 26 | 27 | } // namespace element 28 | -------------------------------------------------------------------------------- /src/ui/designer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace element { 11 | class Designer::Content : public StandardContent 12 | { 13 | public: 14 | Content (Designer& d, Context& c) 15 | : StandardContent (c), 16 | context (c), 17 | designer (d) 18 | { 19 | } 20 | 21 | private: 22 | friend class Designer; 23 | [[maybe_unused]] Context& context; 24 | [[maybe_unused]] Designer& designer; 25 | }; 26 | 27 | Designer::Designer (Context& c) 28 | { 29 | content = std::make_unique (*this, c); 30 | addAndMakeVisible (content.get()); 31 | setSize (640, 360); 32 | } 33 | 34 | Designer::~Designer() {} 35 | 36 | void Designer::resized() 37 | { 38 | content->setBounds (getLocalBounds()); 39 | } 40 | 41 | void Designer::paint (juce::Graphics&) 42 | { 43 | } 44 | 45 | void Designer::refresh() 46 | { 47 | content->stabilize(); 48 | content->stabilizeViews(); 49 | } 50 | 51 | } // namespace element 52 | -------------------------------------------------------------------------------- /src/ui/emptyview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | class EmptyContentView : public ContentView 12 | { 13 | public: 14 | EmptyContentView() 15 | { 16 | setName ("EmptyView"); 17 | } 18 | 19 | inline void paint (Graphics& g) override 20 | { 21 | g.fillAll (Colors::contentBackgroundColor); 22 | g.setColour (Colors::textColor); 23 | g.setFont (16.f); 24 | 25 | #if JUCE_MAC 26 | const String msg ("Session is empty.\nPress Shift+Cmd+N to add a graph."); 27 | #else 28 | const String msg ("Session is empty.\nPress Shift+Ctl+N to add a graph."); 29 | #endif 30 | g.drawFittedText (msg, 0, 0, getWidth(), getHeight(), Justification::centred, 2); 31 | } 32 | }; 33 | 34 | } // namespace element 35 | -------------------------------------------------------------------------------- /src/ui/graphmixerview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #define EL_VIEW_GRAPH_MIXER "GraphMixerView" 9 | 10 | namespace element { 11 | 12 | class GraphMixerView : public ContentView 13 | { 14 | public: 15 | GraphMixerView(); 16 | ~GraphMixerView(); 17 | 18 | void resized() override; 19 | void stabilizeContent() override; 20 | void initializeView (Services&) override; 21 | 22 | private: 23 | class Content; 24 | friend class Content; 25 | std::unique_ptr content; 26 | }; 27 | 28 | } // namespace element 29 | -------------------------------------------------------------------------------- /src/ui/graphsettingsview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "ui/buttons.hpp" 9 | 10 | namespace element { 11 | 12 | class GraphPropertyPanel; 13 | class GraphSettingsView : public ContentView, 14 | public Button::Listener, 15 | private Value::Listener 16 | { 17 | public: 18 | GraphSettingsView(); 19 | ~GraphSettingsView(); 20 | 21 | void setPropertyPanelHeaderVisible (bool); 22 | void setGraphButtonVisible (bool isVisible); 23 | void setUpdateOnActiveGraphChange (bool shouldUpdate); 24 | 25 | void resized() override; 26 | void didBecomeActive() override; 27 | void stabilizeContent() override; 28 | void buttonClicked (Button*) override; 29 | 30 | private: 31 | std::unique_ptr props; 32 | GraphButton graphButton; 33 | Value activeGraphIndex; 34 | bool updateWhenActiveGraphChanges = false; 35 | boost::signals2::connection connNodeTouched, connNodeRemoved; 36 | void valueChanged (Value& value) override; 37 | }; 38 | 39 | } // namespace element 40 | -------------------------------------------------------------------------------- /src/ui/guicommon.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "ElementApp.h" 17 | #include "ui/buttons.hpp" 18 | #include "ui/viewhelpers.hpp" 19 | #include "messages.hpp" 20 | -------------------------------------------------------------------------------- /src/ui/keymapeditorview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "ElementApp.h" 7 | #include 8 | 9 | #define EL_VIEW_KEYMAP_EDITOR "KeymapEditorView" 10 | 11 | namespace element { 12 | class KeymapEditorView : public ContentView, public Button::Listener 13 | { 14 | public: 15 | KeymapEditorView(); 16 | virtual ~KeymapEditorView() {} 17 | 18 | void resized() override; 19 | 20 | inline void willBecomeActive() override {} 21 | inline void didBecomeActive() override { stabilizeContent(); } 22 | void stabilizeContent() override; 23 | 24 | void buttonClicked (Button*) override; 25 | 26 | private: 27 | std::unique_ptr editor; 28 | TextButton closeButton; 29 | 30 | void saveMappings(); 31 | }; 32 | } // namespace element 33 | -------------------------------------------------------------------------------- /src/ui/luaconsole.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "ui/console.hpp" 9 | #include "scripting.hpp" 10 | 11 | namespace element { 12 | 13 | class LuaConsole : public Console, 14 | private juce::Timer 15 | { 16 | public: 17 | LuaConsole(); 18 | virtual ~LuaConsole(); 19 | 20 | void textEntered (const String&) override; 21 | void setEnvironment (const sol::environment& e); 22 | 23 | private: 24 | using LuaResult = sol::protected_function_result; 25 | sol::environment env; 26 | String lastError; 27 | StringArray printMessages; 28 | LuaResult errorHandler (lua_State* L, LuaResult pfr); 29 | 30 | friend class juce::Timer; 31 | void timerCallback() override; 32 | }; 33 | 34 | } // namespace element 35 | -------------------------------------------------------------------------------- /src/ui/luaconsoleview.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | #include 6 | 7 | #include "scripting.hpp" 8 | #include "ui/luaconsoleview.hpp" 9 | 10 | namespace element { 11 | 12 | LuaConsoleView::~LuaConsoleView() 13 | { 14 | if (log != nullptr) 15 | { 16 | log->removeListener (this); 17 | log = nullptr; 18 | } 19 | } 20 | 21 | void LuaConsoleView::initializeView (Services& app) 22 | { 23 | auto& se = app.context().scripting(); 24 | sol::state_view view (se.getLuaState()); 25 | console.setEnvironment ( 26 | sol::environment (view, sol::create, view.globals())); 27 | 28 | log = &app.context().logger(); 29 | log->addListener (this); 30 | 31 | String buffer; 32 | for (const auto& line : log->getHistory()) 33 | buffer << line << juce::newLine; 34 | console.addText (buffer.trimEnd(), false); 35 | } 36 | 37 | } // namespace element 38 | -------------------------------------------------------------------------------- /src/ui/luaconsoleview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include "ui/luaconsole.hpp" 8 | #include "log.hpp" 9 | 10 | #define EL_VIEW_CONSOLE "LuaConsoleViw" 11 | 12 | namespace element { 13 | 14 | class Services; 15 | 16 | class LuaConsoleView : public ContentView, 17 | public Log::Listener 18 | { 19 | public: 20 | LuaConsoleView() 21 | { 22 | setName (EL_VIEW_CONSOLE); 23 | addAndMakeVisible (console); 24 | } 25 | 26 | ~LuaConsoleView(); 27 | 28 | void initializeView (Services&) override; 29 | void didBecomeActive() override 30 | { 31 | console.grabKeyboardFocus(); 32 | } 33 | 34 | void resized() override 35 | { 36 | console.setBounds (getLocalBounds().reduced (2)); 37 | } 38 | 39 | void messageLogged (const String& msg) override 40 | { 41 | console.addText (msg, false); 42 | } 43 | 44 | private: 45 | LuaConsole console; 46 | Log* log = nullptr; 47 | }; 48 | 49 | } // namespace element 50 | -------------------------------------------------------------------------------- /src/ui/midiblinker.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | using namespace juce; // FIXME; 8 | 9 | namespace element { 10 | 11 | class MidiBlinker : public Component, 12 | public SettableTooltipClient, 13 | private Timer 14 | { 15 | public: 16 | enum ColourIds 17 | { 18 | backgroundColourId = 0x90001000, 19 | outlineColourId 20 | }; 21 | 22 | MidiBlinker(); 23 | virtual ~MidiBlinker(); 24 | 25 | void triggerReceived(); 26 | void triggerSent(); 27 | 28 | void setInputOutputVisibility (bool in, bool out); 29 | 30 | void paint (Graphics&) override; 31 | void resized() override; 32 | 33 | private: 34 | int holdMillis = 100; 35 | bool haveInput = false; 36 | bool haveOutput = false; 37 | bool showInput = true; 38 | bool showOutput = true; 39 | friend class Timer; 40 | void timerCallback() override; 41 | }; 42 | 43 | } // namespace element 44 | -------------------------------------------------------------------------------- /src/ui/navigationview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "ElementApp.h" 7 | #include "ui/treeviewbase.hpp" 8 | 9 | namespace element { 10 | 11 | class NavigationList; 12 | class NavigationTree; 13 | class PluginManager; 14 | 15 | class NavigationView : public Component 16 | { 17 | public: 18 | NavigationView(); 19 | ~NavigationView(); 20 | 21 | void paint (Graphics&); 22 | void resized(); 23 | 24 | private: 25 | std::unique_ptr navList; 26 | std::unique_ptr navTree; 27 | std::unique_ptr navBar; 28 | StretchableLayoutManager layout; 29 | 30 | friend class NavigationList; 31 | friend class NavigationTree; 32 | void updateLayout(); 33 | void setRootItem (int item); 34 | 35 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NavigationView) 36 | }; 37 | 38 | class PluginTreeView : public TreePanelBase 39 | { 40 | public: 41 | PluginTreeView (PluginManager&); 42 | ~PluginTreeView(); 43 | 44 | void rootItemChanged (int item); 45 | 46 | private: 47 | int rootItem; 48 | PluginManager& plugins; 49 | }; 50 | 51 | } // namespace element 52 | -------------------------------------------------------------------------------- /src/ui/nodechannelstripview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class NodeChannelStripView : public ContentView 11 | { 12 | public: 13 | NodeChannelStripView(); 14 | ~NodeChannelStripView(); 15 | 16 | void resized() override; 17 | void stabilizeContent() override; 18 | void initializeView (Services&) override; 19 | 20 | private: 21 | class Content; 22 | friend class Content; 23 | std::unique_ptr content; 24 | }; 25 | 26 | } // namespace element 27 | -------------------------------------------------------------------------------- /src/ui/nodeeditor.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | #include "ui/pluginwindow.hpp" 6 | 7 | namespace element { 8 | 9 | Editor::Editor() {} 10 | Editor::~Editor() {} 11 | 12 | void Editor::setResizable (bool canResize) 13 | { 14 | _resizable = canResize; 15 | } 16 | 17 | NodeEditor::NodeEditor (const Node& _node) noexcept 18 | : node (_node) {} 19 | NodeEditor::~NodeEditor() {} 20 | 21 | bool NodeEditor::isRunningInPluginWindow() const 22 | { 23 | return nullptr != findParentComponentOfClass(); 24 | } 25 | 26 | } // namespace element 27 | -------------------------------------------------------------------------------- /src/ui/nodemidiprogramcomponent.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "ui/buttons.hpp" 7 | 8 | namespace element { 9 | 10 | struct NodeMidiProgramComponent : public Component 11 | { 12 | Label name; 13 | Slider slider; 14 | IconButton loadButton; 15 | IconButton saveButton; 16 | IconButton globalButton; 17 | IconButton powerButton; 18 | IconButton trashButton; 19 | 20 | NodeMidiProgramComponent(); 21 | void resized() override; 22 | }; 23 | 24 | } // namespace element 25 | -------------------------------------------------------------------------------- /src/ui/nodeportstable.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | //============================================================================== 12 | class NodePortsTable : public juce::Component 13 | { 14 | public: 15 | NodePortsTable(); 16 | ~NodePortsTable() override; 17 | 18 | void setNode (const Node& node); 19 | void refresh (int row = -1); 20 | 21 | void paint (juce::Graphics& g) override; 22 | void resized() override; 23 | 24 | private: 25 | class TableModel; 26 | std::unique_ptr model; 27 | juce::TableListBox table; 28 | juce::TextButton showAllButton, hideAllButton, 29 | saveAsDefaultButton; 30 | }; 31 | 32 | } // namespace element 33 | -------------------------------------------------------------------------------- /src/ui/nodeproperties.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | #include "ElementApp.h" 6 | namespace element { 7 | 8 | class Node; 9 | 10 | struct NodeProperties : public Array 11 | { 12 | enum Groups 13 | { 14 | General = 1 << 0, 15 | Midi = 1 << 1, 16 | ALL = General | Midi 17 | }; 18 | 19 | NodeProperties (const Node& n, int groups); 20 | NodeProperties (const Node& n, bool nodeProps = true, bool midiProps = false); 21 | }; 22 | 23 | } // namespace element 24 | -------------------------------------------------------------------------------- /src/ui/nodepropertypanel.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | 6 | #include "ui/nodepropertypanel.hpp" 7 | #include "ui/nodeproperties.hpp" 8 | 9 | namespace element { 10 | 11 | void NodePropertyPanel::initialize() 12 | { 13 | setName ("NodePropertyPanel"); 14 | setMessageWhenEmpty ("Empty node"); 15 | } 16 | 17 | void NodePropertyPanel::addProperties (const Node& node, int extraSpace) 18 | { 19 | sync.reset (nullptr); 20 | 21 | clear(); 22 | 23 | if (node.isValid()) 24 | { 25 | NodeProperties props (node, NodeProperties::General); 26 | PropertyPanel::addProperties (props, extraSpace); 27 | sync.reset (new NodeObjectSync (node)); 28 | } 29 | else 30 | { 31 | setMessageWhenEmpty ("Invalid node"); 32 | } 33 | 34 | refreshAll(); 35 | } 36 | 37 | } // namespace element 38 | -------------------------------------------------------------------------------- /src/ui/nodepropertypanel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class Node; 11 | class NodeObjectSync; 12 | 13 | /** A PropertyPanel which display node properties */ 14 | class NodePropertyPanel : public juce::PropertyPanel 15 | { 16 | public: 17 | NodePropertyPanel() 18 | : PropertyPanel() 19 | { 20 | initialize(); 21 | } 22 | 23 | NodePropertyPanel (const Node& node) 24 | : PropertyPanel() 25 | { 26 | initialize(); 27 | addProperties (node); 28 | } 29 | 30 | ~NodePropertyPanel() override = default; 31 | 32 | //========================================================================== 33 | /** Add properties from the given node. This will clear the panel before 34 | adding 35 | 36 | @param node The node to get properties from 37 | @param extraSpace Extra space between properties (forwarded to juce::PropertyPanel) 38 | */ 39 | void addProperties (const Node& node, int extraSpace = 0); 40 | 41 | private: 42 | std::unique_ptr sync; 43 | void initialize(); 44 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NodePropertyPanel) 45 | }; 46 | 47 | } // namespace element 48 | -------------------------------------------------------------------------------- /src/ui/pluginspanelview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #ifndef EL_PLUGINS_PANEL_VIEW_H 5 | #define EL_PLUGINS_PANEL_VIEW_H 6 | 7 | #include 8 | 9 | namespace element { 10 | 11 | class PluginManager; 12 | 13 | class PluginsPanelView : public ContentView, 14 | public ChangeListener, 15 | public TextEditor::Listener, 16 | public Timer 17 | { 18 | public: 19 | PluginsPanelView (PluginManager& pm); 20 | ~PluginsPanelView(); 21 | 22 | void resized() override; 23 | void paint (Graphics&) override; 24 | 25 | /** Returns the text in the search box */ 26 | String getSearchText() { return search.getText(); } 27 | 28 | /** @internal */ 29 | void textEditorTextChanged (TextEditor&) override; 30 | void textEditorReturnKeyPressed (TextEditor&) override; 31 | void changeListenerCallback (ChangeBroadcaster*) override; 32 | void timerCallback() override; 33 | 34 | private: 35 | PluginManager& plugins; 36 | TreeView tree; 37 | TextEditor search; 38 | 39 | void updateTreeView(); 40 | 41 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginsPanelView); 42 | }; 43 | 44 | } // namespace element 45 | 46 | #endif // EL_PLUGINS_PANEL_VIEW_H 47 | -------------------------------------------------------------------------------- /src/ui/rackview.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | 6 | #include "ui/rackview.hpp" 7 | 8 | namespace element { 9 | 10 | class RackView::Impl 11 | { 12 | public: 13 | Impl() {} 14 | ~Impl() {} 15 | }; 16 | 17 | RackView::RackView() 18 | { 19 | impl = std::make_unique(); 20 | } 21 | 22 | RackView::~RackView() 23 | { 24 | impl = nullptr; 25 | } 26 | 27 | void RackView::paint (Graphics& g) 28 | { 29 | g.fillAll (Colors::backgroundColor); 30 | 31 | g.setColour (Colors::elemental); 32 | g.setFont (14.0f); 33 | g.drawText ("No Selection...", getLocalBounds(), Justification::centred, true); 34 | } 35 | 36 | void RackView::resized() 37 | { 38 | if (! main) 39 | return; 40 | 41 | main->setBounds (getLocalBounds().reduced (2)); 42 | } 43 | 44 | void RackView::setMainComponent (Component* comp) 45 | { 46 | if (comp != nullptr && comp == main.get()) 47 | { 48 | main = nullptr; 49 | } 50 | else 51 | { 52 | main.reset (comp); 53 | if (main) 54 | addAndMakeVisible (comp); 55 | } 56 | 57 | resized(); 58 | } 59 | 60 | } // namespace element 61 | -------------------------------------------------------------------------------- /src/ui/rackview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #ifndef RACKVIEW_H_INCLUDED 5 | #define RACKVIEW_H_INCLUDED 6 | 7 | #include "ElementApp.h" 8 | 9 | namespace element { 10 | 11 | class RackView : public Component 12 | { 13 | public: 14 | RackView(); 15 | ~RackView(); 16 | 17 | void paint (Graphics&); 18 | void resized(); 19 | 20 | void setMainComponent (Component* comp); 21 | 22 | private: 23 | class Impl; 24 | friend class Impl; 25 | std::unique_ptr impl; 26 | std::unique_ptr main; 27 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RackView) 28 | }; 29 | 30 | } // namespace element 31 | 32 | #endif // RACKVIEW_H_INCLUDED 33 | -------------------------------------------------------------------------------- /src/ui/res.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "acknowledgements.txt.h" 7 | #include "developers.txt.h" 8 | #include "icon.png.h" 9 | #include "icon-template.png.h" 10 | #include "Roboto-Regular.ttf.h" 11 | -------------------------------------------------------------------------------- /src/ui/scriptview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | 11 | class Context; 12 | class Graph; 13 | class Node; 14 | 15 | class ScriptView : public View 16 | { 17 | public: 18 | ScriptView() = delete; 19 | ScriptView (Context&, const Script& s); 20 | virtual ~ScriptView(); 21 | 22 | void stabilize(); 23 | void resized() override; 24 | 25 | /** Set the node to make available in the loaded script. */ 26 | void setNode (const Node& node); 27 | 28 | /** Set the node used by this script. 29 | Can be invalid. 30 | */ 31 | const Node& node() const noexcept; 32 | 33 | /** Returns the graph used by this script. */ 34 | const Graph& graph() const noexcept; 35 | 36 | private: 37 | class Impl; 38 | friend class Impl; 39 | std::unique_ptr impl; 40 | }; 41 | 42 | } // namespace element 43 | -------------------------------------------------------------------------------- /src/ui/sessiondocument.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "ElementApp.h" 7 | #include 8 | 9 | namespace element { 10 | class SessionDocument : public FileBasedDocument, 11 | public ChangeListener 12 | { 13 | public: 14 | SessionDocument (SessionPtr); 15 | ~SessionDocument(); 16 | 17 | String getDocumentTitle() override; 18 | Result loadDocument (const File& file) override; 19 | Result saveDocument (const File& file) override; 20 | File getLastDocumentOpened() override; 21 | void setLastDocumentOpened (const File& file) override; 22 | File getSuggestedSaveAsFile (const File&) override 23 | { 24 | return getFile().getNonexistentSibling (true); 25 | } 26 | 27 | void changeListenerCallback (ChangeBroadcaster*) override; 28 | 29 | private: 30 | SessionPtr session; 31 | File lastSession; 32 | friend class Session; 33 | void onSessionChanged(); 34 | }; 35 | } // namespace element 36 | -------------------------------------------------------------------------------- /src/ui/sessionimportwizard.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class Services; 11 | 12 | class SessionImportWizard final : public Component 13 | { 14 | public: 15 | SessionImportWizard(); 16 | ~SessionImportWizard(); 17 | 18 | void loadSession (const File& file); 19 | SessionPtr session(); 20 | 21 | void paint (Graphics& g) override; 22 | void resized() override; 23 | 24 | private: 25 | class Content; 26 | std::unique_ptr content; 27 | SessionPtr _session; 28 | }; 29 | 30 | class SessionImportWizardDialog : public DialogWindow 31 | { 32 | public: 33 | SessionImportWizardDialog (std::unique_ptr& h, const File& file); 34 | ~SessionImportWizardDialog(); 35 | 36 | bool escapeKeyPressed() override; 37 | void closeButtonPressed() override; 38 | 39 | std::function onGraphChosen; 40 | 41 | private: 42 | std::unique_ptr& holder; 43 | }; 44 | 45 | } // namespace element 46 | -------------------------------------------------------------------------------- /src/ui/sessionsettingsview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "ui/buttons.hpp" 7 | #include 8 | 9 | #define EL_VIEW_SESSION_SETTINGS "SessionSettingsView" 10 | 11 | namespace element { 12 | class SessionPropertyPanel; 13 | class SessionContentView : public ContentView 14 | { 15 | public: 16 | SessionContentView(); 17 | ~SessionContentView(); 18 | 19 | void resized() override; 20 | void didBecomeActive() override; 21 | void paint (Graphics& g) override; 22 | 23 | private: 24 | std::unique_ptr props; 25 | }; 26 | 27 | typedef SessionContentView SessionSettingsView; 28 | } // namespace element 29 | -------------------------------------------------------------------------------- /src/ui/sessiontreeview.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "ui/sessiontreeview.hpp" 5 | #include "ui/sessiontreepanel.hpp" 6 | #include "ui/viewhelpers.hpp" 7 | #include "common.hpp" 8 | 9 | namespace element { 10 | 11 | SessionTreeContentView::SessionTreeContentView() 12 | { 13 | tree.reset (new SessionTreePanel()); 14 | addAndMakeVisible (tree.get()); 15 | } 16 | 17 | SessionTreeContentView::~SessionTreeContentView() 18 | { 19 | tree.reset(); 20 | } 21 | 22 | void SessionTreeContentView::didBecomeActive() 23 | { 24 | } 25 | 26 | void SessionTreeContentView::stabilizeContent() 27 | { 28 | if (auto session = ViewHelpers::getSession (this)) 29 | tree->setSession (session); 30 | resized(); 31 | repaint(); 32 | } 33 | 34 | void SessionTreeContentView::resized() 35 | { 36 | tree->setBounds (getLocalBounds()); 37 | } 38 | 39 | } // namespace element 40 | -------------------------------------------------------------------------------- /src/ui/sessiontreeview.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace element { 9 | 10 | class SessionTreePanel; 11 | 12 | class SessionTreeContentView : public ContentView 13 | { 14 | public: 15 | SessionTreeContentView(); 16 | ~SessionTreeContentView(); 17 | 18 | void didBecomeActive() override; 19 | void stabilizeContent() override; 20 | void resized() override; 21 | 22 | private: 23 | std::unique_ptr tree; 24 | }; 25 | 26 | } // namespace element 27 | -------------------------------------------------------------------------------- /src/ui/systemtray.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "ElementApp.h" 5 | 6 | namespace element { 7 | 8 | class SystemTray : public SystemTrayIconComponent, 9 | public DeletedAtShutdown 10 | { 11 | public: 12 | ~SystemTray() = default; 13 | static SystemTray* getInstance() { return instance; } 14 | static void setEnabled (bool enabled); 15 | 16 | void mouseDown (const MouseEvent&) override; 17 | void mouseUp (const MouseEvent&) override; 18 | 19 | private: 20 | SystemTray(); 21 | static SystemTray* instance; 22 | static bool initialized; 23 | int mouseUpAction = -1; 24 | void runMenu(); 25 | 26 | friend class GuiService; 27 | static void init (GuiService&); 28 | }; 29 | 30 | } // namespace element 31 | -------------------------------------------------------------------------------- /src/ui/transportbar.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | #include "ElementApp.h" 7 | #include "ui/buttons.hpp" 8 | #include 9 | #include 10 | 11 | namespace element { 12 | 13 | class BarLabel; 14 | class TransportBar : public Component, 15 | private Button::Listener, 16 | private Timer 17 | { 18 | public: 19 | TransportBar(); 20 | ~TransportBar(); 21 | 22 | void setBeatTime (const float t); 23 | void updateWidth(); 24 | void stabilize(); 25 | 26 | void paint (Graphics& g) override; 27 | void resized() override; 28 | 29 | private: 30 | SessionPtr session; 31 | AudioEnginePtr engine; 32 | Transport::MonitorPtr monitor; 33 | 34 | std::unique_ptr play, stop, record, toZero; 35 | std::unique_ptr barLabel, beatLabel, subLabel; 36 | 37 | friend class BarLabel; 38 | friend class Timer; 39 | 40 | void buttonClicked (Button* buttonThatWasClicked) override; 41 | void timerCallback() override; 42 | 43 | bool checkForMonitor(); 44 | 45 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TransportBar) 46 | }; 47 | 48 | } // namespace element 49 | -------------------------------------------------------------------------------- /src/ui/window.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "ui/window.hpp" 5 | #include 6 | 7 | namespace element { 8 | 9 | Dialog::Dialog (const String& name) 10 | : DialogWindow (name, Colours::darkgrey, true, true) 11 | { 12 | #if JUCE_IOS 13 | setUsingNativeTitleBar (false); 14 | #else 15 | setUsingNativeTitleBar (true); 16 | #endif 17 | setResizable (true, false); 18 | } 19 | 20 | Dialog::~Dialog() {} 21 | 22 | void Dialog::closeButtonPressed() 23 | { 24 | closedSignal(); 25 | } 26 | 27 | Window::Window (const String& name) 28 | : DocumentWindow (name, Colors::widgetBackgroundColor, DocumentWindow::closeButton | DocumentWindow::minimiseButton, true) 29 | { 30 | #if JUCE_IOS 31 | setUsingNativeTitleBar (false); 32 | #else 33 | setUsingNativeTitleBar (true); 34 | #endif 35 | setResizable (true, false); 36 | } 37 | 38 | Window::~Window() {} 39 | 40 | void Window::closeButtonPressed() 41 | { 42 | closedSignal(); 43 | } 44 | 45 | } /* namespace element */ 46 | -------------------------------------------------------------------------------- /src/urls.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #pragma once 5 | 6 | // clang-format off 7 | //============================================================================== 8 | #define EL_URL_HOME "https://kushview.net" 9 | #define EL_URL_DONATE EL_URL_HOME "/donate/" 10 | 11 | //============================================================================== 12 | #define EL_URL_BUG_TRACKER "https://github.com/kushview/element/issues/new/choose" 13 | #define EL_URL_DISCUSSIONS "https://github.com/orgs/kushview/discussions" 14 | #define EL_URL_CHANGELOG "https://github.com/kushview/element/blob/main/CHANGELOG.md" 15 | 16 | //============================================================================== 17 | #define EL_URL_API_HOME "https://kushview.net/api" 18 | #define EL_URL_MANUAL_HOME "https://element.readthedocs.io" 19 | 20 | #ifndef EL_URL_API_LUA_EL 21 | #define EL_URL_API_LUA_EL EL_URL_API_HOME "/el/latest/index.html" 22 | #endif 23 | // clang-format on 24 | -------------------------------------------------------------------------------- /src/utils.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include "utils.hpp" 5 | 6 | #if JUCE_WINDOWS 7 | #include 8 | #endif 9 | 10 | namespace element { 11 | namespace Util { 12 | 13 | StringArray compiledAudioPluginFormats() 14 | { 15 | StringArray fmts; 16 | 17 | #if JUCE_MAC && JUCE_PLUGINHOST_AU 18 | fmts.add ("AudioUnit"); 19 | #endif 20 | #if JUCE_PLUGINHOST_VST 21 | fmts.add ("VST"); 22 | #endif 23 | #if JUCE_PLUGINHOST_VST3 24 | fmts.add ("VST3"); 25 | #endif 26 | #if JUCE_PLUGINHOST_LADSPA 27 | fmts.add ("LADSPA"); 28 | #endif 29 | 30 | fmts.add ("LV2"); 31 | fmts.add ("CLAP"); 32 | fmts.sort (false); 33 | return fmts; 34 | } 35 | 36 | bool isRunningInWine() 37 | { 38 | #if JUCE_WINDOWS 39 | HMODULE ntdll = GetModuleHandleA ("ntdll"); 40 | return ntdll != nullptr && GetProcAddress (ntdll, "wine_get_version") != nullptr; 41 | #else 42 | return false; 43 | #endif 44 | } 45 | 46 | } // namespace Util 47 | } // namespace element 48 | -------------------------------------------------------------------------------- /subprojects/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !juce.wrap 3 | !lvtk.wrap 4 | !lvtk-host.wrap 5 | !.ignore 6 | !.gitignore 7 | !evg.wrap 8 | !lv2.wrap 9 | !suil.wrap 10 | !lilv.wrap 11 | !pugl.wrap 12 | !serd.wrap 13 | !sord.wrap 14 | !sratom.wrap 15 | !zix.wrap 16 | 17 | # !clap 18 | # !clap-* 19 | !clap*.wrap 20 | -------------------------------------------------------------------------------- /subprojects/.ignore: -------------------------------------------------------------------------------- 1 | !* 2 | -------------------------------------------------------------------------------- /subprojects/clap-helpers.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/free-audio/clap-helpers.git 3 | revision = next 4 | depth = 1 5 | 6 | [provide] 7 | clap-helpers = clap_helpers_dep 8 | -------------------------------------------------------------------------------- /subprojects/clap.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/free-audio/clap.git 3 | revision = 1.2.5 4 | depth = 1 5 | method = cmake 6 | 7 | [provide] 8 | clap = clap_dep 9 | -------------------------------------------------------------------------------- /subprojects/juce.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://gitlab.com/kushview/juce.git 3 | push-url = git@gitlab.com:kushview/juce.git 4 | revision = element 5 | 6 | [provide] 7 | juce-7=juce_dep 8 | juce=juce_dep 9 | -------------------------------------------------------------------------------- /subprojects/lilv.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://gitlab.com/lv2/lilv.git 3 | revision = main 4 | 5 | [provide] 6 | dependency_names = lilv-0 7 | -------------------------------------------------------------------------------- /subprojects/lv2.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://gitlab.com/lv2/lv2.git 3 | revision = v1.18.10 4 | 5 | [provide] 6 | dependency_names = lv2 7 | lv2 = lv2_dep 8 | -------------------------------------------------------------------------------- /subprojects/lvtk-host.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/lvtk/lvtk-host.git 3 | push-url = git@github.com:lvtk/lvtk-host.git 4 | revision = main 5 | 6 | [provide] 7 | lvtk-host-3.0=lvtk_host_dep 8 | lvtk-host-3=lvtk_host_dep 9 | lvtk-host=lvtk_host_dep 10 | -------------------------------------------------------------------------------- /subprojects/lvtk.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/lvtk/lvtk.git 3 | push-url = git@github.com:lvtk/lvtk.git 4 | revision = main 5 | 6 | [provide] 7 | lvtk-3.0=lvtk_dep 8 | lvtk-3=lvtk_dep 9 | lvtk=lvtk_dep 10 | -------------------------------------------------------------------------------- /subprojects/pugl.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/lvtk/pugl.git 3 | push-url = git@github.com:lvtk/pugl.git 4 | revision = lvtk 5 | 6 | [provide] 7 | dependency_names = pugl-0,pugl-gl-0,puglpp-0,pugl-cairo-0 8 | -------------------------------------------------------------------------------- /subprojects/serd.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://gitlab.com/drobilla/serd.git 3 | revision = main 4 | 5 | [provide] 6 | dependency_names = serd-0 7 | -------------------------------------------------------------------------------- /subprojects/sord.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://gitlab.com/drobilla/sord.git 3 | revision = main 4 | 5 | [provide] 6 | dependency_names = sord-0 7 | -------------------------------------------------------------------------------- /subprojects/sratom.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/lv2/sratom.git 3 | revision = main 4 | 5 | [provide] 6 | dependency_names = sratom-0 7 | -------------------------------------------------------------------------------- /subprojects/suil.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://gitlab.com/lv2/suil.git 3 | revision = main 4 | 5 | [provide] 6 | dependency_names = suil-0 7 | -------------------------------------------------------------------------------- /subprojects/zix.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://gitlab.com/drobilla/zix.git 3 | revision = main 4 | 5 | [provide] 6 | dependency_names = zix-0 7 | -------------------------------------------------------------------------------- /test/IONodeTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "engine/ionode.hpp" 3 | 4 | using namespace element; 5 | 6 | BOOST_AUTO_TEST_SUITE (IONodeTests) 7 | 8 | BOOST_AUTO_TEST_CASE (Basics) 9 | { 10 | } 11 | 12 | BOOST_AUTO_TEST_SUITE_END() 13 | -------------------------------------------------------------------------------- /test/OversamplerTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace element; 5 | 6 | BOOST_AUTO_TEST_SUITE (OversamplerTests) 7 | 8 | BOOST_AUTO_TEST_CASE (Basics) 9 | { 10 | Oversampler os; 11 | BOOST_REQUIRE (os.getNumProcessors() == 0); 12 | BOOST_REQUIRE (os.getProcessor (0) == nullptr); 13 | BOOST_REQUIRE (os.getLatencySamples (0) == 0); 14 | BOOST_REQUIRE (os.getFactor (0) == 1); 15 | os.prepare (2, 1024); 16 | BOOST_REQUIRE (os.getNumProcessors() == 3); 17 | BOOST_REQUIRE_EQUAL (os.getFactor (0), 2); 18 | for (int i = 0; i < os.getNumProcessors(); ++i) { 19 | BOOST_REQUIRE (nullptr != os.getProcessor (i)); 20 | if (auto* const proc = os.getProcessor (i)) { 21 | size_t factora = static_cast (std::pow (2.0, (double) (i + 1))); 22 | size_t factorb = proc->getOversamplingFactor(); 23 | BOOST_REQUIRE_EQUAL (os.getFactor (i), (int) proc->getOversamplingFactor()); 24 | BOOST_REQUIRE_EQUAL (factora, factorb); 25 | BOOST_REQUIRE (proc->getLatencyInSamples() > 0.f); 26 | BOOST_REQUIRE (os.getLatencySamples (i) > 0.f); 27 | } 28 | } 29 | 30 | os.reset(); 31 | } 32 | 33 | BOOST_AUTO_TEST_SUITE_END() 34 | -------------------------------------------------------------------------------- /test/PluginManagerTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "engine/clapprovider.hpp" 8 | #include "utils.hpp" 9 | 10 | using namespace element; 11 | 12 | BOOST_AUTO_TEST_SUITE (PluginManagerTests) 13 | 14 | BOOST_AUTO_TEST_CASE (SupportedFormats) 15 | { 16 | PluginManager manager; 17 | for (const auto& supported : Util::compiledAudioPluginFormats()) 18 | BOOST_REQUIRE (! manager.isAudioPluginFormatSupported (supported)); 19 | 20 | manager.getNodeFactory().add (new LV2NodeProvider()); 21 | manager.getNodeFactory().add (new CLAPProvider()); 22 | manager.addDefaultFormats(); 23 | for (const auto& supported : Util::compiledAudioPluginFormats()) 24 | BOOST_REQUIRE_MESSAGE (manager.isAudioPluginFormatSupported (supported), supported.toStdString()); 25 | } 26 | 27 | BOOST_AUTO_TEST_SUITE_END() 28 | -------------------------------------------------------------------------------- /test/RootGraphTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "engine/rootgraph.hpp" 6 | #include "utils.hpp" 7 | 8 | using namespace element; 9 | 10 | struct DummyAudioDeviceSetup : DeviceManager::AudioDeviceSetup { 11 | explicit DummyAudioDeviceSetup (int numIns = 4, int numOuts = 4) 12 | { 13 | inputDeviceName = outputDeviceName = "Dummy"; 14 | inputChannels.setRange (0, numIns, true); 15 | outputChannels.setRange (0, numOuts, true); 16 | sampleRate = 44100.0; 17 | bufferSize = 1024; 18 | } 19 | }; 20 | 21 | BOOST_AUTO_TEST_SUITE (RootGraphTests) 22 | 23 | BOOST_AUTO_TEST_CASE (Layout) 24 | { 25 | Context context (RunMode::Standalone); 26 | { 27 | RootGraph root (context); 28 | DummyAudioDeviceSetup setup; 29 | root.setPlayConfigFor (setup); 30 | BOOST_REQUIRE (root.getSampleRate() == setup.sampleRate); 31 | BOOST_REQUIRE (root.getBlockSize() == setup.bufferSize); 32 | root.clear(); 33 | } 34 | } 35 | 36 | BOOST_AUTO_TEST_SUITE_END() 37 | -------------------------------------------------------------------------------- /test/TestMain.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE Element 2 | #include 3 | #include 4 | using namespace juce; 5 | 6 | #include 7 | #include 8 | 9 | namespace element { 10 | namespace test { 11 | static std::unique_ptr _context; 12 | Context* context() 13 | { 14 | if (_context == nullptr) { 15 | _context = std::make_unique (RunMode::Standalone); 16 | _context->services().initialize(); 17 | _context->services().activate(); 18 | } 19 | return _context.get(); 20 | } 21 | 22 | void resetContext() 23 | { 24 | _context.reset(); 25 | } 26 | } // namespace test 27 | } // namespace element 28 | 29 | struct JuceMessageManagerFixture { 30 | JuceMessageManagerFixture() 31 | { 32 | MessageManager::getInstance(); 33 | juce::initialiseJuce_GUI(); 34 | } 35 | 36 | ~JuceMessageManagerFixture() 37 | { 38 | element::test::resetContext(); 39 | juce::shutdownJuce_GUI(); 40 | } 41 | }; 42 | 43 | BOOST_GLOBAL_FIXTURE (JuceMessageManagerFixture); 44 | 45 | BOOST_AUTO_TEST_SUITE (Element) 46 | 47 | BOOST_AUTO_TEST_CASE (Sanity) 48 | { 49 | BOOST_TEST_REQUIRE (2 + 2 != 5); 50 | } 51 | 52 | BOOST_AUTO_TEST_SUITE_END() 53 | -------------------------------------------------------------------------------- /test/datapathtests.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include "appinfo.hpp" 9 | 10 | using element::DataPath; 11 | using element::Settings; 12 | 13 | BOOST_AUTO_TEST_SUITE (DataPathTests) 14 | 15 | BOOST_AUTO_TEST_CASE (PathsMatch) 16 | { 17 | #if ! EL_APPIMAGE 18 | Settings s; 19 | auto params = s.getStorageParameters(); 20 | params.folderName = params.folderName.replace ("\\", "/"); 21 | const auto fullPath = DataPath::applicationDataDir().getFullPathName().replace ("\\", "/"); 22 | 23 | BOOST_REQUIRE_MESSAGE (params.folderName.endsWith (EL_APP_DATA_SUBDIR), 24 | params.folderName.toStdString()); 25 | BOOST_REQUIRE_MESSAGE (fullPath.endsWith (EL_APP_DATA_SUBDIR), fullPath.toStdString()); 26 | BOOST_REQUIRE_EQUAL (DataPath::defaultSettingsFile().getFullPathName().toStdString(), 27 | s.getUserSettings()->getFile().getFullPathName().toStdString()); 28 | #else 29 | BOOST_REQUIRE (true); 30 | #endif 31 | } 32 | 33 | BOOST_AUTO_TEST_SUITE_END() 34 | -------------------------------------------------------------------------------- /test/engine/LinearFadeTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "engine/linearfade.hpp" 3 | 4 | using namespace element; 5 | using namespace juce; 6 | 7 | class LinearFadeUnit { 8 | public: 9 | void runTest() 10 | { 11 | testLinearFade(); 12 | } 13 | 14 | private: 15 | void testLinearFade() 16 | { 17 | LinearFade fader; 18 | fader.setSampleRate (44100.0); 19 | fader.setLength (0.02); 20 | fader.setFadesIn (false); 21 | 22 | BOOST_REQUIRE (! fader.isActive()); 23 | fader.startFading(); 24 | BOOST_REQUIRE (fader.isActive()); 25 | 26 | int frame = 0; 27 | juce::ignoreUnused (frame); 28 | 29 | while (fader.isActive()) { 30 | float gain = fader.getNextEnvelopeValue(); 31 | frame++; 32 | } 33 | 34 | BOOST_REQUIRE (fader.isActive() == false); 35 | BOOST_REQUIRE (fader.getCurrentEnvelopeValue() == 0.0); 36 | fader.reset(); 37 | BOOST_REQUIRE (fader.getCurrentEnvelopeValue() == 1.0); 38 | } 39 | }; 40 | 41 | BOOST_AUTO_TEST_SUITE (LinearFadeTest) 42 | 43 | BOOST_AUTO_TEST_CASE (Basics) 44 | { 45 | LinearFadeUnit().runTest(); 46 | } 47 | 48 | BOOST_AUTO_TEST_SUITE_END() 49 | -------------------------------------------------------------------------------- /test/fixture/PreparedGraph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "engine/graphnode.hpp" 5 | #include "testutil.hpp" 6 | 7 | namespace element { 8 | 9 | struct PreparedGraph { 10 | GraphNode graph; 11 | 12 | explicit PreparedGraph (double sampleRate = 44100.0, int blockSize = 512) 13 | : graph (*element::test::context()) 14 | { 15 | graph.prepareToRender (sampleRate, blockSize); 16 | } 17 | 18 | ~PreparedGraph() 19 | { 20 | graph.releaseResources(); 21 | graph.clear(); 22 | } 23 | }; 24 | 25 | } // namespace element 26 | -------------------------------------------------------------------------------- /test/fixture/context.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | namespace element { 5 | namespace test { 6 | 7 | class Context : public element::Context { 8 | public: 9 | Context() {} 10 | ~Context() {} 11 | }; 12 | 13 | } // namespace test 14 | } // namespace element 15 | -------------------------------------------------------------------------------- /test/integration/SessionChangedTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace element; 5 | 6 | BOOST_AUTO_TEST_SUITE (SessionChangedTest) 7 | 8 | BOOST_AUTO_TEST_CASE (HasChanged) 9 | { 10 | #if 0 11 | // TODO: need a fixtrure 12 | beginTest ("not flagged changed after session open and save"); 13 | const auto sessionFile = getDataDir().getChildFile ("Sessions/Default.els"); 14 | expect (sessionFile.existsAsFile()); 15 | auto* const controller = services().find(); 16 | controller->openFile (sessionFile); 17 | runDispatchLoop (40); 18 | expect (! controller->hasSessionChanged()); 19 | controller->saveSession (false); 20 | runDispatchLoop (40); 21 | expect (! controller->hasSessionChanged()); 22 | #endif 23 | } 24 | 25 | BOOST_AUTO_TEST_SUITE_END() 26 | -------------------------------------------------------------------------------- /test/osc/node-client/README.md: -------------------------------------------------------------------------------- 1 | 2 | # OSC Test Server and Client in Node.js 3 | 4 | ## Requirement 5 | 6 | [Node.js](https://nodejs.org/en/) must be installed, with its package manager, `npm`. 7 | 8 | You can download it from the above link to install the latest long-term stable version. 9 | 10 | For more flexibility, install [`n`](https://github.com/mklement0/n-install), which allows switching between Node.js versions. 11 | 12 | ```sh 13 | curl -L https://git.io/n-install | bash 14 | ``` 15 | 16 | ## Install dependencies 17 | 18 | ```sh 19 | npm install # or yarn 20 | ``` 21 | 22 | ## Run 23 | 24 | ```sh 25 | node index 26 | ``` 27 | -------------------------------------------------------------------------------- /test/osc/node-client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-test-engine-osc-node-client", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "serve": "node index" 8 | }, 9 | "dependencies": { 10 | "osc-js": "^2.0.4" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/porttypetests.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | using element::PortType; 6 | 7 | BOOST_AUTO_TEST_SUITE (PortTypeTests) 8 | 9 | BOOST_AUTO_TEST_CASE (all) 10 | { 11 | BOOST_REQUIRE_EQUAL (PortType::all().size(), PortType::Unknown); 12 | } 13 | 14 | BOOST_AUTO_TEST_SUITE_END() 15 | -------------------------------------------------------------------------------- /test/scripting/bytestest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | 6 | #include "luatest.hpp" 7 | #include "scripting/dspscript.hpp" 8 | #include "scripting/scriptloader.hpp" 9 | #include "testutil.hpp" 10 | 11 | using namespace element; 12 | 13 | BOOST_AUTO_TEST_SUITE (BytesTest) 14 | 15 | BOOST_AUTO_TEST_CASE (Basics) 16 | { 17 | LuaFixture fix; 18 | sol::state_view lua (fix.luaState()); 19 | auto script = fix.readSnippet ("test_bytes.lua"); 20 | BOOST_REQUIRE (! script.isEmpty()); 21 | try { 22 | lua.safe_script (script.toRawUTF8(), "[test:bytes]"); 23 | } catch (const std::exception& e) { 24 | BOOST_REQUIRE_MESSAGE (false, e.what()); 25 | } 26 | } 27 | 28 | BOOST_AUTO_TEST_SUITE_END() 29 | -------------------------------------------------------------------------------- /test/scripting/scriptmanagertest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | #include "scripting/scriptmanager.hpp" 6 | #include "scripting/bindings.hpp" 7 | #include "sol/sol.hpp" 8 | 9 | #include "testutil.hpp" 10 | 11 | namespace et = element::test; 12 | 13 | BOOST_AUTO_TEST_SUITE (ScriptManagerTest) 14 | 15 | BOOST_AUTO_TEST_CASE (ScanDirectory) 16 | { 17 | element::ScriptManager scripts; 18 | auto d = et::sourceRoot().getChildFile ("scripts"); 19 | scripts.scanDirectory (d); 20 | BOOST_REQUIRE_EQUAL (scripts.getNumScripts(), 7); 21 | } 22 | 23 | BOOST_AUTO_TEST_SUITE_END() 24 | -------------------------------------------------------------------------------- /test/scripting/scriptplayground.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Kushview, LLC 2 | // SPDX-License-Identifier: GPL3-or-later 3 | 4 | #include 5 | #include 6 | 7 | #include "sol/sol.hpp" 8 | #include "testutil.hpp" 9 | 10 | using namespace element; 11 | namespace et = element::test; 12 | using namespace juce; 13 | 14 | BOOST_AUTO_TEST_SUITE (ScriptPlayground) 15 | 16 | BOOST_AUTO_TEST_CASE (Referencing) 17 | { 18 | sol::state lua; 19 | lua.open_libraries (sol::lib::base); 20 | int value = 100; 21 | lua["value"] = value; 22 | value = 101; 23 | auto lval = lua.get ("value"); 24 | BOOST_REQUIRE_NE (value, lval); 25 | } 26 | 27 | BOOST_AUTO_TEST_SUITE_END() 28 | -------------------------------------------------------------------------------- /test/shuttletests.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | using element::Shuttle; 6 | 7 | BOOST_AUTO_TEST_SUITE (ShuttleTests) 8 | 9 | BOOST_AUTO_TEST_CASE (defaults) 10 | { 11 | Shuttle stl; 12 | BOOST_REQUIRE_EQUAL (stl.getSampleRate(), 44100.0); 13 | BOOST_REQUIRE_EQUAL (stl.getTempo(), 120.f); 14 | BOOST_REQUIRE_EQUAL (stl.getFramesPerBeat(), 44100.0 * 60.0 / stl.getTempo()); 15 | } 16 | 17 | BOOST_AUTO_TEST_SUITE_END() 18 | -------------------------------------------------------------------------------- /test/snippets/stream_from_c.lua: -------------------------------------------------------------------------------- 1 | result = "" 2 | local function read_and_print_input() 3 | result = io.read ("a") 4 | print ("data read: " .. result) 5 | end 6 | 7 | currentpos = stream:seek ("cur") 8 | local oi = io.input() 9 | io.input (stream) 10 | 11 | read_and_print_input() 12 | 13 | io.input (oi) 14 | stream:close() 15 | stream = nil 16 | -------------------------------------------------------------------------------- /test/snippets/test_bytes.lua: -------------------------------------------------------------------------------- 1 | local bytes = require ('el.bytes') 2 | local data = bytes.new (1024) 3 | 4 | BOOST_REQUIRE (data ~= nil) 5 | 6 | bytes.set (data, 1, 0xff) 7 | bytes.set (data, 2, 0xfe) 8 | bytes.set (data, 3, 0xfd) 9 | 10 | BOOST_REQUIRE (bytes.size (data) == 1024) 11 | BOOST_REQUIRE (bytes.get (data, 1) == 0xff) 12 | BOOST_REQUIRE (bytes.get (data, 2) == bytes.get (data, 2)) 13 | BOOST_REQUIRE (bytes.get (data, 3) ~= bytes.get (data, 2)) 14 | BOOST_REQUIRE (bytes.get (data, 2) ~= bytes.get (data, 1)) 15 | 16 | local raw = bytes.toraw (data) 17 | bytes.rawset (raw, 1, 0x10) 18 | bytes.rawset (raw, 2, 0x11) 19 | bytes.rawset (raw, 3, 0x12) 20 | BOOST_REQUIRE (bytes.rawget (raw, 1) == 0x10) 21 | BOOST_REQUIRE (bytes.rawget (raw, 2) == bytes.get (data, 2)) 22 | BOOST_REQUIRE (bytes.rawget (raw, 3) ~= bytes.get (data, 2)) 23 | BOOST_REQUIRE (bytes.rawget (raw, 2) ~= bytes.get (data, 1)) 24 | 25 | bytes.free (data) 26 | -------------------------------------------------------------------------------- /test/testutil.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace element { 6 | namespace test { 7 | 8 | /** Returns a global element::Context. */ 9 | Context* context(); 10 | 11 | /** Deletes the global context. 12 | calling test::context() will re-instantiate it 13 | */ 14 | void resetContext(); 15 | 16 | /** Returns the toplevel source directory. */ 17 | inline static juce::File sourceRoot() 18 | { 19 | #ifdef EL_TEST_SOURCE_ROOT 20 | return juce::File (EL_TEST_SOURCE_ROOT); 21 | #else 22 | return juce::File::getCurrentWorkingDirectory().getParentDirectory(); 23 | #endif 24 | } 25 | 26 | } // namespace test 27 | } // namespace element 28 | -------------------------------------------------------------------------------- /util/date.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | # Michael Fisher, 2023 4 | 5 | import datetime 6 | print (datetime.date.today()) 7 | exit(0) 8 | -------------------------------------------------------------------------------- /util/docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Runs the kushview/element docker image. By default it starts 3 | # a bash shell. 4 | 5 | entry="${1}" 6 | if [ -z "${entry}" ]; then 7 | entry="/bin/bash" 8 | fi 9 | 10 | extraopts="" 11 | if [ -d "$HOME/SDKs" ]; then 12 | extraopts="$extraopts --volume ${HOME}/SDKs:/SDKs:ro" 13 | fi 14 | 15 | mkdir -p dist 16 | 17 | docker run --rm -it \ 18 | --entrypoint "${entry}" \ 19 | --volume `pwd`/dist:/dist \ 20 | --volume `pwd`:/project \ 21 | --workdir /project \ 22 | $extraopts \ 23 | -u $(id -u ${USER}):$(id -g ${USER}) \ 24 | kushview/element 25 | -------------------------------------------------------------------------------- /util/getcode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | # Michael Fisher, 2023 4 | 5 | from optparse import OptionParser 6 | 7 | def options(): 8 | parser = OptionParser() 9 | parser.add_option ("--version", type="string", dest="version") 10 | parser.add_option ("--code", type="string", dest="code") 11 | parser.add_option ("--integer", action="store_true", default=False, dest="integer") 12 | (opts, _) = parser.parse_args() 13 | return opts 14 | 15 | opts = options() 16 | 17 | if (opts.version != None and len(opts.version) > 0): 18 | version = opts.version.split (".") 19 | value = ((int(version[0]) << 16) + 20 | (int(version[1]) << 8) + 21 | int(version[2])) 22 | if opts.integer: print (value) 23 | else: print("0x%x" % value) 24 | elif (opts.code != None and len(opts.code) > 0): 25 | code = opts.code 26 | value = ((ord(code[0]) << 24) + (ord(code[1]) << 16) + (ord(code[2]) << 8) + (ord(code[3]))) 27 | if opts.integer: print (value) 28 | else: print("0x%x" % value) 29 | else: 30 | exit(1) 31 | 32 | exit (0) 33 | -------------------------------------------------------------------------------- /util/img2ico.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # converts an image to a Windows ICO file. Required Imagemagick convert. 3 | 4 | convert -background transparent \ 5 | "${1}" -define icon:auto-resize=16,24,32,48,64,72,96,128,256 \ 6 | "${2}" 7 | -------------------------------------------------------------------------------- /util/macos-uninstall-user-plugins.sh: -------------------------------------------------------------------------------- 1 | rootdir="$HOME/Library/Audio/Plug-Ins" 2 | find "$rootdir" -name "KV-Element*" -exec rm -rf {} \; > /dev/null 3 | 4 | -------------------------------------------------------------------------------- /util/meson.build: -------------------------------------------------------------------------------- 1 | 2 | ############# 3 | ### bin2c ### 4 | ############# 5 | bin2c_sources = [ 'bin2c.cpp' ] 6 | bin2c_deps = [ juce_dep ] 7 | 8 | if host_machine.system() == 'windows' and cpp.get_id() == 'gcc' and cpp.get_argument_syntax() == 'gcc' 9 | # bin2c also needs these since it uses JUCE 10 | foreach l : 'uuid wsock32 wininet version ole32 ws2_32 oleaut32 imm32 comdlg32 shlwapi rpcrt4 winmm dxgi'.split() 11 | bin2c_deps += cpp.find_library (l, required : true) 12 | endforeach 13 | endif 14 | 15 | bin2c_install_dir = get_option ('bindir') 16 | 17 | bin2c = executable ('element-bin2c', bin2c_sources, 18 | install : true, 19 | install_dir : bin2c_install_dir, 20 | win_subsystem : 'console', 21 | gnu_symbol_visibility : 'hidden', 22 | dependencies : [ bin2c_deps ], 23 | include_directories : [ element_includes ], 24 | cpp_args : [], 25 | objcpp_args : [], 26 | link_args : [], 27 | link_with : [ libelement_juce ]) 28 | --------------------------------------------------------------------------------