X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=include%2Flua-scripting.html;h=af39f6c37fc93d11428ce820548739c6b7dd6237;hb=8842cf2c02a0ff38f83798d10388c3c81b2d20d4;hp=ae3b3676ed7b240c349c5a270018bffe24182d0f;hpb=1694ece4af52e5e1c23d386e7bc030b5758e2c64;p=ardour-manual diff --git a/include/lua-scripting.html b/include/lua-scripting.html index ae3b367..af39f6c 100644 --- a/include/lua-scripting.html +++ b/include/lua-scripting.html @@ -10,11 +10,12 @@ This Documentation is Work in Progress and far from complete. Also the documente

Preface

-There are cases that a Ardour cannot reasonably cater for with core functionality by itself, either because they're session specific or user specific edge cases. +There are cases that Ardour cannot reasonably cater to with core functionality alone, either because they're session specific +or user specific edge cases.

Examples for these include voice-activate (record-arm specific tracks and roll transport depending on signal levels), -rename all regions after a specific timecode, launch an external application when a certain track is soloed, generate automation curves -or simply provide a quick shortcut for a custom batch operation. +rename all regions after a specific timecode, launch an external application when a certain track is soloed, generate +automation curves or simply provide a quick shortcut for a custom batch operation.

Cases like this call for means to extend the DAW without actually changing the DAW itself. This is where scripting comes in.

@@ -24,15 +25,16 @@ Lua is a tiny and simple language which is easy to learn, yet allows for compreh Lua is also a glue language it allows to tie existing component in Ardour together in unprecedented ways, and most importantly Lua is one of the few scripting-languages which can be safely used in a real-time environment.

-A good introduction to Lua is the book Programming in Lua. The first edition is available online, -but if you have the means buy a copy of the book, it not only helps to support the Lua project, -but provides for a much nicer reading and learning experience. +A good introduction to Lua is the book Programming in Lua. The first edition is +available online, but if you have the means buy a copy of the book, it not only helps to support the Lua project, but provides +for a much nicer reading and learning experience.

Overview

-The core of ardour is a real-time audio engine that runs and processes audio. One interfaces with than engine by sending it commands. -Scripting can be used to interact with or modify active Ardour session. Just like a user uses the Editor/Mixer GUI to modify the state or parameters of the session. +The core of Ardour is a real-time audio engine that runs and processes audio. One interfaces with an engine by sending it +commands. Scripting can be used to interact with or modify the active Ardour session, just like a user uses the Editor/Mixer +GUI to modify the state or parameters of the session.

Doing this programmatically requires some knowledge about the objects used internally. Most Ardour C++ objects and their methods are directly exposed to Lua and one can call functions or modify variables: @@ -55,40 +57,44 @@ Most Ardour C++ objects and their methods are directly exposed to Lua and one ca

-You may notice that there is only a small syntactic difference, in this case. -While C++ requires recompiling the application for every change, Lua script can be loaded, written or modified while the application is running. -Lua also abstracts away many of the C++ complexities such as object lifetime, type conversion and null-pointer checks. +You may notice that there is only a small syntactic difference in this case. +While C++ requires recompiling the application for every change, Lua script can be loaded, written or modified while the +application is running. Lua also abstracts away many of the C++ complexities such as object lifetime, type conversion and +null-pointer checks.

Close ties with the underlying C++ components is where the power of scripting comes from. A script can orchestrate interaction of lower-level components which take the bulk of the CPU time of the final program.

-At the time of writing Ardour integrates Lua 5.3.2: Lua 5.3 reference manual. +At the time of writing Ardour integrates Lua 5.3.5: Lua 5.3 reference +manual.

Integration

-Like Control surfaces and the GUI, Lua Scripts are confined to certain aspects of the program. Ardour provides the framework and runs Lua (not the other way around). +Like Control surfaces and the GUI, Lua Scripts are confined to certain aspects of the program. Ardour provides the framework +and runs Lua (not the other way around).

In Ardour's case Lua is available:

