Page 1 of 1

Ruby Scripting Problems

PostPosted: Fri Aug 21, 2020 1:05 pm
by DSP-Robotron
Any ideas why this code is not working ?
It's overloading something or crashing Ruby or something.


loop do
out = rand(200..800)
output 0, out
sleep 1
end

Re: Ruby Scripting Problems

PostPosted: Fri Aug 21, 2020 1:18 pm
by DSP-Robotron
Try this super buggy script and see what happens.

while @in >= 0.5
tone = rand(200..800)
output 0, tone
end

Re: Ruby Scripting Problems

PostPosted: Fri Aug 21, 2020 3:37 pm
by DSP-Robotron
Here is another Ruby example that is supposed to work but it doesn't.

while @sig == 1
tone = rand(200..800)
output 0, tone
end

Re: Ruby Scripting Problems

PostPosted: Fri Aug 21, 2020 10:06 pm
by trogluddite
DSP-Robotron wrote:It's overloading something or crashing Ruby or something.

Exactly that - all three examples are overloading the Ruby interpreter. While they're all legal Ruby code, I wouldn't expect any of them to work in the context of FlowStone.

For the most part, Ruby components are expected to work like this...
- A value changes at one or more of the RubyEdit input connectors (an "event").
- This causes the code to be executed.
- One or more results are sent to the RubyEdit output connectors.
- (Optional: The code can schedule another "event" to happen at some later time).
- Code execution ends until the next "event".
- The new output values are now used by the rest of the schematic.
(NB: editing the code also triggers execution)

There's also another very important caveat - Ruby is a single-threaded scripting language and the interpreter is shared by the whole schematic. So only one Ruby "event" in one RubyEdit can be processed at a time. This isn't a problem so long as each event takes a limited amount of processing time - events are processed one after another fast enough that the results all arrive where they're needed at the appropriate time.

However, your examples each contain what is effectively an infinite loop. Once the code starts executing, there's never an "end of event". The Ruby interpreter is now totally consumed by executing the loop, so no further Ruby events can be processed, not by this RubyEdit, nor by any other. Within FlowStone, this is considered a fatal condition, and to protect against it, the RubyEdit will be disabled if there's no "end of event" after a few seconds (it can only be enabled again manually in the workspace). The non-Ruby parts of the schematic will continue running, but nothing meaningful will happen at the RubyEdit's outputs, as without an "end of event", the schematic is not told that anything might have changed. (NB: because the "end of event" is so necessary, even the "sleep" method counts as "hogging the interpreter").

To do what (I think) you want to do, you need the code to be only the "body" of your loops, and the looping to be done externally to this code by either...

1) ...using external components to trigger events at appropriate times (e.g. a "ticker" or "Frame Sync" primitive at a RubyEdit input).

2) ...having each event schedule the next one after an appropriate time delay (e.g. the "input" or "scheduleEvent" Ruby methods at the end of the code).

And one further note of warning! There is one very large problem that can happen with the Ruby "fuse". Due to the way that Ruby events are queued internally, when the "fuse" blows in one RubyEdit, it can also blow in other RubyEdits which have events scheduled to happen at the same time. If you get unlucky, this can kill unrelated RubyEdits all over a schematic at load-time, and it is a huge PITA to re-enable them all (you have to follow the modules with red borders). Always save your schematic before making any big changes to Ruby code!!

As you can see, using Ruby within FS is quite a bit different than using it as a stand-alone scripting language (and the documentation doesn't always do a very good job of explaining how!!)

Re: Ruby Scripting Problems

PostPosted: Fri Aug 21, 2020 11:39 pm
by DSP-Robotron
Well, that sucks. Maybe I should use the Assembler module instead of Ruby ? Is the assembler module able to generate continuous output like a random oscillator ? It should work in assembler (maybe) because the oscillators are already able to do continuous output they are just not editable. Which is a shame.

Re: Ruby Scripting Problems

PostPosted: Sat Aug 22, 2020 12:05 am
by DSP-Robotron
How is the Arpeggiator able to generate continuous output if I hold a midi key indefinitely without having the infinite loop problem ? It's supposed to be the same problem or at least very similar.

Re: Ruby Scripting Problems

PostPosted: Sat Aug 22, 2020 1:43 am
by trogluddite
DSP-Robotron wrote:How is the Arpeggiator able to generate continuous output if I hold a midi key indefinitely without having the infinite loop problem ? It's supposed to be the same problem or at least very similar.

The Ruby ones use the event scheduling technique. For each note, a single "event" happens, the first of which is triggered by the user starting to play. Each event does something like the following...
- The previous note (if there was one) is turned off.
- The next note in the sequence is turned on.
- The sequence is advanced by one step (and wrapped if necessary).
- The next event is scheduled to happen after the required time interval.
- End of event.

Scheduling a Ruby event adds an item to an internal queue, saying which RubyEdit and which of its methods to call, and when to call it. Crucially, this queue of events isn't managed by Ruby itself, but by a CPU thread in FlowStone synced to its internal clock. In between events, the Ruby interpreter is idle, and it only gets woken whenever there is an event to process. So the problem of "hogging the Ruby interpreter" doesn't happen in this case, and the "fuse" won't blow. There is still an "infinite loop" of course, but it's in the FlowStone code which scans the event queue rather than in our Ruby code.

It's getting late, so I'll leave the "Assembly Arpeggiator" for later - suffice to say, you have stumbled upon FlowStone's equivalent of the "Quest for the Holy Grail" (whether King Arthur's or Monty Python's, I'm not quite sure! :lol: )

Re: Ruby Scripting Problems

PostPosted: Sat Aug 22, 2020 1:50 am
by DSP-Robotron
trogluddite wrote:
DSP-Robotron wrote:It's overloading something or crashing Ruby or something.

Exactly that - all three examples are overloading the Ruby interpreter. While they're all legal Ruby code, I wouldn't expect any of them to work in the context of FlowStone.


Well then, how can I accomplish a random oscillator, or a random modulator, or a tempo synced random switcher/modulator using Ruby ? Do I have to use the assembler module ? What's the point of having Ruby if it's not allowing anything to work ? How do you make custom modules if Ruby is so useless ? They better include the full source code or something that actually works without headaches.

Re: Ruby Scripting Problems

PostPosted: Sat Aug 22, 2020 2:10 am
by DSP-Robotron
Here is a version that kind of modulates things randomly but it's still using the super buggy Arp code. I need something more simple and more optimized that doesn't overload the CPU as much as the Arp code.

[Moderator Comment: Links and downloads removed]

Re: Ruby Scripting Problems

PostPosted: Thu Nov 05, 2020 2:39 am
by messi
Wicked Cool Ruby Scripts is a compendium of scripts that will make your life easier by saving you time and solving problems