Jump to content


Photo

New Tool (3.0,3.1): xStream

live coding sandbox

  • Please log in to reply
118 replies to this topic

#51 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 28 October 2015 - 14:46

I had run the tool in a previous song session, trying out the new chord memory model, tweaking the gui while playing back a pattern. After playing I closed the tool and started a new empty song, also have loaded different songfiles and suddenly this error. (windows 10, 32 bit renoise)

 

I think I know what went wrong: pattern(s) got removed from the sequence - xStream doesn't really like this ATM. 

 

But there is this option which will let you suspend the tool if the dialog is not visible. Did you enable this? 


Tracking with Stuff. API wishlist | Soundcloud


#52 ffx

ffx

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 2839 posts
  • Gender:Not Telling
  • Interests:Renoise Sidechain

Posted 06 April 2016 - 12:10

Hey danoise,

 

regarding your Qxx-shuffle script, I get some errors.

 

First after loading and pressing play button in xstream:

'/Users/Ju/Library/Preferences/Renoise/V3.1.0/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...

std::logic_error: 'trying to access a nil object of type 'class FilterDeviceParameter'. the object is not or no longer available.'
stack traceback:
  [C]: ?
  [C]: in function '__index'
  [string "do..."]:37: in function <[string "do..."]:35>
  ./source/xStream.lua:1271: in function 'resolve_automation'
  ./source/xStream.lua:1058: in function 'do_output'
  ./source/xStream.lua:65: in function 'callback_fn'
  ./source/xLib/xStreamPos.lua:188: in function 'set_pos'
  ./source/xLib/xStreamPos.lua:209: in function 'track_pos'
  ./source/xStream.lua:1469: in function 'on_idle'
  ./source/xStream.lua:246: in function <./source/xStream.lua:245>

The second appears, I think, when I was "accidentally" changing the target fx column, because the shuffle value was hidden first.

 

Something with "return a nil value"...



#53 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 06 April 2016 - 12:16

regarding your Qxx-shuffle script, I get some errors.

 

Thanks, will look into it.

 

I created the Qxx script with a slightly more recent (unreleased) version of xStream, so I might need to test a bit before release a new version.


  • ffx likes this

Tracking with Stuff. API wishlist | Soundcloud


#54 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 20 May 2016 - 14:28

Version 1.45 of xStream is released 
 
gui_1.45.png?raw=1
 
What's new: 
* FEATURE Rewritten GUI - the "compact mode" is gone, favorites and options are now dialogs
* FEATURE Ability to "pin" the favorites window so it will appear on top
* FEATURE Ability to MIDI-map arguments (CMD/CTRL+M) 
* FIXED A couple of bugs have been fixed here and there
* DOCUMENTATION! 
The ability to MIDI map arguments is the most important one, but I've also have taken the time to document the tool a bit more.
 
You can check out the manual here (work in progress): 
https://github.com/r...se.xStream.xrnx
 
Notice that, as always, you need to backup any custom models you've made before installing the new version. 
Storing data outside the tool folder is a planned for the next version, and will solve this once and for all.
  • joule, kopias and oise like this

Tracking with Stuff. API wishlist | Soundcloud


#55 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 20 May 2016 - 18:53

A quick follow-up: v1.46 is released

 

Thanks to some quick feedback I managed to squeeze a couple more bugs:

FIXED filename lower/uppercase issue on linux
FIXED expand_columns not working when targeting Nth column (not starting from 1)
FIXED better "recovery" when deleting patterns while streaming 

Thanks kopias - linux testing is much appreciated


Tracking with Stuff. API wishlist | Soundcloud


#56 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 23 May 2016 - 19:15

Another update (v1.47), get it from the tools page
FIXED Stop streaming when loading a new song while streaming 
FIXED A few out-of-bounds song position issues (strengthened checks)
FEATURE Tabbed arguments - see Args-Tabbed model for an example
FEATURE Linkable arguments - a "sub-feature" of tabbed arguments
FEATURE Locked and linked argument state now saved as part of a preset
FEATURE Custom userdata folder - containing models, preset and favorites
This is the last time you will need to backup your files before updating, as you can now specify a custom user-data folder - if you want. 
Also, the Euclidean Rhythms model got a nice treatment with the addition of tabbed arguments:
 
Euclidean-tabs.gif?raw=1
 
Note the small "link" icon next to each tabbed argument: clicking it will synchronize the value between all tabs.
It will automatically appear when the argument has a similarly-named argument present in another tab.
  • Djeroek, joule, crazya02 and 2 others like this

Tracking with Stuff. API wishlist | Soundcloud


#57 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

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

Posted 04 June 2016 - 09:53

