-
Notifications
You must be signed in to change notification settings - Fork 149
change proposals for universal engine support
- handles bussing of hardware inputs, outputs and monitor signals and signals to and from loaded SuperCollider-based engine
- implements tape record to disk
- implements tape playback from disk
- implements the always-available (yet enabled/disabled upon demand) softcut engine
- provides softcut voice position via polls:
- provides coarse ADC and DAC levels for VU, via polls (https://github.com/monome/norns/blob/master/crone/src/MixerClient.cpp#L65
- maintains engine metadata (names of all engines), sent to matron upon request via OSC
- maintains engine command metadata, sent to matron upon request after an engine has been loaded via OSC
- maintains engine poll metadata, sent to matron upon request after an engine has been loaded via OSC
- maintains crone none-engine poll metadata (amp, pitch)
- handles loading & freeing engines
- starts and stops registered engine and non-engine (amp, pitch) polls
- sets up amp envelope used in engines
- sets up optional pitch envelope possible to use in engines
- forwards a number of messages originally handled in SC to the C++ based crone.
- answers /crone/ready when it receives a /ready osc message from matron
- dictates dsp processing in scsynth server process (well, custom engine subclasses do, but anyway)
- connects C++ crone and SC crone: https://github.com/monome/norns/blob/master/sc/core/Crone.sc#L82-L88
- clears some environment variables for jack defaults: https://github.com/monome/norns/blob/master/sc/core/Crone.sc#L42
Suggestions by @antonhornquist when adding support for multiple/arbitrary engine backends is added and clean up things a bit
still...
- handles bussing of hardware inputs, outputs and monitor signals and signals to and from loaded SuperCollider-based engine
- implements tape record to disk
- implements tape playback from disk
- implements the always-available (yet enabled/disabled upon demand) softcut engine
- implements VU and softcut phase polls
but also...
- implements higher-resolution amp env polls
- implements pitch polls
- maintain engine metadata (names of all engines)
- maintain engine command metadata
- maintain engine poll metadata
- maintain engine backend and configuration settings required to spawn engines
- possibly: maintain lua utility functions automatically loaded on engine load
complete engine metadata will be read from disk and not sent to matron upon request via OSC
pros: full engine schema always available
con: limits dynamic metadata possible to leverage using OSC
- replace sclang based engines in the current solution.
- adhere to an osc protocol to handle commands and start/stop of polls, as required
- answers /engine/ready when it receives a /ready osc message from matron
- handles loading & freeing engines by providing ways of complete engine setup and teardown on engine load / free based on a number of supported backends
- connects engine jack clients
- forwards the messages for C++ crone backend directly to the C++ process instead of via SC.
- connects core always-running jack clients(?)
Lua engine metadata file consists of lua code that returns a table that is required to include a kind
field which determines what engine backend to use. It is also required to contain backend specific configuration information (such as "path to main source file or executable" and any environment specific stuff) in a config
field.
In addition to this:
if commands are used the commands
field contains a table of commands in the form of: { name="[command_name]", format="[tag]" }
, ie. { name="gate", format="ii" }
. TODO: here metadata could potentially be extended with display_name
, docstring
, controlspec
, i dunno.
if polls are used the polls
field contains a table of polls in the form of: { name="[poll_name]" (, type="[value|data]", periodic=true|false) }
, ie. { name="phase_1" }
. Defaults for optional fields are type = "value" and periodic=true. TODO: here metadata could potentially be extended with display_name
, docstring
... i dunno.
The lua metadata file is (IMO) a good placeholder for utility libraries, like the ones currently used for adding parameters to the global params
table. A top level lib
field could hold a table with these utilities, and they could be loaded and injected automatically in the script environment. This way, there's no longer a requirement for a script to require a lua file for the utilities (which posed problems due to paths having to be regulated).
For example, see:
https://gist.github.com/antonhornquist/b2d76b753e51b27798ca5b348e30a42d#file-engine_ack-lua
kind
= "sc"
config
required to include source
field which should consist of a string designating a path to the main scd file. The path is assumed to be relative to the engine metadata file so it does not matter where the engine folder is put in the file system.
config
optionally to include a include_paths
field which should consist of a table of strings designating paths to a folder containing SC class files or ugens (as above, the paths are assumed to be relative to the engine metadata file).
config
optionally to include a runtime_directory
field which should consist of a string designating a path to a folder which will be set as sclang's runtime directory (as above, the path is assumed to be relative to the engine metadata file). (TODO: not sure on this, whether it's needed, since thisProcess.nowExecutingPath
might serve the same purpose...)
sclang
to get started as from the command line with the scd file as its [file]
argument.
if config
includes an include_paths
field a norns specific norns_conf.yaml
language configuration file (akin to sclang_conf.yaml) will be created (overwritten, if it already exists) in a temporary folder somewhere, with the include_paths expanded to an absolute paths added as the paths in the YAML file list of includePaths
. sclang
will then get started with the -l /path/to/norns_conf.yaml
option. TODO: if omitted, write empty norns_conf.yaml
for clarity (to make sure no arbitrary sclang_conf.yaml
weirdness is used)?
2019-10-17: decide how to handle base sc classes. either in regular SuperCollider extensions directory, or - if a custom one like today is used - always write a norns_conf.yaml
and include the custom base sc class dir in there.
ie:
norns_conf.yaml
includePaths:
- [/absolute/path/to/engine/include_path_1]
- [/absolute/path/to/engine/include_path_2]
...
- [/absolute/path/to/engine/include_path_n]
if config
includes a runtime_directory
sclang
will then get started with the -d [/absolute/path/to/runtime_directory]
option. TODO: if omitted, default this to the folder where main scd script resides?
Example (glut):
local NVOICES = 7
local glut = {
name = "glut",
commands = {
{ name="gate", format="ii" },
{ name="speed", format="if" },
{ name="jitter", format="if" },
{ name="size", format="if" },
{ name="density", format="if" },
{ name="pitch", format="if" },
{ name="spread", format="if" },
{ name="volume", format="if" },
{ name="envscale", format="if" }
},
kind="sc",
config = {
source="relative/path/to/engine_glut.scd"
}
}
glut.polls = {}
for voicenum=1,NVOICES do
table.insert(glut.polls, { name="phase_"..voicenum })
table.insert(glut.polls, { name="level_"..voicenum })
end
return glut
after successfully booting and loading engine, required jack connections for the engine stereo ins and outs needs to be set up (this is not handled in SC anymore).
kind
= "pd"
config
required to include path
field which should consist of a string designating a path to the main pd file. The path is assumed to be relative to the engine metadata file so it does not matter where the engine folder is put in the file system.
config
optionally to include a include_paths
field which should consist of a table of strings designating paths to a folder containing pd patches or externals (as above, the paths are assumed to be relative to the engine metadata file).
config
optionally to include a libs
field which should consist of a table of strings designating paths to shared libraries for pd (as above, the paths are assumed to be relative to the engine metadata file).
pd
to get started as from the command line with the pd file as its [file]
argument, with the -nogui
flag and any other required flags to make sure jack is used.
each path in include_paths
in lua engine metadata is added expanded as absolute path with argument -path [/absolute/path/to/include_path]
to the pd
argument list.
each path in libs
in lua engine metadata is added expanded as absolute path with argument -lib [/absolute/path/to/lib]
to the pd
argument list.
ie.:
Simple engine:
return {
name = "testsine_pd",
commands = {
{ name="amp", format="f" },
{ name="hz", format="f" },
},
kind = "pd",
config = {
patch="relative/path/to/testsine.pd"
}
}
2019-10-17: if base pd abstractions, patches or libs are to be delivered with norns, they can also automatically get included with always appended -path
and -lib
arguments.
- How to handle lua metadata files with engines having the same engine name gracefully?
Adopting some kind of install step when ie. adding engines to include custom ugens or classes was discussed on slack. One way to work around this would be to make sclang extension dir dynamic (as in a field in the lua engine metadata file) and set this as part of the process of selecting / booting a new engine. NEW: see include_paths
for sc engines above.
- Time for changing scripts (and thus, engines) may be longer - at least if we’re to restart processes all the time.
- On the interpreted scd engines approach
- Interpreted sclang performance vs compiled sclang performance (on desktop IMO this is a non-issue but on the rpi it might be wise to do some tests)
- Interpreted sclang code is a bit harder to debug than class based sc code (we can give some tips here).
- Migration of existing class based engines.
- Engine backwards compatibility may get broken, though there are not that many engines yet.
- CroneGenEngine which generates engines from a SynthDef, needs to be rewritten. I'm already rewriting this, so it's not a big deal. Migration of the few CroneGenEngines engines will be simple. (outline somewhere how a 3.0 cronegenengine may look)
- Error reporting, Failures, Monitoring, Logging (this is not my area of expertise, especially not on linux)
- ... would - I guess - require engines at least to have their own osc receive port, set externally in some way (by the process launching the engine based on lua metadata).
- ... would need more UI / script / arcitecture design
- SC: it might be incompatible to run multiple engines in one sclang process if includePaths for classes / ugens are used. then class duplication errors may pop up.
universal engine things https://github.com/monome/norns/wiki/universal-engine-approach
lua engine metadata details https://gist.github.com/antonhornquist/20253f0489a91a4f3b88497998ca320b
monome.org