Jump to content


Photo

How do I do the stuff you can do in Sonic Pi? (gimmie homework please)

Sonic Pi algorithmic composition

  • Please log in to reply
22 replies to this topic

#1 g8tr122

g8tr122

    Member

  • Normal Members
  • PipPip
  • 12 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 15 June 2016 - 23:54

Hello all. I don't frequent these forums very often, but I hope I can eventually contribute something big to the community.

 

So I spent the last month or so learning Ruby and Sonic Pi. And wowie zowie, is it easy to get a crazy awesome beat in SP. But SP is getting frustrating because it's impossible to write a song with transitions. Renoise is baby's-first-DAW, and when I'm doing anything in SP, I always get homesick, and wish I had a tracker interface and pattern editor. So after I read the READ-ME for the Renoise scripting API, and saw that Algorithmic composition is very possible, I knew I had to put my efforts into this. 

But I don't know where to start.

 

About my programming skills: 

I'm not new to programming; I'm learning signal processing in MATLAB next semester. What I am very unfamiliar with, is file-handling, building and managing libraries, working with terminals. I've never used an API before. Even worse, I only really became fully comfortable with OOP when I just learned Sonic Pi; I finally had a practical reason to write big class structures.

I attempted to learn Lua, expecting it to be as easy as it was to pick up Ruby. Boy was I wrong. The whole idea of making your own OOP paradigms seems awesome, but I'm already having trouble with the stateless and stateful iterators. 

 

SP was so easy to jump into. The documentation gives easily understandable explanations for using the SP features. It touches on educating the reader on basic electronic music composition. But it goes so far that it also explains very simple programming paradigms like setting variables! I won't need that much hand-holding of course, but it was very easy to learn SP because the docs were geared towards teaching children. But more importantly, there are examples EVERYWHERE. I didn't have to learn anything when I started. I just copied and pasted code, then changed some numbers, then added parameters, then swapped out fx units, etc. This made it easy to figure out what SP could and couldn't do. Then after messing around like this, I buckled down and got serious, learning all the technical details.

 

My point is that I wish the Renoise docs were this easy. I don't know where to start with this! I'm sure all of what I need is in Renoise.song.api.lua, but I don't know what to do with that information. So maybe I do need some hand-holding. I need examples to illustrate the concepts to me.

 

To narrow things down, I'd be very satisfied if someone could explain this in particular:

- how to put random notes in the pattern matrix, where the notes are chosen randomly from an array/table of notes I specify.
- how to specify the time to 'rest' in-between each note.
If anyone could spoonfeed that to me, I could probably figure out the rest myself. If you're feeling generous, how do I do a similar thing with VST instrument parameters? And with Renoise's built-in effects?

 

If this was as easy as Sonic Pi, I wouldn't be asking you to write code for me, but I really don't know where to begin.

 

TLDR: I want to do algorithmic composition in Renoise. I want easy, fully explained examples so I can have a jumping-off-point. I'm willing to put in hard work (i.e., learn Lua and study API docs), but I don't know where to begin at all. So give me some examples pretty pleeeaaasseeeee. :)

 

Thanks for the help so much! I really need it. 


Edited by g8tr122, 16 June 2016 - 03:31.


#2 fifagifs

fifagifs

    Advanced Member

  • Normal Members
  • PipPipPip
  • 71 posts

Posted 16 June 2016 - 05:05

Bump to check back as I'd love to achieve algocomp but have absolutely no coding experience. A fun way to get some interesting sequence results is to use fairly short phrases with odd length or odd lpb relative to the global LPB. It's not remotely algorithmic but fun nonetheless. Being able to assign phrase lpb and length to instrument macros would get us closer, but not on the level of Sonic Pi. Btw, Sam Aaron is a genius! Do you mind me asking if you use Renoise to process loops made with Sonic Pi? Or do you use them separately?

soundcloud.com/fifagifs


#3 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1467 posts
  • Gender:Not Telling
  • Location:Sweden
  • Interests:music, philosophy, engineering

Posted 16 June 2016 - 09:26

I'm very much in favor of making algorithmic tools to help rapid prototyping of arrangements! :)

 

