New Tool (2.8): Mpe

Hey, that’s real neat thinking! (1st click on Sample opening sample recorder, second click and third click starting and stopping sampling). I’ll have to find out what exactly I did wrong with the palette ;)
Thanks for being so swift with your song-trim-prog-mixer fixes!!
I think you should probably just update it on the tools page… I can work out the palette thing on me own :)

Nice to see the 2.4 update on this with rotary controllers! Btw, can you make them read the current sample’s pitch, because it doesn’t seem to get refreshed to transpose pitch 0 if you switch from a -40 sample to 0 sample.

So far this tool looks very promising. I am having a lot of fun with it!

But it would be even better if all the buttons on the tool are controllable by a midi-controller. Some form of midi-bind would be awesome.

Keep up the good work!

this is really kool

Somebody can make one for the Emu Command Station… if it possible :D

nice gui !!!+

D’you have a screenshot of the Emu Command Station?

Hi, looking at your code, now you first have some Script screenset alterations, and then call global#8 viewpreset…

 vb:button {  
 tooltip = "Disable (Follow Player Position) and (Enable Record Mode).",  
 text = "Step",  
 width = BTN_FUNCTION_WIDTH,  
 color = {0xf5, 0xf5, 0xf5},  
 pressed = function()  
 renoise.app().window.active_middle_frame = 1  
 renoise.app().window.active_lower_frame = 2  
 renoise.app().window.lower_frame_is_visible = true  
 renoise.app().window.upper_frame_is_visible = false  
 renoise.app().window.pattern_matrix_is_visible = false  
  
 renoise.app().window:select_preset(8)  
 renoise.song().transport.follow_player = false  
 renoise.song().transport.edit_mode = true  
 renoise.song().transport.edit_step = 0  
 end  
 },  

So you do both? But however, it’s better to not do the select_preset no more in this tool if you are already calling the specific “preset” inside the script… Right?

you are correct I missed that, fixed for the next version

coming soon…

I am trying to make it work but Im getting strange errors , so far I have only managed to make the instrument transpose rotary > update the sample transpose by its value.

every time i make it read the current samples pitch i get loop notifier errors?

and according to the exampletoolgui…

– there is another way of dealing with “values”, which we will describe in the
– next example more in detail. Basically you can also pass over an Observable
– object to the view (not the raw number, boolen), which then will be used by
– the view instead of its onw value. Any changes to this value can then tracked
– outside of this view. This often is very useful to seperate the GUI code from
– the controller and data. Here is a simple example:

– – (the controller part of your script)
– options.current_velocity = 0x7f
– options.current_velocity.add_notifier(current_value_changed_function)

– – (and the GUI)
– vb:slider {
– bind = options.current_velocity, – only gets a reference passed
– min = 0,
– max = 0x7f

– Valid in the construction table only: Bind the view’s value to a
– renoise.Document.ObservableNumber object. Will change the Observable
– value as soon as the view’s value changes, and change the view’s value as
– soon as the Observable’s value changes - automatically keeps both values
– in sync.
– Notifiers can be added to either the view or the Observable object.
rotary.bind
→ [ObservableNumber Object]

but I cant get the bind function to work for me? anyone have any ideas?

As far as I can tell to do this you’d have to create a Document variable for every sample and keep track of them individually.

Let’s look at it another way:

  • renoise.song().selected_instrument_index_observable
  • renoise.song().selected_sample_index_observable
  • renoise.song().instruments.samples.transpose_observable

You can combine the first two functions in a way that, if something changes, update the rotary. The third is a bit more complicated since you have to add an observable for every possible combination of instrument and sample, which is the same problem faced with using Document variables. Also, after looking at the code I feel you are kind of shooting yourself in the foot. You do alot of :add_notifier, but never remove them. I’m not sure Renoise even cleans these…

If you are feeling brave, I would rewrite a lot of your code using app_idle_observable .

Example:

  
  
function run()  
 if not (renoise.tool().app_idle_observable:has_notifier(update_gui)) then  
 renoise.tool().app_idle_observable:add_notifier(update_gui)  
 end  
end  
  
  
function stop()  
 if (renoise.tool().app_idle_observable:has_notifier(update_gui)) then  
 renoise.tool().app_idle_observable:remove_notifier(update_gui)  
 end  
end  
  
  
function update_gui()  
 -- Dialogue is gone?  
 if (not my_dialog or not my_dialog.visible) then  
 stop()  
 return  
 end  
 -- Update the Rotary  
 -- Update the BPM  
 -- Update the Track  
 -- Etc. Every single thing that needs to be updated goes in this function  
end  
  
-- Add run() to main(), after if (my_dialog and my_dialog.visible) [...] end  
  

With this idea, you get rid of all your other notifiers all over the place and, instead, update the GUI when the app has a few cycles to spare. This also destroys the notifier when the MPE goes away; making it cleaner and safer.

That said, there’s a lot of stuff that will need to be moved around for this to work. Right now main() encapsulates everything as a local, so some stuff you will need can’t be accessed globally, doing some preliminary testing and optiomizing with os.clock() to make sure this works, yada yada yada. Look at Cie’s Step Sequence and Nibbles for inspiration.

Hope this helps.

yes i put it here

released updated version 2.5 (re-written) check tools page. Sorry I don’t own an Emu command station …looks cool (so I wont be coding a tool for it but feel free to do so yourself)

Very awesome.

One thing I noticed, I can open multiple instance of the MPE gui.

I fixed it locally by changing

  
function main()--1 dialog at a time  
 local my_dialog = nil  
 -- [...]  
  

to

  
local my_dialog = nil  
function main()--1 dialog at a time  
 -- [...]  
  

Cheers.

thanks again Conner_Bw! fixed for the next version 2.6 coming soon… also adding midi mapping now.

Yeah, sevenscientist could change “esc” to “_” (btw, if anyone knows what _ is in realspeak, please let me know :)

Underscore?

I’m not sure this can be done from scripts.

Pressing escape seems to close all dialog boxes and I don’t think it is possible to override this.

One work around could be to identify when the dialog is closed and then automagically re-open it again (with this behaviour to be enabled/disabled by the user).

It’s possible.

  
function key_handler(dialog, key)  
 if (key.name == "esc") then return end  
end  
  
my_dialog = renoise.app():show_custom_dialog("Title", foo, key_handler)  
  

It most certainly is possible to override (btw it’s really cool that the API allows for stuff like this!!!). I got a script to stay “on top” even if I’d press ESC on it. This is what I did, ripped off MPE code and altered it to this:

 local function my_keyhandler_func(dialog, key)  
 if not (key.modifiers == "" and key.name == "exclamation") then  
 return key  
 else  
 dialog:close()  
 end  

Nevermind the exclamation :D

Unfortunately not exactly. At least Underscore/underscore didn’t make it so that _ would kill a GUI

Thanks for this, Conner_Bw! Works like a charm :)

Can ya try "local function instead of function…
I wrapped mine inside the viewbuilder

Sorry, that wasn’t usable code. It was a generic pseudo example.

In the MPE code, look for my_keyhandler_func and play with that. Personally I think escape should close the dialogue so I don’t recommend it. The decision will be up to sevenscientist. My comment was for mxb; just to show that it was possible.