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.
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.
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?
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.
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?
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.
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…