-
-
Editor Action Scripts
User initiated actions (menu, shortcuts) for batch processing
-
Editor Hooks/Callbacks
Event triggered actions for the Editor/Mixer GUI
-
Session Scripts
Scripts called at the start of every audio cycle (session, real-time)
-
DSP Scripts
Audio/Midi processor - plugins with access to the Ardour session (per track/bus, real-time)
-
Script Console
Action Script commandline
-
+ + + + + + +
Editor Action ScriptsUser initiated actions (menu, shortcuts) for batch processing
Editor Hooks/CallbacksEvent triggered actions for the Editor/Mixer GUI
Session ScriptsScripts called at the start of every audio cycle (session, real-time)
DSP ScriptsAudio/Midi processor - plugins with access to the Ardour session (per track/bus, real-time)
Script ConsoleAction Script commandline

There are is also a special mode:

-
-
Commandline Tool
Replaces the complete Editor GUI, direct access to libardour (no GUI) from the commandline.
- Be aware that the vast majority of complex functionality is provided by the Editor UI.
-
+ + +
Commandline ToolReplaces the complete Editor GUI, direct access to libardour (no GUI) from the + commandline.
+ Be aware that the vast majority of complex functionality is provided by the Editor UI.

Managing Scripts

@@ -96,28 +102,30 @@ There are is also a special mode: Ardour searches for Lua scripts in the scripts folder in $ARDOUR_DATA_PATH, Apart from scripts included directly with Ardour, this includes

- - - + + +
GNU/Linux$HOME/.config/ardour5/scripts
Mac OS X$HOME/Library/Preferences/Ardour5/scripts
Windows%localappdata%\ardour5\scripts
GNU/Linux$HOME/.config/ardour6/scripts
Mac OS X$HOME/Library/Preferences/Ardour6/scripts
Windows%localappdata%\ardour6\scripts

Files must end with .lua file extension.

Scripts are managed via the GUI

-
-
Editor Action Scripts
Menu → Edit → Scripted Actions → Manage
-
Editor Hooks/Callbacks
Menu → Edit → Scripted Actions → Manage
-
Session Scripts
Menu → Session → Scripting → Add/Remove Script
-
DSP Scripts
Mixer-strip → context menu (right click) → New Lua Proc
-
Script Console
Menu → Window → Scripting
-
+ + + + + + +
Editor Action ScriptsMenu → Edit → Scripted Actions → Manage
Editor Hooks/CallbacksMenu → Edit → Scripted Actions → Manage
Session ScriptsMenu → Session → Scripting → Add/Remove Script
DSP ScriptsMixer-strip → context menu (right click) → New Lua Proc
Script ConsoleMenu → Window → Scripting

Script Layout

@@ -138,23 +146,28 @@ Apart from scripts included directly with Ardour, this includes

-The common part for all scripts is the "Descriptor". It's a Lua function which returns a table (key/values) with the following keys (the keys are case-sensitive): +The common part for all scripts is the "Descriptor". It's a Lua function which returns a table (key/values) with the following +keys (the keys are case-sensitive):

-
-
type [required]
one of "DSP", "Session", "EditorHook", "EditorAction" (the type is not case-sensitive)
-
name [required]
Name/Title of the script
-
author
Your Name
-
license
The license of the script (e.g. "GPL" or "MIT")
-
description
A longer text explaining to the user what the script does
-
+ + + + + + +
type [required]one of "DSP", "Session", "EditorHook", + "EditorAction" (the type is not case-sensitive)
name [required]Name/Title of the script
authorYour Name
licenseThe license of the script (e.g. "GPL" or "MIT")
descriptionA longer text explaining to the user what the script does

-Scripts that come with Ardour (currently mostly examples) can be found in the Source Tree. +Scripts that come with Ardour (currently mostly examples) can be found in the +Source Tree.

Action Scripts

-

Action scripts are the simplest form. An anonymous Lua function is called whenever the action is triggered. A simple action script is shown above.

-

There are 10 action script slots available, each of which is a standard GUI action available from the menu and hence can be bound to a keyboard shortcut