I really want to recommend you to consider using xStream as a platform for such experiments/models. At least check it out. xStream is like an "API" for generating pattern data (including a preset system) and there are already interesting models available that you can learn from! You can quite easily make your own models, or even your own class for it if you feel something fundamental is missing. I think this platform has a lot of potential and that it will get even better. To me, xStream is (or will be) for pattern generation what duplex is for midi controllers (the developer seems pretty committed), so consider using this instead of making your own stand-alone tool from scratch IMO :)

 

I'm currently working on a chord class for xStream, being able to read, manipulate and then write chords (simple mechanics really). By this you'd be able to, for example, convert a chord track to an arp track (even complex arps that you wouldn't normally try to track by hand). Or create a chord track by combining a simple chord track with a 'rhythm track'. Check out https://github.com/s...ule-development . This might be something you could make use of with algorithmic composition as well.

 

xStream currently doesn't support multiple tracks or ability to stack or run multiple models at once, but this doesn't scare me off considering its potential. At the very least, it's a great place to start for simple and convenient prototyping!

 

https://www.renoise.com/tools/xstream

 

PS. The TRK button will render the model into the track. I pretty much disregard the "live" mode.



#4 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6359 posts
  • Gender:Male
  • Location:Berlin
  • Interests:wildlife + urban trekking

Posted 16 June 2016 - 12:50

What joule said - take a look at xStream. It's definitely the closest thing Renoise has to Sonic Pi and it's getting more powerful with each new release. 

 

SP was so easy to jump into. The documentation gives easily understandable explanations for using the SP features. It touches on educating the reader on basic electronic music composition. But it goes so far that it also explains very simple programming paradigms like setting variables! I won't need that much hand-holding of course, but it was very easy to learn SP because the docs were geared towards teaching children. But more importantly, there are examples EVERYWHERE.

 

Yup, examples are definitely the most 'real' way of learning to do stuff. Think of the Renoise API docs as a reference - you need that too. 

 

But first step - no matter what - if you are serious about scripting in Renoise, enable the scripting console (explained here: https://github.com/renoise/xrnx)

Then you will be able to run little snippets of code and examine the outcome. 


Tracking with Stuff. API wishlist | Soundcloud


#5 g8tr122

g8tr122

    Member

  • Normal Members
  • PipPip
  • 12 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 16 June 2016 - 14:50

Yeah, I did see xStream. Seemed like it was what I wanted too, but same thing; I didn't know where to begin. Also, I went to the "favorites" dialog, and when I tried to resize it, I got an error message, so I was afraid it might be busted. I'll take a look at it again though. I guess I'll read the docs for any methods that come up, and try to get some sense of it that way.

Do you guys know any sources that give an xStream tutorial?

 

xStream currently doesn't support multiple tracks or ability to stack or run multiple models at once, but this doesn't scare me off considering its potential. At the very least, it's a great place to start for simple and convenient prototyping!

 

https://www.renoise.com/tools/xstream

 

PS. The TRK button will render the model into the track. I pretty much disregard the "live" mode.

 

I'm not worried about "live mode" either. At least for now. But I wasn't sure what it meant when it said it didn't support multiple tracks? That just means you can only operate on one track at a time, right? Like, you can't write a single script that processes two different tracks? 
 

Bump to check back as I'd love to achieve algocomp but have absolutely no coding experience. A fun way to get some interesting sequence results is to use fairly short phrases with odd length or odd lpb relative to the global LPB. It's not remotely algorithmic but fun nonetheless. Being able to assign phrase lpb and length to instrument macros would get us closer, but not on the level of Sonic Pi. Btw, Sam Aaron is a genius! Do you mind me asking if you use Renoise to process loops made with Sonic Pi? Or do you use them separately?

Sam Aaron is a genius. Have you seen this research paper of his? Some crazy CS stuff in there.
https://www.doc.ic.a...m14-sonicpi.pdf

 

I thought about using the pattern matrix to stitch together loops I prerecorded. But I'd definitely rather have the full programming aspect. Then I could manually edit and fine tune a random sequence to my liking. (Which Sonic Pi doesn't do well at all.)



#6 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1467 posts
  • Gender:Not Telling
  • Location:Sweden
  • Interests:music, philosophy, engineering

Posted 16 June 2016 - 18:07

I'm not worried about "live mode" either. At least for now. But I wasn't sure what it meant when it said it didn't support multiple tracks? That just means you can only operate on one track at a time, right? Like, you can't write a single script that processes two different tracks?


Actually you can do that quite easily, but xStream isn't primarily "meant" to be used like that (yet, I think).

You do have access to the whole renoise.song() object. If you want to output to (or input from) a different track, the key is to use xpos.line and xpos.sequence instead of xline (which is current track only).
 

local current_pattern = rns.sequencer.pattern_sequence[xpos.sequence]
local current_line = xpos.line
local output_track_x = whatever_track_index

rns:pattern(current_pattern):track(output_track_x):line(current_line) -- do whatever with this!

Nice things with using xStream imo is 1) live sandbox coding, 2) everything "in sync" and flexible, xinc%x rocks 3) interesting models already available, 4) a great tool probably having a bright future, so might as well start using it for these kind of tasks. 5) preset system already implemented, 6) midi triggering features already implemented for the hipsters, 7) system for setting up a GUI for variables is already implemented


Edited by joule, 16 June 2016 - 18:11.


#7 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6359 posts
  • Gender:Male
  • Location:Berlin
  • Interests:wildlife + urban trekking

Posted 16 June 2016 - 20:11

xinc%x rocks

  
Let me spreadshirt that!


  • joule likes this

Tracking with Stuff. API wishlist | Soundcloud


#8 g8tr122

g8tr122

    Member

  • Normal Members
  • PipPip
  • 12 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 16 June 2016 - 22:03

Still don't know where to begin, even with xStream. The examples are too dense for me to decipher. Even worse, it's not opening some of the examples. I tried opening Euclidian rhythms.lua, and I got: Error: a model already exists with this nameWhen I try to delete some models (not all), I get: No such file or directory

 

Again, is there a resource that slowly and thoroughly explains how to use the members in Renoise.Song.API.lua? Or just how to use the API in general? I need baby steps with this stuff. 



#9 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6359 posts
  • Gender:Male
  • Location:Berlin
  • Interests:wildlife + urban trekking

Posted 16 June 2016 - 22:27

I tried opening Euclidian rhythms.lua, and I got: Error: a model already exists with this nameWhen I try to delete some models (not all), I get: No such file or directory

 

xStream will import all models from the /userdata/models folder when first initialized, so there is no need to open/import a model. This would also explain the error message you are getting, because the tool will not accept two models with the same name. Instead, just select the model you want to run from the popup menu in the topmost toolbar? 

 

When it comes to documentation, video tutorials would be nice - there are only _so_ many things you can reliably communicate in writing. Small, focused videos explaining some of the more basic stuff - like: how to open a model and create some content in the pattern.


Tracking with Stuff. API wishlist | Soundcloud


#10 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1467 posts
  • Gender:Not Telling
  • Location:Sweden
  • Interests:music, philosophy, engineering

Posted 17 June 2016 - 08:44

Check out "demo-Periodic output". That's the "hello world" of xstream, I think. Or "demo-transpose".

When it comes to the Renoise Lua API, you pretty much wanna get familiar with the pattern lines in this case, as this is what you're gonna manipulate with xstream 90% of the time. Understanding pattern lines, for loops/if statements, simple arithmetics and basic lua syntax will allow you to achieve very much with xStream.

First babystep to make the Renoise Lua API less scary:

1) Enable the lua console in Renoise -- https://github.com/renoise/xrnx
2) Familiarize yourself with the renoise.song() object in the lua terminal. Check the output from the following commands:
2a) oprint(renoise.song())
2b) rprint(renoise.song().patterns[1].tracks[1].lines)
2c) oprint(renoise.song().patterns[1].tracks[1].lines[1]) -- is the same as renoise.song():pattern(1):track(1):line(1)
(rprint is for investigating tables)

xline in xStream is basically such a line object, slightly customized. In an xStream model: xline.note_columns[1].note_value = 40 -- will insert a note value of 40 on every line.

The renoise song API can be found here: https://github.com/r...se.Song.API.lua . I've only checked it (ctrl-f) occasionally, and found that you'll learn the most by experimenting in testpad.lua or the terminal.


