The Api Wishlist Thread

+ renoise.song().clipboard observable and writable

Return true -> continue paste processing
Return false -> stop further execution. (like event.stopropagation() / stop bubbling)

Please add an observer forrenoise.song().selection_in_pattern

Please add:

+ renoise.tool().trigger_short_cut(path) To be able to trigger ANY shortcut from the renoise short page…

+ renoise.song().selected_line_index_observable, so it triggers on every manual edit pos change…

+ renoise.song().current_pdc / renoise.song().latency , for scenarios see below

+renoise.song().transport:play_one_line_at(pos), just like if you pressing return for playing only one line. Without any position scrolling. And without enabling the play symbol! And please BEFORE the playing of keyboard or midi input happens!!! So it plays like it wasn’t edited.

I would like to enable playing the current line while editing

If I try to play the song on a edit position with current functionality, I have to stop it after the delay of one line… this also does not work correctly.

So another request:

  • Modifiedrenoise.song().transport:start_at(pos) to be modified that it will play immediately the first line. Even on immediate stop afterwards.

See my problem live here:Attachment 5884 not found.

EDIT: This version quite works now… Also seems to work with high latencies. But would be much better with these api extensions.

  • Bind “Pattern Editor:Navigation:Toggle Play On Edit” to a shortcut.
  • Press shortcut once to activate.
  • Activate edit mode.

Now you should be able to listen to the current position on editing position changes. …

My problems now are:

  • it doesn’t work so well, since i have to fire a transport.stop() with a delay…

  • Also, sometimes strange velocity values will occur or note-offs!!!??! (I edited with keyboard!)

  • The current edit is now double played. The note you enter will be played on key down + on reply immediately again…

Here is the code:

