diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2023-09-15 20:21:35 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2023-09-15 21:17:08 +0300 |
commit | 0b47e7cf9bb7b77fa28a02aea1964540b81a7c84 (patch) | |
tree | b1b0be0317d594cac680bf69d3857253f7f0341c | |
parent | 7fc0f17fb37326c86a83627b856a5b75f522c090 (diff) | |
download | applause2-0b47e7cf9bb7b77fa28a02aea1964540b81a7c84.tar.gz |
documentation update
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | TODO | 35 | ||||
-rw-r--r-- | applause.lua | 6 | ||||
-rw-r--r-- | dssi.lua | 2 | ||||
-rw-r--r-- | evdev.lua | 5 | ||||
-rw-r--r-- | sndfile-stream.lua | 1 |
6 files changed, 34 insertions, 19 deletions
@@ -44,7 +44,7 @@ Example (one channel): echo -ne "25 \nStream.SinOsc(440):play()" | socat -,ignoreeof TCP:127.0.0.1:10000" -See also `client.tes` for a SciTECO integration. +See also `client.tes` for a [SciTECO](https://github.com/rhaberkorn/sciteco) integration. # Joysticks and Gamepads @@ -68,3 +68,5 @@ to expose them as MIDI events. * [midicontroller](https://sourceforge.net/projects/midicontrol/) for producing MIDI CC events * MIDI Tracker ??? * evtest to find and test HID devices +* listplugins and analyseplugin to inspect LADSPA plugins +* dssi_list_plugins and dssi_analyse_plugin to inspect DSSI plugins @@ -3,14 +3,9 @@ * Stream:foreach() cannot be interrupted Perhaps C core should export an interrupted variable that we can check from Lua. For Stream:play() this is solved differently. -* Stream:gtick() is not real-time safe but called from tick functions currently. - This could be resolved by letting gtick() return an initializer function and only - this initializer function will return the tick function. - Streams could implement a get_tick_init() method and Stream:gtick() would continue - to exist as a shortcut. -* EvdevStream("TrackPoint"):evrel('REL_X'):scale(440,880):SinOsc():play() - Afterwards even Stream.SinOsc(880):play() will stutter. - However, this seems to happen only with the builtin speakers and with other programs as well. +* SndfileStream(...):sub(...) does not work for multi-channel audio files. + The reason is that SubStream ticks in gtick() to seek in the source stream + which cannot work in cached streams (SndfileStream:ctor() caches for multi-channel streams). # Features @@ -26,22 +21,29 @@ * Multi-core support via GStreamer-like queue: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-queue.html * Stream optimizer - * Automatic caching (finding identical subtrees) + * Automatic caching (finding identical subtrees). + * Removing contraproductive caching, e.g. after plain number streams, MIDIStream, EvdevStream... * Automatic paralellization * Automatic eager evaluation of small Streams independant of real-time input. - * Resolving Stream:sub() by alternative means, e.g. specifying an osciallator phase or - passing in a seek to a SndfileStream. + * Moving Stream:evabs() and Stream:sub() closer down the source, so we can make + use of per-class optimizations. * ... +* Allow stringified timestamps everywhere, where we currently accept lengths in samples. tosamples()? * Github pages (LDoc documentation). They can be automatically pushed by a Github action. Since they will always be public, copyright questions should be resolved first. # Improvements -* add optional Stream:gtickCtx() (or Stream:get_tick_init()) containing potentially real-time unsafe code. - Higher-order streams call Stream:gtickCtx() for all dependant streams only - once in their own gtickCtx() function. - This will allow gtick() to be called in tick-functions (that must be real-time safe). +* Stream:gtick() is currently not real-time safe but called from tick functions + (either to reset the stream or to start is whenever this cannot be prepared for in the parent gtick()). + This is especially a problem for SndfileStream. + We must somehow avoid all costly operations in gtick(), doing them in ctor() instead. + Furthermore, we could theoretically avoid table lookups in gtick() by binding + Stream attributes to local variables. + This could be achieved most easily by assigning self.gtick to a lambda in ctor(). + Furthermore, tick() functions should always cache self.gtick, so as to avoid + table lookups. * It could be useful to pass a timestamp (in samples) into the tick function. This will simplify some calculations and allows resetting a stream elegantly (for instance in RepeatStream). It will also speed up seeks, as in SubStream. @@ -63,3 +65,6 @@ The reduced accuracy shouldn't hurt us much. * Allow building LuaJIT with -DLUAJIT_ENABLE_LUA52COMPAT. This will enable #Stream and we may implement an __ipairs metamethod. +* Per-class optimizations. + * SndfileStream:sub() for seeking in sound files. + * EvdevStream:evabs() for retrieving the minimum/maximum values automatically. diff --git a/applause.lua b/applause.lua index 08d0415..2d86aa6 100644 --- a/applause.lua +++ b/applause.lua @@ -90,7 +90,7 @@ end samplerate = 44100 --- Convert seconds to sample numbers --- These are functions, so we can round the result +-- These are functions, so we can round the result. -- automatically. -- @number[opt=1] x Number of seconds -- @treturn int Number of samples @@ -1709,7 +1709,9 @@ function SubStream:gtick() -- overwritable gtick_seek(). Problem as always is that -- this would have to chain to substreams. -- Perhaps, it would be wiser to let this be handled by - -- an optimizer stage that resolves Stream:sub-calls. + -- an optimizer stage that resolves Stream:sub()-calls. + -- @fixme Actually, this is plain wrong and does not work + -- if self.stream is cached. for _ = 1, self.i-1 do tick() end local i = self.i @@ -546,6 +546,8 @@ DSSIStream = DeriveClass(Stream) -- -- @fixme We could simplify things by just assuming a flat array of -- input ports. +-- @todo We have everything to provide in-program plugin listing and introspection. +-- E.g. DSSIStream.list(). function DSSIStream:ctor(file, midi_event_stream, ...) local plugin_file, label = file:match("^([^:]+):(.+)") plugin_file = plugin_file or file @@ -62,10 +62,12 @@ EvdevStream = DeriveClass(Stream) -- @treturn EvdevStream -- A stream of C structures, describing the event in detail. -- Its fields will be 0 if no event ocurred. --- @todo Document the C structure as a Lua table. -- @see Stream:evrel -- @see Stream:evabs -- @see Stream:evkey +-- @todo Document the C structure as a Lua table. +-- @todo We could introduce something like EvdevStream.list() to get at least some +-- introspection without having to call evtest. function EvdevStream:ctor(id, grab) local grab = grab == nil or grab @@ -158,6 +160,7 @@ end -- @fixme min and max can be read from the properties of the corresponding code. -- This would however require us to do all postprocessing already in EvdevStream:gtick() -- or even in applause_evdev_new(). +-- Or simply overwrite this function in EvdevStream as an optimization. function Stream:evabs(code, min, max) code = ffi.cast("enum applause_evdev_abs", code) diff --git a/sndfile-stream.lua b/sndfile-stream.lua index 248f82a..1c394b8 100644 --- a/sndfile-stream.lua +++ b/sndfile-stream.lua @@ -52,6 +52,7 @@ function SndfileStream:gtick() -- read pointer which is important when reusing the stream. -- NOTE: We could do this with a single handle per object but -- by maintaining our own read position and seeking before reading. + -- @fixme On the downside, this gtick() is not real-time safe. local handle = sndfile:new(self.filename, "SFM_READ", self.samplerate, self.channel_no, self.format) |