Edited by joule, 17 June 2016 - 09:29.

  • oise likes this

#11 g8tr122

g8tr122

    Member

  • Normal Members
  • PipPip
  • 12 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 19 June 2016 - 19:59

I've been using the terminal as my general Lua console for now, lol.

I've been reading Renoise.Song.API.Lua, and yeah seems like a reference-only document. 

 

Check out "demo-Periodic output". That's the "hello world" of xstream, I think. Or "demo-transpose".

 

...

xline in xStream is basically such a line object, slightly customized. In an xStream model: xline.note_columns[1].note_value = 40 -- will insert a note value of 40 on every line.

 

I'll start with these. Thanks for pointing me there!

I'm looking at the xStream readme, and there are dialog boxes on there that are different from mine, and some that I haven't even seen! Is that readme up to date??

and NEVERMIND. I FOUND THIS. https://github.com/r...ource/xLib/docs
This is all I needed guys. But one more thing, do I post my future xStream questions on the general forum? (here:) http://forum.renoise...l-3031-xstream/


Edited by g8tr122, 19 June 2016 - 20:01.


#12 g8tr122

g8tr122

    Member

  • Normal Members
  • PipPip
  • 12 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 21 June 2016 - 05:07

I'm looking at the xStream readme, and there are dialog boxes on there that are different from mine, and some that I haven't even seen! Is that readme up to date??

Okay, I noticed that there was an xStream update on the 16th, so that answers why the readme confused me. 
 

Check out "demo-Periodic output". That's the "hello world" of xstream, I think. Or "demo-transpose".

I JUST deciphered "periodic-output"!!! I was able to properly mess around with it too! It felt GREAT. Now I just need to get this lua table business straightened out, as well as working with random stuff in lua. 
*looks up math.random and realizes it interfaces with the C stdlib*
Well I guess I gotta figure out this C API as well...  :( Which means I'll probably be spending the rest of July reading most of Programming in Lua

So thanks a bunch joule for getting me started! lol
Hopefully I can figure the rest out myself. But I will have questions regarding xStream; again, do I post my future xStream questions on the general forum? (here:) http://forum.renoise...l-3031-xstream/



#13 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1467 posts
  • Gender:Not Telling
  • Location:Sweden
  • Interests:music, philosophy, engineering

Posted 21 June 2016 - 08:44

math.random() is just a simple LUA function that generates a random number AFAIK, as seen here: http://lua-users.org...LibraryTutorial
 
I'm sure there are ways to generate randomness that are flexible and advanced like hell (?), but the simple way to use it would probably be something like:

if (math.random(1, 20) == 1) then
  print("I had a five percent chance of being printed")
end

I would guess that a more "musical" way to generate randomness (line hits) that I'd try would be to determine a specific amount of hits that should be distributed for every 16 lines (for example). And then perhaps add another layer allowing that number to fluctuate +- a specific amount of hits. Controlled randomness :)


Edited by joule, 21 June 2016 - 08:53.


#14 g8tr122

g8tr122

    Member

  • Normal Members
  • PipPip
  • 12 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 21 June 2016 - 23:09

The MagPi articles for Sonic Pi go all over the place with randomness. Including 'resetting' the seed to repeat a psuedo-random sequence; e.g., a bass line with eight random notes, but it repeats the same random notes over, and over. Don't like that random sequence?, change the seed!!
This is where SonicPi really arrests me. All sorts of unpredictable 'glitch' drum beats made by making the seed reset or advance randomly, but with chosen probability.

 

Here's the download for the article: https://www.raspberr...ls-sonic-pi-v1/
The stuff I was talking about is mostly in chapters 3 and 7.



#15 g8tr122

g8tr122

    Member

  • Normal Members
  • PipPip
  • 12 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 22 June 2016 - 01:18

But yeah, I'm sure i can start doing that quickly in xStream. But I'm so impressed by Lua that I feel motivated enough to read the whole documentation. Plus, I'll want to write my own classes, and it seems like Lua does that very unconventionally.


Edited by g8tr122, 22 June 2016 - 01:22.


#16 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1467 posts
  • Gender:Not Telling
  • Location:Sweden
  • Interests:music, philosophy, engineering

Posted 22 June 2016 - 11:07

Yeah, I've just gotten a bit into classes (being a forever noob at programming).

 

If you read the class/OOP part on the official lua page, you'll find that a class is pretty much a template table with one of the elements being a constructor function. This constructor is used when creating copies/objects of this table/class. The constructor function and what setmetatable can do is pretty much what you need to understand to set up simple classes. But.. one thing worth mentioning is that Renoise provides (via luabind?) an 'enhanced' way of dealing with classes that seems to be a bit more convenient.

 

Danoise has explained some of it to me in this thread recently: http://forum.renoise...inner-question/ It might help you get in the ballpark.

 

EDIT: Imo the xStream might benefit from an even more standardized and modular framework. I've been thinking about the possibility of a "Pulse/Oscillator" class for setting up various hit patterns, instead of coding intricate if statements with arithmetics in each and every model.


Edited by joule, 22 June 2016 - 11:22.


#17 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6359 posts
  • Gender:Male
  • Location:Berlin
  • Interests:wildlife + urban trekking

Posted 24 June 2016 - 09:48

The MagPi articles for Sonic Pi go all over the place with randomness. Including 'resetting' the seed to repeat a psuedo-random sequence; e.g., a bass line with eight random notes, but it repeats the same random notes over, and over. Don't like that random sequence?, change the seed!!

 
Yep, random is great. Just in case you've missed this detail, the lua math.random is also seeded. The way you start over (or provide a new sequence) is to call the math.randomseed() function. So, whenever you are calling random it actually would spit out the same sequence of numbers - question is, how & when to set the seed.

 

The way I would use this is to create an argument for your model (+ in the args panel) and provide the following
 
name: rnd_seed (or whatever...)
type : number(integer)
fire-start: enabled
 
Then, add a handler function for the argument by clicking the plus sign below the code editor -> "Add event handler" and choose the argument you just created. 
The code editor should initialize with a blank template. Now add the following into it:

math.randomseed(args.rnd_seed)

And there you are. Whenever you modify the randomseed, it should be reflected in the model.
And, because 'fire-start' is enabled the selected seed should be applied when it's first loaded and when switching between presets. 
 
PS: Now, thinking about it I see a reason to introduce a couple more xStream events - because, you would also want to reset the seed when output is first started. So, if you can wait until the next release I will introduce a set of features to make pseudo/seeded random numbers fully usable  :)

 