I've just started making a model with some usable chord functions here: https://github.com/s...ipulation-model

 

In case anyone feel like having a look at the "documentation" and get some idea about additional chord manipulations that could be included, feel free to provide any ideas.


  • danoise likes this

#58 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 04 June 2016 - 10:14

The functions you outline seems like a perfect candidate for a supporting class?
Then, those methods would be available anywhere and not just in a single model

In any case, looking forward to seeing (hearing) what you'll do with it!
  • joule likes this

Tracking with Stuff. API wishlist | Soundcloud


#59 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 14 June 2016 - 18:47

OK, version 1.5 is out!

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

+ MIDI Support (send/receive)
+ Voice Manager
+ Buffer access (scheduling)
+ Events handlers for 
  * Model events (MIDI, VOICE)
  * Renoise events (a whole lot)
  * Arguments (if any)
+ Various bug fixes and enhancements

It's pretty crazy stuff ... the voice manager alone is powerful enough to warrant 2 new models to demonstrate the feature.

 

One model triggers live MIDI messages which gets routed into Renoise (selected track/instrument). The other one will record directly into the pattern and was also used for testing the scheduling (quantize to beats and bars)

Both of them offers control of the polyphony limit and automatic note-column allocation.  

 

Think I'll come up with a hybrid model which will combine the best parts of both, to deliver a truly "enhanced keyboard" for Renoise.

Ideas are welcome  ^_^

 

And as always, if something is not working as expected - please let me know... 


  • joule likes this

Tracking with Stuff. API wishlist | Soundcloud


#60 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 15 June 2016 - 02:05

if something is not working as expected - please let me know...

 

Thanks to kopias, a bug on linux was fixed and I found another one too: 

 

Quick-fix release v1.51 (might take a few minutes before download link is working)

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


  • ghostwerk likes this

Tracking with Stuff. API wishlist | Soundcloud


#61 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 16 June 2016 - 11:56

Another release, 1.52 - tool page

Last one for the next few days, I promise :-)

FIXED Automation output accidentally got broken in 1.51
FIXED Event notification no longer fired on inactive models
FIXED Model "modified" state no longer reset when stream starts
FEATURE Renamed models - simple demonstrations are now prefixed by 'Demo-'
FEATURE Skip evaluation of callback if main contains no code (comment only)
FEATURE Scheduling a note or effect column now able to merge with existing content
FEATURE New models, ColumnEraser and Arpeggiator 

I was burning the midnight oil yesterday and came up with a nice, functional arpeggiator. 

It works nicely, but - for now - only with a live MIDI keyboard. So you need to specify your controller in the xStream MIDI options before giving it a go. 

 

Another new model is the ColumnEraser. It allows you to "punch out" (erase) individual columns in a track, simply by muting them.

It's very nice to generate complex Euclidean rhythms and then use this model to adjust things afterwards.


  • Djeroek and ffx like this

Tracking with Stuff. API wishlist | Soundcloud


#62 ffx

ffx

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 2839 posts
  • Gender:Not Telling
  • Interests:Renoise Sidechain

Posted 17 June 2016 - 09:17

Wow if you could put such energy into renoise core.... :)

#63 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

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

Posted 25 June 2016 - 11:10

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.


Just some input.. I would probably "abuse" stacked models for generating multiple tracks rather than stacking up different criteria for a single track. I think I'd prefer one model per generated track, but that the coding of models instead was simplified as much as possible.

About an oscillator class.. 1) A simple oscillator class would be very similar with how we use the LFO device. It's a proven concept. 2) An oscillator class could be used not only for generating "note hits", but also to set values in any of the other columns.
 
osc_note = oscillator("pulse", 16, 0, 0, 1) -- type (pulse is not the same as square), lines, ticks, start value, end value .. construct only if object doesn't exist, else just return value
osc_vol = oscillator("saw", 64, 0, 255, 0)
-- osc_comb = c_oscillator("multiply", first_osc, second_osc) .. something like this for combining oscillators?

if osc_note then
  xline.note_column[1] = blabla
  xline.note_column[1].volume_value = osc_vol
  osc_vol:reset() -- more functions possible? :reverse() could reverse the oscillator at its current position .. :reset([percentage_of_full_cycle]) .. :offset(jump_percentage_of_full_cycle)
end
Everything here would be pretty easy to make. Basic maths on xinc, except for the :reverse() function that would be a bit trickier/uglier.

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


#64 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 25 June 2016 - 11:36

Just some input.. I would probably "abuse" stacked models for generating multiple tracks rather than stacking up different criterias for a single track. I think I'd prefer one model per generated track, but that the coding of models instead was simplified as much as possible.

 

