New Tool (2.8): Ezgroovesettingsformidi

EDIT: Incorporated into Paketti

Yep, now you can map the groovesettings to midi-CC. It’s really roughshot code

--Dec 18-19,2011, esaruoho (esaruoho@gmail.com), for F7  
  
--Groove Amount#1  
renoise.tool():add_midi_mapping{name = "Global:Groove Settings:Groove#1",  
invoke = function(message)  
local s=renoise.song()  
local resulta=nil  
local ga=s.transport.groove_amounts  
  
if not renoise.song().transport.groove_enabled then renoise.song().transport.groove_enabled=true end  
  
resulta=(message.int_value/100)  
if resulta>1.0 then resulta=1.0 end  
  
renoise.song().transport.groove_amounts = {resulta, ga[2], ga[3], ga[4] }  
 end}  
renoise.tool():add_midi_mapping{name = "Global:Groove Settings:Groove#2",  
  
--Groove Amount#2  
invoke = function(message)  
local s=renoise.song()  
local resulta=nil  
local ga=s.transport.groove_amounts  
if not renoise.song().transport.groove_enabled then renoise.song().transport.groove_enabled=true end  
  
resulta=(message.int_value/100)  
if resulta>1.0 then resulta=1.0 end  
  
--Groove Amount#3  
renoise.song().transport.groove_amounts = {ga[1], resulta, ga[3], ga[4] }  
 end}  
renoise.tool():add_midi_mapping{name = "Global:Groove Settings:Groove#3",  
invoke = function(message)  
local s=renoise.song()  
local resulta=nil  
local ga=s.transport.groove_amounts  
  
if not renoise.song().transport.groove_enabled then renoise.song().transport.groove_enabled=true end  
  
resulta=(message.int_value/100)  
if resulta>1.0 then resulta=1.0 end  
  
--Groove Amount#4  
renoise.song().transport.groove_amounts = {ga[1],ga[2], resulta, ga[4] }  
 end}  
renoise.tool():add_midi_mapping{name = "Global:Groove Settings:Groove#4",  
invoke = function(message)  
local s=renoise.song()  
local resulta=nil  
local ga=s.transport.groove_amounts  
    
if not renoise.song().transport.groove_enabled then renoise.song().transport.groove_enabled=true end  
  
resulta=(message.int_value/100)  
if resulta>1.0 then resulta=1.0 end  
renoise.song().transport.groove_amounts = {ga[1],ga[2],ga[3],resulta}  
 end}  
  

But it does seem to do what’s required. after mapping
Global Mappings->Global->Groove Settings->Groove#1
Global Mappings->Global->Groove Settings->Groove#2
Global Mappings->Global->Groove Settings->Groove#3
Global Mappings->Global->Groove Settings->Groove#4

when you move a fader, it will try to fit the incoming CC data within 0.0 and 1.0, and if it goes to 1.27 it changes to 1.0. also, when you move a fader, the groove settings enabled is toggled to true.

Nice work, can the groove changes be recorded into automation?

can automation talk to api?

The loop marker script from It-alien could be recorded into automation.

do you have ahandy link for it? btw, didn’t it also use virtual midiports to work or something?

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: