A good while ago i have written a small terminal script to render out a song separated by instrument, This would maybe work for your case, if you use one instrument per track. Give it a try maybe. Since this is no tool, you have to copy it per hand into the Renoise scripts folder. On Windows this would be “C:\UsersUsername\AppData\Roaming\Renoise\V3.0.1\Scripts”. then inside Renoise open your song, then go into the scripting terminal, load the LUA file and press the execute button at the bottom right. If needed you can also adjust some settings at the top of the file for the render output.
This was written for an older version of Renoise and i did some quick adjustments for Renoise 3 before the upload which were not tested that much, did a quick render though and it seemed fine.
--[[----------------------------------------------------------------------------
Author : Alexander Stoica
Creation Date : 01/19/2012
Last modified : 12/24/2014
Renders a song separated by instrument.
----------------------------------------------------------------------------]]--
local render_options = {
sample_rate = 44100, -- 22050, 44100, 48000, 88200, 96000
bit_depth = 16, -- 16, 24, 32
interpolation = "precise", -- default, precise
priority = "low" -- realtime, low, high
}
--[[globals]]-------------------------------------------------------------]]--
local thread = nil
--[[functions]]-----------------------------------------------------------]]--
function render()
local output_path = renoise.app():prompt_for_path(
"Select the destination folder:"
)
if not io.exists(output_path) then
print("Error: Invalid output folder specified, aborting!")
return
end
local rs = renoise.song()
-- cache volume levels
local cache = table.create()
for i, instrument in ipairs(rs.instruments) do
cache:insert(i, table.create())
cache[i] = {
pv = instrument.plugin_properties.volume,
sv = table.create()
}
for s, sample in ipairs(instrument.samples) do
if sample.sample_buffer.has_sample_data then
cache[i].sv:insert(s, sample.volume)
end
end
if cache[i].sv:is_empty() and
not instrument.plugin_properties.plugin_loaded then
cache[i] = nil
end
end
-- loop through each instrument
for t, vt in pairs(cache) do
local current_instrument = rs:instrument(t)
-- set volume of all instruments and their samples to 0
for i, _ in pairs(cache) do
local instrument = rs:instrument(i)
if instrument.plugin_properties.plugin_loaded then
instrument.plugin_properties.volume = 0
end
if not cache[i].sv:is_empty() then
for s, _ in pairs(cache[i].sv) do
local sample = instrument:sample(s)
sample.volume = 0
end
end
end
-- restore volume of the current instrument to render
if current_instrument.plugin_properties.plugin_loaded then
current_instrument.plugin_properties.volume = vt.pv
end
if not vt.sv:is_empty() then
for s, _ in pairs(vt.sv) do
local sample = current_instrument:sample(s)
sample.volume = vt.sv[s]
end
end
-- start rendering
local output_filename = output_path ..
string.format("%03d", t - 1) ..
string.format(" %03dBPM ", rs.transport.bpm) ..
string.gsub(current_instrument.name, "[<>:\"/\\|?*]", "")
output_filename = output_filename:match("^(.*%S)")
print("Rendering file: " .. output_filename .. ".wav")
rs.transport:panic()
rs:render(render_options, output_filename, render_done)
-- wait for renoise to finish rendering
coroutine.yield()
end
-- restore all volume levels
for i, vi in pairs(cache) do
local instrument = rs:instrument(i)
if instrument.plugin_properties.plugin_loaded then
instrument.plugin_properties.volume = vi.pv
end
if not vi.sv:is_empty() then
for s, _ in pairs(vi.sv) do
local sample = instrument:sample(s)
sample.volume = vi.sv[s]
end
end
end
print("Rendering completed!")
end
function render_done()
-- resume rendering thread
print("... done")
coroutine.resume(thread)
end
--[[entry point]]---------------------------------------------------------]]--
thread = coroutine.create(render)
coroutine.resume(thread)
---------------------------------------------------------------------[[EOF]]--