Yes, abuse would be the right term. Surely we can come up with better solutions?  

 

Stacked models = ability to run multiple models, as if (from a user perspective) they were a single unit. So not much additional UI complexity, just more "modularity". 

One very obvious purpose would be to use a simple model as note generator, but chain reactions would be possible too. Very interesting stuff!! 

Technically, the models would share a single buffer, and the xline would have an accompanying stack property so you could access the xline from any level in the stack

 

Multiple instances = the ability to run multiple models side by side, each one targeting a specific track (and prominently featured in the UI).

This is basically xStream XL - a multitrack version. Technically, each instance would have it's own buffer and shared timing, but not much else.

 

I've been looking into simple ways of controlling/automating those xstream instances too - primarily via pattern commands. 

 

An oscillator class would be very similar with how we use the LFO device. It's a proven concept

 

Exactly - the standalone Renoise LFO device would suck if you couldn't hook it up to key/velocity-trackers, or automate it. So, it's more about much integration it can enjoy - as in, what the tool can offer in terms of event handlers, automation, notifications and such. 


  • joule likes this

Tracking with Stuff. API wishlist | Soundcloud


#65 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

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

Posted 25 June 2016 - 11:56

Not sure I can contribute much since I'm still trying to wrap my head around the practicallities of stacked models :) I am guessing that these would not just be generating pattern data in a serial fashion, from one model to the other until it reaches the last model generating the finite pattern data? Rather, I guess that these models would be just parallell 'sandboxes' sharing the same variables? That would imo imply that you would need to 1) do a little bit of formalizing as of how to structure models depending on their type (note value generator, note hit/rhythm generator et c), and 2) end all chains with a "write pattern data" model.

 

Am I complicating matters unnecessarily?



#66 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 25 June 2016 - 12:27

Well, in my mind it really is that simple - passing data (xlines) from one model to the next until we reach the last one, at which point the pattern data is written. 

And ideally, one model would not need to know about where that data came from. Args would still be args - the syntax would not have to change. Instead we add a stack property that you can query to obtain the xline from any model - right down to the original one. Want to access an argument from another model - again, the stack delivers

 

Here are a couple of ideas for how a stack could be used: 

  • Post-processing models which offer basic functionality such as having a master volume for notes, or remapping notes to a specific instrument etc. The generic kind of stuff that currently just bloats up the size of our models. 
  • Currently, the Exponential Delay model responds to already-existing notes in the first note column. It leaves that column unchanged, and creates its output in columns 2-12. With a stacked model approach, you could use the Euclidean model as a generator for the first note column, and the Exponential Delay would respond to that, not being aware that the note had just been "handed over" to it. 
  • Supporting "mute" notes for the Euclidean model - e.g. to blank out the kick when there was a snare hit, etc. Basically, what you mentioned that you would like to implement. This sort of stuff should be possible with stacking too, by adding a simple "post-processing" model, specifically tailored for that purpose. 
  • With direct buffer access, scheduling xlines as a response to input from another model could create interesting chain reactions. 

Tracking with Stuff. API wishlist | Soundcloud


#67 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

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

Posted 25 June 2016 - 14:44

That sounds good indeed.

I am thinking that a 'good practice' way of making models under such circumstances would be to provide an args.model_input_line which would be any of { xline, model_1_output, model_2_output, et c }. Then you would have a flexible system (capable of "paralell processing") as well as being common sense GUI wise. It would not matter in what order you insert models, as long as you select the correct input. This would, however, call for finalizing the chain with a "write pattern data" model (or hell.. using a midi output model, making xstream a sequencer on its own)

 

I am guessing your stack idea would be doing something like this, but just thought it would be good to reveal this input selection clearly as a select box in the GUI (with args?).

 

You might want one chain to generate the volume column and one chain to generate note data. These would then be finalized with a "merge and output" model providing two args.input, as well as some args ticks that would for example handle tasks like "only output volume data when there is note data" (only input 2 on input 1), and perhaps even revealing some boolean operations for merging.

 

In addition, the possibility of grouping chains would double as multi-track capability, starting each chain with an "input model" that basically does thischain_xline = rns:pattern(xpos.pattern_index):track(args.track_index):line(xpos.line) -- (too hackish? breaking some of the purpose of xstream/xline?)

I imagine every model would need to be finalized with a statement like "output = my_line" in that case. (Or rather, the name of the internal xline variable is being fixed)


Edited by joule, 25 June 2016 - 15:08.


#68 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 25 June 2016 - 16:04

