Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
* introduced MIDIStream which provides a raw stream of MIDI messages
(mangled into a single integer).
* MIDIVelocityStream has been replaced by
MIDIStream:mvelocity()
* MIDICCStream has been replaced by
MIDIStream:CC()
* MIDIStreams can be directly passed to DSSIStreams
|
|
* The LADSPA module has been extended to support DSSI plugins as well.
If DSSI support is detected, the first input stream is considered a MIDI
event stream.
* The MIDI event handling must be updated to allow streams of MIDI messages
for this to be useful.
* ladspa.lua has been subsequently renamed to dssi.lua
|
|
* this has long been broken. ZipStream implicitly assumes an associative
operation when "inlining" nested ZipStreams.
Since the above mentions operations are not associative,
the result was a faulty calculation.
Example: s1 - (s2 - s3) was calculated like (s1 - s2) - s3.
* For the time being, the inlining is avoided by using unique
lambdas.
|
|
|
|
* only really useful for DSSI plugins that do not expose a LADSPA
entry point and do not need MIDI NOTE commands (ie. effects).
* full DSSI support might be added in a subclass that adds a MIDI
command stream.
Applause's MIDI handling could be extended to directly provide
such streams (ie. by having a queue of these events and producing
0 if they are empty) with MIDICCStream and MIDIVelocityStream being
refactored into pure Lua classes which extract the relevant
information and cache the previous value.
|
|
* User-provided arguments should correspond to the n'th input port
instead of the n'th overall port.
This failed if output ports were mixed with input ports (or come first)
in the list of ports that the LADSPA plugin defines.
|
|
* When specified as part of a port-mapping array or list, they
are automatically expanded.
I.e. if `stream` is stereo, LADSPAStream(..., stream) is equivalent to
LADSPAStream(..., stream:demux(1), stream:demux(2))
* This is often handy because stereo input ports are usually
defined consecutively by LADSPA plugins.
|
|
* Constants were converted to infinite streams.
This allows them to be handled specially. They are stored in their own
input buffer now, initialized and connected once but need no ticking.
* In contrast to the Applause primitives, this can be done centrally and
for all possible LADSPA plugins.
* This gives a speed increase of up to 20% if all input ports are mapped
to constants (measured with the "sine" plugin).
|
|
* E.g. LADSPAStream("sine", 880):play().
The sine plugin is currently twice as fast as the native Applause implementation
even though a block size of 1 sample is used (ie. compared to Stream.SinOsc).
* all LADSPA features should be supported
* Takes arbitrary Streams as input and produces a normal Applause stream.
* multi-channel output plugins supported
* LADSPA port mapping is possible by array, by name and by argument
list.
* Even though LADSPAStream is not muxable (it is more like SndfileStream),
every input stream or default value is currently converted to a Stream.
This can be optimized by storing scalars in their own arrays.
They don't have to be ticked.
|
|
it should have no runtime penalty and eases debugging core dumps
|
|
* all of these filters were ticking the input stream twice, effectively
resulting in the input signal to be pitched.
* the quality factor should be allowed to be a stream since there is no
technical reason against it.
|
|
metamethod
|
|
stream determines the length
* this makes them compatible with the scalar operations like Stream:mul(), Stream:add() etc
when the right stream is a scalar turned into an infinite stream.
* Consequently, both operations could be merged: Stream:mul() and the __mul operator
are now synonymous.
The methods are kept since they are sometimes handy to avoid braces when writing
from left to right.
Since the old way of mapping a stream for scalars is still a bit faster compared to using
a ZipStream, this method is still applied for scalars as an optimization.
Both the methods and the operators will now work with scalars and arbitrary streams, though.
* This means that many primitives based on scalar operations previously will now
work with streams as well. This applies to Stream:scale(), Stream:ccscale(), Stream:mix(),
Stream:pan() and even line().
* Added Stream:min() and Stream:max() as shortcuts for binary operations from the
math package.
* All the binary operations from the math and bit packages will work with streams now
as well (without performance penalties).
* Stream:clip() has been revised and works with stream arguments now as well.
* Optimized ConcatStream, MapStream, ScanStream, FoldStream and esp. ZipStream.
* The new ZipStream semantics allow for new useful idioms.
For instance, to add an envelope to an infinite stream (stream*env), a SubStream
was often necessary to restrict the resulting stream to the length of the envelope
as in (stream*env):sub(1,env:len()).
This can now be written more elegantly as (env*stream).
To extend a stream to infinite length, you may still write 0+stream or
stream..0
|
|
* SawOsc has been broken for a long time
* phases are useful since they are trivial to implement at the Phasor level
and cumbersome to emulate using SubStream (basically you would need
:sub(sec(1)/freq*phase)).
Also, this way, phases will work even for modulated frequencies
or if the frequency is unknown.
They should come with no additional runtime overhead.
|
|
|
|
InstrumentStream for finite on-streams
|
|
* an explicit FFI finalizer must be used.
* fixes "Too many open files" errors
|
|
channels and libsndfile format
|
|
command line help is provided using -h or when specifying an unknown option
|
|
|
|
vice versa
* mton() can handle MIDINoteStream values just like mtof()
* both are exposed as Stream methods as well (e.g. Stream:mton())
* MIDIVelocityStream accepts note names now as well in addition to MIDI note numbers
* added scoping to the cache used by mtof()
|
|
|
|
* properly named attributes can be used instead of putting all
stream arguments into a `streams` attribute. This is no longer
necessary since there is no more Stream:reset() method.
|
|
* this function is not the tick function itself but rather a generator
(returning the tick function).
* Calling these methods gtick() is less confusing but still concise.
|
|
* allows a stream of note velocities to trigger a note-on and note-off stream.
* usually used on a MIDIVelocityStream
* allows a single note to be triggered including attack, sustain and decay
phases
* by letting the note-on and note-off streams depend on the note/velocity stream,
the note can use the NOTE ON velocity.
* The InstrumentStream constructor will also accept functions on the note_stream,
so it is possible to define the note-on/off streams depending on the velocity stream
on a single line of source code.
* A NOTE OFF velocity is currently not used, though that could be achieved by
letting MIDIVelocityStream generate negative numbers for NOTE OFF velocities.
* This will only work with a single note (ie. a fixed frequency);
when wanting to play polyphony, users will have to mix many different InstrumentStreams, e.g.
iota(69, 79):map(function(note)
return MIDIVelocityStream(note, 1):instrument(function(v) return InstOn(note, v) end,
InstOff(note))
end):fold(function(x,y) return x+y end):ravel()
|
|
* the syncing had some serious issues: It was not possible to repeat
a synced stream since its tick() iterators were not independant.
E.g. Foo = Bar:sync(); (Foo..Foo):play()
would not have the expected result (Bar..Bar):play()
* syncing required the Stream.reset() mechanism
* instead of syncing, we now do caching (CachedStream) in a dedicated
sampleCache table. Instead of alternating the clock signal, the
cache is now simply table.clear()ed for each output sample.
This results in some allocation overhead on the first sample since
sampleCache will not yet have its final size.
(Although this overhead could be avoided by counting the
number of cached streams recursively and allocating sampleCache
using table.new())
* SndfileStream suffered from similar problems, it could not be repeated
because every object's tick() shared the same handle.
Instead every tick() now opens its own handle.
This means that using the same SndfileStream multiple times no longer
requires explicit syncing/caching and SndfileStreams can be repeated.
On the down-side we must check whether the file changed after
the initial object construction.
|
|
* Unicode identifiers allowed in LuaJIT 2
* We add the shortcuts directly to applause.lua but using Unicode escapes.
Thus we don't have to maintain a separate file and we can still edit applause.lua
using a non-UTF editor like SciTECO
* Stream:sub (subtract) renamed to Stream:minus. This was previously overwritten by
the SubStream wrapper.
|
|
* DelayStream must currently have a constant length (ie. duration)
* Stream:mix() allows mixing two streams by a constant wet/dryness factor.
0 means only the first stream, while 1 is only the second stream.
* Stream:echo() builds on this for an echo effect with constant delay
and wetness factor. The source stream is automatically synced.
|
|
* use socat now for SciTECO integration. It correctly shuts down
the connection when interrupted.
This has the effect as cancelling the current command, just as
^C would on the Applause command line.
|
|
|
|
* In contrast to RTcmix, they are calculated on-demand.
Like any stream, they can be turned into a "lookup table" using :eval()
|
|
These are useful whenever a single-channel stream should be muxed
into multi-channel stream (e.g. mono to stereo signal)
|
|
* benchmark() has been inmproved.
* added Stream:benchmark()
|
|
* This is implemented without introducing the notion of frames into the tick() methods
since most multi-channel stream operations can be understood as duplicating the
operation on each channel.
* Instead there is only ONE explicitly multi-channel stream: MuxStream.
It can be used to construct a multi-channel stream from various normal mono streams
and is also used internally.
* MuxStreams can still be used just like any other stream since the new base class
MuxableStream will automatically apply the class constructors on each channel in order.
The channels of streams being combined must be equal, unless mono streams are involved.
* Mono-streams are automatically blown-up to multi-channel streams when involved in
operations with a multi-channel stream.
* The remaining multi-channel specific code has been isolated in Stream:foreach()
which now receives frames instead of individual samples.
* When playing() a multi-channel stream, the applause output ports are played in order.
I.e. playing a mono-stream fills output_1. A stereo stream, output_1 and output_2.
* The number of Jack output ports can be specified on the applause command line.
* All system playback ports are tried to be connected to corresponding applause output ports.
|
|
working directory
|
|
|
|
|
|
* Stream:foreach() is also useful on the command line.
It is used to apply a function to all samples of a stream
as fast as possible. Some existing methods have been simplified using foreach()
* an alternative to foreach() would be to use Streams exclusively to
introduce side-effects into sample processing and provide a simple method
like sink() to fetch all samples as fast as possible.
Other methods like save() could then be simple wrappers
|
|
|
|
* should speed up things since the C function calls can be inlined
* the C function does only rudimentary argument checking using assert()
since they are only called internally.
This means, calling it with wrong arguments can result in controlled
crashes. This will point to programming errors since the real argument
checking is done in Lua code at stream construction.
* The MIDI*Stream.getValue() functions have been kept as wrappers around
the native functions, to ease using them in other stream implementations
that want to support MIDI natively.
|
|
|
|
* the low-level C part is now implemented in a normal
C function applause_push_sample() which is called using the FFI
API
* this is supposedly faster than the old Lua/C way, but the
speed improvement seems to be miniscule.
However changes like this are still good since they simplify
the C core.
* speed improvements will probably be larger for the
MIDI*Stream functions since here we call Lua/C functions at
sample rate.
|
|
* the server is basically a second way to modify the Lua state of Applause
* concurrently to interactive input, messages can be sent over a TCP socket
which are evaluated just like command lines.
All stdout/stderr output is returned and the socket is closed.
* Server currently hardcoded at 127.0.0.1:10000
* Interruptions are currently not possible.
This would require another thread.
* The threading could be simplified by making the applause binary
a server-only application.
The Read-Eval-Print loop could then be a standalone LuaJIT script.
|
|
and print stack tracebacks
|
|
* all sub-substreams must now be in the `streams` attribute
|
|
and construction using the Class() idiom
* Class:instanceof() deprecates several fields like is_azipstream;
is_a_stream is still useful
* Constructors are now defined as ordinary methods (looks better)
* every object and class table now has a `base` field that points to the
base class since getmetatable() will no longer point to the base table/class.
* Objects can be constructed both using Class:new() and Class().
The old behaviour of stream() for serialization is used less frequently.
* Streams can be serialized using the Stream:eval() method.
I don't think that the object system should be tweaked even more to support
different metamethods for class tables and objects as it is quite convoluted already.
|
|
* could be used to introduce classes like SinOsc that are simply shortcuts
for some higher order stream (just like Stream.SinOsc is currently) but
can be instantiated consistently using SinOsc:new().
|
|
(or infinitely)
* this currently also works for very long streams without precalculating stuff
* On the other hand, after each iteration the target stream must be reinitialized.
This is not safe in generator functions (FIXME).
|
|
* we have to make sure that exactly the same function values are used
|