Get Automation Value

Sadly, there doesn’t seem to be a function to get the automation value at any given time. Has anyone done this before?

I could probably make an interpretor for point and linear interpolation (playmode), but the curve mode is more than I can achieve.

renoise.song():pattern():track().automation:get_value() would have been very handy.

taktik? :)

At any given time? As in the interpolated value between programmed points? Afraid I don’t believe it’s possible. At least can’t see anythign but reading specific point in the API documentation.

Although I have to admit I failed to even read off the value of points for the currently selected automation parameter. I know it should be (is) possible but for some reason I struggled with that, which I would thought should be basic and I wish was covered by a “selected_parameter” object.

Of course it’s possible. It’s just a matter of maths.

  
local parameter = renoise.song().selected_parameter  
if (parameter ~= nil) then  
 local automation = renoise.song().selected_pattern_track:find_automation(parameter)  
 if (automation ~= nil) then  
 -- do something with automation.points  
 rprint(automation.points)  
 end  
end  
  

Exactly what I was thinking as I went to get food during dinner break ;)

dBlue: selected_parameter has been added in API3 has it not? Sure I looked for it hard before requesting it in API2…

It’s always been in there, afaik.

It’s listed in Renoise.Song.API.lua in the scripting documentation. You can even find it in the 2.6 XRNX starter pack:

Oh yeah, I think I did use selected_parameter in my Automation tool now I cast my mind back (along with record_value)… But, IIRC, it is very limited compared to using renoise.song()patterns[].tracks[].automation[] as this gives you a lot more actions you can do to the automation lane.

Noticed there is also a selected_parameter_index. Can this be used with the above somehow?

Something like this to find the correct lane?
renoise.song().selected_track:find_automation(renoise.song().selected_parameter)

Although I didn’t quite get the renoise.PatternTrackAutomation object…

The code I posted above should contain everything you need to get started.

The PatternTrackAutomation object is the automation envelope (or ‘lane’ if you prefer) for a specific parameter, in a specific pattern, in a specific track. This object allows you to read/write the automation points, change the envelope curve type, etc.

renoise.song().selected_parameter_index is not a unique index that can be used to identify a specific parameter somewhere in the entire song. It actually refers to the index of the parameter relative to the currently selected device. So for example, if you’re currently editing the automation for a Compressor’s Threshold parameter then selected_parameter_index will be 1, for the Ratio parameter it will be 2, and so on.

renoise.song().selected_parameter, on the other hand, returns a complete DeviceParameter object. Although this object does have the record_value() function which you can use to record a single automation point (or pattern command) at the current pattern editor position, you can’t really do much else directly related to automation with this object alone. You can check if the parameter can be automated somehow, and also check if it already is automated somewhere in the song.

However, we can use this DeviceParameter object to find the automation object we’re actually interested in. That’s what my code above does.

renoise.song().selected_pattern_track:find_automation() will return the complete PatternTrackAutomation object, which we can use to modify the points and other properties.

renoise.song().patterns[].tracks[].automation[] will return the same type of PatternTrackAutomation object. If you already know which automation you want, then you can access it directly this way.

You could in theory loop through each available renoise.song().patterns[].tracks[].automation[] and compare the automation[].dest_parameter property against renoise.song().selected_parameter to see if they match, but renoise.song().selected_pattern_track:find_automation() will do the same job must faster.

Cheers. Added this thread to my Watch list for when (if) I get time to work further on my tools :)

dblue,

Any idea regarding the question I asked? :)

I’m making a hack to edit pattern effect values via the automation editor. Chances are that curve mode will be pretty slow, if there even is a formula available.

OK think this might be right ballpark for Cubic (although this will only work if first point is lower in value than second and is always assuming a 0-1 range):

[s]EDIT: “Spoiler tagged” it out for the moment as realised I have a normal cubic curve, which gives most subtle change at the centre point, whereas the Renoise Cubic curve has the greatest change in the middle. Still might be of some use though…

EDIT2: in Spoiler[/s]

EDIT3: Doh! Inverse function of cubed is the cube-root!

X/Y = point to be calculated (location/value)
x1/y1 = first programmed point (location/value)
x2/y2 = second programmed point (location/value)
length = x2-x1
spread = y2-y1
mid = (y1+y2)/2

mod = (X-0.5length)/0.5length --This will give you a range of -1<>1
Y = mid + mod^3*spread/2 --The mod^(1/3) is due to it being Cubic. May even work for Linear without this, although serious overkill.

EDIT2: Rather than mod^3 if you use 1-(1-x)^3 for positive (above mid) half and -1+(1+x)^3 for negative half it appears to get close…

As mentioned this will only work for curves where x1 is lower value than x2 and assumes you are using the 0-1 range which Renoise stores the points in (I know there are ways to access the real values too, such as record_point.) There also may be quite a few errors as have done this quickly on paper at work and not tested anything.

kazakore, I’ll look into this! Thanks.

It will be easy to verify your code by checking the current parameter value at any row.

Yeah that’s what I would have been doing if I had Renoise in front of me. ;)

Sure it’s still not quite right though, something just doesn’t feel like it should, and it would be nice to not have to split each curve section into two halves to calculate (but that’s not the end of the world I guess.)

Realised I was being blind-sighted and seriously over-complicating things! The inverses function of cubing something is just the cube-root. So using a power of 1/3 instead of 3 on the mod value gives you a curve in the right direction. Whether the numbers come out right I don’t know though…