New Tool (3.0,3.1): xStream

Yep!unpack works! Thanks.

Buttable.unpack is vanilla lua, so I was just trying to use that.

Yeah, I was thinking that the “noisy” error messages would be done away with if using an external editor.

  1. table.unpack is Lua 5.2, I think. Renoise uses Lua 5.1 which uses just “unpack”.

  2. I think you can override any custom logging from xStream by overriding the TRACE() function with something like this. Maybe there is a cleaner way, but this should work.

TRACE = function() return nil end

Hey Joule. Wasn’t sure of what you meant by this:

  1. table.unpack is Lua 5.2, I think. Renoise uses Lua 5.1 which uses just “unpack”.

  2. I think you can override any custom logging from xStream by overriding the TRACE() function with something like this. Maybe there is a cleaner way, but this should work.

TRACE = function() return nil end

Do you mean the TRACE function in cDebug.lua? (line 138)

And just to be clear, I only want to remove the syntax errors in an xStream model. I definitely want to keep any other error messages, since I’m constantly adding new stuff to the xStream source files.

Also, I had no idea Renoise used Lua 5.1. Which is definitely troubling, since I’ve been testing all my code outside of Renoise with Lua 5.3… :rolleyes:

So I’ve been running into another problem.

When I hit the play button, it seems as though I can’t access line 0 in the pattern editor. Or at least not until the playback reaches the end of the current pattern and then hits pattern line 0 on the next pattern.

============================================================

So, I actually_can_ access line 0. Sort of. Just not with xpos.

Let’s say this is my xStream model:

print("pattern, line = ", xpos.sequence, xpos.line)

xline.note_columns[1].note_value = NOTE_OFF_VALUE

And let’s say the pattern editor ‘cursor’ is at line 16. Hitting the play button and stopping after a bit puts an “OFF” note value on:

  • pattern line 16,

  • and on pattern lines 1 through .

But my console output is this:

pattern, line = 1 17

pattern, line = 1 2

pattern, line = 1 3

pattern, line = 1 4

In short, xpos.line never returns ‘1’, at least not until the playback reaches a new pattern (and reaches pattern line 0).

But xStream does do its work on pattern line 0 (it does print an “OFF”).

============================================================

Even worse is when I hit the record button, and then the play button.

Then, I don’t even get an “OFF” note value on pattern line 0. Only on pattern lines 1 through …

My console output is this:

pattern, line = 1 2

pattern, line = 1 3

pattern, line = 1 4

============================================================

Basically, I can’t get xpos.line to return 1 (corresponding to pattern line 0) until I reach a new pattern (and the playback rolls over pattern line 0).

Is this intended? It seems like an inconvenience if it is.

============================================================

I’m wondering because I’m using an if block to execute code only once at the beginning of playback. I mentioned this in an earlier post:

Click to view contents

Praise be the lambda calculus…I’m onto something

I was thinking if I had some kind of latch - which would allow theifconditional to evaluate totrueonly once - then theifblock would only execute once.

All thanks to closures, I can define a function that : returns a 0 the first time its called, butnilfor any successive calls:

latch2nil = function()

latch = function (val)

if val then

val = nil

return 0

else

return nil

end

end

i = 0

return latch(i)

end

And then in my xStream model, I put something like this:

if (xinc==latch2nil()) then