EDIT: Imo the xStream might benefit from an even more standardized and modular framework. I've been thinking about the possibility of a "Pulse/Oscillator" class for setting up various hit patterns, instead of coding intricate if statements with arithmetics in each and every model.

 

I can see how a lean & mean syntax for a "pulse generator" might be appealing, but it's (IMHO) more important to keep that part as flexible and open as possible. For example, if we take a cue from our talks about the Euclidean rhythms model, this is a promise of the (planned) stacked models feature - the almighty Euclidean pulse generator.


Tracking with Stuff. API wishlist | Soundcloud


#18 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1467 posts
  • Gender:Not Telling
  • Location:Sweden
  • Interests:music, philosophy, engineering

Posted 25 June 2016 - 11:39

edit: moved, sorry.


Edited by joule, 25 June 2016 - 11:41.


#19 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6359 posts
  • Gender:Male
  • Location:Berlin
  • Interests:wildlife + urban trekking

Posted 25 June 2016 - 11:48

Yeah, our little conversation got technical/theoritical enough to be moved the main xStream topic  ^_^

http://forum.renoise...tream/?p=348673


Tracking with Stuff. API wishlist | Soundcloud


#20 g8tr122

g8tr122

    Member

  • Normal Members
  • PipPip
  • 12 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 04 July 2016 - 19:23

If you read the class/OOP part on the official lua page, you'll find that a class is pretty much a template table with one of the elements being a constructor function. This constructor is used when creating copies/objects of this table/class. The constructor function and what setmetatable can do is pretty much what you need to understand to set up simple classes. But.. one thing worth mentioning is that Renoise provides (via luabind?) an 'enhanced' way of dealing with classes that seems to be a bit more convenient.

 

Danoise has explained some of it to me in this thread recently: http://forum.renoise...inner-question/ It might help you get in the ballpark.

