Freeze Track Snippet

@esaruoho had a question and problem rendering a track, in order to “freeze” it.

Here’s a snippet on how this could work. Maybe this helps others too. I think this has been done in other tools as well:

-- Define render state (initialized when starting to render)
local render_context = {
  source_track = 0,
  target_track = 0,
  target_instrument = 0,
  temp_file_path = ""

-- Callback function to load the rendered file into a sample buffer
-- of the first sample of the first instrument
function rendering_done_callback()
  local song =
  song:describe_undo("Freeze Track")
  local source_track = song:track(render_context.source_track)
  -- Turn All Render Track Note Columns to "Off"
  for i=1,source_track.max_note_columns do
    source_track:set_column_is_muted(i, true)
  -- Collapse Render Track
  source_track.collapsed = true
  -- Unsolo Source Track
  -- Insert New Track Next to Render Track
  local target_track = song:insert_track_at(render_context.target_track)
  song.selected_track_index = render_context.target_track

  -- Rename New Track using Render Track Name = (render_context.source_track .. " Rendered")

  -- Insert C-4 + Rendered Instrument number to Rendered Track
  local target_pattern = song:pattern(1):track(render_context.target_track)
  local target_note_column = target_pattern:line(1):note_column(1)
  target_note_column.note_string = "C-4"
  target_note_column.instrument_value = render_context.target_instrument - 1
  -- Create New Instrument
  local target_instrument = song:insert_instrument_at(render_context.target_instrument) =
  -- Load the rendered audio file into the sample buffer
  local target_sample_buffer = target_instrument:insert_sample_at(1).sample_buffer

function freezeTrack()
  local song =
  song:describe_undo("Freeze Track")
  -- Set render context
  render_context.source_track = song.selected_track_index
  render_context.target_track = render_context.source_track + 1
  render_context.target_instrument = #song.instruments
  render_context.temp_file_path = os.tmpname(".wav")

  -- Solo Source Track
  local source_track = song.tracks[render_context.source_track]
  if not source_track.solo_state then
  -- Render Selected Track
  local render_options = {
    sample_rate = 44100,
    bit_depth = 32,
    interpolation = "precise",    
    priority = "high",
  -- Start rendering with the correct function call
  local success, error_message = song:render(
    render_options, render_context.temp_file_path, rendering_done_callback)
  -- Handle possible errors during the render initiation
  if not success then"Rendering failed: " .. error_message)
  -- Rest is done when rendering finished


thanks for introducing the temp_path for OS, this means i can get my version working with Windows, Linux and macOS in one go. i’ll incorporate bits from your snippet, and make the samplerate + bitrate configurable within Paketti. and still work in the #line-in detection for realtime vs high.

i appreciate you taking the time to incorporate the OS detection into the mix, as that was what i was looking forward to doing the least.

1 Like