Snippet: Random Sample Layering

Here is a small terminal script, which allows you to layer a bunch of samples and generate new ones out of them with a few customizations. Obviously works best when using source samples with a similar sound, e.g. snares, hats and so on. Make sure to run this with Renoise 2.7 Beta 2 or newer.

--[[----------------------------------------------------------------------------  
  
 Author : Alexander Stoica  
 Creation Date : 03/13/2011  
 Last modified : 03/16/2011  
 Version : 1.0  
  
 How to use:  
  
 1. Start a new song in Renoise.  
 2. Add all the samples to the instrument list, which you want to use as  
 source material for the new samples.  
 3. Look through the options below to customize the randomization behaviour.  
 4. Tweak the samples by adding effects to the layers (tracks) or master track.  
 The pattern matrix is also useful to mute/unmute certain layers for a  
 sample quickly.  
 5. When happy with the result, render the song and use the "Save each pattern  
 to separate track" option.  
 6. Process the generated samples with a wave editor to trim any silence from  
 the end.  
  
----------------------------------------------------------------------------]]--  
  
--[[global options]]------------------------------------------------------]]--  
  
local samples_to_generate = 10 -- number of layered samples to create  
local sample_length = 16 -- new sample length in lines  
local sample_layers = 8 -- how many layers for each new sample should be used  
  
--[[randomizer options]]--------------------------------------------------]]--  
  
local note_randomization_enabled = true  
local note_default = 48 -- C-4  
local note_random_lower_range = 0 -- note_default - note_random_lower_range  
local note_random_upper_range = 12 -- note_default + note_random_upper_range  
local note_random_chance = 60 -- chance of randomized note in percent  
  
local volume_randomization_enabled = true  
local volume_default = 128  
local volume_random_range = 64 -- volume_default - volume_random_range  
local volume_random_chance = 50 -- chance of randomized volume in percent  
  
local panning_randomization_enabled = true  
local panning_default = 64  
local panning_random_range = 16 -- panning_default + or - panning_random_range  
local panning_random_chance = 50 -- chance of randomized panning in percent  
  
local delay_randomization_enabled = true  
local delay_default = 0  
local delay_random_range = 32 -- delay_default + delay_random_range  
local delay_random_chance = 20 -- chance of randomized delay in percent  
  
local width_randomization_enabled = true  
local width_default = 0  
local width_random_range = 255 -- width_default + width_random_range  
local width_random_chance = 80 -- chance of randomized width in percent  
  
--[[end of options]]------------------------------------------------------]]--  
  
local rs = renoise.song()  
local instrument_pool = table.create()  
  
for i, instrument in ipairs(rs.instruments) do  
 for _, sample in ipairs(instrument.samples) do  
 if (sample.sample_buffer.has_sample_data) then  
 instrument_pool:insert(i)  
 break  
 end  
 end  
end  
  
if not instrument_pool:is_empty() then  
  
 local function clip(value, min, max)  
  
 if value < min then  
 value = min  
 elseif value > max then  
 value = max  
 end  
  
 return value  
  
 end  
  
 for _, pattern in ipairs(rs.patterns) do  
 pattern:clear()  
 end  
  
 rs.sequencer:insert_sequence_at(1, 1)  
  
 while #rs.sequencer.pattern_sequence > 1 do  
 rs.sequencer:delete_sequence_at(#rs.sequencer.pattern_sequence)  
 end  
  
 while #rs.sequencer.pattern_sequence < samples_to_generate do  
 rs.sequencer:insert_sequence_at(1, 1)  
 end  
  
 rs.sequencer:make_range_unique(2, samples_to_generate)  
  
 for _, pattern in ipairs(rs.patterns) do  
 pattern.number_of_lines = clip(  
 sample_length, 1, renoise.Pattern.MAX_NUMBER_OF_LINES  
 )  
 end  
  
 for t, track in ripairs(rs.tracks) do  
 if track.type == renoise.Track.TRACK_TYPE_SEND or  
 track.type == renoise.Track.TRACK_TYPE_SEQUENCER and  
 t > sample_layers then  
  
 rs:delete_track_at(t)  
 end  
 end  
  
 if #rs.tracks - 1 < sample_layers then  
 for t = 1, sample_layers + 1 - #rs.tracks do  
 rs:insert_track_at(1)  
 end  
 end  
  
 for t = 1, sample_layers do  
  
 local track = rs:track(t)  
  
 track.visible_note_columns = 1  
 track.volume_column_visible = volume_randomization_enabled  
 track.panning_column_visible = panning_randomization_enabled  
 track.delay_column_visible = delay_randomization_enabled  
  
 if width_randomization_enabled then  
 track.visible_effect_columns = 1  
 else  
 track.visible_effect_columns = 0  
 end  
  
 end  
  
 math.randomseed(tonumber(tostring(os.time()):reverse():sub(1, 6)))  
  
 for i = 1, 10 do  
 math.random()  
 end  
  
 for _, pattern in ipairs(rs.patterns) do  
 for t = 1, sample_layers do  
  
 local note = pattern:track(t):line(1):note_column(1)  
 local effect = pattern:track(t):line(1):effect_column(1)  
  
 note.note_value = clip(note_default, 0, 119)  
  
 if note_randomization_enabled then  
 if math.random(100) <= clip(note_random_chance, 1, 100) then  
 note.note_value = clip(math.random(  
 note_default - note_random_lower_range,  
 note_default + note_random_upper_range  
 ), 0, 119)  
 end  
 end  
  
 note.instrument_value = clip(  
 instrument_pool[math.random(#instrument_pool)], 0, 254  
 )  
  
 if volume_randomization_enabled then  
 if math.random(100) <= clip(volume_random_chance, 1, 100) then  
 note.volume_value = clip(math.random(  
 volume_default - volume_random_range,  
 volume_default  
 ), 0, 128)  
 else  
 note.volume_value = clip(volume_default, 0, 128)  
 end  
 end  
  
 if panning_randomization_enabled then  
 if math.random(100) <= clip(panning_random_chance, 1, 100) then  
 note.panning_value = clip(math.random(  
 panning_default - panning_random_range,  
 panning_default + panning_random_range  
 ), 0, 128)  
 else  
 note.panning_value = clip(panning_default, 0, 128)  
 end  
 end  
  
 if delay_randomization_enabled then  
 if math.random(100) <= clip(delay_random_chance, 1, 100) then  
 note.delay_value = clip(math.random(  
 delay_default + delay_random_range  
 ), 0, 255)  
 else  
 note.delay_value = clip(delay_default, 0, 255)  
 end  
 end  
  
 if width_randomization_enabled then  
 effect.number_string = "0A"  
 if math.random(100) <= clip(width_random_chance, 1, 100) then  
 effect.amount_value = clip(math.random(  
 width_default + width_random_range  
 ), 0, 255)  
 else  
 effect.amount_value = clip(width_default, 0, 255)  
 end  
 end  
  
 end  
 end  
  
else  
 print("Warning! No sample based instruments found, script aborted.")  
end  
  
---------------------------------------------------------------------[[EOF]]--   

thnks have got some interesting results!