print(“I’m only here once :(”)

end

Now, the if block executes only once! At least, until I hit the play button in xStream again.

Gotta love how lua functions have lexical scoping. I guess I could get the same result without using closures, but this is much nicer.

I’m gonna keep playing around with this to see what I can get away with…

— EDIT : —

Thatlatch2nilfunction is really sloppy. Here’s a better version:

latch2nil = function()

local latch = function (val)

if val then

val = nil

return 0

end

end

local i = 0

return latch(i)

end

I’m using this technique to instantiate objects. But I can’t access the objects on pattern line 0 since the if block won’t run until xpos.line returns 1.

That is, when my if block looks like this:

if (xpos.line==latch2nil()) then

print(“I’m only here once :(”)

end

and assuming that latch2nil would return 1 the first time it’s called.

I’m gonna look into the model user-data stuff. All I’m really wanting is to have an object be persistent throughout playback/recording from xStream. This latch2nil stuff is really hacky, and doesn’t even preserve the state of an object between playback in xStream.

Yeah, so I just figured out how to use the modeldatatable like howyou (Danoise) were trying to tell me earlier:

Ehrm, sorry, let me clarify this:
->datais referring to data that you want to reference in your loop. You can add an initial value using the “+”, or simply define them on-the-go.

Instead of trying to explain the concept, I would suggest you take a look at some of the models that make use of “data”, such as the arpeggiator or LFO?

They both take advantage of the feature to add helper methods, are being initialized with specific values, etc.

Essentially, data is just there for convenience, a way to access and define numbers/tables/functions/etc, so you can keep the main loop clean and focused.

In theory, you could define your (non-luabind) classes there too.

Don’t know why I couldn’t get it working before…

So this is definitely a more legitimate technique for instantiating objects. Plus, you get the ‘persistence’ I was needing (ie, the data maintains its state between xStream playback instances).

It’s kinda clunky though. If I wanna change something in my object, or add something new, I’ll always have to reload the tool, no?

Is there any way to modify the model data table without reloading the tool?

EDIT: (see below)

What was that when you said “You can add an initial value using the ‘+’” ?

And now I’ll take the opportunity to sneak in a feature request :

Can we get access to this model data table in a window alongside the editor window?

Or maybe there should be a mini console to add new members? or modify existing ones?

====================================================

from EDIT :

So I just realized that yes, you can simply add and modify existing data members with ordinary declarations and assignments.

Which now leaves me with a new question:

Is there a way to ‘reset’ the data table to what it was when the tool was initially loaded?

Let’s say I put in the model’s lua file:

data = {

[“val”] = " return 0 ",

},

In my xStream model (the callback), I have this:

if xinc==10 then

data.val = 1

data.new = “hi”

end

Is there a way to “reset” the data table so that I can go back to the initial state?

(ie, data.new gets erased, and data.val becomes 0 again)

Because hitting the play button would just maintain any new additions.

The only way I know how is to just reload the tool.

I suppose I could write a reset function as a member of the data table. But I can’t think of how to do this generically. It would have to be specific to every xStream model.

When I have some time I’ll look into the “accessing first line” issue.

Thanks for the details!

Is there a way to “reset” the data table so that I can go back to the initial state?

(ie, data.new gets erased, and data.val becomes 0 again)

Yes, good idea.

I would want to do it via the GUI somehow (reset, like a refresh but without reloading), but also programmatically.

Okay, one of my little projects is more or less ready for early viewing.

https://github.com/g8tr1522/xStream-fork-thing/tree/BRANCH-userlib-with-LAM

It has two things I’d like you all to see (see below).

Use the branch “BRANCH-userlib-with-LAM” and replace your version of xStream with that.

It uses a git submodule, so you’ll need to run appropriate git commands to get the LuaArrayMethods package loaded.

I think git submodule init --remote LuaArrayMethods will do it? Or maybe git submodule update --remote LuaArrayMethods. I literally learned git just before making this, so fair warning.

========================================================

So first thing I ‘did’ is my hacky way of adding libraries/packages to xStream.

This is more or less my “xStream-fork-thing” repo.

I made a ‘userlib’ module (kept in “source/userlib/userlib.lua”). This single module is required in main.lua. But your packages are required as members of the userlib module. I have an example package to demonstrate.

To make your package visible to an xStream model, you must add an appropriate member to the props_tablein xStreamModel.lua.

You can get a vanilla userlib under the branch “BRANCH-userlib-vanilla”.

========================================================

The other thing is my very handy LuaArrayMethods package.

https://github.com/g8tr1522/LuaArrayMethods

(master branch is always stable)

This makes array manipulation wayyy easier. At least in xStream. It’s documentation is still really lacking, but I do have a basic tutorial in its README.

There is also an xStream model (in my xStream fork) which demonstrates some basic uses of it. It’s titled “~LAM - demo”.

========================================================

This leaves me with a few questions:

Where should I host the discussion of my xStream fork? Should it be here on this thread?

Where should I make a discussion for my LuaArrayMethods package? I made it primarily for Renoise, but I’m not sure if it’s appropriate to open up a thread for it on these forums.

and

Is my hacky ‘userlib’ technique viable for future xStream releases? I’m sure there’s a lot that can be improved upon it before I make a formal pull request. But do you think it could eventually be a legitimate feature?

Also, many apologies for any sloppiness in my code. I’m not a programmer by profession; if it makes music, then it works for me.

I can’t get xStream to run on Renoise 3.1.1 on OS X 10.10.5, whether I use the published 1.57 version or the master branch from git (currently at19d4fecc41c34796b7389c364b1c99239ee17999)

I get this error when installing V1.57

'/Users/padillac/Library/Preferences/Renoise/V3.1.1/Scripts/Tools/com.renoise.xStream.xrnx/main.lua' failed in one of its notifiers.
The notifier will be disabled to prevent further errors.

Please contact the author (danoise [bjorn.nesby@gmail.com]) for assistance...

main.lua:155: attempt to index field 'preferences' (a nil value)
stack traceback:
  main.lua:155: in function <main.lua:153>

and then trying to run Tools->xStream I get

'/Users/padillac/Library/Preferences/Renoise/V3.1.1/Scripts/Tools/com.renoise.xStream.xrnx/' failed to execute in one of its menu entry functions.

Please contact the author (danoise [bjorn.nesby@gmail.com]) for assistance...

./source/xStream.lua:42: attempt to index field 'prefs' (a nil value)
stack traceback:
  ./source/xStream.lua:42: in function <./source/xStream.lua:28>
  [C]: in function 'xStream'
  main.lua:116: in function 'show'
  main.lua:142: in function <main.lua:141>

I cloned the repo from git and sym-linked xStream into the tools directory, and I get this error when launching Renoise:

'/Users/padillac/Library/Preferences/Renoise/V3.1.1/Scripts/Tools/com.renoise.xStream.xrnx/' failed to load.

Please remove this tool or contact the author (danoise [bjorn.nesby@gmail.com]) for assistance...

main.lua:27: module 'source/cLib/classes/cLib' not found:
  no field package.preload['source/cLib/classes/cLib']
  no file './source/cLib/classes/cLib.lua'
  no file '/usr/local/share/lua/5.1/source/cLib/classes/cLib.lua'
  no file '/usr/local/share/lua/5.1/source/cLib/classes/cLib/init.lua'
  no file '/usr/local/lib/lua/5.1/source/cLib/classes/cLib.lua'
  no file '/usr/local/lib/lua/5.1/source/cLib/classes/cLib/init.lua'
  no file '/Users/padillac/Library/Preferences/Renoise/V3.1.1/Scripts/Libraries/source/cLib/classes/cLib.lua'
  no file '/Applications/Renoise.app/Contents/Resources/Scripts/Libraries/source/cLib/classes/cLib.lua'
  no file './source/cLib/classes/cLib.so'
  no file '/usr/local/lib/lua/5.1/source/cLib/classes/cLib.so'
  no file '/usr/local/lib/lua/5.1/loadall.so'
  no file '/Users/padillac/Library/Preferences/Renoise/V3.1.1/Scripts/Libraries/source/cLib/classes/cLib.so'
  no file '/Applications/Renoise.app/Contents/Resources/Scripts/Libraries/source/cLib/classes/cLib.so'
  no file '/Users/padillac/Library/Preferences/Renoise/V3.1.1/Scripts/Libraries/source/cLib/classes/cLib.dylib'
  no file '/Applications/Renoise.app/Contents/Resources/Scripts/Libraries/source/cLib/classes/cLib.dylib'
stack traceback:
  [C]: in function 'require'
  main.lua:27: in main chunk

Hi Pat!
Good to see you around. Last time you last popped in to say hi to xStream you left quite a lot of good feedback…

I get this error when installing V1.57

You’ve encountered the same issue as so many others. The problem is known and has been “fixed” (worked around)
https://github.com/renoise/xrnx/issues/102

So yeah, solution is to clone from git. But I recently switched to submodules instead of symlinking, and need to update the README (installation instructions)

I’ll look into straight away…

Edit: yep, as I suspected I hadn’t added submodules for xStream. Done now.

To include the submodules when cloning, you need to pass the --recursive argument

git clone --recursive https://github.com/renoise/xrnx.git

Hope this helps!

Hi Pat!
Good to see you around. Last time you last popped in to say hi to xStream you left quite a lot of good feedback…

You’ve encountered the same issue as so many others. The problem is known and has been “fixed” (worked around)
https://github.com/renoise/xrnx/issues/102

So yeah, solution is to clone from git. But I recently switched to submodules instead of symlinking, and need to update the README (installation instructions)

I’ll look into straight away…

hrm okay. I didn’t see the submodule stuff. I was hoping that would be an easy fix… I did

git submodule init && git submodule update

from the main xrnx folder and that seemed to work, it cloned a bunch of submodules.

But I still get the third error message I showed above there, the one about cLib. For some reason (that I don’t understand) the xStream submodules aren’t getting pulled. Here’s what I get when I init:

Submodule 'Tools/com.renoise.Duplex.xrnx/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.Duplex.xrnx/cLib'
Submodule 'Tools/com.renoise.Duplex.xrnx/xLib' (https://github.com/renoise/xLib) registered for path 'Tools/com.renoise.Duplex.xrnx/xLib'
Submodule 'Tools/com.renoise.MidiPerformer.xrnx/source/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.MidiPerformer.xrnx/source/cLib'
Submodule 'Tools/com.renoise.MidiPerformer.xrnx/source/vLib' (https://github.com/renoise/vLib) registered for path 'Tools/com.renoise.MidiPerformer.xrnx/source/vLib'
Submodule 'Tools/com.renoise.MidiPerformer.xrnx/source/xLib' (https://github.com/renoise/xLib) registered for path 'Tools/com.renoise.MidiPerformer.xrnx/source/xLib'
Submodule 'Tools/com.renoise.Noodletrap.xrnx/classes/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.Noodletrap.xrnx/classes/cLib'
Submodule 'Tools/com.renoise.Noodletrap.xrnx/classes/xLib' (https://github.com/renoise/xLib) registered for path 'Tools/com.renoise.Noodletrap.xrnx/classes/xLib'
Submodule 'Tools/com.renoise.PhraseMate.xrnx/source/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.PhraseMate.xrnx/source/cLib'
Submodule 'Tools/com.renoise.PhraseMate.xrnx/source/vLib' (https://github.com/renoise/vLib) registered for path 'Tools/com.renoise.PhraseMate.xrnx/source/vLib'
Submodule 'Tools/com.renoise.PhraseMate.xrnx/source/xLib' (https://github.com/renoise/xLib) registered for path 'Tools/com.renoise.PhraseMate.xrnx/source/xLib'
Submodule 'Tools/com.renoise.ScaleMate.xrnx/source/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.ScaleMate.xrnx/source/cLib'
Submodule 'Tools/com.renoise.ScaleMate.xrnx/source/xLib' (https://github.com/renoise/xLib) registered for path 'Tools/com.renoise.ScaleMate.xrnx/source/xLib'
Submodule 'Tools/com.renoise.SliceMate.xrnx/source/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.SliceMate.xrnx/source/cLib'
Submodule 'Tools/com.renoise.SliceMate.xrnx/source/vLib' (https://github.com/renoise/vLib) registered for path 'Tools/com.renoise.SliceMate.xrnx/source/vLib'
Submodule 'Tools/com.renoise.SliceMate.xrnx/source/xLib' (https://github.com/renoise/xLib) registered for path 'Tools/com.renoise.SliceMate.xrnx/source/xLib'
Submodule 'Tools/com.renoise.VoiceRunner.xrnx/source/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.VoiceRunner.xrnx/source/cLib'
Submodule 'Tools/com.renoise.VoiceRunner.xrnx/source/vLib' (https://github.com/renoise/vLib) registered for path 'Tools/com.renoise.VoiceRunner.xrnx/source/vLib'
Submodule 'Tools/com.renoise.VoiceRunner.xrnx/source/xLib' (https://github.com/renoise/xLib) registered for path 'Tools/com.renoise.VoiceRunner.xrnx/source/xLib'
Submodule 'Tools/com.renoise.cLib.xrnx/source/vLib' (https://github.com/renoise/vLib) registered for path 'Tools/com.renoise.cLib.xrnx/source/vLib'
Submodule 'Tools/com.renoise.vLib.xrnx/source/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.vLib.xrnx/source/cLib'
Submodule 'Tools/com.renoise.vLibBoilerPlate.xrnx/source/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.vLibBoilerPlate.xrnx/source/cLib'
Submodule 'Tools/com.renoise.vLibBoilerPlate.xrnx/source/vLib' (https://github.com/renoise/vLib) registered for path 'Tools/com.renoise.vLibBoilerPlate.xrnx/source/vLib'
Submodule 'Tools/com.renoise.xCleaner.xrnx/source/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.xCleaner.xrnx/source/cLib'
Submodule 'Tools/com.renoise.xCleaner.xrnx/source/vLib' (https://github.com/renoise/vLib) registered for path 'Tools/com.renoise.xCleaner.xrnx/source/vLib'
Submodule 'Tools/com.renoise.xCleaner.xrnx/source/xLib' (https://github.com/renoise/xLib) registered for path 'Tools/com.renoise.xCleaner.xrnx/source/xLib'
Submodule 'Tools/com.renoise.xLib.xrnx/source/cLib' (https://github.com/renoise/cLib) registered for path 'Tools/com.renoise.xLib.xrnx/source/cLib'
Submodule 'Tools/com.renoise.xLib.xrnx/source/vLib' (https://github.com/renoise/vLib) registered for path 'Tools/com.renoise.xLib.xrnx/source/vLib'

So… lots of submodules, but none of the xStream ones.

Oh, look above. For whatever reason, I hadn’t added xLib etc. to the xStream tool.

Looking forward to your input - since last time, I’ve fixed some annoying bugs and reworked the streaming to make it a lot faster.

okay thanks! btw I thought I was going crazy… I wiped the dir, cloned to get a clean repo, and it didn’t work. I wiped the dir again, cloned again, and it worked this time – I hadn’t realize that you had fixed it in between the times I had cloned it! :slight_smile:

Okay I’m up and running, checked out some stuff and it’s cool – I’m getting the hang of xStream models again.

(btw I had stayed away from xStream for a while because I’m more interested in it for offline work for the time being, and it didn’t really support that workflow for a while. Anyway…)

The challenge I’m running into right now is that the model I’m working on is somewhat complex, and for me to have a chance at completing it I need to take a more structured approach to it – at the very least, write tests so that I know I have my basic examples working. Splitting things into separate files and editing with a text editor would be sweet too.

Do you have any suggestions for how to go about constructing a library outside of xStream that I can use inside it? I saw this post which looks like it aims to do something like that.

It may be that my idea (a voice leading tool, which joule_did say would be challenging…) is too big for an xStream model and is better off as its own tool. But I_really like the xStream approach, configuration with args etc. What do you think?

I just wanted to drop a very small idea regarding the GUI, before I delete it, that could perhaps inspire some further revamping. I think the xStream GUI has quite an intense scare factor to new users, with all its custom buttons and symbols.

7897 xgui.gif

@joule: good idea. I can get confused myself :slight_smile:

Edit: btw: did you actually implement these changes? Could you perhaps share them with me (I’m lazy)

It may be that my idea (a voice leading tool, which joule_did say would be challenging…) is too big for an xStream model and is better off as its own tool. But I_really like the xStream approach, configuration with args etc. What do you think?

Indeed, some things are just too big or complex to make them suitable for a model. But unless there’s some major restructuring required, it would be quite simple to “knock a hole” through the xStream sandbox and provide access to your own library/class.

If your class is well structured, it should be easy to port it over, make a standalone tool at a later point. Using xStream as a rapid-prototype kind of tool :slight_smile:

On a more general note, “streaming” dictates a certain kind of thinking, where you can only respond to things as they happen.

A person (can’t remember who) asked if it would be possible to sort notes using xStream. My response : not the right tool for the job, because you don’t know what’s going to happen at a later time. This is something I’m not planning to change.

Do you have any suggestions for how to go about constructing a library outside of xStream that I can use inside it? I saw this post which looks like it aims to do something like that.

Hey, that’s me!

Yeah, so I’ve successfully gotten my own external libraries to work in xStream.

https://github.com/g8tr1522/xStream-fork-thing/tree/BRANCH-userlib-vanilla

Initialize the repo in your tools folder in a folder named “com.renoise..xrnx”.

(I haven’t set this up as a fork off of the official renoise repo yet).

Checkout the branch “BRANCH-userlib-vanilla” to get a clean slate.

I have small instructions in “source/userlib/userlib.lua” and in “source/xStreamModel.lua”.

I write and test my libraries’ code externally before testing/using it in xStream. I haven’t had many hiccups. The trick is to put everything into one module (which I called userlib), and require that module in main.lua. Otherwise, you get weird errors for requiring two or more things in main.lua. You must also make your libraries visible in “source/xStreamModel.lua”.

I’ll also shamelessly plug my LuaArrayMethodslibrary again. You can check that out if you checkout the branch “BRANCH-userlib-with-LAM”.

I just wanted to drop a very small idea regarding the GUI, before I delete it, that could perhaps inspire some further revamping.

No further revamping, but I (still) think this is a good idea.
Other than that, I’m just looking to polish off the improvements we’ve made, and (try to) properly test it.

What news will there be since the last official version? :slight_smile:

I’ve been keen on submitting some actual suggestions (gui improvements and “xlight menu”) but didn’t know what branch to start from.

EDIT:

  1. Having a brief look at cLib/cSandbox. The __index metamethod looks VERY suboptimal (like table.find on every call et c). It would be better to set up an environment with allowed keys on init. And the properties scheme there is a bit extravagant with some overhead, compared to storing stuff directly in the environment table. The sandbox variables are quite ‘fixed’ in the xStream implementation anyway, I’d suppose.

This should be quite easy to optimize heavily, for a less green environment?

  1. I made a trace function that features indentation B) , like a virtual code tree if you put TRACE inside every function. I’ll try sharing this after trying to add a (rough) function counter inside. That should be really interesting for optimizing a big tool like xStream, clearly showing what functions to focus most on. Maybe these things could be interesting for cDebug

It will mostly be improvements to the buffer (the massive speedup we did together), which still lacked proper testing.
And it’s well worth the effort - I’ve already found a few stupid typos and such.

The “stacked models” branch is of course still there too. I’m most likely going to cherry-pick things from it, once this release has settled a bit.

didn’t know what branch to start from.

I’m currently working on merging the xstream-new-buffer-implementation branch into the master

  • mostly working on this locally, but already made a few commits to the master, I think.

This is the milestone I’m working towards, btw.
https://github.com/renoise/xrnx/milestone/3

Re the sandbox: yeah, how it was planned to work, and how it actually ended up being used are two slightly different things.
I think by now you’ve been diving deeper into lua meta-methods than I have, so I’m keen to hear your input/opinions.

AFAIK the “table as a switch” (using associative, string based keys for access) is very efficient in lua, comparable with environment tables.
But perhaps you have evidence that shows otherwise? I must admit, profiling code is often the last thing I do …

I will have a look and get back here. It’s not at all certain that I’m correct in everything that I say :o

This is one of those times I wish there was a real way to trace function calls backwards in some IDE. The whole xStream code (like any larger project) isn’t very easy to penetrate and get a full birds-eye perspective on.

At least, I’m pretty positive that this particular __index metamethod is the single one function that is most frequently called within the whole software :slight_smile: (not counting native/renoise metamethods)