New Tool (2.8): Ezgroovesettingsformidi

Haven’t used it in a while as it stopped working for me somehow in 2.7.2, it doesn’t use a virtual midi port like midi yoke if I remember correctly, but Renoise’s Midi control meta device.

This wouldn’t work with rendering would it?

i’m fairly sure that midi input from midi-cc (midiknobs) gets frozen while rendering-selection.

Yes it’s possible. Maybe this helps

  
function add_automation(parameter, track_nr, time, value)  
  
 local pattern_index = renoise.song().selected_pattern_index  
 local automation = renoise.song().patterns[pattern_index].tracks[track_nr]:find_automation(parameter)  
  
 if automation ~= nil then  
 -- value/127 must be between 0.0 - 1.0  
 automation:add_point_at(time, value/127)  
 else  
 --print('Try to create a new automation')  
 automation = renoise.song().patterns[pattern_index].tracks[track_nr]:create_automation(parameter)  
 automation:add_point_at(time, value/127)   
 end  
  
end  
  
  

Delete:

  
 if automation:has_point_at(time) then  
 automation:remove_point_at(time)  
 end  
  

hmm. so, if groove_settings are not currently automatable, how do i force them to be automatable, i.e. can this script be modified to also allow for the user to draw automation which affects the groove settings which these 4 midimap-controls already control?

Pardon my ignorance, but does the above also mean that we can’t use pattern effect commands to alter the groove settings? I’m assuming a loopback would be required if it doesn’t?

Only enable & disable groove (ZGxx), not change the values as far as I know.

The below given code allows you to change the groove values through automation using a meta device.
The requirement is that you need a DSP meta device with four parameter sliders (I have picked an instrument automate device) and then rename the device to either ‘global groove’ or ‘groove device’. (chars in the devicename will be lowercase forced so case doesn’t matter).
Embed that code and you make a lot of folks happy. But do take care that the groove_monitor() function is called appropriately → app_new_document_observable when a new song is created or another is loaded and renoise.song().tracks_observable when the track- or group track count is modified.

  
groove_master_device = nil  
groove_device_number = -1  
groove_master_track = nil  
  
--------------------------------------------------------------------------------  
-- Main functions  
--------------------------------------------------------------------------------  
  
-- This example function is called from the GUI below.  
-- It will return a random string. The GUI function displays   
-- that string in a dialog.  
local function monitor_groove()  
 local song = renoise.song()  
  
 groove_master_track = song.sequencer_track_count + 1  
 for x = 1, #song.tracks[groove_master_track].devices do  
 local device_name = string.lower(song.tracks[groove_master_track].devices[x].display_name)  
 if device_name == 'global groove' or device_name == 'groove device' then  
 groove_device_number = x  
 break  
 end  
 end  
  
 if groove_device_number ~= -1 then  
 groove_master_device = song.tracks[groove_master_track].devices[groove_device_number]  
 if not groove_master_device.parameters[1].value_observable:has_notifier(set_groove_slider_1) then  
 groove_master_device.parameters[1].value_observable:add_notifier(set_groove_slider_1)  
 end  
 if not groove_master_device.parameters[2].value_observable:has_notifier(set_groove_slider_2) then  
 groove_master_device.parameters[2].value_observable:add_notifier(set_groove_slider_2)  
 end  
 if not groove_master_device.parameters[3].value_observable:has_notifier(set_groove_slider_3) then  
 groove_master_device.parameters[2].value_observable:add_notifier(set_groove_slider_3)  
 end  
 if not groove_master_device.parameters[4].value_observable:has_notifier(set_groove_slider_4) then  
 groove_master_device.parameters[4].value_observable:add_notifier(set_groove_slider_4)  
 end  
 end  
  
end  
  
  
function set_groove_slider_1 ()  
 set_groove_slider(1)  
end  
function set_groove_slider_2 ()  
 set_groove_slider(2)  
end  
function set_groove_slider_3 ()  
 set_groove_slider(3)  
  
end  
function set_groove_slider_4 ()  
 set_groove_slider(4)  
  
end  
  
function set_groove_slider(parameter)  
 local song = renoise.song()  
 if groove_master_device.is_active then  
 if not song.transport.groove_enabled then  
 song.transport.groove_enabled = true  
 end  
 print('groove_parameter:',groove_master_device.parameters[parameter].value)  
 local song_groove = song.transport.groove_amounts  
  
 song_groove[parameter] = groove_master_device.parameters[parameter].value  
 song.transport.groove_amounts = song_groove  
 end   
end  
  
  

One more remark, the device has to be placed on the master track, but i guess that seems pretty clear from the code, but just in case adding it to the mention.

1 Like

Ahh, thanks, this looks perfect! :drummer: <- newly automated grooved drummer of course!

Sorry to nag, but I’m kind of stuck in this tune and not really familiar with the processes involved in getting a tool updated (nor do I have any idea how to implement this code). I assume it’d be more than just copying and pasting this into the current tool’s code?

Thanks for any further help :)

If you are really that desperate, you can try the installable version. You have to add a Instr. automate device on the master track first and rename it to “groove device”, then click the groove automater in the tools drop-down before it is activated.
Though this is really raw material so the least sanity checks and lots of manual things to be done.If you forget a step, you would have to reload the tool.

who0p. here we go

That’s great vV, hugely appreciated. I’ll get cracking on it and see how I fare.

The groove automator snippet is the secret to automate a lot of other stuff that one can currently not automate (like instrument envelopes :D)

1 Like

Well, it’s ‘kind of’ working! I’m basically trying to put in groove changes at the start of every pattern but it seems that it only works in certain circumstances which I’m yet to figure out.
I start with all 4 set to 00, next pattern I set 12xx and 14xx to 80, then 11xx and 13xx in the next (by this point, all 4 are at 80), then the 4th pattern I set 12xx and 14xx to 00. It seems that setting 1380 after entering 1300 earlier on in a different pattern didn’t seem to work. There’s probably a pattern to it all somewhere but it’s most baffling. Maybe just something linked to the 3rd groove slider? I’ve tried reinitialising the tool and removing and replacing the ‘groove device’ and selecting tools > groove automater, but no dice. If you select the automater again, is comes up with an error:

failed to execute in one of its menu entry functions.
std::logic_error: ‘add notifier: the given function was already registered to this notifier.’
stack traceback:
[C]: in function ‘add_notifier’
main.lua:59: in function main.lua:38

Anyway, I don’t want to burden you with requests for a measily function like this, but if there’s anything glaringly obvious to you coding gurus… :rolleyes:

This error is fixed.
May also solved the other problem as slider 2 got linked to the wrong notifier, quite remarkable because Renoise should have fired the notifier error from the start but somehow the notifier attachment request is probably done faster than the attachment was done .

could this sort of automation be rendered?

Tested it, the groove effect seems rendered…

This is indeed fixed - you still have to select Tools>Groove automater upon reloading the song to initialise it, but all is good from tat point on :) Nice work once again vV and thanks!

Yeah, but the snippet was created for lackluster to work out so i hope he has found a nice spot for this framework.

1 Like