Permalink
21d5867 Jun 24, 2016
1 contributor

Users who have contributed to this file

2511 lines (1968 sloc) 67.6 KB
--[[============================================================================
GlobalMidiActions.lua
DO NOT EDIT THIS FILE IN THE RENOISE RESOURCE FOLDER! UPDATING RENOISE WILL
TRASH YOUR MODIFICATIONS!
TO EXTEND MIDI MAPPINGS, COPY THIS FILE TO THE RENOISE PREFERENCES SCRIPT
FOLDER, THEN DO YOUR CHANGES AND ADDITIONS THERE.
============================================================================]]--
--[[
List of actions which defines the set of global MIDI mappings in Renoise.
The message parameter, passed to invoke the action, is defined as:
class "TriggerMessage"
-- returns if the should be invoked at all
function is_trigger() -> boolean
-- check which properties are valid
function is_switch() -> boolean
function is_rel_value() -> boolean
function is_abs_value() -> boolean
-- [0 - 127] for abs values, [-63 - 63] for relative values
-- valid when is_rel_value() or is_abs_value() returns true, else nil
int_value
-- valid [true OR false] when :is_switch() returns true, else nil
boolean_value
-- [0.0 - 1.0] min/max range scaling for parameter values. always valid.
value_min_scaling
value_max_scaling
---- Adding new mappings
If you want to extend the default MIDI mapping set, first copy this file to the
"Scripts" folder in your preferences folder. Then do your changes there. The
file in the Renoise resource folder may be overwritten when updating Renoise.
Click on "Help" -> "Show Preferences Folder..." in Renoise to locate the folder.
New MIDI actions can not be bound to the Renoise GUI (the highlighted frames in
the GUI that get visible with the MIDI mapping dialog). They will only show
up in the "Available & Active Messages" list in the MIDI mapping dialog.
Any errors that may happen in the MIDI message handlers, are not shown to the
user. They are only dumped into the scripting terminal. Make sure its open
when changing anything in here to make debugging easier.
When editing this file in Renoises "Scripting Terminal&Editor", any changes
to the message set will instantly be applied as soon as you save the file.
This way you can quickly test out your changes.
When working with an external editor, you can manually reload this script and
apply changes by clicking on the small "refresh" button in Renoise's MIDI
Mapping dialog. Watch out for a small refresh icon next to the "Available &
Active Messages" list.
Scripting developer tools must be enabled to see the "refresh" button and the
scripting terminal. Please see http://scripting.renoise.com for more info about
this.
---- Add mappings via XRNX tools
Alternatively to editing this file, you can also define new midi mappings via
Renoise XRNX tool bundles. This way new mappings can be easily installed (drag
& drop the xrnx tool bundle) and upgrading Renoise won't remove your mappings.
Please have a look at the "Renoise.ScriptingTool.API.lua" documentation for more
info about this.
]]
--------------------------------------------------------------------------------
-- Globals (interface to Renoise)
--------------------------------------------------------------------------------
-- max mapping counts
MAX_SECTION_MAPPINGS = 64
MAX_SEQUENCE_MAPPINGS = 256
MAX_TRACK_MAPPINGS = 64
MAX_SEND_TRACK_MAPPINGS = 32
MAX_GENERIC_PARAMETER_MAPPINGS = 32
-- available_actions
local action_names = table.create()
function available_actions()
return action_names
end
-- invoke_action
local action_map = {}
function invoke_action(name, message)
local action = action_map[name]
if (action == nil) then
error(string.format("trying to invoke undefined action '%s'", name))
end
action(message)
end
--------------------------------------------------------------------------------
-- Locals (message registration & helpers)
--------------------------------------------------------------------------------
-- add_action
local function add_action(name, func)
--[[ debug:
if (name:match("%[Trigger%]$") == nil and
name:match("%[Toggle%]$") == nil and
name:match("%[Set%]$") == nil)
then
error(("action '%s' should be marked, " ..
"end with: [Trigger], [Toggle] or [Set]"):format(name))
end
if (action_map[name] ~= nil) then
error(("action '%s' was already added"):format(name))
end
]]
action_map[name] = func
action_names:insert(name)
end
--------------------------------------------------------------------------------
-- app
local app = renoise.app
-- song
local song = renoise.song
-- sequencer_track
local function sequencer_track(track_index)
if (track_index <= song().sequencer_track_count) then
return song():track(track_index)
else
return nil
end
end
-- send_track
local function send_track(send_index)
if (send_index <= song().send_track_count) then
-- send tracks are always behind the master track
return song():track(song().sequencer_track_count + 1 + send_index)
else
return nil
end
end
-- master_track
local function master_track()
-- master track is always behind the sequencer tracks
return song():track(song().sequencer_track_count + 1)
end
-- selected_track
local function selected_track()
return song().selected_track
end
-- selected_track_device
local function selected_track_device()
return song().selected_track_device
end
-- selected_track_device_index
local function selected_track_device_index()
return song().selected_track_device_index
end
--------------------------------------------------------------------------------
-- clamp_value
local function clamp_value(value, min_value, max_value)
return math.min(max_value, math.max(value, min_value))
end
-- wrap_value
local function wrap_value(value, min_value, max_value)
local range = max_value - min_value + 1
assert(range > 0, "invalid range")
while (value < min_value) do
value = value + range
end
while (value > max_value) do
value = value - range
end
return value
end
-- quantize_value
local function quantize_value(value, quantum)
if (value >= 0) then
value = value + quantum / 2
else
value = value - quantum / 2
end
return math.floor(value / quantum) * quantum
end
--------------------------------------------------------------------------------
-- boolean_message_value
local function boolean_message_value(message, value)
if (message:is_switch()) then
return message.boolean_value
else
return value
end
end
-- toggle_message_value
local function toggle_message_value(message, value)
if (message:is_trigger()) then
return not value
else
return value
end
end
-- message_value_with_offset
local function message_value_with_offset(message, value,
offset, min_value, max_value)
if (message:is_abs_value()) then
return clamp_value(message.int_value + offset, min_value, max_value)
elseif (message:is_rel_value()) then
return clamp_value(value + message.int_value, min_value, max_value)
else
return value
end
end
-- message_value
local function message_value(message, value, min_value, max_value)
return message_value_with_offset(message, value, 0, min_value, max_value)
end
-- inc_message_value
local function inc_message_value(message, value, min_value, max_value)
if (message:is_trigger()) then
return clamp_value(value + 1, min_value, max_value)
else
return value
end
end
-- dec_message_value
local function dec_message_value(message, value, min_value, max_value)
if (message:is_trigger()) then
return clamp_value(value - 1, min_value, max_value)
else
return value
end
end
-- parameter_message_value
local function parameter_message_value(message, parameter)
local new_value = parameter.value
local quantum = parameter.value_quantum
local parameter_min = (parameter.value_max - parameter.value_min) *
message.value_min_scaling + parameter.value_min
local parameter_max = (parameter.value_max - parameter.value_min) *
message.value_max_scaling + parameter.value_min
if (quantum > 0) then
new_value = quantize_value(new_value, quantum)
parameter_min = quantize_value(parameter_min, quantum)
parameter_max = quantize_value(parameter_max, quantum)
end
local parameter_range = parameter_max - parameter_min
if (message:is_abs_value()) then
new_value = parameter_min + (message.int_value / 127 * parameter_range)
if (parameter.polarity == renoise.DeviceParameter.POLARITY_BIPOLAR) then
local center_value = parameter.value_min +
(parameter.value_max - parameter.value_min) / 2;
if (math.abs(center_value - new_value) < parameter_range / 128) then
-- snap to center
new_value = center_value
end
end
elseif (message:is_rel_value()) then
if (quantum > 0) then
if (message.int_value > 0) then
new_value = new_value + quantum
else
new_value = new_value - quantum
end
else
new_value = new_value + parameter_range / 127 * message.int_value;
if (parameter.polarity == renoise.DeviceParameter.POLARITY_BIPOLAR) then
local center_value = parameter.value_min +
(parameter.value_max - parameter.value_min) / 2;
if (math.abs(center_value - new_value) < parameter_range / 128) then
-- snap to center
new_value = center_value
end
end
end
new_value = clamp_value(new_value,
math.min(parameter_min, parameter_max),
math.max(parameter_min, parameter_max)
)
elseif (message:is_switch()) then
if (message.boolean_value) then
new_value = parameter_max
else
new_value = parameter_min
end
elseif (message:is_trigger()) then
if (quantum > 0) then
-- walk through quantized values
if (parameter_max > parameter_min) then
new_value = new_value + quantum;
if (new_value > parameter_max) then
new_value = parameter_min
end
elseif (parameter_max < parameter_min) then
new_value = new_value - quantum
if (new_value < parameter_max) then
new_value = parameter_min
end
end
else
-- toggle between min/max
if (parameter.value > parameter_min + parameter_range / 2) then
new_value = parameter_min
else
new_value = parameter_max
end
end
end
return new_value
end
-- parameter_message_fader_value
local function parameter_message_fader_value(message, volume_parameter)
if (message:is_abs_value() and message.int_value == 0 and message.value_min_scaling == 0) then
return 0 -- always -INF at the bottom
end
if (message:is_abs_value() or message:is_rel_value()) then
local range_min_db
local range_max_db
if (app().window.mixer_fader_type == renoise.ApplicationWindow.MIXER_FADER_TYPE_24DB) then
range_min_db = -24
range_max_db = 3
elseif (app().window.mixer_fader_type == renoise.ApplicationWindow.MIXER_FADER_TYPE_48DB) then
range_min_db = -48
range_max_db = 3
elseif (app().window.mixer_fader_type == renoise.ApplicationWindow.MIXER_FADER_TYPE_96DB) then
range_min_db = -96
range_max_db = 3
else
return parameter_message_value(message, volume_parameter)
end
local hardware_value = message.int_value / 127
-- scaling is entered on a linear 0-1 scale so must convert to fv
-- with the right fader type before we can scale the value
local param_range = volume_parameter.value_max - volume_parameter.value_min
local min_lin = volume_parameter.value_min + message.value_min_scaling * param_range
local max_lin = volume_parameter.value_min + message.value_max_scaling * param_range
local min_db = math.lin2db(min_lin)
local max_db = math.lin2db(max_lin)
local min_fv = math.db2fader(range_min_db, range_max_db, min_db)
local max_fv = math.db2fader(range_min_db, range_max_db, max_db)
local fader_value
if (message:is_abs_value()) then
fader_value = min_fv + hardware_value * (max_fv - min_fv)
else
local quantum = volume_parameter.value_quantum
if (quantum < 1) then
quantum = 1/127
end
local old_db = math.lin2db(volume_parameter.value)
local old_fv = math.db2fader(range_min_db, range_max_db, old_db)
if (hardware_value > 0) then
fader_value = old_fv + quantum * (max_fv - min_fv)
else
fader_value = old_fv - quantum * (max_fv - min_fv)
end
if (fader_value < 0) then
return 0 -- always -INF at the bottom
else
fader_value = clamp_value(fader_value, min_fv, max_fv)
end
end
local db_value = math.fader2db(range_min_db, range_max_db, fader_value);
local lin_value = math.db2lin(db_value);
lin_value = clamp_value(lin_value, volume_parameter.value_min, volume_parameter.value_max)
return lin_value
else
return parameter_message_value(message, volume_parameter)
end
end
-- section helpers
local gather_section_positions = function()
local positions = {}
for k,v in ipairs(song().sequencer.pattern_sequence) do
if song().sequencer:sequence_is_start_of_section(k) then
table.insert(positions,k)
end
end
return positions
end
local get_section_index_by_seq_pos = function(seq_pos)
local positions = gather_section_positions()
if not table.is_empty(positions) then
for k,v in ipairs(positions) do
if (v > seq_pos) then
return k-1
elseif (v == seq_pos) then
return k
end
end
return #positions,positions
end
end
--------------------------------------------------------------------------------
-- Transport
--------------------------------------------------------------------------------
-- Transport:Playback
add_action("Transport:Playback:Panic [Trigger]",
function(message)
if message:is_trigger() then
song().transport:panic()
end
end)
add_action("Transport:Playback:Start Playing [Trigger]",
function(message)
if message:is_trigger() then
local play_mode = renoise.Transport.PLAYMODE_RESTART_PATTERN
song().transport:start(play_mode)
end
end)
add_action("Transport:Playback:Stop Playing [Trigger]",
function(message)
if message:is_trigger() then
song().transport:stop()
end
end)
add_action("Transport:Playback:Start/Stop Playing [Set]",
function(message)
local start_playing = boolean_message_value(
message, song().transport.playing)
if (start_playing ~= song().transport.playing) then
if start_playing then
local play_mode = renoise.Transport.PLAYMODE_RESTART_PATTERN
song().transport:start(play_mode)
else
song().transport:stop()
end
end
end)
add_action("Transport:Playback:Loop Pattern [Set]",
function(message)
song().transport.loop_pattern = boolean_message_value(
message, song().transport.loop_pattern)
end)
add_action("Transport:Playback:Loop Pattern [Toggle]",
function(message)
song().transport.loop_pattern = toggle_message_value(
message, song().transport.loop_pattern)
end)
add_action("Transport:Playback:Loop Block [Set]",
function(message)
song().transport.loop_block_enabled = boolean_message_value(
message, song().transport.loop_block_enabled)
end)
add_action("Transport:Playback:Loop Block [Toggle]",
function(message)
song().transport.loop_block_enabled = toggle_message_value(
message, song().transport.loop_block_enabled)
end)
add_action("Transport:Playback:Loop Block Range [Set]",
function(message)
-- reverses the range, so we don't use message_value...
if message:is_abs_value() then
song().transport.loop_block_range_coeff = clamp_value(
message.int_value, 2, 16)
elseif message:is_rel_value() then
song().transport.loop_block_range_coeff = clamp_value(
song().transport.loop_block_range_coeff - message.int_value, 2, 16)
end
end)
add_action("Transport:Playback:Move Loop Block Backwards [Trigger]",
function(message)
if message:is_trigger() then
song().transport:loop_block_move_backwards()
end
end)
add_action("Transport:Playback:Move Loop Block Forwards [Trigger]",
function(message)
if message:is_trigger() then
song().transport:loop_block_move_forwards()
end
end)
add_action("Transport:Playback:Follow Player [Set]",
function(message)
song().transport.follow_player = boolean_message_value(
message, song().transport.follow_player)
end)
add_action("Transport:Playback:Follow Player [Toggle]",
function(message)
song().transport.follow_player = toggle_message_value(
message, song().transport.follow_player)
end)
-- Transport:Record
add_action("Transport:Record:Undo Last Action [Trigger]",
function(message)
if message:is_trigger() then
if(song():can_undo()) then
song():undo()
end
end
end)
add_action("Transport:Record:Redo Last Action [Trigger]",
function(message)
if message:is_trigger() then
if(song():can_redo()) then
song():redo()
end
end
end)
add_action("Transport:Record:Metronome Enabled [Set]",
function(message)
song().transport.metronome_enabled = boolean_message_value(
message, song().transport.metronome_enabled)
end)
add_action("Transport:Record:Metronome Enabled [Toggle]",
function(message)
song().transport.metronome_enabled = toggle_message_value(
message, song().transport.metronome_enabled)
end)
add_action("Transport:Record:Quantization Enabled [Set]",
function(message)
song().transport.record_quantize_enabled = boolean_message_value(
message, song().transport.record_quantize_enabled)
end)
add_action("Transport:Record:Quantization Enabled [Toggle]",
function(message)
song().transport.record_quantize_enabled = toggle_message_value(
message, song().transport.record_quantize_enabled)
end)
add_action("Transport:Record:Quantization Amount [Set]",
function(message)
song().transport.record_quantize_lines = message_value(
message, song().transport.record_quantize_lines, 1, 32)
end)
add_action("Transport:Record:Decrease Quantization Amount [Trigger]",
function(message)
song().transport.record_quantize_lines = dec_message_value(
message, song().transport.record_quantize_lines, 1, 32)
end)
add_action("Transport:Record:Increase Quantization Amount [Trigger]",
function(message)
song().transport.record_quantize_lines = inc_message_value(
message, song().transport.record_quantize_lines, 1, 32)
end)
add_action("Transport:Record:Parameter Record Mode [Set]",
function(message)
local record_into_automation = (song().transport.record_parameter_mode ==
renoise.Transport.RECORD_PARAMETER_MODE_AUTOMATION)
if boolean_message_value(message, record_into_automation) then
song().transport.record_parameter_mode =
renoise.Transport.RECORD_PARAMETER_MODE_AUTOMATION
else
song().transport.record_parameter_mode =
renoise.Transport.RECORD_PARAMETER_MODE_PATTERN
end
end)
add_action("Transport:Record:Parameter Record Mode [Toggle]",
function(message)
local record_into_automation = (song().transport.record_parameter_mode ==
renoise.Transport.RECORD_PARAMETER_MODE_AUTOMATION)
if toggle_message_value(message, record_into_automation) then
song().transport.record_parameter_mode =
renoise.Transport.RECORD_PARAMETER_MODE_AUTOMATION
else
song().transport.record_parameter_mode =
renoise.Transport.RECORD_PARAMETER_MODE_PATTERN
end
end)
add_action("Transport:Record:Start/Stop Sample Recording [Trigger]",
function(message)
if message:is_trigger() then
song().transport:start_stop_sample_recording()
end
end)
add_action("Transport:Record:Cancel Sample Recording [Trigger]",
function(message)
if message:is_trigger() then
song().transport:cancel_sample_recording()
end
end)
-- Transport:Song
add_action("Transport:Song:BPM [Set]",
function(message)
song().transport.bpm = message_value_with_offset(
message, song().transport.bpm, 60, 32, 999)
end)
add_action("Transport:Song:Decrease BPM [Trigger]",
function(message)
song().transport.bpm = dec_message_value(
message, song().transport.bpm, 32, 999)
end)
add_action("Transport:Song:Increase BPM [Trigger]",
function(message)
song().transport.bpm = inc_message_value(
message, song().transport.bpm, 32, 999)
end)
add_action("Transport:Song:LPB [Set]",
function(message)
song().transport.lpb = message_value(
message, song().transport.lpb, 1, 256)
end)
add_action("Transport:Song:Decrease LPB [Trigger]",
function(message)
song().transport.lpb = dec_message_value(
message, song().transport.lpb, 1, 256)
end)
add_action("Transport:Song:Increase LPB [Trigger]",
function(message)
song().transport.lpb = inc_message_value(
message, song().transport.lpb, 1, 256)
end)
add_action("Transport:Song:Shuffle Enabled [Set]",
function(message)
song().transport.groove_enabled = boolean_message_value(
message, song().transport.groove_enabled)
end)
add_action("Transport:Song:Shuffle Enabled [Toggle]",
function(message)
song().transport.groove_enabled = toggle_message_value(
message, song().transport.groove_enabled)
end)
-- Transport:Edit
add_action("Transport:Edit:Edit Mode [Set]",
function(message)
song().transport.edit_mode = boolean_message_value(
message, song().transport.edit_mode)
end)
add_action("Transport:Edit:Edit Mode [Toggle]",
function(message)
song().transport.edit_mode = toggle_message_value(
message, song().transport.edit_mode)
end)
add_action("Transport:Edit:Edit Mode Step [Set]",
function(message)
song().transport.edit_step = message_value(
message, song().transport.edit_step, 0, 64)
end)
add_action("Transport:Edit:Decrease Edit Mode Step [Trigger]",
function(message)
song().transport.edit_step = dec_message_value(
message, song().transport.edit_step, 0, 64)
end)
add_action("Transport:Edit:Increase Edit Mode Step [Trigger]",
function(message)
song().transport.edit_step = inc_message_value(
message, song().transport.edit_step, 0, 64)
end)
add_action("Transport:Edit:Octave [Set]",
function(message)
song().transport.octave = message_value(
message, song().transport.octave, 0, 8)
end)
add_action("Transport:Edit:Decrease Octave [Trigger]",
function(message)
song().transport.octave = dec_message_value(
message, song().transport.octave, 0, 8)
end)
add_action("Transport:Edit:Increase Octave [Trigger]",
function(message)
song().transport.octave = inc_message_value(
message, song().transport.octave, 0, 8)
end)
add_action("Transport:Edit:Keyboard Velocity Enabled [Toggle]",
function(message)
song().transport.keyboard_velocity_enabled = toggle_message_value(
message, song().transport.keyboard_velocity_enabled)
end)
add_action("Transport:Edit:Keyboard Velocity Enabled [Set]",
function(message)
song().transport.keyboard_velocity_enabled = boolean_message_value(
message, song().transport.keyboard_velocity_enabled)
end)
add_action("Transport:Edit:Keyboard Velocity [Set]",
function(message)
song().transport.keyboard_velocity = message_value(
message, song().transport.keyboard_velocity, 0, 127)
end)
add_action("Transport:Edit:Decrease Keyboard Velocity [Trigger]",
function(message)
song().transport.keyboard_velocity = dec_message_value(
message, song().transport.keyboard_velocity, 0, 127)
end)
add_action("Transport:Edit:Increase Keyboard Velocity [Trigger]",
function(message)
song().transport.keyboard_velocity = inc_message_value(
message, song().transport.keyboard_velocity, 0, 127)
end)
add_action("Transport:Edit:Single Track Edit Mode [Toggle]",
function(message)
song().transport.single_track_edit_mode = toggle_message_value(
message, song().transport.single_track_edit_mode)
end)
add_action("Transport:Edit:Single Track Edit Mode [Set]",
function(message)
song().transport.single_track_edit_mode = boolean_message_value(
message, song().transport.single_track_edit_mode)
end)
add_action("Transport:Edit:Patternwrap Mode [Toggle]",
function(message)
song().transport.wrapped_pattern_edit = toggle_message_value(
message, song().transport.wrapped_pattern_edit)
end)
add_action("Transport:Edit:Patternwrap Mode [Set]",
function(message)
song().transport.wrapped_pattern_edit = boolean_message_value(
message, song().transport.wrapped_pattern_edit)
end)
--------------------------------------------------------------------------------
-- Seq. Triggering
--------------------------------------------------------------------------------
-- Seq. Triggering:Trigger
add_action("Seq. Triggering:Trigger:Current [Trigger]",
function(message)
if message:is_trigger() then
song().transport:trigger_sequence(song().transport.edit_pos.sequence)
end
end)
add_action("Seq. Triggering:Trigger:Sequence XX [Set]",
function(message)
if message:is_abs_value() then
local sequence_pos = clamp_value(
message.int_value, 1, song().transport.song_length.sequence)
song().transport:trigger_sequence(sequence_pos)
end
end)
for sequence_pos = 1,MAX_SEQUENCE_MAPPINGS do
add_action(string.format(
"Seq. Triggering:Trigger:Sequence XX:Sequence #%02d [Trigger]",
sequence_pos),
function(message)
if message:is_trigger() then
if sequence_pos <= #song().sequencer.pattern_sequence then
song().transport:trigger_sequence(sequence_pos)
end
end
end)
end
-- Seq. Triggering:Schedule:Section
local set_scheduled_section = function(section_index)
local positions = gather_section_positions()
if positions[section_index] then
song().transport:set_scheduled_sequence(positions[section_index])
end
end
add_action("Seq. Triggering:Schedule:Section:Current [Trigger]",
function(message)
if message:is_trigger() then
local seq_pos = song().transport.edit_pos.sequence
local section_index = get_section_index_by_seq_pos(seq_pos)
set_scheduled_section(section_index)
end
end)
add_action("Seq. Triggering:Schedule:Section:Next [Trigger]",
function(message)
if message:is_trigger() then
local seq_pos = song().transport.edit_pos.sequence
local section_index = get_section_index_by_seq_pos(seq_pos)
set_scheduled_section(section_index+1)
end
end)
add_action("Seq. Triggering:Schedule:Section:Previous [Trigger]",
function(message)
if message:is_trigger() then
local seq_pos = song().transport.edit_pos.sequence
local section_index = get_section_index_by_seq_pos(seq_pos)
set_scheduled_section(section_index-1)
end
end)
add_action("Seq. Triggering:Schedule:Section:Section XX [Set]",
function(message)
if message:is_abs_value() then
local section_index = clamp_value(
message.int_value, 1, MAX_SECTION_MAPPINGS)
set_scheduled_section(section_index)
end
end)
for section_index = 1,MAX_SECTION_MAPPINGS do
add_action(string.format(
"Seq. Triggering:Schedule:Section XX:Section #%02d [Trigger]",
section_index),
function(message)
if message:is_trigger() then
set_scheduled_section(section_index)
end
end)
end
-- Seq. Looping:Section
local loop_section_by_index = function(section_index)
local positions = gather_section_positions()
if table.is_empty(positions) then
return
end
if not positions[section_index] then
return
end
-- rules: enable loop if partially selected, or unselected
-- disable loop if section (and _only_ section) is wholly looped
local section_start = positions[section_index]
local section_end = positions[section_index+1] and
positions[section_index+1]-1 or #song().sequencer.pattern_sequence
local within_range = function(pos,range_start,range_end)
return pos >= range_start and pos <= range_end
end
local enable_loop = false
local loop_seq_empty = (song().transport.loop_sequence_range[1] == 0) and
(song().transport.loop_sequence_range[2] == 0)
if not loop_seq_empty then
local all_looped,all_empty = false,false
for k,v in ipairs(song().sequencer.pattern_sequence) do
if within_range(k,section_start,section_end) then
if within_range(k,song().transport.loop_sequence_start,song().transport.loop_sequence_end) then
if not all_looped then
all_looped = true
end
all_empty = false
else
if not all_empty then
all_empty = true
end
all_looped = false
end
end
end
if all_looped then
enable_loop = false
elseif all_empty then
enable_loop = true
end
else
enable_loop = true
end
if enable_loop then
song().transport.loop_sequence_range = {section_start,section_end}
else
song().transport.loop_sequence_range = {}
end
end
add_action("Seq. Looping:Section:Current Section [Trigger]",
function(message)
if message:is_trigger() then
local seq_pos = song().transport.edit_pos.sequence
local section_index = get_section_index_by_seq_pos(seq_pos)
loop_section_by_index(section_index)
end
end)
add_action("Seq. Looping:Section:Section XX [Set]",
function(message)
if message:is_abs_value() then
local positions = gather_section_positions()
if positions[message.int_value] then
loop_section_by_index(message.int_value)
end
end
end)
for section_index = 1,MAX_SECTION_MAPPINGS do
add_action(string.format(
"Seq. Looping:Section XX:Section #%02d [Trigger]",
section_index),
function(message)
if message:is_trigger() then
loop_section_by_index(section_index)
end
end)
end
-- Seq. Triggering:Schedule:
add_action("Seq. Triggering:Schedule:Current [Trigger]",
function(message)
if message:is_trigger() then
song().transport:set_scheduled_sequence(song().transport.edit_pos.sequence)
end
end)
add_action("Seq. Triggering:Schedule:Next [Trigger]",
function(message)
if message:is_trigger() then
local seq_pos = song().transport.edit_pos.sequence + 1
if song().sequencer.pattern_sequence[seq_pos] then
song().transport:set_scheduled_sequence(seq_pos)
end
end
end)
add_action("Seq. Triggering:Schedule:Previous [Trigger]",
function(message)
if message:is_trigger() then
local seq_pos = song().transport.edit_pos.sequence - 1
if song().sequencer.pattern_sequence[seq_pos] then
song().transport:set_scheduled_sequence(seq_pos)
end
end
end)
add_action("Seq. Triggering:Schedule:Sequence XX [Set]",
function(message)
if message:is_abs_value() then
local sequence_pos = clamp_value(
message.int_value, 1, song().transport.song_length.sequence)
song().transport:set_scheduled_sequence(sequence_pos)
end
end)
for sequence_pos = 1,MAX_SEQUENCE_MAPPINGS do
add_action(string.format(
"Seq. Triggering:Schedule:Sequence XX:Sequence #%02d [Trigger]",
sequence_pos),
function(message)
if message:is_trigger() then
if sequence_pos <= #song().sequencer.pattern_sequence then
song().transport:set_scheduled_sequence(sequence_pos)
end
end
end)
end
-- Seq. Triggering:Add Scheduled
add_action("Seq. Triggering:Add Scheduled:Current [Trigger]",
function(message)
if message:is_trigger() then
song().transport:add_scheduled_sequence(song().transport.edit_pos.sequence)
end
end)
add_action("Seq. Triggering:Add Scheduled:Sequence XX [Set]",
function(message)
if message:is_abs_value() then
local sequence_pos = clamp_value(
message.int_value, 1, song().transport.song_length.sequence)
song().transport:add_scheduled_sequence(sequence_pos)
end
end)
for sequence_pos = 1,MAX_SEQUENCE_MAPPINGS do
add_action(string.format(
"Seq. Triggering:Add Scheduled:Sequence XX:Sequence #%02d [Trigger]",
sequence_pos),
function(message)
if message:is_trigger() then
if sequence_pos <= #song().sequencer.pattern_sequence then
song().transport:add_scheduled_sequence(sequence_pos)
end
end
end)
end
--------------------------------------------------------------------------------
-- Seq. Muting
--------------------------------------------------------------------------------
-- Seq. Muting: Selected Seq.
for track_index = 1,MAX_TRACK_MAPPINGS do
add_action(string.format(
"Seq. Muting:Selected Seq. [Toggle]:Mute Track #%02d [Toggle]", track_index),
function(message)
if message:is_trigger() then
if track_index <= #song().tracks then
local is_muted = song().sequencer:track_sequence_slot_is_muted(
track_index, song().selected_sequence_index)
song().sequencer:set_track_sequence_slot_is_muted(track_index,
song().selected_sequence_index, toggle_message_value(message, is_muted))
end
end
end)
add_action(string.format(
"Seq. Muting:Selected Seq. [Set]:Mute Track #%02d [Set]", track_index),
function(message)
if message:is_switch() then
if track_index <= #song().tracks then
song().sequencer:set_track_sequence_slot_is_muted(track_index,
song().selected_sequence_index, message.boolean_value)
end
end
end)
end
-- Seq. Muting: Seq. #XX
for sequence_pos = 1,MAX_SEQUENCE_MAPPINGS do
for track_index = 1,MAX_TRACK_MAPPINGS do
add_action(string.format(
"Seq. Muting:Seq. XX [Toggle]:Seq. #%02d:Mute Track #%02d [Toggle]",
sequence_pos, track_index),
function(message)
if message:is_trigger() then
if sequence_pos <= #song().sequencer.pattern_sequence then
if track_index <= #song().tracks then
local is_muted = song().sequencer:track_sequence_slot_is_muted(
track_index, sequence_pos)
song().sequencer:set_track_sequence_slot_is_muted(track_index,
sequence_pos, toggle_message_value(message, is_muted))
end
end
end
end)
add_action(string.format(
"Seq. Muting:Seq. XX [Set]:Seq. #%02d:Mute Track #%02d [Set]",
sequence_pos, track_index),
function(message)
if message:is_switch() then
if sequence_pos <= #song().sequencer.pattern_sequence then
if track_index <= #song().tracks then
song().sequencer:set_track_sequence_slot_is_muted(track_index,
sequence_pos, message.boolean_value)
end
end
end
end)
end
end
--------------------------------------------------------------------------------
-- Track Muting
--------------------------------------------------------------------------------
-- Mute/Unmute/Solo
add_action("Track Muting:Mute All [Trigger]",
function(message)
if message:is_trigger() then
for _,track in ipairs(song().tracks) do
if track.type ~= renoise.Track.TRACK_TYPE_MASTER then
track:mute()
end
end
end
end)
add_action("Track Muting:Unmute All [Trigger]",
function(message)
if message:is_trigger() then
for _,track in ipairs(song().tracks) do
track:unmute()
end
end
end)
add_action("Track Muting:Mute/Unmute:Current Track [Toggle]",
function(message)
if message:is_trigger() then
local track = selected_track()
if track.mute_state == renoise.Track.MUTE_STATE_ACTIVE then
if track.type ~= renoise.Track.TRACK_TYPE_MASTER then
track:mute()
end
else
track:unmute()
end
end
end)
add_action("Track Muting:Mute/Unmute:Current Track [Set]",
function(message)
if message:is_switch() then
local track = selected_track()
if track.type ~= renoise.Track.TRACK_TYPE_MASTER then
if message.boolean_value then
track:mute()
else
track:unmute()
end
end
end
end)
add_action("Track Muting:Solo:Current Track [Trigger]",
function(message)
if message:is_trigger() then
selected_track():solo()
end
end)
-- Mute/Unmute/Solo Track XX
for track_index = 1,MAX_TRACK_MAPPINGS do
add_action(string.format(
"Track Muting:Mute/Unmute:Track XX [Toggle]:Track #%02d [Toggle]",
track_index),
function(message)
if message:is_trigger() then
local track = sequencer_track(track_index)
if track ~= nil then
if track.mute_state == renoise.Track.MUTE_STATE_ACTIVE then
track:mute()
else
track:unmute()
end
end
end
end)
add_action(string.format(
"Track Muting:Mute/Unmute:Track XX [Set]:Track #%02d [Set]",
track_index),
function(message)
if message:is_switch() then
local track = sequencer_track(track_index)
if track ~= nil then
if message.boolean_value then
track:mute()
else
track:unmute()
end
end
end
end)
add_action(string.format(
"Track Muting:Solo:Track XX:Track #%02d [Trigger]",
track_index),
function(message)
if message:is_trigger() then
local track = sequencer_track(track_index)
if track ~= nil then
track:solo()
end
end
end)
end
-- Mute/Unmute/Solo Send Track XX
for send_index = 1,MAX_SEND_TRACK_MAPPINGS do
add_action(string.format(
"Track Muting:Mute/Unmute:Send Track XX [Toggle]:Send Track #%02d [Toggle]",
send_index),
function(message)
if message:is_trigger() then
local track = send_track(send_index)
if track ~= nil then
if track.mute_state == renoise.Track.MUTE_STATE_ACTIVE then
track:mute()
else
track:unmute()
end
end
end
end)
add_action(string.format(
"Track Muting:Mute/Unmute:Send Track XX [Set]:Send Track #%02d [Set]",
send_index),
function(message)
if message:is_switch() then
local track = send_track(send_index)
if track ~= nil then
if message.boolean_value then
track:mute()
else
track:unmute()
end
end
end
end)
add_action(string.format(
"Track Muting:Solo:Send Track XX:Send Track #%02d [Trigger]",
send_index),
function(message)
if message:is_trigger() then
local track = send_track(send_index)
if track ~= nil then
track:solo()
end
end
end)
end
--------------------------------------------------------------------------------
-- Track Levels
--------------------------------------------------------------------------------
-- Track Levels::Current Track
add_action("Track Levels:Volume:Current Track (Pre) [Set]",
function(message)
selected_track().prefx_volume:record_value(
parameter_message_fader_value(message, selected_track().prefx_volume))
end)
add_action("Track Levels:Panning:Current Track (Pre) [Set]",
function(message)
selected_track().prefx_panning:record_value(
parameter_message_value(message, selected_track().prefx_panning))
end)
add_action("Track Levels:Width:Current Track [Set]",
function(message)
selected_track().prefx_width:record_value(
parameter_message_value(message, selected_track().prefx_width))
end)
add_action("Track Levels:Volume:Current Track (Post) [Set]",
function(message)
selected_track().postfx_volume:record_value(
parameter_message_fader_value(message, selected_track().postfx_volume))
end)
add_action("Track Levels:Panning:Current Track (Post) [Set]",
function(message)
selected_track().postfx_panning:record_value(
parameter_message_value(message, selected_track().postfx_panning))
end)
-- Track Levels::Master Track
add_action("Track Levels:Volume:Master Track (Pre) [Set]",
function(message)
master_track().prefx_volume:record_value(
parameter_message_fader_value(message, master_track().prefx_volume))
end)
add_action("Track Levels:Panning:Master Track (Pre) [Set]",
function(message)
master_track().prefx_panning:record_value(
parameter_message_value(message, master_track().prefx_panning))
end)
add_action("Track Levels:Width:Master Track [Set]",
function(message)
master_track().prefx_width:record_value(
parameter_message_value(message, master_track().prefx_width))
end)
add_action("Track Levels:Volume:Master Track (Post) [Set]",
function(message)
master_track().postfx_volume:record_value(
parameter_message_fader_value(message, master_track().postfx_volume))
end)
add_action("Track Levels:Panning:Master Track (Post) [Set]",
function(message)
master_track().postfx_panning:record_value(
parameter_message_value(message, master_track().postfx_panning))
end)
-- Track Levels::Track XX
for track_index = 1,MAX_TRACK_MAPPINGS do
add_action(string.format(
"Track Levels:Volume:Track XX (Pre):Track #%02d [Set]",
track_index),
function(message)
local track = sequencer_track(track_index)
if track ~= nil then
track.prefx_volume:record_value(
parameter_message_fader_value(message, track.prefx_volume))
end
end)
add_action(string.format(
"Track Levels:Volume:Track XX (Post):Track #%02d [Set]",
track_index),
function(message)
local track = sequencer_track(track_index)
if track ~= nil then
track.postfx_volume:record_value(
parameter_message_fader_value(message, track.postfx_volume))
end
end)
add_action(string.format(
"Track Levels:Panning:Track XX (Pre):Track #%02d [Set]",
track_index),
function(message)
local track = sequencer_track(track_index)
if track ~= nil then
track.prefx_panning:record_value(
parameter_message_value(message, track.prefx_panning))
end
end)
add_action(string.format(
"Track Levels:Panning:Track XX (Post):Track #%02d [Set]",
track_index),
function(message)
local track = sequencer_track(track_index)
if track ~= nil then
track.postfx_panning:record_value(
parameter_message_value(message, track.postfx_panning))
end
end)
add_action(string.format(
"Track Levels:Width:Track XX:Track #%02d [Set]", track_index),
function(message)
local track = sequencer_track(track_index)
if track ~= nil then
track.prefx_width:record_value(
parameter_message_value(message, track.prefx_width))
end
end)
end
-- Track Levels::Send Track XX
for send_index = 1,MAX_SEND_TRACK_MAPPINGS do
add_action(string.format(
"Track Levels:Volume:Send Track XX (Pre):Send Track #%02d [Set]",
send_index),
function(message)
local track = send_track(send_index)
if track ~= nil then
track.prefx_volume:record_value(
parameter_message_fader_value(message, track.prefx_volume))
end
end)
add_action(string.format(
"Track Levels:Volume:Send Track XX (Post):Send Track #%02d [Set]",
send_index),
function(message)
local track = send_track(send_index)
if track ~= nil then
track.postfx_volume:record_value(
parameter_message_fader_value(message, track.postfx_volume))
end
end)
add_action(string.format(
"Track Levels:Panning:Send Track XX (Pre):Send Track #%02d [Set]",
send_index),
function(message)
local track = send_track(send_index)
if track ~= nil then
track.prefx_panning:record_value(
parameter_message_value(message, track.prefx_panning))
end
end)
add_action(string.format(
"Track Levels:Panning:Send Track XX (Post):Send Track #%02d [Set]",
send_index),
function(message)
local track = send_track(send_index)
if track ~= nil then
track.postfx_panning:record_value(
parameter_message_value(message, track.postfx_panning))
end
end)
add_action(string.format(
"Track Levels:Width:Send Track XX:Send Track #%02d [Set]",
send_index),
function(message)
local track = send_track(send_index)
if track ~= nil then
track.prefx_width:record_value(
parameter_message_value(message, track.prefx_width))
end
end)
end
--------------------------------------------------------------------------------
-- Track DSP
--------------------------------------------------------------------------------
-- Track DSPs:Selected FX Active
add_action("Track DSPs:Selected FX Active [Toggle]",
function(message)
local sel_device = selected_track_device()
local sel_device_index = selected_track_device_index()
-- can't bypass track devices at 1
if sel_device and sel_device_index > 1 then
sel_device.is_active = toggle_message_value(
message, sel_device.is_active)
end
end)
add_action("Track DSPs:Selected FX Active [Set]",
function(message)
local sel_device = selected_track_device()
local sel_device_index = selected_track_device_index()
-- can't bypass track devices at 1
if sel_device and sel_device_index > 1 then
sel_device.is_active = boolean_message_value(
message, sel_device.is_active)
end
end)
-- Track DSPs:Selected FX
for parameter_index = 1, MAX_GENERIC_PARAMETER_MAPPINGS do
add_action(string.format(
"Track DSPs:Selected FX:Parameter #%02d [Set]",
parameter_index),
function(message)
local sel_device = selected_track_device()
if sel_device and parameter_index <= #sel_device.parameters then
local parameter = sel_device.parameters[parameter_index]
parameter:record_value(parameter_message_value(message, parameter))
end
end)
end
-- Track DSP:Selected FX (Mixer Subset)
for parameter_index = 1, MAX_GENERIC_PARAMETER_MAPPINGS do
add_action(string.format(
"Track DSPs:Selected FX (Mixer Subset):Parameter #%02d [Set]",
parameter_index),
function(message)
local sel_device = selected_track_device()
if sel_device then
local mixer_parameters = {}
for _, parameter in pairs(sel_device.parameters) do
if parameter.show_in_mixer then
mixer_parameters[#mixer_parameters + 1] = parameter
end
end
if parameter_index <= #mixer_parameters then
local parameter = mixer_parameters[parameter_index]
parameter:record_value(parameter_message_value(message, parameter))
end
end
end)
end
--------------------------------------------------------------------------------
-- Navigation
--------------------------------------------------------------------------------
-- Navigation:Sequencer
add_action("Navigation:Sequencer:Current Sequence Pos [Set]",
function(message)
if message:is_abs_value() then
local new_edit_pos = song().transport.edit_pos
new_edit_pos.sequence = clamp_value(
message.int_value,
1, song().transport.song_length.sequence)
song().transport.edit_pos = new_edit_pos
elseif message:is_rel_value() then
local new_edit_pos = song().transport.edit_pos
new_edit_pos.sequence = clamp_value(
new_edit_pos.sequence + message.int_value,
1, song().transport.song_length.sequence)
song().transport.edit_pos = new_edit_pos
end
end)
add_action("Navigation:Sequencer:Select Previous Sequence Pos [Trigger]",
function(message)
if message:is_trigger() then
local new_edit_pos = song().transport.edit_pos
new_edit_pos.sequence = clamp_value(
new_edit_pos.sequence - 1,
1, song().transport.song_length.sequence)
song().transport.edit_pos = new_edit_pos
end
end)
add_action("Navigation:Sequencer:Select Next Sequence Pos [Trigger]",
function(message)
if message:is_trigger() then
local new_edit_pos = song().transport.edit_pos
new_edit_pos.sequence = clamp_value(
new_edit_pos.sequence + 1,
1, song().transport.song_length.sequence)
song().transport.edit_pos = new_edit_pos
end
end)
add_action("Navigation:Sequencer:Current Pattern [Set]",
function(message)
song().selected_pattern_index = message_value(
message, song().selected_pattern_index, 1, 1000)
end)
add_action("Navigation:Sequencer:Decrease Current Pattern [Trigger]",
function(message)
song().selected_pattern_index = dec_message_value(
message, song().selected_pattern_index, 1, 1000)
end)
add_action("Navigation:Sequencer:Increase Current Pattern [Trigger]",
function(message)
song().selected_pattern_index = inc_message_value(
message, song().selected_pattern_index, 1, 1000)
end)
-- Navigation:Tracks
add_action("Navigation:Tracks:Current Track [Set]",
function(message)
if message:is_abs_value() then
song().selected_track_index = clamp_value(
message.int_value, 1, #song().tracks)
elseif message:is_rel_value() then
if (message.int_value < 0) then
for i = -1, message.int_value, -1 do
song():select_previous_track()
end
elseif (message.int_value > 0) then
for i = 1, message.int_value do
song():select_next_track()
end
end
end
end)
add_action("Navigation:Tracks:Select Previous Track [Trigger]",
function(message)
if message:is_trigger() then
song():select_previous_track()
end
end)
add_action("Navigation:Tracks:Select Next Track [Trigger]",
function(message)
if message:is_trigger() then
song():select_next_track()
end
end)
-- Navigation:Columns
add_action("Navigation:Columns:Select Previous Column [Trigger]",
function(message)
if message:is_trigger() then
local sel_track_index = song().selected_track_index
local sel_track = song().tracks[sel_track_index]
local note_column_count = sel_track.visible_note_columns
local effect_column_count = sel_track.visible_effect_columns
local column_count = note_column_count + effect_column_count
local new_column_index = 0
if song().selected_note_column_index > 0 then
new_column_index = song().selected_note_column_index - 1
elseif song().selected_effect_column_index > 0 then
new_column_index = note_column_count +
song().selected_effect_column_index - 1
end
-- jump to the previous effect column
if new_column_index >= 1 and
new_column_index > note_column_count then
song().selected_effect_column_index = new_column_index -
note_column_count
-- jump to the previous note column
elseif new_column_index >= 1 then
song().selected_note_column_index = new_column_index
-- jump to the previous effect or note column
else
sel_track_index = wrap_value(sel_track_index - 1, 1, #song().tracks)
sel_track = song().tracks[sel_track_index]
note_column_count = sel_track.visible_note_columns
effect_column_count = sel_track.visible_effect_columns
column_count = note_column_count + effect_column_count
song().selected_track_index = sel_track_index
if effect_column_count > 0 then
song().selected_effect_column_index = effect_column_count
else
song().selected_note_column_index = note_column_count
end
end
end
end)
add_action("Navigation:Columns:Select Next Column [Trigger]",
function(message)
if message:is_trigger() then
local sel_track_index = song().selected_track_index
local sel_track = song().tracks[sel_track_index]
local note_column_count = sel_track.visible_note_columns
local effect_column_count = sel_track.visible_effect_columns
local column_count = note_column_count + effect_column_count
local new_column_index = 0
if song().selected_note_column_index > 0 then
new_column_index = song().selected_note_column_index + 1
elseif song().selected_effect_column_index > 0 then
new_column_index = note_column_count +
song().selected_effect_column_index + 1
end
-- jump to the next note column
if new_column_index <= note_column_count then
song().selected_note_column_index = new_column_index
-- jump to the next effect column
elseif new_column_index <= column_count then
song().selected_effect_column_index = new_column_index -
note_column_count
-- jump to the next tracks note or effect column
else
sel_track_index = wrap_value(sel_track_index + 1, 1, #song().tracks)
sel_track = song().tracks[sel_track_index]
note_column_count = sel_track.visible_note_columns
song().selected_track_index = sel_track_index
if note_column_count > 0 then
song().selected_note_column_index = 1
else
song().selected_effect_column_index = 1
end
end
end
end)
add_action("Navigation:Columns:Select Previous Note Column [Trigger]",
function(message)
if message:is_trigger() then
local sel_track_index = song().selected_track_index
local sel_track = song().tracks[sel_track_index]
local note_column_count = sel_track.visible_note_columns
-- jump to previous note column in the selected track
if song().selected_note_column_index > 1 then
song().selected_note_column_index =
song().selected_note_column_index - 1
-- jump to a previous track with note columns
else
for i = 1,#song().tracks do
sel_track_index = wrap_value(sel_track_index - 1, 1, #song().tracks)
sel_track = song().tracks[sel_track_index]
note_column_count = sel_track.visible_note_columns
if note_column_count > 0 then
song().selected_track_index = sel_track_index
song().selected_note_column_index = note_column_count
break
end
end
end
end
end)
add_action("Navigation:Columns:Select Next Note Column [Trigger]",
function(message)
if message:is_trigger() then
local sel_track_index = song().selected_track_index
local sel_track = song().tracks[sel_track_index]
local note_column_count = sel_track.visible_note_columns
-- jump to next note column in the selected track
if song().selected_note_column_index > 0 and
song().selected_note_column_index <
note_column_count then
song().selected_note_column_index =
song().selected_note_column_index + 1
-- jump to a next track with note columns
else
for i = 1,#song().tracks do
sel_track_index = wrap_value(sel_track_index + 1, 1, #song().tracks)
sel_track = song().tracks[sel_track_index]
note_column_count = sel_track.visible_note_columns
if note_column_count > 0 then
song().selected_track_index = sel_track_index
song().selected_note_column_index = 1
break
end
end
end
end
end)
add_action("Navigation:Columns:Show Volume Column [Toggle]",
function(message)
if message:is_trigger() then
local selected_track = selected_track()
if selected_track.max_note_columns > 0 then
selected_track.volume_column_visible = toggle_message_value(
message, selected_track.volume_column_visible)
end
end
end)
add_action("Navigation:Columns:Show Volume Column [Set]",
function(message)
if message:is_trigger() then
local selected_track = selected_track()
if selected_track.max_note_columns > 0 then
selected_track.volume_column_visible = boolean_message_value(
message, selected_track.volume_column_visible)
end
end
end)
add_action("Navigation:Columns:Show Panning Column [Toggle]",
function(message)
if message:is_trigger() then
local selected_track = selected_track()
if selected_track.max_note_columns > 0 then
selected_track.panning_column_visible = toggle_message_value(
message, selected_track.panning_column_visible)
end
end
end)
add_action("Navigation:Columns:Show Panning Column [Set]",
function(message)
if message:is_trigger() then
local selected_track = selected_track()
if selected_track.max_note_columns > 0 then
selected_track.panning_column_visible = boolean_message_value(
message, selected_track.panning_column_visible)
end
end
end)
add_action("Navigation:Columns:Show Delay Column [Toggle]",
function(message)
if message:is_trigger() then
local selected_track = selected_track()
if selected_track.max_note_columns > 0 then
selected_track.delay_column_visible = toggle_message_value(
message, selected_track.delay_column_visible)
end
end
end)
add_action("Navigation:Columns:Show Delay Column [Set]",
function(message)
if message:is_trigger() then
local selected_track = selected_track()
if selected_track.max_note_columns > 0 then
selected_track.delay_column_visible = boolean_message_value(
message, selected_track.delay_column_visible)
end
end
end)
add_action("Navigation:Columns:Show Sample FX Column [Toggle]",
function(message)
if message:is_trigger() then
local selected_track = selected_track()
if selected_track.max_note_columns > 0 then
selected_track.sample_effects_column_visible = toggle_message_value(
message, selected_track.sample_effects_column_visible)
end
end
end)
add_action("Navigation:Columns:Show Sample FX Column [Set]",
function(message)
if message:is_trigger() then
local selected_track = selected_track()
if selected_track.max_note_columns > 0 then
selected_track.sample_effects_column_visible = boolean_message_value(
message, selected_track.sample_effects_column_visible)
end
end
end)
-- Navigation:Track DSPs
add_action("Navigation:Track DSPs:Current Track DSP [Set]",
function(message)
if message:is_abs_value() then
song().selected_track_device_index = clamp_value(
message.int_value, 1, #selected_track().devices)
elseif message:is_rel_value() then
song().selected_track_device_index = clamp_value(
song().selected_track_device_index + message.int_value,
1, #selected_track().devices)
end
end)
add_action("Navigation:Track DSPs:Select Previous Track DSP [Trigger]",
function(message)
if message:is_trigger() then
song().selected_track_device_index = clamp_value(
song().selected_track_device_index - 1,
1, #selected_track().devices)
end
end)
add_action("Navigation:Track DSPs:Select Next Track DSP [Trigger]",
function(message)
if message:is_trigger() then
song().selected_track_device_index = clamp_value(
song().selected_track_device_index + 1,
1, #selected_track().devices)
end
end)
-- Navigation:Instruments
add_action("Navigation:Instruments:Current Instrument [Set]",
function(message)
if message:is_abs_value() then
song().selected_instrument_index = clamp_value(
message.int_value, 1, #song().instruments)
elseif message:is_rel_value() then
song().selected_instrument_index = clamp_value(
song().selected_instrument_index + message.int_value,
1, #song().instruments)
end
end)
add_action("Navigation:Instruments:Decrease Current Instrument [Trigger]",
function(message)
if message:is_trigger() then
song().selected_instrument_index = clamp_value(
song().selected_instrument_index - 1, 1, #song().instruments)
end
end)
add_action("Navigation:Instruments:Increase Current Instrument [Trigger]",
function(message)
if message:is_trigger() then
song().selected_instrument_index = clamp_value(
song().selected_instrument_index + 1, 1, #song().instruments)
end
end)
add_action("Navigation:Instruments:Capture Nearest From Pattern [Trigger]",
function(message)
if message:is_trigger() then
song():capture_instrument_from_pattern()
end
end)
add_action("Navigation:Instruments:Capture From Pattern [Trigger]",
function(message)
if message:is_trigger() then
song():capture_nearest_instrument_from_pattern()
end
end)
--------------------------------------------------------------------------------
-- GUI
--------------------------------------------------------------------------------
-- GUI:Window
add_action("GUI:Window:Fullscreen Mode [Toggle]",
function(message)
app().window.fullscreen = toggle_message_value(
message, app().window.fullscreen)
end)
add_action("GUI:Window:Fullscreen Mode [Set]",
function(message)
app().window.fullscreen = boolean_message_value(
message, app().window.fullscreen)
end)
-- GUI:Dialogs
add_action("GUI:Dialogs:Show Sample Recorder [Set]",
function(message)
app().window.sample_record_dialog_is_visible = boolean_message_value(
message, app().window.sample_record_dialog_is_visible)
end)
add_action("GUI:Dialogs:Show Sample Recorder [Toggle]",
function(message)
app().window.sample_record_dialog_is_visible = toggle_message_value(
message, app().window.sample_record_dialog_is_visible)
end)
-- GUI:Presets
add_action("GUI:Presets:Activate Preset [Set]",
function(message)
if message:is_abs_value() then
app().window:select_preset(clamp_value(message.int_value, 1, 8))
end
end)
for preset_index = 1,8 do
add_action(string.format(
"GUI:Presets:Activate Preset #%02d [Trigger]", preset_index),
function(message)
if message:is_trigger() then
app().window:select_preset(preset_index)
end
end)
end
-- GUI:Browser
add_action("GUI:Show Disk Browser [Trigger]",
function(message)
if message:is_trigger() then
app().window.disk_browser_is_visible =
not app().window.disk_browser_is_visible
end
end)
add_action("GUI:Show Disk Browser [Set]",
function(message)
app().window.disk_browser_is_visible = boolean_message_value(
message, app().window.disk_browser_is_visible)
end)
-- GUI:Instrument Box
add_action("GUI:Show Instrument Box [Trigger]",
function(message)
if message:is_trigger() then
app().window.instrument_box_is_visible =
not app().window.instrument_box_is_visible
end
end)
add_action("GUI:Show Instrument Box [Set]",
function(message)
app().window.instrument_box_is_visible = boolean_message_value(
message, app().window.instrument_box_is_visible )
end)
-- GUI:Upper Frame
local upper_frame_views = {}
table.insert(upper_frame_views,
renoise.ApplicationWindow.UPPER_FRAME_TRACK_SCOPES)
table.insert(upper_frame_views,
renoise.ApplicationWindow.UPPER_FRAME_MASTER_SPECTRUM)
add_action("GUI:Upper Frame:Show Upper Frame [Toggle]",
function(message)
app().window.upper_frame_is_visible = toggle_message_value(
message, app().window.upper_frame_is_visible)
end)
add_action("GUI:Upper Frame:Show Upper Frame [Set]",
function(message)
app().window.upper_frame_is_visible = boolean_message_value(
message, app().window.upper_frame_is_visible)
end)
add_action("GUI:Upper Frame:Select Previous [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_upper_frame = wrap_value(
app().window.active_upper_frame - 1, 1, #upper_frame_views)
end
end)
add_action("GUI:Upper Frame:Select Next [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_upper_frame = wrap_value(
app().window.active_upper_frame + 1, 1, #upper_frame_views)
end
end)
add_action("GUI:Upper Frame:Select [Set]",
function(message)
app().window.active_upper_frame = message_value(
message, app().window.active_upper_frame, 1, #upper_frame_views)
end)
add_action("GUI:Upper Frame:Show Track Scopes [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_upper_frame =
renoise.ApplicationWindow.UPPER_FRAME_TRACK_SCOPES
end
end)
add_action("GUI:Upper Frame:Show Master Spectrum [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_upper_frame =
renoise.ApplicationWindow.UPPER_FRAME_MASTER_SPECTRUM
end
end)
-- GUI:Middle Frame
local middle_frame_views = {}
table.insert(middle_frame_views,
renoise.ApplicationWindow.MIDDLE_FRAME_PATTERN_EDITOR)
table.insert(middle_frame_views,
renoise.ApplicationWindow.MIDDLE_FRAME_MIXER)
table.insert(middle_frame_views,
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_PHRASE_EDITOR)
table.insert(middle_frame_views,
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_SAMPLE_KEYZONES)
table.insert(middle_frame_views,
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_SAMPLE_EDITOR)
table.insert(middle_frame_views,
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_SAMPLE_MODULATION)
table.insert(middle_frame_views,
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_SAMPLE_EFFECTS)
table.insert(middle_frame_views,
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_PLUGIN_EDITOR)
table.insert(middle_frame_views,
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_MIDI_EDITOR)
add_action("GUI:Middle Frame:Select Previous [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame = wrap_value(
app().window.active_middle_frame - 1, 1, #middle_frame_views)
end
end)
add_action("GUI:Middle Frame:Select Next [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame = wrap_value(
app().window.active_middle_frame + 1, 1, #middle_frame_views)
end
end)
add_action("GUI:Middle Frame:Select [Set]",
function(message)
app().window.active_middle_frame = message_value(
message, app().window.active_middle_frame, 1, #middle_frame_views)
end)
add_action("GUI:Middle Frame:Show Pattern Editor [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame =
renoise.ApplicationWindow.MIDDLE_FRAME_PATTERN_EDITOR
end
end)
add_action("GUI:Middle Frame:Show Mixer [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame =
renoise.ApplicationWindow.MIDDLE_FRAME_MIXER
end
end)
add_action("GUI:Middle Frame:Show Pattern Matrix [Set]",
function(message)
app().window.pattern_matrix_is_visible = boolean_message_value(
message, app().window.pattern_matrix_is_visible)
end)
add_action("GUI:Middle Frame:Show Pattern Matrix [Toggle]",
function(message)
app().window.pattern_matrix_is_visible = toggle_message_value(
message, app().window.pattern_matrix_is_visible)
end)
add_action("GUI:Middle Frame:Show Pattern Advanced Edit [Set]",
function(message)
app().window.pattern_advanced_edit_is_visible = boolean_message_value(
message, app().window.pattern_advanced_edit_is_visible)
end)
add_action("GUI:Middle Frame:Show Pattern Advanced Edit [Toggle]",
function(message)
app().window.pattern_advanced_edit_is_visible = toggle_message_value(
message, app().window.pattern_advanced_edit_is_visible)
end)
add_action("GUI:Middle Frame:Show Instrument Phrase Editor [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame =
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_PHRASE_EDITOR
end
end)
add_action("GUI:Middle Frame:Show Instrument Sample Editor [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame =
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_SAMPLE_EDITOR
end
end)
add_action("GUI:Middle Frame:Show Instrument Sample Keyzones [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame =
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_SAMPLE_KEYZONES
end
end)
add_action("GUI:Middle Frame:Show Instrument Sample Modulation [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame =
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_SAMPLE_MODULATION
end
end)
add_action("GUI:Middle Frame:Show Instrument Sample Effects [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame =
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_SAMPLE_EFFECTS
end
end)
add_action("GUI:Middle Frame:Show Instrument Plugin Editor [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame =
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_PLUGIN_EDITOR
end
end)
add_action("GUI:Middle Frame:Show Instrument Midi Editor [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_middle_frame =
renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_MIDI_EDITOR
end
end)
-- GUI:Lower Frame
local lower_frame_views = {}
table.insert(lower_frame_views,
renoise.ApplicationWindow.LOWER_FRAME_TRACK_DSPS)
table.insert(lower_frame_views,
renoise.ApplicationWindow.LOWER_FRAME_TRACK_AUTOMATION)
add_action("GUI:Lower Frame:Show Lower Frame [Toggle]",
function(message)
app().window.lower_frame_is_visible = toggle_message_value(
message, app().window.lower_frame_is_visible)
end)
add_action("GUI:Lower Frame:Show Lower Frame [Set]",
function(message)
app().window.lower_frame_is_visible = boolean_message_value(
message, app().window.lower_frame_is_visible)
end)
add_action("GUI:Lower Frame:Select Previous [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_lower_frame = wrap_value(
app().window.active_lower_frame - 1, 1, #lower_frame_views)
end
end)
add_action("GUI:Lower Frame:Select Next [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_lower_frame = wrap_value(
app().window.active_lower_frame + 1, 1, #lower_frame_views)
end
end)
add_action("GUI:Lower Frame:Select [Set]",
function(message)
app().window.active_lower_frame = message_value(
message, app().window.active_lower_frame, 1, #lower_frame_views)
end)
add_action("GUI:Lower Frame:Show Track DSPs [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_lower_frame =
renoise.ApplicationWindow.LOWER_FRAME_TRACK_DSPS
end
end)
add_action("GUI:Lower Frame:Show Track Automation [Trigger]",
function(message)
if message:is_trigger() then
app().window.active_lower_frame =
renoise.ApplicationWindow.LOWER_FRAME_TRACK_AUTOMATION
end
end)