Click to view contents
renoise.tool():add_keybinding {
  name = "Pattern Editor:Navigation:Toggle Play On Edit",
  invoke = function()
   local s = renoise.song()
   if (s == nil) then return end
  
   local t = s.transport
   self.isPlayOnEdit = not self.isPlayOnEdit
   -- on
   if (self.isPlayOnEdit) then
    self:showStatusDelayed("Toggle Play On Edit ACTIVATED")
    self.lastPos = s.selected_line_index

    self.editPosFunc = function()
     local curPos = t.edit_pos.line -- s.selected_line_index
     local ms_per_line = 1000 / t.bpm * 60 / t.lpb
     local posDirectionDown = (self.lastPos - curPos) < 0
    
     -- editing pos change
     if (not t.playing and t.edit_mode and self.lastPos ~= curPos) then
     
      -- remember metronome etc settings, switch to no follow :(
      local curMetroPreValue = t.metronome_precount_enabled
      local curMetroValue = t.metronome_enabled
     if (self.curFollow == nil) then
       self.curFollow = t.follow_player
     end
      t.metronome_precount_enabled = false
      t.metronome_enabled = false
      t.follow_player = false
     
      -- kill timer func
      local clearFunc = function ()
       if (self.playLineFunc ~= nil and renoise.tool():has_timer(self.playLineFunc)) then
        renoise.tool():remove_timer(self.playLineFunc)
        self.playLineFunc = nil
       end    
      end
     
      self.playLineFunc = function ()
       if (
       posDirectionDown and (t.edit_pos.line >= curPos or t.edit_pos.line <= 2 and curPos >= s.selected_pattern.number_of_lines - 1)
       or
       not posDirectionDown
       ) then
        -- stop preview play
        clearFunc()
        t:stop()
        -- sets t.follow_player = self.curFollow 500ms later
        self:setFollowDelayed()
        t.metronome_precount_enabled = curMetroPreValue
        t.metronome_enabled = curMetroValue
       end
       
      end
     
      -- register timeout for stop
      clearFunc()
     
      -- preview play the current pos
      if (posDirectionDown) then
       renoise.tool():add_timer(self.playLineFunc, ms_per_line * 2)
       t:start_at(self.lastPos)
      else
       -- The value "1.5" is a delicate one, try between 1.2 - 2 to feel the change!!!!
       renoise.tool():add_timer(self.playLineFunc, ms_per_line * 1)
       t:start_at(curPos) 
      end
      self.lastPos = curPos
      --print("playing at "..curPos)
    end
    end
   
    renoise.tool():add_timer(self.editPosFunc, 15)
   
   -- off
   else
     if (self.editPosFunc ~= nil) then
      self:showStatusDelayed("Toggle Play On Edit DISABLED")
      renoise.tool():remove_timer(self.editPosFunc)
      self.editPosFunc = nil
     end
   end
  end
 }

jhkghj

post-428-0-92523700-1445390573.png

get/ set for .selected_instrument_index in the *Instr. Automation device (so we could change from Twin 2 to another inst. in the pic above)

The DSP_Parameter assignments to different Plugin_Parameters would be handy in the API too as they are only accessible via xml. preset . Though I guess that may be more difficult as non generic to DSP devices.

For Renoise 3.2:

renoise.song().tracks[].insert_column_at(index) (index == 0 -> on the very left)

So you easily can insert a column to a track, without taking care of nasty manual note data copy action :stuck_out_tongue:

moving track columns using lua

It was added just before 3.1 release, but I cannot find it in the lua api… Moving track column via api. So insert_column_at wouldn’t be hard to do…

1000% speed up of lua api and pattern operations

If you start to iterate over many loops, you will quickly realize has slooow the renoise api is. Normally even multiple looping over a whole song should be done in the time of a wink. Even more nowadays, with those power cpus… C’mon guys, why is it so slow? It’s also quite slow while using advanced editor… Is it using lua, too, or is the XML song data access so slow? Please consider this…

HTML-ified Renoise LUA API docs

I don’t know how you guys find proper information in your plain text api docs… It’s well written, no doubt here. But for somebody who doesn’tmemorize the complete api, it’s really hard to check if there is a required functionality!

Basically the docs lacks of:

  • A proper method index, sorted by topic, clickable with fancy link to the section. Uber would be a permanent index on the left or right.

  • Cross-links! There is a reference to another function ? Fine, then also link to that section within text.

  • More references

C’mon guys. Not everybody writes novels with Latex in his/her spare time… Can you please use an automatic html-ifer tool for your docs? There are many many for php stuff and c++, maybe it can but used for lua stuff, too?

For keeping good track of all alias_pattern_index values in a song, the following seems to be needed:

  1. Use observables that keep track of the sequences and tracks in a song.

  2. Add observables to all alias_pattern_index values of every single patterntrack. This must be updated if tracks or sequences are added/removed.

  3. Make your own scheme (probably comparing tables) for determining what alias(es) have been changed and how.

Perhaps something simpler could be provided? I’m thinking something similar to the line_notifier, returning a table of what was changed and how.

Perhaps: renoise.song().active_aliases_observable – returning { track_index, pattern_index, alias_pattern_index }

  • renoise.song().tracks[].devices[].external_editor_visible (observable)

or is it observable?

+ target instrument of automation device either in active-preset-data or parameters. I would really love to see all parameters in parameter list, even non-automatable, non writable

EDIT:

+renoise.song().patterns[].tracks[].automation[].reading_disabled[boolean]

or

+sng:instruments[].plugin_properties.plugin_device.parameters.reading_disabled [boolean]

for temporary disabling feedback (renoise automation/slider -> actual plugin parameter), so while automation recording, the currently written automation point within a line (PLAYMODE_LINEAR/CUBIC)does not feed-back to the plugin again, and again writes strange automation values

PATCH sng:instruments[].plugin_properties.plugin_device.parameters

Patched in a way, that feed backed / endless looped sending of values is not possible. For example you listen for a parameter, write it to automation, the automation again triggers the plugin, and the plugin triggers again theplugin_device.parameters[x] …

renoise.app():undo_step_record_start()

Set marker to current undo history position as start point for join.

renoise.app():undo_step_join_record()

Ability to join multiple undo steps into one step, starting from “record_start”. If the result is the same value as before, just delete undo steps.

I know that Taktik had good arguments against this (I forgot in detail though :stuck_out_tongue: ), but maybe this approach would work? Lots of tools would profit if you could remove undo steps in the undo history.

Examples of benefit:

Custom Wave Form Generator Tool. If you move the slider while using “live update”, the undo buffer literally is flooded with every tiny slider movement step. Instead here the code could do the following: On mouse down on slider, one time callingundo_step_record_start(), on release one time callingundo_step_join_record().

Fancy color flashing would be possible again, too!

Loads of other tools would profit, for example any kind of automation writing, or pattern manipulation.

If possible, it would be very nice being able to use renoise objects as keys (the same way you can use tables as keys). Normally this is possible in LUA, but the renoise API is not laid out in a way that allows this. Perhaps it could be fixed?

This would simplify some currently advanced logistics immensely. For example, being able to do stuff like:

my_table = { }

my_table[renoise.song().tracks[1]] = { my_track_data }

if my_table[renoise.song().tracks[1]] then
 -- do something
end

From what I gather, it is currently not possible due to:

  1. Renoise objects lack the appropriate __tostring method.
  2. Renoise objects are currently not truly unique and the fetchers of renoise.song() will return data with ever-changing ID:s. They are created when fetched and given a pseudo-uniqueness via API metamethods. Perhaps there is no other way?

I’m mentioning it as something to consider. Maybe I’ve missed some clever workaround?

Access to granular selection could be implemented like this. Thanks for considering!

renoise.song().selection_in_pattern

[end_column] => 1
[end_line] => 14
[end_track] => 2

[end_sub_column_type] => [number]
[start_column] => 1
[start_line] => 4
[start_track] => 2

[start_sub_column_type] => [number]

If possible, it would be very nice being able to use renoise objects as keys (the same way you can use tables as keys). Normally this is possible in LUA

But, in order to use objects as keys, you surely would want them to be unique? Can’t really see how the Renoise API should enforce this.

IMHO, tostring() is not really meant to have practical applications for non-string objects. Definitely useful when debugging (e.g. to print the type of object, and possibly a few of it’s values to the console), but otherwise not.

But maybe I got the idea wrong - you’re saying that this is something you have done elsewhere?

But maybe I got the idea wrong - you’re saying that this is something you have done elsewhere?

You can do it with your own luabind objects, since they maintain their uniqueness. It’s kind of a nifty feature of lua tables (“anything as key”).

This is a useless example that actually works now. Would be quite nice if Renoise objects maintained their uniqueness in a similar way. It’s quite possible that it’s impossible with luabind classes provided from C (I don’t know the deepest workings of it all), but I wanted to mention it just in case.

global_table = global_table or { }

class 'MyClass'

function MyClass:__init(something)
  self._something = something
  global_table[self] = self -- self key will be the lua ID, I think.
end

(No more traversing your global table-record with “if rawequal” et c)

In fact, if Renoise objects provided just something unique and persistent (anything), this could be used as key to simplify a lot of things.

The ViewBuilder could get just a little bit of love imo. Some details missing, to make it more consistent with the native GUI.

  1. A possibility to determine what value an element snaps to when double clicking it. (In the native GUI, this differs depending on the DSP parameter, for example). I think it applies to the following classes:

vb:rotary { default_value = 0.5 }

vb:slider { default_value = 1.0 }

vb:minislider { default_value = 0.3 }

  1. A slider/minislider where 0 is being in its center (typically, like panning sliders). This occurs in the native GUI, but is not available in renoise.ViewBuilder()

3)Textfields with invisiblebackground (as in the clickable DSP parameters). I’d really like this one, just because it looks nice :slight_smile:

