Introducing xStream
xStream allows you to generate or transform existing pattern/automationdata via custom code which can be created and tweaked in realtime
Documentation
When you install the tool, a ‘README.md’ is located in the installation folder. This is a markdown-formatted documentation file, including a quick reference to the xStream-specific Lua API. You can also visit the xStream github page for the newest version of documentation, regardless of what version you have installed.
And of course, you can study the example models. For newcomers, it is highly recommended to start with themodels which are prefixed with ‘Demo-’. These models are designed to demonstrate a particular aspect of xStream without being overly complex.
I’m normally just an occasionallurker at these forums, but this particular tool of yours forces me to sign in and comment.
First of all,seems like an interestingconcept. I’ve only tested the tool for half an hour, but I’mlooking forward to explore its full potential.
Now, one of the ideas for a macro I immediately felt the need to create was a custom chord generator. Unfortunately I don’t speak this lua language, but I managed to figure this much out by copy-pasting from your examples into the empty slot.
--Creates a minor chord from the note value in note column 1
--
--Example:
--enter C-4 (or any other note value) in note column 1 in a track
--select the row
--press fill_selection button in xStream methods
--the C-4 (or other note value) will be replaced with C-4 +
-- D#4 + G-4 which is the C minor chord
--
--------------------------------------------------------------
local existing_note = xline.note_columns[1].note_value
xline.note_columns = {
{
note_value = existing_note + 0,
instrument_value = 13,
volume_value = args.volume,
panning_value = 80
},
{
note_value = existing_note +3,
instrument_value = 13,
volume_value = args.volume
},
{
note_value = existing_note +7,
instrument_value = 13,
volume_value = args.volume
}
}
Now if I want to manipulate the Cx (cutoff note) parameter in the panning_value so that it is for example “C8”, what needs to be done? It only seems to accept numerical values. Any suggestions?
it’s really encouraging to know that you could use the tool without much prior knowledge
Now if I want to manipulate the Cx (cutoff note) parameter in the panning_value so that it is for example “C8”, what needs to be done? It only seems to accept numerical values. Any suggestions?
It follows the Renoise API way of specifying things. So, you can use both value or string, whichever is the most handy.
-- here, the value and string amount to the same thing - a C-8 note
note_string = "C-8"
note_value = 96
The API documentationhas the full information on note and effect-column properties, including special ones like “OFF”
True, you can specify any possible value using numbers. It can be a little complex though, because you’d need to pass values through a little calculation first.
In most cases, strings are much easier to work with, what you see in the pattern editor you can also enter as a string value:
panning_string = "C8"
If the value “8” happened to be the result of some kind of calculation, you could hand over a string by using string.format()
local my_ticks_value = 8
panning_string = ("C%d"):format(my_ticks_value)
But if you are applying a value as a result of some kind of expression, or you are comparing values, numbers are useful.
For example, this little snippet will only transform notes that are not empty or note-offs
-- transpose notes down one semitone
if (xline.note_columns[1].note_value < 120) then
xline.note_columns[1].note_value = xline.note_columns[1].note_value - 1
end
This is so, because the “note off” and “empty” are both higher than 119 (120 and 121, respectively)
For me xStream seems to have a lot more potential in offline mode.
I imagine inthe future xStreamwould hosta hugenumber of models/buttons (placed on a second screen in dual monitor setup), each buttonexecuting anunique custom macro operation. Maybe hundreds of such models would need to be placed within selectable categoriesor something for a better overview. Thiswould bemy first feature request, because it would make it easier to organize stuff.
I imagine inthe future xStreamwould hosta hugenumber of models/buttons (placed on a second screen in dual monitor setup), each buttonexecuting anunique custom macro operation. Maybe hundreds of such models would need to be placed within selectable categoriesor something for a better overview. Thiswould bemy first feature request, because it would make it easier to organize stuff.
Indeed, this is something I’ve been thinking about as well. Right now, it’s presenting whatever models you have in a single folder - logical next steps would be to list those models in a table, grid or some other container, along with the ability to categorize presets by putting them into subfolder (I’m a big fan of using the file system to describe a hierarchal structure). Right now, it’s a problem that you so easily can run out of space on the screen.
And while “hundreds of models” might sound a little overwhelming, yeah - why not. I think I would personally aim for a little more flexibility in my models, and use the preset system to create unique variations thereof - but then, obviously the preset system too would need the ability to host hundreds of entries
Anyway, this doesn’t work for me:
Well spotted! There was indeed a little mistake when applying alfa-numeric values that could be interpreted as hex (U8 would work, but your C8 wouldn’t… uploading a fix ASAP
For the first suggestion, I just get the same 3 notes played in the same sequence, endlessly, throughout the track.
Well, it depends on what you “feed” it - since that model is transforming existing pattern data, the notes will remain the same. If you had some melody line, chord sequence, you should be able to hear a difference.
For me xStream seems to have a lot more potential in offline mode.
This is also a point which was raised at the meetup. Basically, xStream will, in its current shape, allow you to do “only one thing at a time”.
While that of course makes sense in this early stage, it also is quite limiting from a live performance, jamming point of view.
My longer-term ideas for xStream involves having a kind of “stream manager”, essentially a type of arranger which will allow you to control multiple models, and schedule events at certain times.
But right now, this is really a pipe dream because of the amount of work involved. Focusing on making the core as efficient and stable as possible has the top priority!!
FIXME attempt to fix crash-proneness : apply the callback string during idle loop instead of right away
FEATURE detect when model is changed, ability to revert to last saved state
CORE better unit tests for song pos
Edit: this update seems to resolve one of the major problems so far, which was a tendency to crash Renoise - especially true with the most complex models (‘Sequencer4’).
My theory as to why this could happen? It turned out that, when switching between models, or setting a model for the first time, the act of updating the user interface - more specifically, the textfield containing the callback code - would call it’s notifier once for every line. This would result in xStream trying to compile the callback method maybe 50 times in a split-second…
While doing such a thing shouldn’t really be able to take down Renoise - ever - xStream is using some pretty “unusual” features of the lua language, and as such, we might have headed a little bit into unknown/untested territory here.
Bottom line is, I have improved xStream in this regard - the user interface will now wait for the idle update before submitting a modified string. Hopefully, this should prevent crashes from happening. Please report this if it still happens to you.
Also, there is now a “revert to saved” button, and the “save” button is enabled only when the model has been modified.
FIXME attempt to fix crash-proneness : apply the callback string during idle loop instead of right away
FEATURE detect when model is changed, ability to revert to last saved state
CORE better unit tests for song pos
Edit: this update seems to resolve one of the major problems so far, which was a tendency to crash Renoise - especially true with the most complex models (‘Sequencer4’).
Have been working on that too and found out what the problem is: The buttons which do select new models do update/rebuilt all buttons which select new models too when clicking them, so pressing a model button killed the button that was currently pressed. We’re internally avoiding doing such things, but for tools we can’t make such “prerequisites”, so I’ll fix that here for the next Renoise update.
If you need a workaround for your tool now: avoid rebuilding the model buttons when selecting a new model via a model button - then it should work.
TBH the audio in video needs some compression for upper volumes, expandation/gating for quitter stuff and eq on highs. Was quite difficult at least for me to understand the words… My respect you did this presentation and explained it so detailed.
Can this tool go through a selection of notes and sort these over time, from lowest note to highest note or the other way around? The time it takes to sort, generated as pattern content…something like this;