+

Action scripts are the simplest form. An anonymous Lua function is called whenever the action is triggered. A simple action +script is shown above.

+

There are 10 action script slots available, each of which is a standard GUI action available from the menu and hence can be +bound to a keyboard shortcut.

Session Scripts

Session scripts similar to Actions Scripts, except the anonymous function is called periodically every process cycle. @@ -191,7 +204,7 @@ function factory (params) end a = a + n_samples if (a > timeout * Session:frame_rate()) then - Session:request_transport_speed(0.0, true) + Session:request_transport_speed (0.0, true, ARDOUR.TransportRequestSource.TRS_UI) end end end @@ -199,7 +212,8 @@ end

Action Hooks

-

Action hook scripts must define an additional function which returns a Set of Signal that which trigger the callback (documenting available slots and their parameters remains to be done).

+

Action hook scripts must define an additional function which returns a Set of Signal that which trigger the +callback (documenting available slots and their parameters remains to be done).


 ardour {
@@ -247,53 +261,72 @@ end
 

See the scripts folder for examples for now.

Some notes for further doc:

    -
  • required function: dsp_ioconfig (): return a list of possible audio I/O configurations - follows Audio Unit conventions.
  • +
  • required function: dsp_ioconfig (): return a list of possible audio I/O configurations - follows Audio + Unit conventions.
  • optional function: dsp_dsp_midi_input (): return true if the plugin can receive midi input
  • optional function: dsp_params (): return a table of possible parameters (automatable)
  • optional function: dsp_init (samplerate): called when instantiation the plugin with given samplerate.
  • optional function: dsp_configure (in, out): called after instantiation with configured plugin i/o.
  • -
  • required function: dsp_run (ins, outs, n_samples) OR dsp_runmap (bufs, in_map, out_map, n_samples, offset): DSP process callback. The former is a convenient abstraction that passes mapped buffers (as table). The latter is a direct pass-through matching Ardour's internal ::connect_and_run() API, which requires the caller to map and offset raw buffers.
  • +
  • required function: dsp_run (ins, outs, n_samples) OR dsp_runmap (bufs, in_map, out_map, n_samples, + offset): DSP process callback. The former is a convenient abstraction that passes mapped buffers (as table). The + latter is a direct pass-through matching Ardour's internal ::connect_and_run() API, which requires the caller + to map and offset raw buffers.
  • plugin parameters are handled via the global variable CtrlPorts.
  • -
  • midi data is passed via the global variable mididata which is valid during dsp_run only. (dsp_runmap requires the script to pass raw data from the buffers according to in_map)
  • -
  • The script has access to the current session via the global variable Session, but access to the session methods are limited to realtime safe functions
  • +
  • midi data is passed via the global variable mididata which is valid during dsp_run only. + (dsp_runmap requires the script to pass raw data from the buffers according to in_map)
  • +
  • The script has access to the current session via the global variable Session, but access to the session methods are + limited to realtime safe functions

Accessing Ardour Objects

The top most object in Ardour is the ARDOUR::Session. Fundamentally, a Session is just a collection of other things: -Routes (tracks, busses), Sources (Audio/Midi), Regions, Playlists, Locations, Tempo map, Undo/Redo history, Ports, Transport state & controls, etc. +Routes (tracks, busses), Sources (Audio/Midi), Regions, Playlists, Locations, Tempo map, Undo/Redo history, Ports, Transport +state and controls, etc.

Every Lua interpreter can access it via the global variable Session.

-GUI context interpreters also have an additional object in the global environment: The Ardour Editor. The Editor provides access to high level functionality which is otherwise triggered via GUI interaction such as undo/redo, open/close windows, select objects, drag/move regions. It also holds the current UI state: snap-mode, zoom-range, etc. -The Editor also provides complex operations such as "import audio" which under the hood, creates a new Track, adds a new Source Objects (for every channel) with optional resampling, creates both playlist and regions and loads the region onto the Track all the while displaying a progress information to the user. +GUI context interpreters also have an additional object in the global environment: The Ardour Editor. The Editor +provides access to high level functionality which is otherwise triggered via GUI interaction such as undo/redo, open/close +windows, select objects, drag/move regions. It also holds the current UI state: snap-mode, zoom-range, etc. +The Editor also provides complex operations such as "import audio" which under the hood, creates a new Track, adds a new +Source Objects (for every channel) with optional resampling, creates both playlist and regions and loads the region onto the +Track all the while displaying a progress information to the user.

Documenting the bound C++ methods and class hierarchy is somewhere on the ToDo list. -Meanwhile luabindings.cc is the best we can offer. +Meanwhile luabindings.cc is the best we +can offer.

Concepts

    -
  • There are no bound constructors: Lua asks Ardour to create objects (e.g. add a new track), then receives a reference to the object to modify it.
  • -
  • Scripts, once loaded, are saved with the Session (no reference to external files). This provides for portable Sessions.
  • -
  • Lua Scripts are never executed directly. They provide a "factory" method which can have optional instantiation parameters, which returns a lua closure.
  • -
  • No external lua modules/libraries can be used, scripts need to be self contained (portable across different systems (libs written in Lua can be used, and important c-libs/functions can be included with ardour if needed).
  • +
  • There are no bound constructors: Lua asks Ardour to create objects (e.g. add a new track), then receives a reference + to the object to modify it.
  • +
  • Scripts, once loaded, are saved with the Session (no reference to external files). This provides for portable + Sessions.
  • +
  • Lua Scripts are never executed directly. They provide a "factory" method which can have optional instantiation + parameters, which returns a Lua closure.
  • +
  • No external Lua modules/libraries can be used, scripts need to be self contained (portable across different systems + (libs written in Lua can be used, and important c-libs/functions can be included with Ardour if needed).

-Ardour is a highly multithreaded application and interaction between the different threads, particularly real-time threads, needs to to be done with care. -This part has been abstracted away by providing separate Lua interpreters in different contexts and restricting available interaction: +Ardour is a highly multithreaded application and interaction between the different threads, particularly real-time threads, +needs to to be done with care. This part has been abstracted away by providing separate Lua interpreters in different contexts +and restricting available interaction:

  • Editor Actions run in a single instance interpreter in the GUI thread.
  • -
  • Editor Hooks connect to libardour signals. Every Callback uses a dedicated lua interpreter which is in the GUI thread context.
  • +
  • Editor Hooks connect to libardour signals. Every Callback uses a dedicated Lua interpreter which is in the GUI thread + context.
  • All Session scripts run in a single instance in the main real-time thread (audio callback)
  • DSP scripts have a separate instance per script and run in one of the DSP threads.

-The available interfaces differ between contexts. e.g. it is not possible to create new tracks or import audio from real-time context; while it is not possible to modify audio buffers from the GUI thread. +The available interfaces differ between contexts. For example, it is not possible to create new tracks or import audio from +real-time context; while it is not possible to modify audio buffers from the GUI thread.

Current State

@@ -305,87 +338,26 @@ Fully functional, yet still in a prototyping stage:
  • Further planned work includes:
    • Built-in Script editor (customize/modify Scripts in-place)
    • -
    • convenience methods (wrap more complex Ardour actions into a library). e.g set plugin parameters, write automation lists from a lua table
    • +
    • convenience methods (wrap more complex Ardour actions into a library). e.g set plugin parameters, write + automation lists from a Lua table
    • Add some useful scripts and more examples
    • -
    • Documentation (Ardour API), also usable for tab-exansion, syntax highlighting
    • +
    • Documentation (Ardour API), also usable for tab-expansion, syntax highlighting
    • bindings for GUI Widgets (plugin UIs, message boxes, etc)
  • +-

    Examples

    +-

    Please see the example scripts included with the source-code. +All the files that start with a leading underscore are not inlcluded with releases, but are intended as example snippets.

    -

    Examples

    -

    Apart from the scripts included with the source-code here are a few examples without further comments... - -

    Editor Console Examples

    -
    -
    
    -print (Session:route_by_remote_id(1):name())
    -
    -a = Session:route_by_remote_id(1);
    -print (a:name());
    -
    -print(Session:get_tracks():size())
    -
    -for i, v in ipairs(Session:unknown_processors():table()) do print(v) end
    -for i, v in ipairs(Session:get_tracks():table()) do print(v:name()) end
    -
    -for t in Session:get_tracks():iter() do print(t:name()) end
    -for r in Session:get_routes():iter() do print(r:name()) end
    -
    -
    -Session:tempo_map():add_tempo(ARDOUR.Tempo(100,4), Timecode.BBT_TIME(4,1,0))
    -
    -
    -Editor:set_zoom_focus(Editing.ZoomFocusRight)
    -print(Editing.ZoomFocusRight);
    -Editor:set_zoom_focus(1)
    -
    -
    -files = C.StringVector();
    -files:push_back("/home/rgareus/data/coding/ltc-tools/smpte.wav")
    -pos = -1
    -Editor:do_import(files, Editing.ImportDistinctFiles, Editing.ImportAsTrack, ARDOUR.SrcQuality.SrcBest, pos, ARDOUR.PluginInfo())
    -
    -#or in one line:
    -Editor:do_import(C.StringVector():add({"/path/to/file.wav"}), Editing.ImportDistinctFiles, Editing.ImportAsTrack, ARDOUR.SrcQuality.SrcBest, -1, ARDOUR.PluginInfo())
    -
    -# called when a new session is loaded:
    -function new_session (name) print("NEW SESSION:", name) end
    -
    -
    -# read/set/describe a plugin parameter
    -route = Session:route_by_remote_id(1)
    -processor = route:nth_plugin(0)
    -plugininsert = processor:to_insert()
    -
    -plugin = plugininsert:plugin(0)
    -print (plugin:label())
    -print (plugin:parameter_count())
    -
    -x = ARDOUR.ParameterDescriptor ()
    -_, t = plugin:get_parameter_descriptor(2, x) -- port #2
    -paramdesc = t[2]
    -print (paramdesc.lower)
    -
    -ctrl = Evoral.Parameter(ARDOUR.AutomationType.PluginAutomation, 0, 2)
    -ac = plugininsert:automation_control(ctrl, false)
    -print (ac:get_value ())
    -ac:set_value(1.0, PBD.GroupControlDisposition.NoGroup)
    -
    -# the same using a convenience wrapper:
    -route = Session:route_by_remote_id(1)
    -proc = t:nth_plugin (i)
    -ARDOUR.LuaAPI.set_processor_param (proc, 2, 1.0)
    -
    -
    -
    - -

    Commandline Session

    +

    Commandline Session

    The standalone tool luasession allows one to access an Ardour session directly from the commandline. +It can also be used as #! interpreter for scripted sessions. Interaction is limited by the fact that most actions in Ardour are provided by the Editor GUI.

    -luasession provides only two special functions load_session and close_session and exposes the AudioEngine instance as global variable. +luasession provides only two special functions load_session and close_session and +exposes the AudioEngine instance as global variable.

    @@ -397,16 +369,23 @@ print (AudioEngine:current_backend_name()) for i,_ in backend:enumerate_devices():iter() do print (i.name) end -backend:set_input_device_name("HDA Intel PCH") -backend:set_output_device_name("HDA Intel PCH") +backend:set_device_name("HDA Intel PCH") +backend:set_buffer_size(1024) print (backend:buffer_size()) print (AudioEngine:get_last_backend_error()) s = load_session ("/home/rgareus/Documents/ArdourSessions/lua2/", "lua2") -s:request_transport_speed (1.0) + +assert (s) + +s:request_transport_speed (1.0, true, ARDOUR.TransportRequestSource.TRS_UI) print (s:transport_rolling()) + s:goto_start() + +ARDOUR.LuaAPI.usleep (10 * 1000000) -- 10 seconds + close_session()