Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Observables

The Renoise API makes extensive use of the Observer pattern. In short, many values are wrapped in "Observable" objects. You can register "notifier" functions on these objects, which will be called whenever the underlying value changes. This is a powerful way to react to changes in the application state without constantly polling and comparing values.

When browsing the API documentation, you will find many properties with an _observable suffix. Let's see how to use this feature by attaching a notifier that runs when the user loads a new song.

local function on_new_document()
  renoise.app():show_message("Loaded a new song!")
end

-- Get the tool's new_document observable and add our function as a notifier.
renoise.tool().app_new_document_observable:add_notifier(on_new_document)

A common pattern is to attach notifiers to song-specific properties inside the app_new_document_observable notifier. This ensures that your notifiers are re-attached whenever a new song is loaded. To listen for changes on a specific value, you typically add _observable to the property name and add a notifier to it.

Let's extend the previous snippet to also fire a message whenever the name of the song changes.

local function on_song_name_changed()
  local song_name = renoise.song().name
  renoise.app():show_message("New name was set!\nName: " .. song_name)
end

local function on_new_document()
  renoise.app():show_message("Loaded a new song!")
  -- When a new song is loaded, attach a notifier to its name_observable
  renoise.song().name_observable:add_notifier(on_song_name_changed)
end

renoise.tool().app_new_document_observable:add_notifier(on_new_document)

Now, try changing the song title in the "Song Settings" tab to see your message pop up.

With this technique, you can listen to all sorts of events, which is very useful when you want your tool to react to user actions like selecting a new instrument, track, or sample.

There are different Observables for each primitive type, such as ObservableBoolean, ObservableNumber, or ObservableString, as well as list types like ObservableBooleanList. You can explore the entire Observables API to see them all.