Thanks Joule! I'm still really confused about the metatables, so this will help.



#21 g8tr122

g8tr122

    Member

  • Normal Members
  • PipPip
  • 12 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 04 July 2016 - 21:41

Wasn't sure if I should post this in the xStream thread or not. Sorry if it needs to be. 

I'm confused about the random seed in xStream. I.e., I can't reproduce the same sequence of random numbers. Pls help me Danoise.

 

 PS: Now, thinking about it I see a reason to introduce a couple more xStream events - because, you would also want to reset the seed when output is first started. So, if you can wait until the next release I will introduce a set of features to make pseudo/seeded random numbers fully usable  :)

 

 

I'm assuming your PS will address these questions, but maybe I just did something wrong with that event handler? Anyways, 
----------------------------------------------------------
I create a new model, and simply give it one line: xline.note_columns[1].note_value = math.random(36,48) I keep applying to the selected track, but I'll get a new random sequence every time**. 

If I give the model a second line, math.randomseed(0) and I apply to the track, every note is the same note***. I'm guessing this is because of the behavior of xLine*? 

 

So I get rid of that second line. But now I was clever and thought about setting the random seed in the scripting console; maybe that can set Renoise's global random seed? So I enter the command math.randomseed(0) directly into the terminal. A satisfyingly green math.randomseed(0) appears in the console. After I played around with that, I realized that I could reproduce the same random sequence. But I have to enter math.randomseed(0) into the terminal every  single time before I apply the model to the track. If I don't, I get a new sequence every time I apply**. (I explain further below at the footnote**)

Is that event handler supposed to take care of that? I did exactly as you said, but I still get a new sequence every time I apply**.

 

I'm so confused :(

----------------------------------------------------------

*I wish I could confidently say I got that behavior because xLine re-applies the model at every line in the track; if I reset the seed at every line, of course I'll get the same note over and over.
      But that's the thing, I have no exact idea how xLine operates. I tried to read the lua code, but I couldn't make heads or tails of it. I wish your documentation would describe it better. I wish it said something like, "xLine has two methods, note_columns and effect_columns", "See renoise.NoteColumn for details on editing note values", "here's an example on how to blah blah blah". Instead, I'm faced with these cryptic function names with cryptic descriptions that mean nothing to me. I have no exact idea how xLine or xinc works. Only a confident guess [of their behavior] after experimenting around with them. (I don't even know what xpos does).
    This is why I'm having such a hard time. There's no "xStream for Dummies" that I can pour over. All I have is the many examples, with no line-by-line comments, and the cryptic documentation with "functions" that aren't even used in the examples. I hate being a whiner, but I seriously am so confused because of this.

 

