Module xVoiceManager

This class keeps track of active, playing voices as they are triggered.

.

In more detail

This class offers advanced voice-management for your own applications. This includes the ability to trigger and release specific instruments in specific tracks, while preserving the ability to freely move around in Renoise while doing so.

Without voice-management it would be too easy to create hanging notes. Everything from switching track, instrument or octave while playing, to having multiple MIDI sources could cause trouble. A good voice-manager will understand this and be able to determine the originating 'place' where the voice got triggered.

Column allocation

The class is able to assist with automatic note-column allocation while recording. It's a basic approach, but close enough to how Renoise usually works to feel familiar.

  • Recordings start from the currently selected note column
  • New note columns (voices) are allocated as new notes arrive
  • Voices stay within their column as other voices are released/removed

Polyphony limits

In Renoise, you can play a maximum of 12 voices in a single track (maximum number of note-columns).

If you are familiar with MIDI recording in Renoise, you probably have noticed that there exist a monophonic trigger option. Enabling this option will restrict the number of possible voices (and note-columns) during a recording session. xVoiceManager has no "monophonic" mode as such, but setting the voice_limit to 1 should yield the same result.

Column allocation

When automatic column-allocation is enabled, new note columns are allocated as the need arises. When this feature is enabled, the polyphonic limit can never be larger than the number of available columns, starting from the column_index of the first voice. So if you start recording while in note-column 11, you have a maximum polyphony of 2 voices before voice stealing kicks in.

Voice stealing

Voice stealing takes effect the moment you feed a xVoiceManager with more voices than the current polyphony limit allows. xVoiceManager is using a simple heuristic which will replace the oldest voice with the new one (just like how Renoise does it).

Observable events

Attach notifiers to detect when voices are triggered or released.

triggered_observable -> fired right after a voice starts playing
released_observable -> fired right before a voice is released

After you have attached a notifier, you will receive a 'bang', but no argument. Instead, you should look for the triggered/released_index properties - they will contain the value you need.

Usage example

How to instantiate a copy of this class, and feed xMidiMessages into it:

local voicemgr = xVoiceManager{
  follow_track = false,
}

voicemgr.triggered_observable:add_notifier(function()
  -- use 'voicemgr.triggered_index'
end)
voicemgr.released_observable:add_notifier(function()
  -- use 'voicemgr.released_index'
end)

local xmsg = some_note_on_message -- provide your own message
voicemgr:input_message(xmsg) -- should trigger our notifier

Functions

__init (table) [Constructor] accepts a single argument for initializing the class
input_message (xmsg) [Class] Input a message into the voice-manager
input_note_column (xnotecol, col_idx, line_idx) [Class] Alternative input method, convert notecol to xmsg (when possible) and invoke input_message
release_all () [Class] Release all active voices
release_all_instrument (instr_idx) [Class] Release all voices associated with a specific instrument
release_all_track (track_idx) [Class] Release all voices associated with a specific track
release (voice_idx) [Class] Release specific voice
get_voice_index (xmsg) [Class] Locate among active voices, taking the pitch + track + instrument into consideration (if all match, the voice is considered active...)
get_available_columns (track_idx) [Class] Get the first column which does not have a playing voice assigned to it
_steal_voice () [Class] Release the oldest voice (release, then trigger stolen_observable)
_attach_to_song () [Class] Monitor changes to tracks and instruments
get_by_pitch (pitch) [Class] Get a voice with a specific pitch
get_higher (idx) [Class] Get a voice which has a higher pitch than the provided one
get_highest () [Class] Get the voice with the highest pitch
get_lower (idx) [Class] Get a voice which has a lower pitch than the provided one
get_lowest () [Class] Get the voice with the lowest pitch
_register (xmsg) [Class] Register/add a voice
_check_expired () [Class] Check if any voices have expired (when duration is set)

Tables

self.voices table, active voices

Fields

self.voice_limit the maximum number of voices (0 = 'unlimited')
self.duration number, note duration in seconds (0 = infinite)
self.column_allocation bool, whether to use automatic column allocation or not
self.released_index voice about to be released (0 = none)
self.triggered_index newly triggered voice (0 = none)
self.stolen_index when voice got stolen (refer to released_index)


Functions

__init (table)
[Constructor] accepts a single argument for initializing the class

Parameters:

  • table {

    voice_limit (number)
    duration (number)
    column_allocation (boolean)
    follow_track (boolean)
    follow_instrument (boolean)
    follow_octave (boolean)
    

    }

input_message (xmsg)
[Class] Input a message into the voice-manager

Parameters:

  • xmsg (xMidiMessage)

Returns:

  1. xMidiMessage (added/removed), false (ignored/active) or nil (invalid)
  2. int (voice index), when added or active
input_note_column (xnotecol, col_idx, line_idx)
[Class] Alternative input method, convert notecol to xmsg (when possible) and invoke input_message

Parameters:

  • xnotecol (xNoteColumn)
  • col_idx (number)
  • line_idx (number)
release_all ()
[Class] Release all active voices
release_all_instrument (instr_idx)
[Class] Release all voices associated with a specific instrument

Parameters:

  • instr_idx
release_all_track (track_idx)
[Class] Release all voices associated with a specific track

Parameters:

  • track_idx
release (voice_idx)
[Class] Release specific voice

Parameters:

  • voice_idx
get_voice_index (xmsg)
[Class] Locate among active voices, taking the pitch + track + instrument into consideration (if all match, the voice is considered active...)

Parameters:

  • xmsg (xMidiMessage) should be a MIDI note-message

Returns:

    number or nil
get_available_columns (track_idx)
[Class] Get the first column which does not have a playing voice assigned to it

Parameters:

  • track_idx , which track to check

Returns:

    table, available column indices
_steal_voice ()
[Class] Release the oldest voice (release, then trigger stolen_observable)
_attach_to_song ()
[Class] Monitor changes to tracks and instruments
get_by_pitch (pitch)
[Class] Get a voice with a specific pitch

Parameters:

  • pitch (number)

Returns:

  1. xMidiMessage or nil
  2. int or nil
get_higher (idx)
[Class] Get a voice which has a higher pitch than the provided one

Parameters:

  • idx (number)

Returns:

  1. xMidiMessage or nil
  2. int or nil
get_highest ()
[Class] Get the voice with the highest pitch

Returns:

  1. xMidiMessage or nil
  2. int or nil
get_lower (idx)
[Class] Get a voice which has a lower pitch than the provided one

Parameters:

  • idx (number)

Returns:

    xMidiMessage or nil
get_lowest ()
[Class] Get the voice with the lowest pitch

Returns:

    xMidiMessage or nil
_register (xmsg)
[Class] Register/add a voice

Parameters:

  • xmsg (xMidiMessage) should be a MIDI note-message
_check_expired ()
[Class] Check if any voices have expired (when duration is set)

Tables

self.voices
table, active voices

Fields

self.voice_limit
the maximum number of voices (0 = 'unlimited')
self.duration
number, note duration in seconds (0 = infinite)
self.column_allocation
bool, whether to use automatic column allocation or not
self.released_index
voice about to be released (0 = none)
self.triggered_index
newly triggered voice (0 = none)
self.stolen_index
when voice got stolen (refer to released_index)
generated by LDoc 1.4.2