EDIT: Can be done by using valuefield instead - use tonumber/tostring properties and it can easily act as a nicer textfield.

  1. Snapback for slider is also missing in the viewbuilder. Not terribly important, maybe.

EDIT: 5) A vertical mode for vb:switch, as seen in the sample modulations sets.

  1. Text and bitmap capabilities of vb:checkbox - no more usage of toggle buttons having an incorrect/arbitrary color for its active state.

These are the non-complex stuff I’ve found natively so far, that would be nice to have.

I’m not sure if already requested or if there’s some trick that I’ve missed:

vb:bitmap { repeat = true } – or possibly “repeat”, “repeat-y” and "repeat-x"

Currently, using many big images becomes quite sluggish, but a repeat property could optimize performance when you want to fill a bigger area with an image (like an opacity image).

I’m using rows and columns to restrict the boundaries of “background images”, and they have to be made very big to ensure that they will always fill the area. (can of course be optimized a bit by dynamically loading different images depending on what’s needed).

The background in this example shows a case where this becomes an obvious performance bottleneck: https://dl.dropboxusercontent.com/u/6812754/gui1.gif

The background in this example shows a case where this becomes an obvious performance bottleneck: https://dl.dropboxusercontent.com/u/6812754/gui1.gif

Is that what I think it is? :panic:

If I’m not mistaken, the only way to change the pattern index of a sequence is via renoise.song().selected_pattern_index ? (or have I missed something?)

This means that you have to change “cursor position” to set up a sequence list, which seems like bad design.

I think that renoise.song().sequencer.pattern_sequence should be read/write. Alternatively, add a method - renoise.song().sequencer:set_pattern(sequence_index, pattern_index)

PS. I wouldn’t mind if .selected_pattern_index was changed to read-only. It’s the kind of subtle consistency that forces us into the right mindset :slight_smile:

I think that the width property of viewbuilder objects would benefit from being refined when it comes to % values. The % calculation seems a bit crude, not always ensuring that the total width is kept (rounding errors when summing an array). If you do dynamic gui stuff with %-widths, it becomes jittery with a lot of nervous pixels on width changes :slight_smile:

Suggestion:

  1. Make % values support fractions.

  2. Use a rounding principle (% to pixels) that keeps the sum of all widths constant.

Some inspiration that might be useful for the maths: http://stackoverflow.com/a/792490 … (not sure it’s working 100%)

(Possibly a dupl request?)

*** Resizable window.**

Would be absolutely great for doing some next-gen stuff :wink: I am guessing it would require some kind of buffering that would make it a tiny bit complicated to implement? LUA-wise, it wouldn’t have to be anything special - e g just pad with empty area if the user abuses a resizable dialog by not designing it properly with % widths/heights in the “top layer” et c.

local my_dialog = renoise.app():show_resizable_dialog("Title", vb_content, my_keyhandler_func)

*** “Remembering” window positions**.

Could basically be implemented and handled with just something like:

local my_dialog = renoise.app():show_custom_dialog("Title", vb_content, my_keyhandler_func)

-- relative to the screen or to the Renoise window?
my_dialog.x = 100
my_dialog.y = 200

I would like to request granular/exact cursor positioning. As of now, all note fx columns are missing/non-implemented as far as I know.

I would very much like it to be granular enough that you’re able to jump to, for example, the second digit of an effect column. This way, it would be possible to make workarounds for improving the Renoise pattern navigation, not having to wear down the arrow keys on my keyboard.

Listbox…