**Well, I don't exactly get a new sequence every time. I get a reproducible sequence of sequences. If I reset the seed in the terminal, and apply the model three times, I get three different sequences. But If I reset the seed, and apply the model three times, I'll get the same sequences (but they'll all be different). I made this picture (at bottom) for clarification, and in case you need to reproduce this behavior.
     I get the same behavior if I use the event handler you described. If I set the "rnd_seed" argument value to 0, I can get the same sequence of sequences. But the only way I can reproduce the sequences is if I change the argument value to something else, apply the model to the track, and then I change the argument value back to 0 (and apply to track). So am I doing something wrong? 

***I don't really care about an answer for this one, but I thought I'd let you know. In this situation, I'd expect xStream to fill the column all with the same, but a different note if I change the seed value. If I set the seed to 0,1,2,3... (and apply after changing) I keep getting "C-4". But if I type in an arbitrary number, I get something different. But if I increment this arbitrary number and apply again, it's the same note value. No matter how much I increment the seed. 
----------------------------------------------------------
This is the picture which clarifies what I mean by "sequence of sequences".

renoise_forum_question.jpg

                                                                                                         ^ Right here, it should say "step 3", not "step one".  


Edited by g8tr122, 04 July 2016 - 21:56.


#22 g8tr122

g8tr122

    Member

  • Normal Members
  • PipPip
  • 12 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 04 July 2016 - 22:12

WHOOOOOOOOOOPSSSSSsssssssies

Well I just realized immediately after posting that last one why I get the "sequence of sequences". 

If you stream the model to the track, it repeats this "sequence of sequences". More specifically:
I reset the seed to 0 in the console, and stream my example model. Then I'll get the output in Step 4. Until the stream reaches the top again. Then I'll get the output in Step 5. When it reaches the top again, I'll get the output in step 6 (and so on).

But the problem still persists; I still have to enter math.randomseed(0) into the console if I want those same sequences to be streamed.


Edited by g8tr122, 04 July 2016 - 22:14.


#23 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6359 posts
  • Gender:Male
  • Location:Berlin
  • Interests:wildlife + urban trekking

Posted 05 July 2016 - 21:32

I create a new model, and simply give it one line: xline.note_columns[1].note_value = math.random(36,48) I keep applying to the selected track, but I'll get a new random sequence every time**. 
If I give the model a second line, math.randomseed(0) and I apply to the track, every note is the same note***. I'm guessing this is because of the behavior of xLine*? 
 
So I get rid of that second line. But now I was clever and thought about setting the random seed in the scripting console; maybe that can set Renoise's global random seed? So I enter the command math.randomseed(0) directly into the terminal. A satisfyingly green math.randomseed(0) appears in the console. After I played around with that, I realized that I could reproduce the same random sequence. But I have to enter math.randomseed(0) into the terminal every  single time before I apply the model to the track. If I don't, I get a new sequence every time I apply**. (I explain further below at the footnote**)
Is that event handler supposed to take care of that? I did exactly as you said, but I still get a new sequence every time I apply**.

Yes, you nailed it. The random seed has to be set at the right moment to work like expected. And the right time (in this case, anyway) would be when output is first started.
That would be the purpose of the event handler - it would simply be a "hook" which you hang your randomseed statement on.

So please don't be confused. It's certainly true that xStream documentation is rather scarce, but that just makes it so much easier to improve  :)

 

But that's the thing, I have no exact idea how xLine operates. I tried to read the lua code, but I couldn't make heads or tails of it. I wish your documentation would describe it better. I wish it said something like, "xLine has two methods, note_columns and effect_columns", "See renoise.NoteColumn for details on editing note values", "here's an example on how to blah blah blah". Instead, I'm faced with these cryptic function names with cryptic descriptions that mean nothing to me. I have no exact idea how xLine or xinc works. Only a confident guess [of their behavior] after experimenting around with them. (I don't even know what xpos does).

 

xLine is a 'virtual' representation of the renoise.Patternline, accepting exactly the same input - note_string, instrument_value, etc. But, unlike renoise.PatternLine it doesn't have to existing in an actual pattern somewhere. Having a virtual representation is required for a tool like xStream to work, because the final line on which output is written might change during playback (for example, if you enable pattern loop near the end of a pattern the tool will redirect it's output to the top of the pattern instead of the next pattern). Also, it allows us to capture things in a buffer and optimize the output in various ways. 

 

xpos is also a virtual representation of a fundamental Renoise API component - the renoise SongPos. It contains the current sequence index and line number. 

(remember, you can always use print(), rprint() and oprint() to output various debug information to the console)

 

xinc is the ever-increasing counter that doesn't care about patterns but simply keeps increasing for as long the tool is streaming. 

So you should use xpos if you somehow wanted your model to rely on the pattern structure, or xinc if you don't. 

 

All I have is the many examples, with no line-by-line comments, and the cryptic documentation with "functions" that aren't even used in the examples.

 

In one of the last released I renamed a bunch of models to "Demo-something" since they are less complex than the rest. Not with line-by-line comments, but that should certainly be doable. So, not saying that the documentation can't be improved - it always can. 

 
And when you refer to the cryptic documentation, I guess you found the xLib documentation, contained somewhere deep in the source of xStream? Well, that's the framework powering all of my newer tools: xRules, PhraseMate, Noodletrap, etc. This is definitely not meant to be a entry point into xStream, rather it should be hidden from plain sight. I'm sorry - seeing now that the README does refer to the xLib documentation. instead, I'll change it to use the description above + add a mention of how to make good use of xinc in the 'Getting started' section of the readme  :ph34r:

  • oise likes this

Tracking with Stuff. API wishlist | Soundcloud






Also tagged with one or more of these keywords: Sonic Pi, algorithmic composition