# Lua Math - How To Define Space

Let’s say completely imaginary:

numberspace is 2-16, you can’t go below 2 or over 16. You’ve got one shortcut which sends -1 and one shortcut which sends +1 .

How do you read the current_status of numberspace , add -1 to it or add +1 to it, and make that be the current_status_of_numberspace? I’m not entirely sure what you’re trying to do, but maybe this will help…

``````
local min = 2
local max = 16
local current = 2

-- plus one
current = math.max(min, math.min(max, current + 1))

-- minus one
current = math.max(min, math.min(max, current - 1))

``````

I’m trying to do a similar thing to

``````
name = "Global:Impulse:Protman Jump Lines Up",
invoke = function() Jump(-1) end
}
name = "Global:Impulse:Protman Jump Lines Down",
invoke = function() Jump(1) end
}

``````
• except for a different keybinding and obviously a different function. First test will be to get Metronome LPB to increase or decrease according to keybinding press, second to get Metronome BPB to do the same.
Then it’s time to hope against hope that LoopBlock can do the same thing Eventually this’d allow one to map a shortcut for changing current_sample’s loop_mode, and so on.

So something like this or…?

``````
function keybindx(minus)
local min = 2
local max = 16
minus = math.max(min, math.min(max, minus -1))
renoise.()song.transport_function (as a faulty example)

function keybindx(plus)
local min = 2
local max = 16
plus = math.max(min, math.min(max, plus +1))
(followed by keybind)

``````

esaruoho,

I’m not 100% sure I fully understand what you are asking.

Do you mean you want a function that receives a relative value (i.e. +1 or -1), performs some math with it (i.e. adds it to another value from Renoise), restricts the range of the value and then uses that somewhere (i.e. sends it back)?

If so the following pseudocode snippet may be helpful as an idea:

``````function do_something(delta_value)
-- set values
local current_value = renoise.song().somevalue
local max = 16
local min = 1

-- modify
new_value = current_value + delta_value

-- restrict range
if new_value > max then
new_value = max
elseif new_value < min then
new_value = min
end

-- send back to renoise
renoise.song().somevalue = new_value
end
``````

I have written similar code in the past for a variety of tools. One that is fairly well documented can be retrieved from this thread.

Thanks for your help mxb!
At first my re-work of what you wrote didn’t work, but then I added

``````
new_value = nil

``````

and hey presto:

``````
---- +1 / -1 on MetroLPB and MetroBPB
function metlpb(metrlpb)
-- set values
local current_value = renoise.song().transport.metronome_lines_per_beat
local max = 16
local min = 1
local new_value = nil

-- modify
new_value = current_value + metrlpb

-- restrict range
if new_value > max then
new_value = max
elseif new_value < min then
new_value = min
end
-- send back to renoise
renoise.song().transport.metronome_lines_per_beat = new_value
renoise.app():show_status("[Metronome LPB is]: " .. new_value
.. " [Beats per Bar is]: " .. renoise.song().transport.metronome_beats_per_bar)
end

function metbpb(metrbpb)
-- set values
local current_value = renoise.song().transport.metronome_beats_per_bar
local max = 16
local min = 1
local new_valuebpb = nil

-- modify
new_valuebpb = current_value + metrbpb

-- restrict range
if new_valuebpb > max then
new_valuebpb = max
elseif new_valuebpb < min then
new_valuebpb = min
end
-- send back to renoise
renoise.song().transport.metronome_beats_per_bar = new_valuebpb
renoise.app():show_status("[Metronome LPB is]: " .. renoise.song().transport.metronome_lines_per_beat
.. " [Beats per Bar is]: " .. new_valuebpb)
end

name = "Global:Impulse:MetrLPB -1",
invoke = function() metlpb(-1)
end
}

name = "Global:Impulse:MetrLPB +1",
invoke = function() metlpb(1)
end
}
name = "Global:Impulse:MetrBPB -1",
invoke = function() metbpb(-1)
end
}

name = "Global:Impulse:MetrBPB +1",
invoke = function() metbpb(1)
end
}

``````

[quote=“esaruoho, post:6, topic:32725”]
Thanks for your help mxb!
At first my re-work of what you wrote didn’t work, but then I added

``````
new_value = nil

``````

and hey presto:

``````
<snip><br>
<br>
local new_value = nil<br>
<br>
-- modify<br>
new_value = current_value + metrlpb<br>
<br>
<snip><br>
<br>```

<br>[/quote]<br>
<br>
Sorry, I missed out a 'local'.<br>
<br>
These two lines can be combined into one statement as so if you wish:<br>
<br>

```lua<br><br>
local new_value = current_value + metrlpb<br>
<br>```

</snip></snip>``````

Here’s a quick tip from me regarding the code that restricts the value ranges.

math.min(a, b) will return whichever value is the lowest. For example: math.min(16, 17) will return 16.

math.max(a, b) will return whichever value is the highest. For example: math.max(2, 1) will return 2.

So instead of this bit of code: (which is perfectly functional but not very elegant)

``````
if value > max then
value = max
elseif value < min then
value = min
end

``````

You can do this instead, which is much more sexy:

``````
value = math.max(min, math.min(max, value))

`````` Finally, here’s something a bit more compact, just for fun:

``````
-- +1 / -1 on Metronome LPB and Metronome BPB

-- Local reference to transport
local t = renoise.song().transport

t.metronome_lines_per_beat = math.max(1, math.min(16, t.metronome_lines_per_beat + lpb_delta))

t.metronome_beats_per_bar = math.max(1, math.min(16, t.metronome_beats_per_bar + bpb_delta))

-- Show status
renoise.app():show_status(
"Metronome : " .. t.metronome_lines_per_beat .. " LPB : " .. t.metronome_beats_per_bar .. " BPB"
)

end

name = "Global:Impulse:Metronome LPB -1",
invoke = function() adjust_metronome(-1, 0) end
}

name = "Global:Impulse:Metronome LPB +1",
invoke = function() adjust_metronome(1, 0) end
}
name = "Global:Impulse:Metronome BPB -1",
invoke = function() adjust_metronome(0, -1) end
}

name = "Global:Impulse:Metronome BPB +1",
invoke = function() adjust_metronome(0, 1) end
}

``````

Thanks, dBlue! I’ll start using those local “aliases” for functions, seems like it’ll look prettier.

Can there be local aliases that stretch across the whole script, or are these local definitions always limited to the function they are in?

Not just visually nicer, but also more efficient from a performance point of view. Every time you call something like renoise.song().transport, each piece of that command has to be resolved one by one. First renoise must be resolved, then song(), then transport, etc.

If you have a function that performs multiple tasks with some properties of the transport object, then you can save some processing overhead by making a local reference to it first, and then doing your processing on the reference object.

You can of course put these references pretty much anywhere you want in your code. For example, you could do something like this:

``````
local t = renoise.song().transport

function foo()
-- do something here with t.something
end

function bar()
-- do something here with t.something
end

``````

But you should be very careful when doing this. If you try to access renoise.song() from the main body of your main.lua function, then it’s very easy to get an error. For example, when your tool is first loaded into memory by Renoise, no song() actually exists at that point in time, so you will get an error for trying to access a non-existent object. It’s also possible that the user loads/creates a new song while your tool is running, so now your reference to renoise.song() will be invalid if you don’t update it yourself.

There are of course notifiers to check when the song changes and things like that, so it is possible to do this stuff if you want, but generally speaking it’s much safer to just keep your local references within the functions themselves. This way you can safely assume that when the function is called there is actually a valid, up-to-date song() object for it to work with.