Currently working on
-
2020-10-27 : Fixed a bug in the sample and hold mechanism of the RandSigs module.
Sample and hold would only work on the leftmost two outputs, it now operates
correctly on all outputs.
-
2020-11-19 : Added a linear decay mode to the EnvARRetrig module. By default it
will start up in exponential decay mode, like it used to be.
-
2020-11-22 : Added a range selector to the Envelope (follower) module to allow it
to act like a very slow exponential slew rate limiting module.
-
2020-11-22 : Fixed an issue in the MidiClockIn module where BPM ClockGen could not
be selected for the Mode parameter.
-
2020-11-22 : Fixed an issue with the ClockGen module where the external tempo
(BPM) control could not work with a control signal > 1, which limited it's use to
about 240 BPM.
-
2020-11-23 : Made a new MultiDiv module, it consists of eight individually
settable divider sections with a common clock and two common outputs.
The individual dividers all have their own output and on top of that there is a
built in multiplexer selecting from the individual outputs and routing to the mix
output. The multiplexer is controlled by a sel input signal and it's start and
span can be set and modulated as well. The xfade input will fade over the set span
starting at the selection start.
Each multiplexer step has in individual step output which will be active when that
step is active, as indicated by the associated light.
The idea is to clock this module with a relatively fast clock (for example the x16
output of the ClockGen module) such that steady patterns can be programmed with an
occasional drum roll. Using the xfade controls steps can be faded over to each
other (instead of abrubptly being switched over).
Added a value control for each step with a mix output for it, this behaves like a
set of multiplexed values, or like a sequencer. The individual outputs are zero
when the step is not selected and equal to the knob set value when the step is
active.
Moved the module from the logic to the seq1 tab, and changed it's color
accordingly.
Note: the xfade control does not make smooth transitions as output values will
change value on a clock edge only.
-
2020-11-24 : From now on I'll start to use the dark green and orange colors on
outputs as well (it used to be used on inputs only to reflect logic inputs that
switch at 0.5 instead of 0.0 units). For outputs it will mean that it is a logic
output with a 0.0 to 1.0 range instead of the usual -1.0 to 1.0 range. Otputs with
switchable ranges will not be affected and will still have the lighter green
color. Orange for audio rate high logic, and dark green for control rate high
logic signals.
Now if only I could remember the exissting modules using a 0.0 - 1.0 logic output
range … ah, the MultiCompare module on it's individual outputs (but not on
it's bus outputs), and that seems to be the only one sofar.
-
2020-11-27 : Sped up the filter for the MidiClockIn module by a factor of hundred
or so, making rhe module perform a factor of around sixty better.
-
2020-11-30 : Fixed a bug on all the filterbank based modules. When the ModeLow (or
ModeHigh) mode would be changed from lowpass to bandpass (or from highpass to
bandpass) (or the other way around) the filter would not get re-initialized
properly and would sound wrong. A workaroud was to change some other parameter
(like the filter frequency) to get it working properly again, this is no longer
needed.
-
2020-12-02 : Added an inverted output to the scale quantizer module, it calculates
the inverted note as ( 19 - Note - ReferenceNote) mod 12. Not sure if this is the
right thing for general negative harmony, but for the scale of C major it seems to
be okay.
-
2020-12-20 : Added a MonoPoly module, it can switch a signal from mono to poly
mode under control of it's poly input.
-
2020-12-21 : Added a MonoPolyMulti module, it can switch a set of signals from
mono to poly mode under control of it's poly input.
-
2020-12-23 : Added a 'dead zone' control to the RandSigs module. When the absolute
value of the calculated output value would be below the 'dead zone' value the
actual output will be set to zero. The 'dead zone' can be set from zero to one,
and it can be modulated.
-
2020-12-24 : Changed sthe step count for the Chladni filter module's p paramaeter
from 257 to 4097 to get finer control over the value. Changed the module version
to 2 to be able to convert old patches to the new behaviour.
-
2020-12-24 : Added a Fact/Cent selector on the Chladni filter, in Fact(or) mode it
will behave as it always did (upping the frequency with a factor for the next
filter channel). In Cent mode it will set the amount of cents between the filter
channels.
-
2020-12-25 : Added a FifthBankModule, in addition to the Tritone and Third ones,
it implements perfect fifths from step to step (factor 1.5 (3:2)). Omitted the
frequency values under the sliders.
Removed frequency references for all filter bank modules, to make them one unit
(15 pixels) less high.
-
2020-12-30 : todo: add links to Wren videos.
-
2021-01-10 : Removed the shortcut indicator for the memu popup for displays, it
used to say ctrl+enter but the actual shortcuts are either enter (after it got
activated by clicking on it) or ctrl+left_mouse_button. I've fixed the popup menu
shortcut indicator to shpw enter instead of ctrl+enter.
-
2021-01-14 : Added assignable output type for the Logic Not module.
-
2021-01-14 : Added amplitide modulation to the Math Amplifier module.
in version 2020.10.17.0
-
2020-09-11 : Added cents modulation to a couple of oscillator modules (Osc,
MultiOsc and MultiPhaseOsc), maybe nice to add a little drift to them when used in
poly mode (with connecting an LFO in random walk mode or something).
-
2020-09-15 : I've added a new range for the Tapper, MidiClockIn and RateConverterr
modules, they are now able to control the new 1 minute delay time (DEL long 1:00,
for controlling that range on the DelayPoly module). This may break existing
patches in that the range after loading an old patch may not be what was set when
the patch was saved. So you'll want to check your settings for these three module
types.
-
2020-09-17 : Changed the BPM detection for the MidiClockIn module to react a bit
less nervously. This makes the output signals better suitable to control long
delay loops. BPM values are now updated only when a sync occurs. Also made the
indicated value for the BPM rate indicator to show the filtered value instead of
the raw detected value. It behaves reasonable now for a drum loop of over half a
minute, it was pretty glitchy for loops of such a length before.
-
2020-09-17 : Fixed a bug in the FreqCount module, the channel selection was not
working properly.
-
2020-09-17 : Added a new module type, a timer. This one just displays how long the
the run input has been active. The mode can be set such that on every time the run
input goes active timing will either continue from where it was (incr. mode) or it
will be be reset to zero (once mode). It will display the run time as
hours:minutes:seconds.milliseconds (and it will overflow and start at zero again
if a day boundary is past).
Added a couple of outputs to be able to do something with the measured time
interval. Output d for fraction of the day, h for fraction of hour, m for fraction
of minute and s for fraction of second, all make positive saw waves with a range
[0.0, 1.0].
-
2020-09-23 : Sped up the MovingAverage module, it was silly slow.
-
2020-09-24 : Added Q modulation to the TritoneBank and ThirdBank modules.
-
2020-09-27 : Added input type control to the StereoPan module, such that it works
the same way as the (mono) Pan module.
-
2020-09-30 : Added a counter display to the Divider module, to be able to see the
current internal state of it. For slowly counting counters this is handy to get an
idea about how long it will take before the output flips. In my current patch this
will be hours … right 256 * 256 * 7 minutes, and although the triggering
input is random, it is good to know about … ow … that's a bit over
318 days, damn, better shorten things a bit!
-
2020-10-04 : I've change the way poly to mono signal conversion is treated. It
used to calculate the sum and then divide by the polyphony. but this made patches
to be too soft often. So I decided to divide by the square root of the polyphony
instead. This will make the sum of signal paths having identical signals too loud,
but also it will make that sum less too soft in cas the signals are uncorrelated.
I might end up eventually by not dividing at all … even … you just
can not do this right …
Ok, bad idea as it gives issues with feedback loops, undid it, attenuation is back
to what it was, and it will still be needed to have some end stage amplification
(or compression) on polyphonic patches to get the levels right.
-
2020-10-04 : I've made a MonoOverride option for modules to allow modules in a
polyphonic patch to be forced to execute in mono mode. This will cause the module
to listen to channel 1 only and also it will output on channel 1 only (but maybe
the latter will be changed such that it will output on all channels … not
sure here). the override to mono can be set from the module popup menu, monofied
modules will show with a distinctive (currently white) border.
Okay, changed it so that the ouput will be sent to all channels and not just to
the first one.
Also added a distinctive (currently yellow) border for modules that are
intrinsically monophonic. These can still be set to mono mode BTW, in which case
their will change in that they do not process an input sum over all polyphony
channels, but instead will just use channel 1 on it's own (and their border will
go (currently) white in that case.
Updated the patch layout version to 12 for this while maintainng backwards
compatibility.
-
2020-10-05 : Added a light cross hatch on mono modules to better indicate their
status, and removed the border while keeping the colors yellow and white …
see image above … hmm, the color mixing for 'lighting up' the hatch could
be improved upon, for now I've just changed yellow to lime green.
That didn't work too well either for me, sooooo, instead I made both white but did
a cross hatch for intrinsically mono and a diagonal cross hatch for overriden to
mono modules. So, for isnstance, in the image above the Compressor is
intrinsically mono, and the Limiter, Volume and AudioOut modules are explicitly
monofied, and the two mixers are 'regular polyphonic' modules.
I guess, as it makes no sense for Limiter, Volume and AudioOut to be poly afrter
an intrinsically mono module (the Compressor), this could be automated. That will
be for a later date tho, if at all.
Not always it will be the case that an intrinsically monophonic module will be
followed by mono paths only. For instance the regular Delay, or the Reverb module
have modulation inputs which can result in polyphonic output behaviour … so
automation will need some thought.
Overall, I do like these changes. It used to be that some extra patching was
needed to make parts of the patch mono (by using PolySelect modules here and
there) which can now be done by monofication of modules. This both saves some
cycles and I just don't want all parts of the patch to be poly all the time.
When another voice than voice 1 is wanted for a mono section one could still
insert a PolyShift module before a monofied section.
Possible alternatives would have been to use the concept of 'poly cables' (as VCV
uses them) or to use abstractions set to a different polyphony than the main patch
(as an extension to the 'effects area' idea as used in the NM G2). But I guess I'll
just keep what I currently have.
-
2020-10-06 : Made the visual feedback on mono modules depend on the selected
polyphony, it will not be shown for patches with polyphony set to 1. Also made it
optional in the Settings Screen F3 to be turned off completely.
-
2020-10-06 : Another way to look at it it is that an intrinsical mono module is
a summing module, in that it sums it's mono input signals over all poly
channels (but this may not be true for all of it's inputs, for instance
the standard delay modules will sum the incoming audio, but each voice will still
have it's own uniquely modulatable tap). Whereas a monofied module is a
selecting module, it only processes signals from the first poly channel
(and that holds for all of it's inputs).
So a summing (intrinsically) mono module may still have a polyphonic output,
depending on the control signals being polyphonic or not. A monofied module will
always have a monofied output as it will only look at signals in the first poly
channel (but it will still output into (but identical for) all poly channels of a
receiving module).
-
2020-10-07 : Fixed a bug in the MovingAverage module where filter size changes
would make it behave badly (had to clear the filter state). And also the
old–data pointer was one off, resulting in incorrect filtering and
integrating behaviour. This bug was introduced by the speedup implemented before.
-
2020-10-12 : Built a simple limiter into the Compressor module (as I always ended
up adding one manually), it acts in the same way as the Limiter module, so it is
not parameterized, but it can be turned on or off. Limiting, when active, acts
upon the Side, L and R outputs (after compression and not in bypass mode, bypass
mode always couples the inputs to the outputs directly).
-
2020-10-14 : For some reason in the Settings Screen F3 the sample rate selector
got mislabeled as 'midi delay', fixed this.
-
2020-10-14 : Added a sample and hold input to the RandSigs module. When it is not
connected it does nothing, when it is connected a low to high logic transition on
it will copy the internal output state to the actual outputs, and otherwise it
will hold the latest output value. This can be used to sync the change of the
random values to some external event. When not connected the module behaves like
it always did with continues output changes. [UNTESTED as of yet].
-
2020-10-17 : Added manual BPM control to the MidiClickIn module. This serves two
purposes, being a) to be able to set a BPM value manually in case a MIDI clock is
not available and b) to remember the latest BPM value in a saved patch, such that
when on patch load a MIDI clock is not availble the module will use the BPM value
the patch was saved with.
When an incoming MIDI clock is being detected this will override the manual
setting. Currently for some reason when the external MIDI clock is active hovering
the mouse over the manual control will act a bit weird, but so be it for now
… ok, fixed that too.
Manual BPM settings can not be fractional, detected BPM rates howver generally
will be. A BPM rate saved with a patch will be rounded to the nearest possible
manual rate.
-
2020-10-17 : I've removed all the 'smart' latency control stuff from the MIDI note
in modules, it was not working properly. The only way to get it working okay is to
have low enough audio latency (small enough audio buffers), all the fancying up is
just crap. So anyway, a note is turned on and off like as quickly as possible now.
in version 2020.9.9.0
-
2020-07-27 : Changed the internal representation of MIDI time to fractional
seconds (instead of milli seconds) to have it the same as the synth timing.
(Preparing for full MIDI event enqueuement, to be able to get the note-on and CC
timing solid too, might also help to get clock sync better …).
After some experimention I ended up not using an RX queue for now, to make it work
properly it would be needed to also implement extra audio latency. The queue would
be used to eliminate jitter on received MIDI, but when it is at the cost of added
latency it is maybe better to accept some jitter and instead minimize that by
selecting short audio queues (an audio queue of 512 frames at 48ks/s makes for a
jitter of around 11 ms).
-
2020-07-30 : The MIDI optimizations broke the handling of RPN data, as this was
done by the MidiReceiver object (of class TMidiReceiver) which is no longer used.
RpnMode is obeyed by the TX modules only now. Also MIDI RX logging is broken now,
TX logging should still work.
-
2020-07-30 : Started preparing for polyphony, upped the patch version to 11 and
made the underlying system ready for propagating value sets over wires (instead of
single values). The patch editor has a polyphony count, and so does the synhesizer
module, now all the modules will need some work … and there will have to be
some polyphony specific modules too.
-
2020-08-03 : Made a good lot of the modules poly aware, skipping the hard ones a
bit though. Now optimizing things a bit as the performance in mono mode is a bit
disappointing sofar. Not unhappy though about the poly performance, going from
mono to duophony does not double the CPU load, it just increases a bit. Well a bit
more than a bit actually, but nothing like doubling.
Implemented a couple of poly specific modules: PolySplit, PolyMerge, PolySum,
PolySelect, PolyShift and PolyStatus – all doing some voice magic. The
splitter takes off the voices from the poly bus routing them to individual outs,
the merger does the reverse thing, bundling up individual inputs into voices. The
PolySelect can select a voice from a bundle and output that on it's output. The
PolyShift shifts voice positions in the bundle, voice one can be routed to voice
two, and then two will go to three, and in a cyclic manner the highest voice
number present is routed to voice one then, the amount of shift steps can be set
with a knob. The PolyStatus just outputs the voice number on it's output, scaled
from zero to one over the current polyphony, this can be used, for instance, to
control a multiplexer which will then do some voice specific selection. Or control
the wave shape of a shape modulatable oscillator, so voice one can be a sine,
voice two a triangle, etc.
But it is still a bit crashy at times, and for mono mode the overhead is quite
large. The crashyness is related to the recorder module maybe, didn't really check
it out, but didn's see it as of yet in patches not having a recorder module in it.
Also didn't figure out the 'level issue' yet, a duophonic patch potentially is
twice as loud an the mono version of it, but when the voices are independent it
will, or can, be at almost the same level. Will probaly be left as an excercise
for the user … to get the levels right, or maybe some square root based
compensation magic on the final mix, or in all places where a voice mix is being
made (like in reverb modules, but that's all a bit arbitrary still).
I've hard limited the maximum voice count to 16.
-
2020-08-04 : Some notes about the implementation of polyphony. Most modules are
completely polyphonic, some are monphonic and some are mixed mode modules.
Fully polyphonic modules are either stateless (that is no memory of a previous
sample set is being kept) or they have a separate internal state per voice. An
example of a stateless module is a mixer, mixers can be computed on a sample by
sample base, they implement just a couple of multiplications and additions. A
filter would be an example of a module having state, as the computation of the
current sample depends on what samples it saw before. A fully polyphonic filter
will keep that information on a per voice base, each voice has it's own memory.
Monophonic modules are pretty simple too, if they have state it will be shared
over all voices. An example of this is the Vocoder module. Monpphonic modules
generally will, on their inputs, sum the incoming voices, then they proces that
sum as a single signal. Then the results will be distributed over all output
voices equally. For clock inputs, for instance, this scheme makes no sense though,
in such cases only the input from the first voice will be processed, the output
will still be distributed over all voices. Note that polyphonic clocked modules,
in contrast, treat the clock separately for each voice, so they will alwyas
listen to all voices. Some examples of mono modules are the reverbs, not only
would it be expensive, CPU wise, to make them fully polyphonic, it does not seem
to make much sense either to have polyphonic reverb. Some more effects will be
kept monophonic, like the compressor, where others, like pitch shifters, would be
nice in poly mode.
Then the mixed mode ones, these will have some shared state over the voices. For
example the delay based modules may have a monophonic input, that is they listen
to the sum of all voices. They wil then store that sum in a shared delay line, but
the outputs can be polyphonic. each voice can have it's own delay modulation.
Especially for the very long delays (like five minutes) it would be costly to have
a delay line for each voice. I am considering some new fully polyphonic delays,
but they will have short–ish delay lines, a couple of seconds, then, not
minutes.
At times I have been too lazy to figure out the per voice state for modules, such
modules may become polyphonic at some later stage. The MIDI modules for instance
need work, their current implementation makes sense in a mono world only.
I will label mixed mode modules as being polyphonic, for instance the Input module
is labeled as poly, but there is no such thing as polyphonic input from a sound
card. There are channels though, and those can be routed to separate voices if
needed (by using some PolyMerge modules). The output module is mixed mode too, it
will sum it's input voices before sending them to the sound card. The Recorder
module behaves just like the Output module. The delay modules are labeled as poly
as well, as explained in the mixed mode section above.
All the 'simple' modules have been decided and implemented now as either poly or
mono. There are still about 100 module types (of roughly 300) I still need to pay
attention to. Not only for the mono/poly issue, but poly modules need things to be
reorganized a bit as well for optimization reasons, and I started with a non
optimized rough version.
Still, as long as I do not have a recorder module in the patch things seem stable
sofar. Also patches with polyphony set to one need a bit more CPU time than in the
monophonic program versions before, but I am pretty happy with the poly
performance sofar.
As there is more computation involved per module in poly mode, it may be needed to
accept more audio latency, but will have to optimize better to be sure.
Anyways, a couple of days more work will go into it easily.
-
2020-08-07 : About 40 module type more polyphonized, still 60 or so undecided
ones. Some are a real bitch to have them un-monoed … especially the filter
banks took me lot of hours, but all filters are fully polyphonic now, including
the voice like vowel filters. Next thing probably should be to change the MIDI
modules, or come up with some new ones maybe, poly specific ones.
-
2020-08-07 : I seem to have fixed the recorder bug, it probably was a bit crashy
in the Wren release version too.
-
2020-08-07 : Decided to add a polyphonic MIDI note in module and leave the old
MIDI note in modules as as is (for compatibility with previous mono patches). The
new module will set the 'max notes' value (as the Midi8NoteIn module has it) to be
equal to the selected patch polyphony. Otherwise it should work exactly the same
as the Midi8NoteIn module. With this module a patch can be made as if it were
mono, and by upping the polyphony it will give more voices. For mono patches this
may need a bit more CPU than in previous Wren versions, but with upped
polyphony it will pay off.
-
2020-08-07 : Polyfied MidiClockIn, Tapper and RateConverter modules. So there now
is fully modulatable polyphonic MIDI and Tapper sync. Still 55 module types to
consider, some will stay mono.
-
2020-08-08 : I guess Wren now is a polyphonic multitimbral
inter-voice cross-modulating virtual analog modular synthesizer … or
something.
-
2020-08-08 : All modules have had a look at, the following ones were kept
monophonic for various reasons :
AMuse, CellAut, CellAut2, ClockGen, ClockedDelay, ClockedSieve, Compressor,
Convoder, Economy, eSpeakVoice, FlangeChorus, GVerb, GenePlayer, GrainDelay,
Granulator, LifeSeq, Markov, Midi8NoteIn, MidiCCIn, MidiMultiNoteIn, MidiNoteIn,
MidiPCOut MidiPNOut, MidiPlayer, MidiSysexOut, PitchChange, Reverb, RndGranulator,
SeqPattern, SeqValues, Sieve, SimpleGranulator, SmallLifeSeq, Smear, Song,
SwanSong, Talkie, TextWriter, VitaPHoBium, and Vocoder.
Most mono modules will listen on the first voice only and will output equally over
all voices. Some modules however will mix the incoming voices before processing,
especially so for the FX modules. This may still need some fine‐tuning.
-
2020-08-08 : So now the question is … is it any good … am I going to
keep this?
Anyway, doing some test runs now on mostl large old patches, finding some bugs
here and there, and fixing those, but most stuff seems to still be runnable on a
poly setting of 1, will test some more …
-
2020-08-08 : I've changed the divtrig parmameter for the Seq16 and the Seq16Rep
modules to have a maximum of 1024 instead of 255, this will cause some patch
incompatibilities with previous versions (where the divtrig output was used).
-
2020-09-02 : Added a new DelayPoly module which is fully polyphonic but it does
not support delay times up to five minutes, only the short and medium ranges. So
the time can be set from 100µs to 3s.
Extended the maximum delay time to be 1 minute with a new long3 range, as I had
some patches with delays in that range and wanted those delays to be polyphonic
too. The rationale for not supporting 5 minutes is that such can eat up a lot of
memory in poly mode (as the maximum length for the range will be allocated to
allow for modulation over the full range).
-
2020-09-03 : Added a multi channel polyphonic voice slector, and also fixed a bug
in the single channel version of it (the PolySelect module, just actually used
the module for the first time – it had some shortcomings).
-
2020-09-03 : I've upped the process priority for Wren to
ABOVE_NORMAL_PRIORITY_CLASS, or at least made code to do so, a warning will be
issued in the logs when setting the priority failed. The (relative) thread
priority for the audio thread was alread set to THREAD_PRIORITY_TIME_CRITICAL,
PortAudio apparently does that. Anyway, it's meant to to have it run a bit more
smoothly, seems to be a marginal improvement at best.
in version 2020.7.27.0
-
2020-07-27 : Fixes for MIDI modules. MIDI was not really dropping notes, but
note-offs could follow immediately after note-ons, so a trigger out did not get
generated. Changed the timing, such that the actual note duration is being tracked
now. Another issue was that the MIDI modules were not fast enough, so changed
their processing to be at audio rates. The third issue was that the low level MIDI
code was posting messages to the GUI thread to signal incoming data. This was
changed to let the MIDI driver inject MIDI messages directly into audio thread.
This also greatly reduced the sensitivity to GUI events happening.
Ran some tests on this and on my laptop with an ASIO buffer size of 256 the MIDI
modules can now handle 1/16 notes at rates of 240 BPM. Audio buffer size matters
still for MIDI timing accuracy, as a note-on event is not synced with the audio
thread, only the duration is being calculated in samples now – so there
still is note onset jitter, but that's a couple of milli seconds at most with the
settings mentioned before.
in version 2020.7.23.0
-
2020-07-23 : Some issues still with ins and params being mislabeled in places.
Fixed the diagnostics for it and fixed the issues with it.
-
2020-07-23 : Midi is supposed to be dropping notes. I've changed the handling for
note-on and -off messages a bit. Also removed the direct control of the mide rx
LED, just setting a flag for it and let the GUI task pick that up and turn the LED
on. Also removed some memory allocation operations from the MIDI thread by setting
a fixed size buffer. which gets then direcrly passed to the synth. The still is a
small issue with this as the synth processes the MIDI in the audio thread, which
works block wise, meaning that only avery buffer-size-samples the MIDI get to
actually be processed. This is jittery with a frame size of 2048 samples, with 256
it is better. Not quite seeing how I could decouple this though.
in version 2020.7.20.0
-
2020-07-20 : Made some unit testing code for param and in/out pin validation,
found several hundreds of issues and amongst those were hidden a handful of bugs
which may have resulted in the program to crash under certain conditions.
I've fixed the bugs, the other issues were all due to irrelevant typos, lazy
module naming, strange param names for multi valued controls (xypad and spiral),
something with internal values being stored as parameters and how module
inheritancce is being used. Anyways, all such issues were manually checked to be
ok, and code was written to not show those anymore when the test is being run.
in version 2020.7.18.0
-
2020-06-25 : Added some x64 specific optimizations; Turned on DAZ and FTZ flags to
treat all denormals as zero and reduced the denormal correction functions to be
Nops. Furthermore the check for denormals functionality built into the program
will never see any for the 64 bit version. This seems to approximately give an
extra 20% speed gain (as in 36% -> 30%) for the x64 version.
-
2020-06-28 : I've made audio caching, such that a used audio file in wave player
like modules will be loaded into memory only once. When the same audio is being
used in another wave player like module the data will be shared. When the data is
no longer used in the patch it will be deleted.
This speeds up patching too when long waves are being used (as on a structural
patch change (wires / modules / added / removed) all resources would be created
anew, so audio would have to be reread from memory. In the current situation such
data will be kept till after recompilation completed and only then, when the data
turns out to be no longer needed, it will be released).
-
2020-06-28 : Moved the 06-25 optimizations to a wider scope, it encompasses all
real-time audio processing now (inccluding the bits for the level meters). It is
not however used for offline audio processing, i.e. recording – planning to
substantially change the recording mechanism anyway … but for now recording
may still give exceptions on subnormals, infinities and NaNs.
Note: As of 2020-07-02 the old non-real-time recording mechanism was removed, this
leaves the debug wave plotting as the one non-real-time mode left, and as I'll
probably keep that for a while it should be 64 bit optimized too (as is it can
generate invalid floating point results or exceptions now).
Note as of 2020-07-03 the above got fixed. Graphing is sillily slow though.
-
2020-07-01 : Made a recorder module. I'ts tape length can be set from 1 to 30
minutes in one minute increments. When the tape is full it will loop, recording
over the oldest material. There is a clear button to erase the tape and a write
button to write out the tape to a disk file (a WAV file). The number of tape
tracks can be set from 1 to 8 (WAV files can have up to 65536 channels). Recording
can be start or stopped with the 'active' control. A file to write to must be
selected before starting a writeout, or nothing will happen.
The record output goes active when recording is stoped, connecting it to the clear
and write inputs will cause the wave to be written to disk and to then be cleared.
The full output goes active when the loop is 100% full, connected to the clear and
write outputs will cause a recording to be saved each time the loop gets full.
The eight audio outputs will output the input signal with a delay time set by the
delay controls and the delay modulation input, as if it were a tape montoring
signal.
So … basically it is some sort of a primitive 8 track recorder with a
looped tape.
Made it use date and time prepended to the filename on save, such that when auto
save is patched in a new file will be generated without overwriting old ones every
time the tape gets full. Auto naming is optional trough the timestamped / normal
selector, but it's on by default.
Made auto normalization to be a user option as well, as when multiple takes are
made automatic volume normalization would possibly lead to level inconsitencies
between the various tracks. With normalization off they should be gluable in a
wave editor.
Changed the delay setup a bit. There now is a pre delay which can be set all the
way from zero to 30 minutes and then there is delay modulation added to that. The
modulation can be set from 100µs to 30ms for its maximum length and it can
be modulated in a range -1 to 1 times the set value.
Note: recording 30 minutes with 8 channels @ 96 kbps will fail as the maximum RIFF
chunk size of 4 GiB would be exceeded. Some limits will have to be put in to make
sure that a valid wave will always be written. And then again. maybe a limit of 2
GiB should be used to avoid problems with software implementing the size fields as
signed 32 bit numbers.
@ 2010-07-02: Ok .. sorted it out, the following time limits will be enforced, and
this will work for both the 32 and the 64 bit versions … hmm, not so for
the 32 bit version as the total program memory allocation should stay under 2 GiB
… so it's impossible to tell upfront … hmm hmm. Ok, the x32 numbers
are based on an empty patch, so it will be always less than or equal to the
indicated duration. Added an indicator to the module telling the true available
time, or in case of an an error some error message.
sample rate | channel count | max duration x64 | max duration x32 |
44k1 | 1 | 30:00 | <= 30:00 |
| 2 | 30:00 | <= 30:00 |
| 3 | 30:00 | <= 20:00 |
| 4 | 30:00 | <= 15:00 |
| 5 | 30:00 | <= 12:00 |
| 6 | 30:00 | <= 10:00 |
| 7 | 27:59 | <= 08:00 |
| 8 | 24:35 | <= 07:00 |
sample rate | channel count | max duration x64 | max duration x32 |
48k | 1 | 30:00 | <= 30:00 |
| 2 | 30:00 | <= 24:00 |
| 3 | 30:00 | <= 16:00 |
| 4 | 30:00 | <= 12:00 |
| 5 | 30:00 | <= 10:00 |
| 6 | 30:00 | <= 08:00 |
| 7 | 25:42 | <= 07:00 |
| 8 | 22:35 | <= 06:00 |
sample rate | channel count | max duration x64 | max duration x32 |
88k2 | 1 | 30:00 | <= 30:00 |
| 2 | 30:00 | <= 15:00 |
| 3 | 30:00 | <= 10:00 |
| 4 | 23:52 | <= 07:00 |
| 5 | 19:19 | <= 06:00 |
| 6 | 16:13 | <= 05:00 |
| 7 | 13:59 | <= 04:00 |
| 8 | 12:17 | <= 03:00 |
sample rate | channel count | max duration x64 | max duration x32 |
96k | 1 | 30:00 | <= 28:00 |
| 2 | 30:00 | <= 14:00 |
| 3 | 30:00 | <= 09:00 |
| 4 | 21:55 | <= 07:00 |
| 5 | 17:45 | <= 05:00 |
| 6 | 14:54 | <= 04:00 |
| 7 | 12:51 | <= 04:00 |
| 8 | 11:17 | <= 03:00 |
@ 2010-07-02: Added a feature, when %patchname% is used in the file name to save
under the string %patchname% will be replaced by the name of the patch. So when
the patch is called 'silly-putty' and the file name was selected to be
'C:\MyRecordings\cc_%patchname%.wav' the wave data will be written to the file
'C:\MyRecordings\cc_silly-putty.wav'.
-
2020-07-01 : Fixed a bug for the DelayMod and DelayMix modules, the range
selections were not working.
-
2020-07-02 : I've removed the non real-time recording mode, the new recorder
module is to be used instead. The non-real-time mode would stop audio generation
and it would record the first two channels only. The new module can record from
one to eight channels and real-time audio will keep running while recording.
-
2020-07-03 : Fixed a bug for the recorder module where it would occasionally
access undefined memory on changing channel count or duration.
-
2020-07-04 : Added volume control to the WavePlayer and the LoopPlayer modules.
-
2020-07-04 : Added amplitude modulation (am) inputs to all of the LFOs, except for
the Tod and ClockGen modules.
-
2020-07-05 : Added amplitude modulation (am) inputs to all of the audio rate
oscillators that did not have it yet, except for the DTMF and the Phasor modules.
-
2020-07-06 : To get better control over the modulation range for the BPM related
modules (MidiClockIn, RateConverter and Tapper) I've added pivot controls to them,
they set the 'center' of the modulation.
-
2020-07-06 : Fixed a bug in the patch writer to make it write out the allowance
for randomization of the DataMaker component. This implements, a.o. the graph in
the AudioGraph module, for which the randomiztion allowance was not saved. The
patch reader did handle the situation correctly already. The patch version was not
changed for this. As a side effct the randomization allowance for some other
components gets written out too now, but always with a value of 0 (zero, do not
allow).
-
2020-07-06 : Made a folder selection dialog for all the various file types that
can be used in for different purposes in a patch. So can have all files neatly
stuffed away in separate folders now. See the image below. It is a bit fascistoid
this, I'd agree on that … the former freedom drove me mad and I'm making
chocolate orange cocos icecream right now.
-
2020-07-07 : Made a stereo narrower module, it sums he left and right signals and
then mixes those with that sum in a controllable way, that way fading from stereo
to mono. This can also be used to zoom in on phase issues where in the mono signal
left and right would cancel each other when in anti phase. The module is rate
smart and will work full rate when audio rate signals get connected to it.
-
2020-07-07 : Fixed some more issues on the AudioGraph module, it was not allowing
randomization by default and the auto-scale feature could not be turned off. It
now behaves as intended.
-
2020-07-07 : Moved all MIDI configuration items to the 'MIDI devices' dialog,
which I then renamed into 'MIDI setup'. Also changed how these settings are
written into and read from the ini file, you probably will need to reconfigure
your MIDI settings.
-
2020-07-07 : Moved all OSC configuration items to a new 'OSC setup' dialog. Also
changed how these settings are written into and read from the ini file, you
probably will need to reconfigure your OSC settings (I've added a help button in
the OSC setup).
-
2020-07-07 : Reconfigured the Settings Screen F3 a bit to fill out the holes
…
-
2020-07-08 : Started splitting off parameters from inputs; up to now all knobs and
things were treated just like inputs were (except no wires could be connected to
it … although I have considered to allow for this at times), when done with
this knobs and such will be params and only the true inputs will be inputs.
Probably a couple of days work …. Started left with the i/o modules and
sofar did 97 of 325 modules - at Modal2 now, more tomorrow.
-
2020-07-09 : Going on with splitting, 99 done now and moving to the Mix tab. And
the mix tab is done, 117 of 325. Switches were easy, 127 now, 137 after ctrl1.
And after ctrl2 22 more, makes 139, still not halfway trough, let's first do some
error checking now. 10 typo's fixed, and 16 more modules done, 155 now, on to the
next tab: math. But dinner first and cherries and icecream!
Things expanded a little, just passed the 300,000 lines mark again, 2 over it
now. +21 for the math modules, makes 176 – more than half done (:-)
Then 24 more for the logic tab making 200. And that was another 15 from seq1
making 215, the sequencers need a lot of attention, on to the seq2 page …
tomorrow (:-)
-
2020-07-10 : Going on with splitting, 226 done now and moving to the Gen tab. Plus
19 to 245, on to FX tab, 80 to go. 18 more to make 263, on to the Delay tab. And
another 14 @ 277 now, next tab is Voice – dinner stuff first though. pwew
… done, now check stuff and test stuff (:-)
Checked all kinds of stuff … like not mixing up i_xxx and p_xxx thingies in
the Params[ p_xxx], AddParam( p_xxx), Inputs[ i_xxx] and AddInput( i_xxx), and
also i_xxx and p_xxx ranges MUST start at 0 and there MUST not be gaps or things
will crash later on …
I've been thinking about how to enforce this making use of strong typing, but
could not think up a way that would not be clumsy (i.e. using type ins = (
i_xxx, i_yyy …); and then must have {$SCOPEDENUMS ON}, and then
use Inputs[ Ord( ins.i_xxx)] everywhere) or use variables instead of
constants (like var i_xxx; … i_xxxx := AddInput( 'xxx');) which
would make things slower by adding an indirection level.
Also one would like to do type TInputId = type Integer; TInput = record id:
TInputId; name: string; end; TInputs = array of TInput maybe. But that would
need some typecasting in places, like where the Id's go into set of's.
Generics could help there I guess, but still the demand for consecutive numbers
starting at 0 would be ugly then.
So, let's just run it again (:-)
At least there is basic functionality, an older somewhat more complicated patch
seems to run okay. Not bad for after turning it inside out completely.
Release compile works, with about the same load as before the operation. Had it
expected it to be somewhat faster, oh well, it is the separation that it was done
for, would have accepted somewhat slower as well.
Anyways .. time for backups and such.
-
2020-07-11 : Hmm, it seems to have fukt the 32 bit version somehow. Okay that was
unrelated. Something something floating point exception masks mumble mumble. Those
always are an interesting subject in the summer course 'how to crash your computer
and have no idea why', anyways do NOT put garbage into your flotaing point
exception masks.
The 32 bit version is fine too now.
-
2020-07-11 : Exploring the generics idea mentioned a couple of sections back:
const
NO_PARM = 'noparam';
NO_INPUT = 'noinput';
NO_OUTPUT = 'nooutput';
NO_ID = -1;
type
TParamId = type UInt16;
TInputId = type UInt16;
TOutputId = type UInt16;
TIdNameMap<T> = record
ID : T;
Name : string;
end;
TIdNameMaps<T> = array of TIdNameMap<T>;
and then later on:
TMod = class
// Synth module prototype
...
...
FParamMaps : TIdNameMaps<TParamId >; // Maps param names to Id's
FInputMaps : TIdNameMaps<TInputId >; // Maps input pin names to Id's
FOutputMaps : TIdNameMaps<TOutputId>; // Maps output pin names to Id's
...
...
being used as:
function GetParamCount : Integer;
function FindParamID ( anID: TParamId ): Integer;
function FindParamName ( anID: TParamId ): string;
procedure AddParam ( anID: TParamId ; const aName: string);
function GetInputCount : Integer;
function FindInputID ( anID: TInputId ): Integer;
... etc
being implemented as:
function TMod.GetParamCount: Integer;
begin
Result := Length( FParamMaps);
end;
function TMod.FindParamID( anID: TParamId): Integer;
var
i : Integer;
begin
Result := NO_ID;
for i := 0 to ParamCount - 1
do begin
if FParamMaps[ i].ID = anID
then begin
Result := i;
Break;
end;
end;
end;
function TMod.FindParamName( anID: TParamId): string;
var
p : Integer;
begin
p := FindParamID( anId);
if p <> NO_ID
then Result := FParamMaps[ p].Name
else Result := NO_PARAM;
end;
procedure TMod.AddParam( anID: TParamId; const aName: string);
var
p : Integer;
N : string;
begin
N := Trim( aName);
p := FindParamID( anID);
if p <> NO_ID
then FParamMaps[ p].Name := N
else begin
SetLength( FParamMaps, ParamCount + 1);
FParamMaps[ ParamCount - 1].ID := anID;
FParamMaps[ ParamCount - 1].Name := N;
end;
end;
... etc
Anyways, this all will still accept plain non negative integer constans, so it
offers no protection at all. I must have misunderstood the:
type typename = type something;
construct, I'll keep it in tho for clarity towards the casual code reader.
-
2020-07-11 : Added reset inputs to the Looper and StereoLoopr modules. When they
trigger the loop pointer is set back to the start position.
-
2020-07-11 : The folder selection does not seem to work as intended yet.
-
2020-07-11 : Custom wire colors can change when the custom color is one of the
standard colors and the rate smart module performs a rate change. Fixed this with
a kludge by not allowing the user to set those exact colors, except when a choice
is made for the default color, Hmm .. no good, will need a better fix. like
explicitly setting a custom color.
That was way more non-trivial than it should have been, but seems fixed now.
-
2020-07-11 : Fixed the issue where a sped up module would not de-speep when the
fast connection was removed. needed a complete clearance of all sped up stuff
followed by a repeated fixup until no more work is done. It's a bit ugly, but it
works, and things really need to ripple trough all the modules and wires, nothing
much can be done about that. Turns out this was related to the wire coloring
issue.
-
2020-07-12 : Added a stereo panner module, will need to change the control curve a
bit, panned left or right the levels are too high. With some bounces instead of
clips it works nicer, makes the code look symmetric too.
Control :=
1.0
+ Clip(
FParams[ p_position ]
+ FParams[ p_posmodamt]
* FInputs[ i_control ],
-1.0,
1.0
);
In1 := FInputs[ i_in1];
In2 := FInputs[ i_in2];
Sum := In1 + In2;
A1 := Bounce( Control, False);
A2 := Clip ( 1.0 - Control, 0.0, 1.0);
A3 := Clip ( Control - 1.0, 0.0, 1.0);
A4 := Bounce( Control , False);
FOutputs[ o_out1] := A1 * In1 + A2 * Sum;
FOutputs[ o_out2] := A3 * Sum + A4 * In2;
-
2020-07-12 : Changed the layout of the MixAudio module to make it more clear what
belongs to what channel, this must be about the first time that a module got
larger without extra controls being added (:-)
-
2020-07-12 : An issue was reported where "at the top left of the edit screen the
individual module types are sometimes grayed-out, they do get their color back
when I run the cursor over them". Probably the module selector, the only things
there having color are the tabs … well some module glyphs have a tad of
color … so probably the tabs loosing color?
Maybe this is related to another thing, where sometimes no tab at all will be
selected in which case no module glyphs are being shown.
Seems not related, when the program starts in full screen mode the tab colors are
not set up yet when the program needs them. This is reproducable, good (:-)
@2020-07-12 : And it was fixable too, but definitely not related to the 'no tab
selected' issue, still investigating that one (it's badly reproducible).
-
2020-07-13 : Added an option to the audio device selector window to select
<nothing> for the input- or output-device (or both, but PortAudio will
complain on that, thus without any devices selected it will also be impossible now
to record, but otherwise nothing too useful in selecting nothing at all). When
<nothing> is being selected for inputs no inputs will be opened by
PortAudio, likewise for outputs. An input only setting could still be used to
record audio.
On first load with this new feature the audio devices will have to be reselected,
but it will be remembered ok once that is done.
-
2020-07-14 : Made the title fields on the pannel1, 2, 3, 4 and 5 modules larger,
so they can double as patch comments, sort of.
-
2020-07-14 : Added multiplier inputs to the Constant and MConst modules. They
operate on the constant value only, not on the add input. This way they can act as
a 'constant', or or as an 'add constant' or 'multiply by constant', or as your
'multiply and add' operator for simple FIR filters. Or as a single input chainable
mixer.
-
2020-07-15 : Fixed the 'no tab' issue mentiond on 2020-07-12 too, thanks Airlock
for pointing out that shift+space would cause it to happen, that finally made it
reproducible, and thus fixable. The fix is not perfect, as there will be a repaint
glitch still, but it will do.
-
2020-07-15 : Hmm .. fukt up the main form, so had to go back into some ill defined
backup, there might be some regression isues … yuck … and the Delphi
saved backups were no good at all, some very old stuff was there and some already
fukt pretty recent stuff … so had to use human memory here … what a
fokking mess.
Had deleted most of the setup stuff from FormMain by accident and no Ctrl+Z was
available for some reason, then did a manual save of the unsaved files, but fukt
that myself (restoring the pas instead of the dfm and then doing a save), and then
there were no usable Dephi backups, and I didn't do a git commit either for a
while … pomtidom dom dom oliekoken dom.
Ok, the no tab issue was refixed, and the no colors issue as well. Multiplier
inputs were not affected, neither were title field changes on panels, the
<nothing> things should be fine, new modules should be fine, custom wire
colors, I'll need ro check those, but prolly ok … folder selection needs a
check too, Reset inputs on modules should be ok, floating point issues were
redone, the splitting stuf was not affected, the MIDI and OSC config changes look
okay, AudioGraph should not be affected, StereoNarrower should be fine, patch
writer bug should be fine, BPM stuff idem, am stuff as well, no worries about wave
player mods, or recorder bugs, real time recording is gone okay, DelayMod should
not be affected, recorder should be ok, the after 06-25 scope expansion should be
fine no (after fixing), audio caching and x64 specific optimizations should be
fine too – hmm, they were not, but fixed it.
So. will need to check on custom wire colors, ok that got fukt too and needs be
redone, ok, did that but needs a check, seems fine now.
-
2020-07-15 : Made the Recorder module more simple, and made a new TapeRecorder
module having the old Recorder functionaliry, and as the TapeRecorder is more like
a delay module put it on the Delay tab.
-
2020-07-16 : Made the recoreder record in 32 bit float format, so when it is not
normalizing on disk write a heavily clipped recording can still be recovered by
normalizing it externally (checked that with Reaper, Acoustica and Audacity).
-
2020-07-16 : Added output type selectors for MConst, Monadic and Dyadic modules.
-
2020-07-17 : Added modulation inputs to the Reverb module.
-
2020-07-17 : (un-de-)Normalization was calcuated wrongly in the Reverb module,
resulting in math exceptions in the 32 bit version, fixed that.
-
2020-07-17 : LfoMultiPhase module makes nonsense wave forms. Ah, the warp
modulation (which it does not have implemented on the user interface) was set to
almost zero. Fixed it.
-
2020-07-17 : Added a frequency control parameter to the TritoneBank, ThirdBank,
TritoneSplitter, ThirdSplitter, TritoneCombiner and ThirdCombiner modules. Before
they only had FM inputs with an attenuator.
-
2020-07-18 : Changed the startup screen a bit to reflect the current version
better. In the Settings Screen F3, and in the title bar, when this is enabled,
some extra version info is being displayed as well now (to be able to see if it a
release, debug, 32 and / or 64 bit version, stuff like that. This has no effect on
the version checking option in the program, as just the basic version info (like
2020.6.24.0, for instance) is being used for that.
in version 2020.6.24.0
-
2020-05-30 : made double buffering for the XYScope module, it is still not fast
enough though.
-
2020-05-31 : Introduced module versioning, such that moddule autocorrection can be
applied when an older module version is loaded from a patch. Had to up the patch
version for this to 10. The modifications are backwards compatible in that
unversioned modules will be assigned version 1, which is the current version for
all modules.
-
2020-06-02 : Changed ModQuantizer to use HighLogic inputs insteadd of Logic
inputs.
-
2020-06-06 : Added more diagnostics to logfile for opening PortAudio as it
still was not clear from the current logs if the DLL was available and
where it was found. The code now does a walk over the entries found in the PATH
environment variable and it will print all found occurances of portaudio.dll.
-
2020-06-11 : Made some new code to be able to read more wave types, for now it
supports WAV, AIFF, AIFC and SF2 (sound font) files with arbitrary sample rates,
arbitrary channel counts, and sample depths of 8, 16, 24, 32 or 64 bits for
integer samples and sample depths of 32 or 64 bits for floating point samples.
Also it can support (multiple) looping regions now [with repeat counts], regions
and labels.
Wave compression is not being supported and sample rate conversion is currently
not being applied.
When present in the WAV file it can read an ACID section too, I've not seen such
information yet in AIFF or AIFC files, so no idea how to get that information
from those file types. Also loop info in those file types is incompletely written
by the wave file editors I've used so far. SF2 files seem to have such
information on a per sample base, still need to parse that out in some way though.
The MultiWave base class I've made has some flexibility in it for actual modules
to make use of such data.
Not sure yet as to how this will affect what modules and how, a work in progress
it is.
2020-06-12 : Made a display for it too .. it's a bit small all, but for simple
loops it would do I guess. To speed things up a bit I started using peak files as
otherwise painting the wave takes ages. It still does take ages, but just once so
now, after the wave was first used or after it got changed. Peak files are saved
into a sub folder (wren-peaks-23A396E5-4A4A-42FB-90B6-3FCA46862F3F) of the folder
where the wave or aiff was found, and it will have the same name as the wave it
was obtained from with an appended file extension of
.wren-peak-23A396E5-4A4A-42FB-90B6-3FCA46862F3F, .guessing those names will never
conflict with anything … When the folder can not be created or when it is
not writeable no peak file will be used and there will be no warnings, it will
just be slow.
The module shown is just a thest thingy for the new wave stuff, still not sure
what exactly to do with it all. something wih looping I guess …
Not sure yet how to deal with sf2 (sound font) files, for existing wave based
modules the contained samples are just being concatenated, but there is room for
better stuff I think … I can think up …
-
2020-06-07 : Just passed the 300,000 lines of code mark.
-
2020-06-15 : Changed the WavePlayer module to use the new wave file reading code.
This means that it will now read WAV, AIFF, AIFC and SF2 files (but it will just
concatenate all the samples from the sound font, and it will assume all the sample
rates to be the same, the rate of the first sample will be used; loop points are
being ignored) with arbitrary sample rates, arbitrary channel counts, and sample
depths of 8, 16, 24, 32 or 64 bits for integer samples and sample depths of 32 or
64 bits for floating point samples. Wave compression is not being supported.
Sample rate conversions are not being applied, however the playback speed will be
adjusted when the system sample rate changes.
This also means that the Mono / Stereo selection got lost; Mono files will now
output on both L and R outputs, and when the wave has more than one channel the
first channel will be played on the L output and the second one on the R output.
Any further channels will be ignored.
Furthermore waves will be amplitude normalized when read in, no DC offset
correction is applied on normalization. And sample memory size got limited to 128
MiSamples (which for a stereo file will result in 2 GiB of memory being used, all
wave data is being kept in memory as 64 bit floats).
Changed the WavePlayTrig and WavePlayTrig2 modules in the same way.
-
2020-06-15 : Removed the Wave Audio dependencies from the project (using the code
mentioned above). And now it's under 300,000 lines of code again ( and about 20 kB
smaller for the resuling executable – it is always amazing how little gain
is being obtained from removing code vs. how much a little extra code costs, there
must be some law for that).
Anyways, ready now for some new sample based modules, but first the 2020-06-20
june solstice concert … with existing modules and
functionality, more changes after that … best.
-
2020-06-23 : Now that the event is out of the way … Started working on a 64
bit version, found some odd bugs that I fixed and it seems promising sofar
… not yet working is the freeverb reverb module, as it has some 32 bit
assembler code in it. Will have to run lots of tests now – and checks for
(in)valid type casts and int sizes and such. It runs the current patch I was
working in almost half the CPU cycles … hmm … let's say 60 to 66
%, and also PortAudio will now discover 64 bit ASIO drivers (ReaRoute in
this case). So, some promising results sofar.
Sofar tried to open like 20 larger old patches, except for the now fixed scala bug
and the reverb that needed a fix they seem to all run fine.
The executable size is somewhat larger, as is the memory footprint of the program.
-
2020-06-23 : Rewrote the Reverb module to not use ASM anymore and to work with
doubles instead of singles. it now works in the 64 bit version. It also seems to
sound way better, odd.
-
2020-06-23 : Fixed a bug in the Scala lookup routines where a negative notenumber
would cause an exception to occur. Also fixed a bug where an exception would be
raised when a scale or mapping file did not exist, or where a mapping got set
before a scale was set.
-
2020-06-23 : The SAPI speech module seems broken, not going to fix that as eSpeal
can do it all too. Oh and eSpeak still works with the new 64 bit DLL. Opps wrong
… SAPI still works too, my test code for it failed instead.
-
2020-06-24 : Made new compiles for the PortAudi DLL for Win32 and Win64 both in
debug and relesae versions. Both versions have FL Studio ASIO blacklisted. Anyway,
both the 32 and the 64 bit Wren version can co–exist now with FL Studio
using the FL Studio ASIO driver.
in version 2020.5.30.0
-
2020-05-29 : Added a new midi in module, Midi8NoteIn, a copy of the
MidiMultiNoteIn module but with a maximum of eight channels instead of four. The
actual channel count can be set with the max. notes control.
-
2020-05-29 : There was a bug in the MidiMultiNoteIn and the Midi8NoteIn modules,
the mode input got never processed. Also had some doubts about how note off
messages were being processed, so changed the code for that a bit too.
-
2020-05-29 : There was a bug in the internal MIDI send code where sending to
internal channels (ic1 to ic16 (from all of the MIDI send modules), to modules in
the patch directly) did not work correctly.
-
2020-05-30 : Some more issues with the MidiMultiNoteIn and Midi8NoteIn.
I've combined the code for both with the MultiNote in using a fixed channel count
of 4 and the 8Note one using a user settible limit from 1 to 8. Consider
MidiMultiNoteIn to be obsolete, it will have the same performance as the 8Note one
set to a 4 notes maximum.
I've changed the scheduling for note-offs to find the oldest same valued
note present to turn off. For aftertouch the youngest same valued note is
used to apply the aftertouch to. This does not change the channel selection used
for note-on events, for those the selected algorithm will be applied always.
Fixed an issue with AfterTouch and ChannelPressure not being in range [0.0,1.0].
Fixed an issue with PitchBend not being in range [-1.0,1.0].
-
2020-05-30 : the MidiNoteIn, MidiMultiNoteIn and Midi8NoteIn modules did not
correctly handle note-on events with velocity zero, it is now treated as a
note-off event.
The MidiNoteOut module can still send note-on events with velocity zero.
in version 2020.5.27.0
-
2020-04-23: Added a random walk shape type to the LFO modules. The step size for
the walk can be set with the warp controls, a low warp value giving a small step.
Done: for the next release must update the skin stuff for this.
-
2020-04-26: Made it possible to turn off the patch hints (the ones popping up for
knobs and buttonss and such). This to "solve" a nasty issue with wine
where the hint windows "hang" and that I do not know how to properly
solve. It is a setting in the Settings Screen F3.
-
2020-04-27: Added some extra controls to the OscTrig module to make it more
suitable for Pulsar Synthesis like effects. It now has phase modulation, shape
modulation and warp control just like the main Osc module has them.
-
2020-04-28: Added an output type selector on the Osc and OscTrig modules, to make
them more suitable for AM (amplitude modulation) type modulation (instead of RM,
or ring modulation).
-
2020-04-28: Added a modulatable repetition count to the WavePlayer2 module. This
to be able to play bursts of short samples. This is also meant to make Pulsar
Synthesis easier to accomplish.
-
2020-04-28: Made two extra inputs on the WavePlayTrig2 module for programmaticly
switching the retrig– and the loop–mode.
-
2020-04-30: Made a new sequencer type (Seq16Rep). This is an extension of the
seq16 type where a repetition count can be set for each step (1 to 256 counts).
Also a trigger pattern can be selected from n(one - no trigger pulse), s(ingle -
one pulse per step), a(ll - one pulse per count) and g(ate - one long pulse over
all counts). The repetition count and pattern are modulatable per individual step.
The Individual trigger outputs (trigs) as well as the main trigger output (trig)
will output the selected trigger pattern, the tr. chain output will trigger once
for every next step being taken, this can be used for chaining up another squencer
such that it can stay in sync.
Pulse length for trigger pulses can be changed by changing the duty cycle of the
the incoming trigger pulse.
-
2020-04-28: Added a new range for envelope times, the vfast range. it runs from
50µs to 10ms. This applies to all modules that work with changeable envelope
timing ranges, those are: PulseDelay, EnvARRetrig, EnvAHD and EnvADSR. The
granulators still use fast, I'm considering changing that to vfast to make them
more usable. Anyway, audio rate envelopes are pretty nice for Pulsar like
Synthesis.
-
2020-05-01: Added two new signal types HighLogic (orange, audio rate) and
HighLogicCtrl (dark green, control rate). These will be used on inputs only (so
there will not be wires in these colors). The difference with the regular logic
signals (yellow and lime) is that the latter switch for levels > 0.0 and the
new types switch for levels > 0.5. This makes it easier for some logic inputs
to be controlled from unipolar signals. There had been a couple of existing
modules already having the new behaviour, for those modules the colors have been
changed to the new colors to make the input type clear.
-
2020-05-01: Added ranges for granular times too now, it supports the fast and
vfast modes (as they existed for envelope times already). The bloody things need
more work though as they still sound no good.
-
2020-05-05: Added relative LFO rate control (r.rate) for setting a global LFO rate
multiplier. This is currently not being used anywhere, decided to do MIDI syncing
in a more modular way. Oops, correction .. it actually does work as a global LFO
rate multiplier, but it does not change the scaling of the delay lines.
-
2020-05-05: Made some changes to the Tapper module. An extra control mode was
added (LFO fast 0.254) to allow for faster tempos with an LFO set to fast range.
Some internal clipping was removed to allow for larger BPM ranges. An external tap
input was added so this module can now be auto-tapped from an LFO (prably set to
run in BPM mode for exact BPM matches) or from a ClockGen module's * 16 or * 96
output. The order of the control modes in the selector was changed, so some older
patches may not be compatible without manually correcting the mode(s).
-
2020-05-06: Made a MIDI clock receiver module, click on the image to see the docs
for it. It is to be used for MIDI clock synchronization. The sync output will give
a short blip once every measure (24 PPQN is assumed and 4/4 mode).
Had to modify the overal MIDI reception structure for this, will have to test
(N)RPN receivers after these changes.
-
2020-05-06: Made a RateConverter module, click on the image to see the docs. It
is to be used for synchronization of LFOs and delays.
-
2020-05-07: Added alpha and hysteresis modulation to the CuClipStereo module, just
like the mono version already had it.
-
2020-05-10: On Sequencer reset (Seq16 and Seq16Rep) the first step should become
active immediately. Changed some things for it, seems better now.
-
2020-05-13: Added rate multiplier modulation to the MidiClockIn and Tapper
modules. The RateConverter module already had this.
-
2020-05-13: Added a sync divisor to the MidiClockIn module.
-
2020-05-13: Added XFade modulation to the Mux module.
-
2020-05-13: Added an inhibit (inh) input on the EnvAR and EnvARRetrig modules,
when it is active the envelope will not be started. This is a HighLogic input, it
will be active for signal levels > 0.5.
-
2020-05-14: Added output type selection for the Noise and NoiseTrig modules
(bipolar, positive only etc.). Some are redundant, like the pair 'positive only'
and 'inverted positive only', which would end up being 'identical' in the long
run.
-
2020-05-15: Changed the grain modules to use a mixing buffer for sample
insertions, this smooths out the discontinuity between the oldest and newest
sample in the sample buffer and so makes grain playing less glitchy. I've set the
mix area to be 16 samples long which seems to be sufficient, it is a bit of a
trade off, a longer fade area makes it substantially slower (limiting the maximum
grain count to be used).
Did that same thing for the GrainDelay module, but that one still seems a bit
glitchy …
Also removed a bug where the grain duration could become zero, which caused a
division by zero.
-
2020-05-15: Changed clipping of the main program window on program load to allow
for it to be sized to the screen size (without it being maximized). It used to be
clipped 20 pixels short of that (unless it was maximized).
-
2020-05-15: Removed the slave output from the RateConverter module, it was only
passing on it's input – so not too much use for it. (note to self: some
patches of the last 10 days will need repair for this).
-
2020-05-16: Had fukt up the (trig) noise for the regular bipolar output range,
fixed that.
-
2020-05-16: Added 'dust' as a new random signal type for the Noise, NoiseTrig,
NoiseLFO and NoiseLFOTrig modules. It consists of randomly timed spikes, the
distribution over time is set by the color controls. This is after an idea
obtained from SuperCollider – via the Hetrick Dust module for VCV. I've
changed the implementation a bit to use two independent noise values for
spike–distribution and –magnitude. This is unsynced dust.
-
2020-05-16: Added a ValueSync module, a value synchronizer. It acts a bit like a
sample and hold but it will pass on the value captured when the pulse input got
active only when a sync signal was seen after that. The Q ouput will go on for 1ms
after a sync occurred, the captured value will be held untill a new pulse and sync
sequence was seen.
-
2020-05-17: Added 'crackle' as two new random signal types for the Noise,
NoiseTrig, NoiseLFO and NoiseLFOTrig modules. There are two versions Crkn for the
normal and Crkb for the broken mode. The ideas comes from the HetrickCV Crackle
VCV module (and originally from SuperCollider).
-
2020-05-18: Added an active output on the MidiClockIn module, intially or after
receiveing a MIDI Start or Continue message it will be on. It will go off on
receiving a MIDI Stop message. When active is offthe latest calculated BPM value
will be set to zero and there will be no further sync pulses on the output.
However the control and slave outputs will be frozen to where they were, so
everything controlled by it will keep running as it was. When started again the
sync output will go active briefly.
-
2020-05-18: Fixed a bug in the global LFO rate setting. All displays of LFOs would
react correctly but the actual tate was never acted upon. It now works as
intended, but at some later stage I might also want to alter delay times and
envelope times.
-
2020-05-19: Added sequence length modulation to the Seq16 and Seq16Rep modules.
The parameter value is being multiplied by the preset number of steps and can make
the actual step count both larger and smaller, however the range will still be 1
to 16 steps.
-
2020-05-21: For the ModGateSeq module the gate modulation inputs were changed to
HighLogic (dark green, switching at 0.5) mode.
-
2020-05-21: Added some functionality to the slew module. Slew can be modulated now
and up and down slew have been separated to allow for a different change rate in
one direction than the other.
-
2020-05-26: Added a new signal type to the LFO modules, calling it the 'Random
Block' mode. It will produce random levels of random duration, but changes will
always be synced to the LFO rate. The chance of change to happen can be set with
the warp controls, more warp makes a change more likely. When this signal type is
differentiated with one of the Dif modules or wirth the ChangeDetector the result
will be a sort of 'synced dust'. The 'dust' type signals from the random modules
are unsynced.
in version 2020.4.13.0
-
2020-02-28: Changed file formats to all (except MIDI files, which are
binary) use UTF-8.
Worst case, that is when you have used non ASCII characters in file names or
module names, this may cause Wren to not start up anymore or
to not be able to quit. Save your current Wren directories before
upgrading to this.
I've tried to program a fix for this to make things backwards compatible, but can
not oversee all possible situations. In case you see any trouble please report
‐ what will fix it is removing the wren.ini file, but I'd prefer to
provide a solution without history loss.
I ran into trouble with the previous version when I wanted to save a patch with a
greek name which was not handled correctly. The new version of Wren handled all migration issues for me – YMMV … let me know please
– and I'll fix it.
-
2020-04-13: Made builtin MIDI, making the NetMidi program obsolete.
MIDI port selection is trough a new menu item setup/MIDI devices (the audio
setup menu item was renamed to setup/Audio devices). MIDI Channel selection
and (N)RPN preference setting still works trough the Settings Screen F3.
-
2020-01-18: Made steps modulation on the Quantizer module.
-
2020-01-18: Made step value modulation to the LUT module. This transforms it into
something inbetween a constant step and a piecewise linear step processor
(depending on the setting of the fade control). The modulation inputs are set to
1.0 when not connected so in that case the old generator only behaviour is
maintained (modulation inputs are being multiplied by the slider set step values).
Also added an AM input, affecting all outputs but not acting on the chain input
and also not active when the module is in Note mode.
-
2020-01-18: Changed 2010 to 2020 in places …
-
2020-01-22: A new module, a double pendulum simulation.
This resolves the [2017-08-12 : Double pendulum] request.
This module can either be free running or clocked, it will be clocked when
something gets connected to the clk input. The m1 / m2 control sets the mass ratio
between the masses at the ends of the pendulum arms. The sum of the masses is
set fixed to 20 kg. The l1 / l2 control sets the length ratio between the lengths
of the pendulum arms, the sum of the lengths is set fixed to 20m. The speed
control and it's modulation input set the simulation step size, the simulation
will not proceed when the speed is zero. For negative speeds the simulation will
run in opposite direction (but gravity stays as it is). For large speeds the
precission of the simulation will diminish and somewhat longer runs may result in
non–chaotic behaviour. The reset input or button can bring the module back
to it's starting state. With the G mod. input gravity can be changed, it can be
made negative too, unconnected this input will have a value of 1.0 for standard
downward gravity.
DPendulum animation example
-
2020-01-23: Changed mazes.4th to version 1.1 - just a color change really. Must
not forget to use this one for the next release (it is in the web folder already
but needs to be put into the zip-yet-to-be-created.
-
2020-01-23: There is an issue with the LUT module, xfade is not working correctly
when the postion wraps back to the first one. Also outputs 2 and 4 seem to behave
different than outputs 1 and 3? Hmm, nope, all ouputs act the same, so that bit is
ok.
XFade is working correctly after all. As it can not look into the future it can
not know that the position will wrap back in the next sample. So I've declared it
to be a "feature" instead.
-
2020-01-23: I've changed the triangular wave forms to not use integration anymore
but to use a BLAMP'ed trivial waveform instead. This behaves better with wave
warping.
Changed the default bandlimiting to 1.004, close to 1 (which works best overall
(it was set to 1.5 or so by default)).
Affected modules are Osc, MultPhaseOsc, MultiOsc, OscTrig and SquareTrig modules.
- 2020-01-27: A new module, a dual filter.
Two 12 dB/Octave
filters with three selectable configuarations and frequency spread control and
pre/post distortion.
The two filters are connected in series, the first filter frequency is set with
the frequency controls and the second filter follows it with a modulatable
separation offset (which can be negative by using the separation modulation
inputs).
The filter mode can be set to low pass (lp), high pass (hp) or band pass (bp). In
low and high pass modes it will act as a 24 dB / oct. filter where the resonance
peak can be split in two by the separation controls. In band pass mode there are
two 12 dB / oct. filters where the bandwidth is controlled with the separation
controls.
The lev control sets the input level and there is pre and post filter distortion
available.
The Q control sets the filter Q for both filters, and it can be modulated
positively and negatively trough the two modulation inputs.
-
2020-01-30: Added a divider on the clock out of the Seq16 module. I'm using this
for chaining Seq16 modules at a different rate than it's "natural" rate
(as set with the number of steps). This would save an extra divider module.
-
2020-01-31: Added a multiplier input to the PitchShift module, it is multiplied by
the shift parameter to, for instance, allow for quick zero to set value
jumps or for set value to minus set value jumps.
-
2020-01-31: Added "add" inputs to the Constant and MConst modules. They
can provide a value to be added to the output value.
- 2020-02-13: A new module, a fast mode LFO.
It is fast in that it is
computed at audio rate instead of control rate, but otherwise it is the same as
the LFO module. This module can be used to control delay line time modulatuion
with less zippering than would be caused by using the standard LFO.
- 2020-03-05: A new module that does … nothing …
It is handy at times for routing
wires. and it adds one sample of delay. Just a bit cheaper than a mixer or
something you could use for the same purpose. Besides, every program environment
needs it's nop 😉
- 2020-03-19: A genome player module, translating RNA strands into
control signals.
This module
scans text files for A, C, G and T (or U) characters (case insensitive) and builds
a sequence from those with the letters mapped to the numbers 0, 1, 2 and 3 (such
that A and T (U) are complemental, as are C and G). U is treated as if it were T.
Additionally W, S, M, K, R, Y, B, D, H, V and N are recognized, these are
(according to their rules) randomly translated in one of A, C, G or T. W into A or
T; S into C or G; M into A or C; K into G or T; R into A or G; Y into C or T; B
into C, G or T; D into A, G or T; H into A, C or T; V into A, C or G; N into A, C,
G or T.
All other characters (including Z, white space and numerals) will be skipped.
On playback the letters can be chained into groups of size 1 to 7 (3 would be the
central dogma, codons encoding for amino acids (of which some may not exist for
random letter sequences, but this module will assume existing sequences)). For a
single letter there are four values [0.0, 0.25, 0.5, 0.75] or [0,0, 0,33, 0.67,
1.0] on the scaled output; for a group of two the values woud be [0.0, 0.125,
0.25, 0.375, 0.5. 0.625, 0.75, 0.875] (or their scaled equivalents).
On each trig the next group will be output, when the unit is in repeat mode it
will jump back to the start when everything was played and when it is in once mode
it will stop at the end. The res input will reset the sequence to the beginning.
The changed output will fire when a value change on the output was seen. The
leftmost outputs are complement outputs, for ease of implementation just 1.0 -
output.
That sars2 thingie was a tad boring though to listen to … oh well …
in version 2020.1.18.0
-
2020-01-16: Embarrassing bug … there are anti aliasing errors in various
oscillator modules when PWM or Warp is not set tp 50% (extra aliasing was added
instead …). Also the PWM modulation does not work as intended on the PWM
enabled modules. The affected modules are Osc, Square, OscTrig, SquareTrig,
MultiPhaseOsc and MultiOsc.
Fixed all of this but the MultiOsc lost its PWM control in the process. It did
hower get warp control instead which does PWM too except that the parameter names
are different so some repatching will be needed on that.
Checked LFO PWM as well, which seems to be fine.
The Square, Saw and Tri waves sound a lot better now and PWM works as intended.
-
2020-01-09: Added solo buttons and a solo chain input and output to the MixS2to1
module. Making solo active on the left or right pair will block the audio chain
inputs and and it will also block the other audio input pair. Also the solo chain
output will then be active which is signalled by a yellow light. When the solo
output is connected to a downstream MixS2to1 module that module will block it's
local inputs and it will pass on only it's chain inputs. This will be signalled on
that module by having an orange solo light.
Did the same thing for the MixS5to1 module.
-
2020-01-10: Added add, subtract an multiply modes for the A and R times on the
EnvARRetrig modules. These control how the modulation inputs will act. In add
mode, which is how things currently work and which will be the default setting,
the modulation input value is added to the knob value to determince the actual
time used. In subtract mode the modulation will be subtracted from the knob value
and in multiply mode (which is how the modulation once a long time ago worked -
and I wanted to have that again) the modulation input will be multiplied with the
knob setting to determine the actual time.
-
2020-01-13: Added wave morphing to the OSC module. The morph input signal is being
multiplied by four and then added to the wave selector control value. From this
two waves are selected ( sine, tri), ( tri, saw), (saw, square) or (square, sine)
and a mix from those two will be sent to the output, proportionally to the morph
input value. It is the red input left of the wave selector.
-
2020-01-15:
Added scaled clipping control to the RandSigs module. This to be able
to make it spend more time at it's extreme values, which may result in more
interesting volume patterns, for example (when used for volume control).
-
2020-01-16: Added pluck level modulation (AM) to Karplus-Strong based modules (KS
and Pluck); Added AM input to HrastFilter (and made it a bit less high - pixel
wise); Added AM to the HrastOsc. Added AM on SVF flter input; Moog filter, idem.
Also AM now for Square, OscTrig, SquareTrig modules.
-
2020-01-09:
Added a modulated gate sequencer, the modulation inputs can enable or
disable a sequencer step. That is, a step manually set to one of the active modes
can be turned off by setting the mdulation to zero or smaller. When the modulation
is above zero a step set active by the buttons will be made active. Unconnected
modulation inputs are set to one, so then the step will follow the button setting.
Steps that are turned off trough the modulation inputs will flash orange instead of
yellow. They will not be skipped, but they will not pulse the output.
-
2020-01-15:
Added a scaled clipper. The input values are first being level scaled according to
the input type setting. Then they are being multiplied by the set level (level
knob setting multiplied by the level modulation input) and clipped into a
[-1.0,1.0] range. Finally the signal is being rescaled according to the selected
output type.
The idea is that signals clipped this way will spend more time at their extreme
values, i.e. a saw shaped input will be output as a trapezium shaped wave. But it
can be used for all sorts of input values to make them spend more time at the
extreme values.
in version 2020.1.6.0
-
2020-01-03: There are some issues with the TextWriter module (considered to be
fixed now):
Changed the TextWriter module to allow it to only write into an existing folder.
Also made it so that the text file will now be rewritten when the prefix settings
changed.
When the folder would not exist (or maybe be located on a disconnected network
drive) patch changes would get very slow while windows was looking to find the
folder. The requirement for the folder to exist is assumed to solve this issue.
This will not work when windows still thinks the drive to be present, which
happens after network issues. Sometimes it will come back, sometimes it will not
in which case opening the drive in explorer will help – mostly.
Added an option to the Settings Screen F3 to allow the TextWriter module to work
at all. By default the mechanism is disabled, so if you've used the TextWriter
module before you'll now have to explicitly enable it.
-
2020-01-06: Delay times for the DelayMix module were not set properly, fixed.
-
2020-01-06: Added three extra delay ranges for the Delay, DelayMix, DelayStereo,
Delay8, RndGranulator, Granulator, SimpleGranulator, GrainDelay, Looper and
StereoLooper modules. Actually the ranges are the same, but there are 8192 steps
instead off the 256 for the existing ranges. This allows for more precission in
setting the delay time. All displayed time will show one or more extra digits too
now, not only for the delay modules but for all modules displaying time.
-
2020-01-06: Upped the patch version to 9 to handle the changes made for the delay
times properly. Older version patches should still be read properly. The displayed
values though will have one or more extra digits, so things may look a bit
different (like 110 ms in the medium range will now be displayed as 109.9 ms, but
it still is the same actual delay time). This affects not only the delay based
modules, but all modules capable of displaying time (like LFOs and envelopes, for
instance). I've changed the display widths a bit for the longer representation to
fit.
in version 2020.1.1.0
-
Sometimes it would happen that wire speed fixup was not processed correctly. The
ouput module, for instance, would have blue input wires making things sound bad
(as the signal would be control-rate then). Put a patch on this which seems to fix
it, but it is a bit odd all … it depends on the order wires are drawn, a
blue <- blue <- blue <- blue <- red chain should be transferred into
an all red chain, but sometimes the leftmost two would stay blue.
As a temporary fix for current versions this can usually be solved by adding a
module and removing it again (maybe twice), or by redrawing the affected wire
connections. But the issue may reappear when the patch is loaded again.
-
There is a bug in the HardClip module, and maybe in other modules having the Lock
option too. When Lock is set to off, on reloading the module the high level will
be set to the inverse low level (which should only happen when Lock is set to
Mirror Mode. In the Off mode the high an low levels should be independent.
Solved it by setting the default pairing mode to off instead of mirrored. All
other modules with paired knobs already had the default mode set to off. Things
will work okay when the pairing mode is turned on in the patch (on the module)
itself.
-
When on the module selector the number of tab button rows gets larger than two,
modules become mostly invisible and can no longer be selected. To change this I
have made the program check for the number of rows and when it gets larger than
two the width of the selector will be accomodated to reduce the number of rows to
two.
This will not change the layout when the number of rows was one or two.
-
Fixed a bug in the "new patchname template" where the $N macro was not
treated properly.
-
Changed the way module registration conflicts are handled. This used to cause the
ini file to be corrupted, not so anymore (an issue encountered mostly during
development of new modules).
-
Fixed the text color for the TEdit components on the Settings Screen F3, to make
the text more readable. Default is white on grey now, the actual colors are user
selectable (edit font color, under colors).
-
Made it possible to hide groups of controls from the toolbar. When made vissibe
they will still be in a pre‐determined order. This can be set from the
Settings Screen F3, but also there is a popup menu for it on the tool bar as well
as there are items for it in the view menu.
-
Got a bit much going on in the OSC tab in the module selector, split it up into
OSC1 and OSC2 tabs. Also rearanged the oscillators a bit better by category.
-
Added a freeze input to the Delay module. It will mix the fixed output and the
input and that mix will be the actual input to be recorded into the delay line.
When unconnected the module behaves as it ever did.
-
Added A, D, S and R lights on the ADSR module, likewise for A, H and D on the AHD
one. And then added A, H and R lights on the two AR type envelopes as well.
-
Added an amplitude modulation (am) input to the GVerb module. When not connected
it's value is 1, and it is being multiplied by the in level value to set the input
attenuation.
-
Added a "1" output on the GateSeq module, it will be active when the
sequencer is on it's first step.
-
Made a shuffle input on the seq16 module, it will randomly swap some slider values
when activated.
-
Added an End Of Cycle (eoc) output to the EnvARRetrig module. Feeding it back into
the trigger input will turn it into an LFO. It can also be used to make a sequence
of triggered envelopes. The eoc output will only fire when the envelope curve was
completed, so when the module is triggered too fast for completion to occur (it
retriggers) this output will not go active.
Added the eoc output to the EnvAR module as well. This module will not retrigger
so it will always complete it's cycle and so eoc will fire always.
-
Added an AM input to the filterbank modules.
-
Added a triggered wave player module, and a variation on it with variable start
point and duration and some more control over the parameters. These are level
triggered modules, the sample will start playing once the trigger input goes
within the range set with the trigger level and the trigger range. This makes it
possible to fire samples from a saw shaped LFO, each at its own time.
There is a loop mode setting allowing the wave to be played once or repeatedly (as
long as the trigger condition is met). The trigger mode can be set to normal or to
retriggerable ‐ in normal mode the wave will have to finish before it can
restart, in retriggerable mode it can be restarted while playing by making the
trigger condition false and then true again.
The playback speed can be controlled with the speed and the freq and/or fm
controls, negative speeds (playing the wave backwards) are allowed too.
-
Added a wealth distribution simulation thingie. It has a pool of 1001 clients and
on every internal update clock a transaction will be performed by two clients.
Clients can transact only when they have more wealth than - kappa. When they
transact the transaction will be some fraction of the wealth of the poorest of the
two clients. This fraction ranges from 0% to 5%. When chi (the tax factor) is set
to zero this will pretty quickly explode into an oligarchy where one client has
all the wealth and the rest in maximum debt (as set by kappa). When chi is upped a
fraction of the value of the transaction will be transferred from the richest to
the poorest in the transaction and this will stabilize the system. The total
internal wealth will be equal to 1001 times the set capital value (which is
capital per capita), at least after a reset was issued (when tweaked wildly this
may not be true).
On every input clock a random client is selected and it's wealth will be put on
the output. Also a minimum and a maximum wealth is maintained, those values will
(also when the clock goes active) be sent to the max and min outputs.
Now all of this really makes just a fancy random generator where small numbers
will occur more often than large numbers (and where larger numbers will be spread
out more in range as well), and as such it might be of musical use, especially
when combined with the MinMaxRange module (see below) to make the output range
more predictable. But also, it seems to make a nice rainy type of noise.
The internal update clock will either run at the sample rate or at the control
rate, depending on the module being connected to a fast (red/yellow) or to slow
(blue/green) modules only. The min and max values are recalculated once every 1001
internal clocks. For fast output clocking the min and max values may not always be
accurate (as it could clock faster than the 1001 cycle period time). The numbers
on the left show the current min and max wealth.
1001, a thousand and one nights she sat beside the sultan's bed. But also it is 7
x 11 x 13.
-
Made a MinMaxRange module. This is a scaler module for the case where the minimum
and maximum values of a signal are known (as for instance in the Economy module
above). The module will transfer a signal (sig) that moves within a range min to
max into a range [0,1].
When the minimum value happens to be larger than the maximum value the module will
still return valid output values, but it will work inversely (where the largest
input value will map to zero instead of one).
Signals that are outside the [min,max] range will also be handled but will end up
as an output signal outside the range [0,1] .
When the minimum and maximum values are almost equal the minimum value will be
returned for whatever the signal value happens to be.
-
Made an equal division quantizer. An "octave" can be set which will be
divided into the set number of divisions, all intervals thus created being equal
in size. An "octave" of 2 is the usual octave, and 12 divisions will
then create the usual 12EDO, 12TET or chromatic scale. The input range can be
trimmed down with the range controls, these are common for all four channels.
The lights will indicate errors in the entered values (i.e. values that are not
understood by Wren.
-
Made a replica of the Mutable Instruments Branches
module, or the Bernoulli gate as it is also named. The Wren version
has four gates, however they share a common mode- and p-parameter.
The module has four modes of operation:
-
normal: on a rising input edge with probability p the topmost output will be
turned on and otherwise it will be the bottom one. On a falling edge both
outputs are being turned off.
-
toggle: on a rising input edge with probability p the inactive output will be
turned on and otherwise it will be the active one again. On a falling edge
both outputs will be turned off.
-
lnormal: or latched normal, as the normal mode, except the currently active
output will stay active until the other one gets active.
-
ltoggle: or latched toggle, as the toggle mode, except the currently active
output will stay active until the other one gets active.
Made the output indicators bi-color, as the Mutable one has them. Dark means both
outputs are off, yellow means the top output is active and orange indicates the
bottom one being active.
The probability p is determined by the sum of the p knob and the p input. The
resulting value will be clipped to a [0,1] interval.
-
Made a square wave rate multiplier. It Takes a square shaped input and then turns
every edge in it into a pulse. It does not try to square up the signal, so the
duty cycle information is lost. Modules can be cascaded to get 4, 8 etc. rate
multiplications (but the pulses will not be spread out evenly then).
in version 2019.11.12.0
-
2019-11-12: Oops … made a bug in the WavePlayer which causes it to not
always play, fixed it for version 2019.11.12.0.
-
2019-11-12: An undocumented new module for Gabe to check out.
in version 2019.11.11.0
-
Fixed a bug causing occasional memory allocaton errors in the eSpeak module.
Added a check to see if ESpeak had actually been installed by reading
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{7192AA2F-F759-43E9-91E7-226371EF6B2F}\1.0\0\win32
from the registry, when that key is present and it's (default) value points to an
existing file, it is assumed ESpeak was installed (at one time at least …).
I'm not sure this will always work … this key is defined in the ESpeak
source code for version 1.48.04, but it might break on later ESpeak versions.
-
Fixed a bug in the ProgDivider module which caused it to set out of range division
values under some conditions. Also the divider could get out of sync when the
counts were changed, that is it would get triggered on the oposite input edge,
fixed this too.
-
Fixed the multiplex module such that it will no longer go out of range and also
fixed the crossfading for it to work properly when less than the maximum amount of
steps is set. The demultiplexer had the same issues, fixed those too.
Added a changed output to both the mux and demux modules which will generate a
short trigger pulse whenever the selected step changes.
-
Removed a handful of range errors and divisions by zero and such. Did not run with
range, overflow etc. checking enabled for a a good while ‐ I should have!
(after all it's Pascal :-)
-
It seems to not be possible to have a single quote character in a patch name.
Something to look into. Ok, this was a patch writer issue it did not do proper
quote escapement (the patch reader already did it right). The same problem would
arise on module titles with quotes in it. I've fixed this for both cases. User
typed string values in edit controls were properly escaped already. Now there
still may be an issue with multi‐line string values … k …
the patch reader would not read line‐feed characters, which is fine for
everything except for the value popup editor ‐ fixed this as well.
-
When oscillators are copied from a patch into another one in another instance of
Wren with a different tuning being set, the new tuning is either not being applied
or not visible in the user interface. Currently the only way to fix it seems to be
to alter the tuning and then undo that. This will probably apply to all tuning
sensitive modules, filters for instance. Indeed, the tuning of the imported
modules is applied to the patch instead of the tuning of the patch being applied
to the imported modules. This will probably go wrong with importing saved module
clusters from file as well. Fixed it, only loading a completely new patch will
affect the current tuning parameters, and none of the pasting or module read
options will do so.
-
Fixed a "bug" on the Looper and StereoLooper module where it would not
output any sound until the speed knob changed position. Also changed the speed
input for the WavePlayer module to have a default value of 1 (to make the wave
being played without any furter connections, when you'd want a "standing
wave" connect the speed input to a constant zero value).
Later I've added a selector for the speed mode, by default it is on which makes
the wave to be played at regular speed. When turned off it makes the wave stand
still. When the speed input is connected to something however this will override
the speed mode setting. So you can now have it function in both the old and the
new way.
When the wave stands still it can still be played by varying the pos input, for
instance by connecting a saw shaped LFO to it.
-
Fixed a bug for the Constant, SeqValues, Lut and Knobs4 modules where, when the
mode was set to "note", the value knobs and sliders affected by this mode
would loose their value on module copy or patch reload. These were all cases where
the step count of the associated control would change with the selected mode.
-
Fixed a bug for the SeqValues module where wrongly colored dots could be set on
the P, S and E controls.
-
Changed the Vocoder FFT overlap from 75% to 50%, with the Hann window used 75%
created some nasty squeals at 1/3 of the sample rate (which of course I didn't
hear in my old ear ;-) ‐ but the spectral analyzer …
And while at it, I made the FFT size user selectable. A larger size first will
sound better afte which it tends to smear things, but also a larger size will give
more processing delay.
-
Changed the WavePlayer module to always play at the same rate, indepent of the
current sample rate. It still only accepts 44k1 stereo or mono wav files.
-
Made the VU meter update rate independent of the lights update rate, it is fixed
now at a 23.8Hz rate.
-
Added two macro's to the TextWriter module. %patchname% will be substituted
by the name of the current patch and %prefix% will be replaced by the
TextWriter prefix value, which can be set trough the Settings Screen F3 ( when
prepend prefix is checked it will be prepended always, when it is not checked it
will be prepended only when the %prefix% macro is used in the TextWriter module
‐ the prefix value itself can be left blank too when no prefix is wanted).
-
Added an active input to the eSpeaker, when active speech will proceed, when not
it will be frozen in-place. With an SR flip-flop triggered from an LFO and reset
from, for instance, the word trigger out of the module, speech onset can be synced
to the LFO. It will still be async while it runs, and this will cause clicks due
to the abrupt starting and stopping, but at least it's synced a bit.
-
Added inverted outputs to the RangeConverter module, where the regular ones go up
the inverted ones go down (over the same range), and vice versa.
-
Added changed outputs (in the column marked "C") to the seq16 module.
These will go active briefly when the associated sequencer output changes.
And also added clear inputs for "one", "some" and
"all", similar to the randomizer. The some inputs will clear or
randomize four steps that are separated by four steps. The starting step is chosen
randomly from the first four inputs.
Added three extra chain inputs, to make it possible to chain all four sequencer
lines. Some patches may need modification (connect the original one chain input
to the three new ones) for it to function the same way as it did before. This is
the columne of inputs marked with "c"
-
Added an "am" (amplitude modulation) input to the basic Osc module.
-
Added an "am" (amplitude modulation) input to the Looper and
StereoLooper modules.
-
Added shape warping to the basic LFO module. This acts like PWM for a square
output, a triangle can be morphed from saw to ramp, etc. This works for all the
wave forms, but the random waves will not be much different on warping.
-
Added a range selector to the ARRetrig envelope module. This allows for way longer
times to be set for it. For patch compatibility it will come up with the default
fast mode (it always had).
-
Added module feedback to the edit history window, a selected history item will now
highlight the associated module in the patch editor.
-
Added a brownian noise mode to various random generators.
-
Added a Filter mode to the PulseDelay module, this will cause it to only be able
to re‐fire after the input was inactive for a couple of sample times (
depending on the control rate divisor). The ouput is quaranteed to stay low for a
couple of sample times after the stretch period ended. This makes it possible to
set a maximum rate for the output to fire. For instance, when the input rate is
1Hz and the filter time is set to 2.5s the ouput will fire no more often than once
every 2.5s, so in this case it will fire once every three seconds. This differs
from the stretch mode where with the same settings the ouput would never go low.
-
Added a PADSynth like module, it use IFFT to generate sound from a spectrum which
is created by a set of faders and some extra controls for spread, peak bandwidth
and bandwidth scaling with frequency. Some of the controls are clicky as the IFFT
has to be recalculated (and I was too lazy to make fades for that). Also this does
not fully implement the PADSynth, it just uses it's basic ideas as laid out by Nasca Octavian Paul ‐ anyways, it can make some nice
sounds.
The faders set the spectrum, the bw (bandwidth) controls set the width of the
spectral peaks.
The spread parameter manipulate how the spectral peaks will be spread.
The module works by generating an in‐memory waveform from the spectrum. This
waveform can be played at different rates and from different positions by using
the position speed and frequency controls. At some stage I should modify this to
have multiple wave forms to be generated with cross fading implemented over that,
too lazy for that now.
The module has a stereo output, a diffrent tap point is used that for that on the
calculated wave.
The IFFT size to be used can be set, small values will act a bit weird, anything
up from 8192 seems okay. Values from 64 to 262144 can be used.
-
The 300th module :-)
Added a new granulator type module, working better than the three existing ones.
It has a delay line able to hold 5 minutes of audio and a maximum of 128 grains
can be set (provided that the CPU can cope with that).
It has grain controls for pre-delay, spread (or grain distance), pan, duration,
frequency, speed and amplitude. All these controls can be modulated. Additionally
the amount of grains can be set from 1 to 128, and this can be modulated too.
Several grain envelope types can be set to change the sound character: bell,
pulse, exp, reverse exp, tri and box, for all of these there is a noisy variation
as well.
-
Added a smearing module … why? because I could. It smears the phase of the
incoming signal with a controllable random amount and it adds some delay, FFT
based.
-
Added a MinMaxMix module after an idea from an idea from Ricko at the electro-music.com forum. When both input signals are positive
the ouput gives the largest one of them. When both are negative the output is the
smallest one. When the signs are opposite the sum of both inputs will be sent to
the output.
-
Added a PhaseSplitter module, it will split the incoming signal into two signals
that are 90 degrees out of phase. This can be used as a building block for
various audio effects. for instance the Bode frequency shifter internally makes
use of the same splitter code.
-
Added a Detector module, it will split the incoming signal into two signals
that are 90 degrees out of phase, thus "complixifying" it. It will then
use the complex signal to derive instantaneous amplitus\de, phase and frequency.
This works properly only for sine shaped signals, but also "sort of"
(as in "nicely") for more complex signals. I've used it to analize a
voice signal to control an oscillator to implement pitch shifts on that voice.
-
Added an AbsAdder module, it adds up positive input values only, all negative
inputs are clipped to zero. This is a sort of a "Micky Mouse" logic
"OR" function, the ouput will never go negative.
-
Added a DTMF tone generator. It's input value range 0 .. 1 is scaled into a range
0 .. 15 which then is used to select a symbol from [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
A, B, C, D, #, *]. The symbol then is converted into two tones according to the
following table:
|
1209 Hz |
1336 Hz |
1477 Hz |
1633 Hz |
697 Hz | 1 | 2 | 3 | A |
770 Hz | 4 | 5 | 6 | B |
852 Hz | 7 | 8 | 9 | C |
941 Hz | * | 0 | # | D |
-
Added two Xenakis like number sieve modules, one with a blue (addressing) input
control and a clocked version.
Wren's notation for basic modules is:
-
[n,m] : a sieve module with modulus n and residue m
[3,1] -> {1,4,7...}.
-
{numbers|n} : a litteral number sequence, f.i. {1,5,13,14,21|24}
n is the modulus, 24 in this example.
-
fibonacci : the fibonacci sequence {0,1,1,2,3,5,8,13...}.
-
prime : the prime numbers {2,3,5,7,11,13...}.
-
hanoi : the hanoi disc sequence {0,1,4,5,8...}.
-
hanoipegs1 : hanoi peg sequence 1 - non alternating {0,1},
{0,1,3,5} , {0,1,3,5,6,6,7,8}.
-
hanoipegs2 : hanoi peg sequence 2 - alternating {0,2}, {0,1,3,5},
{0,2,3,4,6,6,8,10}.
-
hofstadterq : the Hofstadter Q sequence, chaotic.
-
metafib(n) : genralization of hanoi, n being the order, a whole number.
-
random(f) : a sequence of random numbers, f selects the chance for any
number to be present in the sequence. 0 <= f <= 1, f.i random(0.33).
These can be combined using the following operators:
-
+ : the union of two sieves: [3,0]+[4,0] -> {0,3,4,6,8,9,12...},
the numbers combined (logical or function).
-
* : the intersection of two sieves: [3,0]*[4.0] -> {0,12,24...},
the numbers present in both (logical and function).
-
^ : the symmetric difference of two sieves:
[3,0]^[4,0] -> {3,4,6,8,9,15...}, the numbers in one but not in the
other (logical xor function).
-
! : the complement of a sieve: ![3,0] -> {1,2,4,5,7...}, the
numbers not in the sequence (logical not function).
Parenthesis can be used to enforce an evaluation order, f.i. as in (([3,0]+4,0)*
fibonacci)+prime to first evaluate the left +, then the * and the right + last.
A simplified formula will be calculated when the formula changes, or when the
external period changes. The simplification does not use prime decomposition, it
will compute a sequence and from that it will make a sequence of modules joined
through union.
The evaluate input will force reevaluation of the formula, this can be useful
when a random module is present to obtain a new random sieve.
Otherwise this module functions like the Values module, except that the start
value will always be 0 (zero) and the end value is set by the external period.
This means the input value changing over the standard range as set up with the
input range selector will address all sieve values.
The difference (top) output will output differences between sieve sequence values,
in case the last sequence value was selected it will be the value of the last
minus the first element (this cyclic behaviour was not present in the original
concept).
Negative numbers can not be used in sieves and the random sieve's probability
control is the only floating poin number being used. The ouptuts will still use
float values, as they are scaled to standard output ranges ([0,1, [1,0], [-1,0],
[0,-1], [-1,1] or [1,-1].
The simplified formula is displayed above the user supplied formula, or an error
will be displayed when the user supplied formula could not be parsed.
The currently selected sequence and diffrence values are displayed in white, these
are the unscaled values.
The changed output will go active when the ouput value was changed, the difference
output may not have changed then.
The regualar (bottom) output will be scaled such that the external period results
in an internal output of 1, this can be changed then with the output type
selector.
The difference (top) output will be scaled such that the largest difference value
present will result in an output value of 1, again this can be rescaled using the
output type selector.
For more information on the subject try googling for Xenakis sieve, or Xenakis
sieve algorithm. It may find a 221 page paper by Dimitrios Exarchos (Iannis
Xenakis and Sieve Theory), I've found that to be a very useful text.
Older release notes
|