While MIDI output for xlines might sound tempting, it wouldn't really work as you are asking a tool to output MIDI on it's own initiative (== sluggish timing).
This was actually the raison d'etre for this tool, to overcome this limitation while not having to re-invent the wheel over again - having done multiple "streaming" sequencers in the past.
 

You might want one chain to generate the volume column and one chain to generate note data. These would then be finalized with a "merge and output" model providing two args.input, as well as some args ticks that would for example handle tasks like "only output volume data when there is note data" (only input 2 on input 1), and perhaps even revealing some boolean operations for merging.

Perhaps dancing would a fitting analogy here. As long as you don't step on your partners toes, things are good. Same with stacked models: if you could not access the stack, you would have to make sure that model B does not "blindly" overwrite the output of model A. 

But with access to the stack, even if a model does "blindly" overwrite the output, a third model C could in fact separate and clean up the output from the first and second one. 
So, in this case model A and model B would be completely normal models without any knowledge of a stack or anything, while the third one would somehow know about both. 

 

At least, that's how I imagine it would work. Focus is on maximum flexibility, basically. 
 

I imagine every model would need to be finalized with a statement like "output = my_line" in that case

 
Unless you'd want to hand over output to a particular model at a later point in the stack, IMO this should all be done automatically.

But in some special cases, having control over exactly where the output is handed over is definitely valid.


Tracking with Stuff. API wishlist | Soundcloud


#69 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

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

Posted 25 June 2016 - 22:02

I am not quite understanding the stack idea, so maybe you've already thought it thru in a better way.

 

Anyway.. I am guessing you want to structure these stacks in a way that is fairly compatible with how xstream models work right now. If you want to make a simple model current-style, writing to xline, it should still be possible with the same code. The user should not have to configure anything extra in that case, and all presets should work in both single or stacked mode (?).

 

I am guessing the most obvious way would be to provide a select box on each model, stating exactly what xline is to THAT model - 1) the real xline (default), 2) the xline of track x/y, 3) a copy of any of these, 3) the xline from model 1, 2 or 3.



#70 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 26 June 2016 - 13:07

Well, the idea is still forming in my head and so, as time goes, I can only become better at explaining it. 

 

I am guessing the most obvious way would be to provide a select box on each model, stating exactly what xline is to THAT model - 1) the real xline (default), 2) the xline of track x/y, 3) a copy of any of these, 3) the xline from model 1, 2 or 3.

 

Not really. From an model-authoring POV, it should be a simple concept to work with. The xline you are reading at any time is native to that model - it simply contains whatever gets passed. First model in the stack gets the pattern content (like how it currently works), second one gets the output from the first model in the stack, third one the output from the second and so forth. So in most cases, the model simply works "as-is", and there's nothing new to learn. It's only when you actually need/want direct access to the stack that this becomes something to deal with. Which is how it's supposed to work. 

 

The way I have envisioned it, a stacked model should appear alongside normal models - meaning, you can select it from the usual model popup menu. This makes sense, since (from a user perspective) a stacked model doesn't actually bring anything new to the table. Everything that stacked models can offer , you can already do in xStream now, it's just that complex model tend to get unwieldy and the tool is not meant as a full-blown IDE. You might even argue that, as arguments can become spread across a number of models, it's less convenient to a casual user than a non-stacked model ... because you might have to select a model before you can access the visual controls. 

 

Not exactly sure how to deal with import and export of stacks though - we are basically getting into the territory of dependencies (*shudder*), as a stack would be referencing a number of models. But I can't see an easy way to avoid this. So exporting a stack would probably mean exporting a bundle of model, which - when imported, will "install" these models before the stack can be instantiated. Or something like that.

 

So, it's the actual implementation details that are hairy and will take some time to get right. Perhaps you can see why it's a feature that I have (so far) put on the backburner. As a programmer, it brings some cool opportunities for making models more modular. But it also brings some complexity to the table - unfortunately, on the user part. I'm hoping this can somehow be solved without too much hassle. 


Tracking with Stuff. API wishlist | Soundcloud


#71 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

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

Posted 26 June 2016 - 20:22

That sounds great. I assume the user will be able to redefine xline to anything at the top of the models user code?

 

I imagine that a stack of models would contain everything, i e not referencing any kind of "model library". Once a model is added, it would be copied into the stack as something unique in that stack.

 

The only drawback I can see is that the 'core' of a model might get updated. The user would then have to copy/paste and update all stacks (if it's really that relevant, which it probably seldom is). No biggie imo.

 

Yes, the stack/chain function is mainly a GUI thing, but an important one I think.



#72 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

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

Posted 05 July 2016 - 11:00

With this you could for example do:
 
-- setting up
if xinc == 1 then volume_osc = osc.create(sine, 16, 0, 255) end
-- using
xline.note_columns[1].volume_value = volume_osc:value()

Update: I think it's almost done here. Might need some bug fixing and tidying things up. + Documentation (it's quite flexible)

Spoiler

 
EDIT:
 
Not sure danoise will find it useful enough, but I for sure will use it anyway :)
 
Another (totally different) idea I got is a very small and simple helper function that could be available in xStream that I would find quite useful and that would possibly simplify some aspects of xStream coding even more. The following:
 
if on_update(xline.note_columns[1].note_value) then
xline.note_columns[1].effect_value = 10
end
 
Super simple syntax imo.
 
on_update() will return the value only when changed, otherwise it will return nil. The idea is also that the on_update() function would not only accept variable data, but even a whole object (excl methods).
 
It should be pretty easy to code. I imagine that the first time on_update is being ran, it will register the reference in an internal table (variables would be normal values and object/tables would be hash values). Registering/checking objects and tables would require some recursive scanning, sure. On each subsequent update it will compare the current value to what is cached. Not sure how to get the "uniqueness" of the parameter passed into the function, but it should be possible? Or maybe there is a better way already available for similar tasks?

 

EDIT 2: An alternative would be to hook up a document to xline properties, and make use of document observables? Observing xline is quite enough, I think, maybe allowing for something like this if possible:

 

if xline.note_columns[1].note_value:is_updated() == true . Or is something similar already possible?
 
IDEA 3:
 
Another simplifying idea, or at least one that adds flexibility, would be to provide not only xline but also something like xline(offset).
 
xline(16).note_columns[1].effect_value = 10
 
This is sometimes more convenient than 1) caching values for later use or 2) calculating the correct value with a possibly more intricate function (offsetting), 3) dealing with xpos. 
 
A very simple practical example would be to generate a tracked delay in a second column. In this case xline(steps) would imo make more sense, or at least be easier, than storing data in a table for % search or fetching data from previous lines.
 
Just an idea for streamlining/simplifying model coding and improving readability, making new users feel even more welcome :)


Edited by joule, 13 July 2016 - 09:46.


#73 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

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

Posted 15 July 2016 - 10:08

Handy LFO class for use with xStream (or adaptable to anything) can be found here:

 

https://github.com/s...tream-LFO-class

 
The usage in xStream would typically be something like below. Some other parameters are available as well. I'll try posting a video later (mainly for hyping xStream!).
 

if xinc == 0 then
 my_osc = LFO("sine", 16)
end

-- current_value = my_osc.value
scaled_value_for_parameters = my_osc(0, 255, 1) -- min, max, resolution

I will probably start working on something more elaborate that is more adapted to the parameters of the Renoise LFO/meta devices, and various pattern effects. By this xStream could be abused to make LFO/meta devices control pattern data in a more familiar fashion. For instance controlling pitch (with pitch effects) via an LFO meta device. This idea would work with realtime streaming only, though.


Edited by joule, 15 July 2016 - 10:45.


#74 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6257 posts
  • Gender:Male
  • Interests:wildlife + urban trekking

Posted 15 July 2016 - 11:06

Handy LFO class for use with xStream (or adaptable to anything) can be found here:

Looking good! Should definitely be included in xStream once we have some test cases/demo :-)

"LFO" is also a better name for a class. You previously called it "osc", I thought of pointing out that it's more or less a convention to have class names in CamelCase.
Mostly because then, it's easy to distinguish between variables and classes, and calls to static methods of the class itself.
Details, but worth pointing out.

I will probably start working on something more elaborate that is more adapted to the parameters of the Renoise LFO/meta devices, and various pattern effects. By this xStream could be abused to make LFO/meta devices control pattern data in a more familiar fashion. For instance controlling pitch (with pitch effects) via an LFO meta device. This idea would work with realtime streaming only, though.

Don't forget that the output of xStream always is written (one or more lines) ahead of time. Also, if you change an arguments which require new output, those lines will be re-computed at a later time.
So, relying on a otherwise stable LFO movement might not behave as you'd expect it to.

Tracking with Stuff. API wishlist | Soundcloud


#75 Ar2

Ar2

    New Member

  • Normal Members
  • Pip
  • 3 posts

Posted 26 August 2016 - 13:24

Hey there, first of all xStream is amazing!
Turns out I'm a total noob when it comes to programming though so I'd need some help, if you don't mind me asking.

 

What I'm trying to do is playing a note every x lines across the whole song, so basically a counter I guess.
I've been trying to get this to work for days now to no avail.

 

If this is the wrong place to ask, I'm sorry.







Also tagged with one or more of these keywords: live coding, sandbox