--[[============================================================================
Renoise Scripting Reference and HOWTOs - Introduction
============================================================================]]--

Welcome to the Renoise scripting Guide. In all the various "Documention" files,
we will give you an overview on how to write tools for Renoise; how to debug 
them, what's possible to "script", what's not, and much more. Please read this
introduction carefully to get an idea on how to get started, and to avoid common
pitfalls and FAQs.


--------------------------------------------------------------------------------
-- Scripting Development Tools in Renoise
--------------------------------------------------------------------------------

By default Renoise has all scripting utilities hidden; to keep things as easy as
possible for those who don't want to mess around with code. If you want to write
scripts, then the first thing you have to do is enable the hidden development
tools that are built into Renoise. This can be done by:

- Launching the Renoise executable with the argument "--scripting-dev"

- Opening Renoise's config.xml file from the preferences folder, and setting the
  <ShowScriptingDevelopmentTools> property to "true". This way, you don't have
  to pass the above mentioned argument every time you launch Renoise.

Enabling scripting will add a new main menu entry "Tools" (or add new
entries there if it already exists). 

In the "Tools" menu you will find:

- **Reload All Tools:** This will force a reload of all installed and running
  scripting tools. This can be handy when adding new tools by hand or when
  changing them.

- **Scripting Console & Editor:** This is the main developing scripting tool.
  It allows you to:
  + Evaluate scripts or commands in realtime with a terminal (command-line)
  + Watch any script's output (all "print"s and errors will be redirected here)
  + Create, view and edit Lua, text, and XML files that will make up tools
    for Renoise. More about this later...

- Show **Example Tools** that target script developers.


--------------------------------------------------------------------------------
-- What can be scripted, what can't? What's this scripting all about?
--------------------------------------------------------------------------------

Right now (in this Renoise release), you can make use of scripts in the
following places:

- Run scripts and commands via a terminal in realtime using the
  "Scripting Console & Editor". 

- Create tools: Add new and custom functionality to Renoise. Tools are small
  file bundles with Lua script(s) and a description file (manifest.xml) that
  make use of the Renoise API. Tools can be distributed and installed via
  drag and drop (by bundling them and hiding the code). This way, not only
  developers can use scripts, but also users who don't want to mess around with
  technical details. We'll describe these types bundles later on...

  Some examples of what you can do with Renoise Tools:

  + New context menu entries and keyboard shortcuts. Think "My Improved Pattern
    Jump", "My Bypass all DSP Devices in Track", "My Generate Chip Sound
    Sample" commands, and so on.

  + Custom graphical user interface elements with the look and feel of Renoise
    itself. Perfectly integrate your tools into Renoise, and make them easy to
    use for other users.

  + Manipulate Renoise's main window or song (patterns, tracks, instruments, 
    anything that makes up a song). Generate, filter, or process song data in 
    any way you can think of. E.g. for algorithmic composition, instrument 
    creation, automation, etc. The sky is the limit.

  + Nibbles ;)


- MIDI controller scripting: Create bidirectional MIDI or OSC implementations
  for any controller hardware:

  For example, make your Launchpad or Monome behave exactly how you want them 
  to, and share your settings with others. Tools like these can be a simple auto
  mapping of your MIDI controller, like plug & play support for Mackie Control,
  Behringer MIDI Mixers, and so on.

  To make this easier, Renoise offers a tool called "Duplex" which already has
  support for several MIDI/OSC controllers. Duplex is a very flexible,
  object-oriented approach to handling MIDI controllers in Renoise, and also
  offers virtual UIs for the MIDI controllers that are supported by Duplex.
  This way you can virtually test and use such controllers in Renoise without
  even owning them. ;)

  NB: You don't have to use Duplex to write MIDI/OSC controller scripts in
  Renoise, but it is a nice (and supported) framework that makes this type of
  development easier.


- Create, configure, or override Renoise's default MIDI/OSC bindings:
  Renoise has a default set of MIDI mappings that can be assigned manually by
  the user. These can be inherited, extended and tweaked to fit your needs.
  Renoise also has a default OSC implementation which can tweaked and overriden
  to do "your stuff."


What's *NOT* possible with Renoise tools:

- Change Renoise's existing behaviour. Like, you can't make all C-4s in the
  pattern editor yellow instead of white. You can write your own pattern
  editor, but not change the existing one.

- Realtime access. Except for OSC and MIDI IO, you can't write scripts that
  run in the audio player. In other words, you can not script new realtime
  DSPs - yet. But you can, for example, write a tool that creates samples or
  manipulates existing samples. This limitation might change in the future.
  For now you can make a VST, AudioUnit, or LADSPA/DSSI plug-in.


--------------------------------------------------------------------------------
-- Renoise Lua API Overview
--------------------------------------------------------------------------------

The XXX.API files in this documentation folder will list all available Lua
functions and classes that can be accessed from scripts in Renoise.
If you are familiar with Renoise, the names of the classes, functions and
properties should be self explanitory.

Here is a small overview of what the API exposes:

**Renoise.API**  
Renoise API version number and some global accessors like "song", "app" are here.

**Renoise.Application.API**  
Access to the main Renoise application and window, main user interface.

**Renoise.Song.API**  
Access to the song and all its components (instruments, samples, tracks...)

**Renoise.Document.API**  
Generic "observer pattern" document creation and access, used by the
song/app and to create persistent data (preferences, presets).

**Renoise.ScriptingTool.API**  
Available to XRNX tools only: Interact with Renoise; create menus, keybindings.

**Renoise.Socket.API**  
Inter-process and network communication functions and classes.

**Renoise.OSC.API**  
Tools to generate and receive OSC messages, bundles over the network.

**Renoise.Midi.API**  
"Raw" MIDI device interaction (send, receive MIDI messages from any devices.)


A note about the general API design:

- Whatever you do with the API, you should never be able to fatally crash
  Renoise. If you manage to do this, then please file a bug report in our forums
  so we can fix it. All errors, as stupid they might be, should always result in
  a clean error message from Lua.

- The Renoise Lua API also allows global File IO and external program execution
  (via os.execute()) which can obviously be hazardous. Please be careful with
  these, as you would with programming in general...


Some notes about the documentation, and a couple of tips:

- All classes, functions in the API, are nested in the namespace (Lua table)
  "renoise". E.g: to get the application object, you will have to type
  "renoise.app()"

- The API is object-oriented, and thus split into classes. The references
  will first note the class name (e.g. 'renoise.Application'), then list its
  Constants, Properties, Functions and Operators.
  All properties and functions are always listed with their full path to make
  it clear where they belong and how to access them.

- Return values (or arguments / types of properties) are listed in brackets.
  "-> [string]" means that a string is returned. When no brackets are listed,
  the function will not return anything.

- Nearly all functions are actually "methods", so you have to invoke them
  via the colon operator ":" E.g. 'renoise.app():show_status("Status Message")'
  If you're new to Lua, this takes a while to get used to. Don't worry, it'll
  make sense sooner or later. ;)

- Properties are syntactic sugar for get/set functions. "song().comments"
  will invoke a function which returns "comments". But not all properties
  have setters, and thus can only be used as read-only "getters". Those are
  marked as "[read-only, type]".
  Again mind the colon; which you don't need when accessing properties!

- All exposed "objects" are read-only (you can not add new fields, properties).
  In contrast, the "classes" are not. This means you can extend the API classes 
  with your own helper functions, if needed, but can not add new properties to 
  objects. Objects, like for example the result of "song()", are read-only to 
  make it easier to catch typos. `song().transport.bmp = 80` will fire an error,
  because there is no such property 'bmp.' You probably meant
  `song().transport.bpm = 80` here. If you need to store data somewhere,
  do it in your own tables, objects instead of using the Renoise API objects.

- "some_property, _observable" means, that there is also an observer object
  available for the property. An observable object allows you to attach
  notifiers (global functions or methods) that will be called as soon as a
  value has changed. Please see Renoise.Document.API for more info about
  observables and related classes. 
  
  A small example using bpm:

        renoise.song().transport.bpm_observable:add_notifier(function()
          print("bpm changed")
        end)

        -- will print "bpm changed", but only if the bpm was not 120 before
        renoise.song().transport.bpm = 120

  The above notifier is called when anything changes the bpm, including your
  script, other scripts, or anything else in Renoise (you've automated the
  BPM in the song, entered a new BPM value in Renoise's GUI, whatever...)

  Lists like "renoise.song().tracks[]" can also have notifiers. But these
  will only fire when the list layout has changed: an element was added,
  removed or elements in the list changed their order. They will not fire when
  the list values changed. Attach notifiers to the list elements to get such
  notifications.

- Can't remember what the name of function XYZ was? In the scripting terminal
  you can list all methods/properties of API objects (or your own class objects)
  via the global function `oprint(some_object)` - e.g. `oprint(renoise.song())`.
  To dump the renoise module/class layout, use `rprint(renoise)`.


--------------------------------------------------------------------------------
-- Creating Renoise Tools
--------------------------------------------------------------------------------

- Developing XRNX tools:
  As previously mentioned, Renoise tools are file bundles with an XRNX
  extension. Tools have the following layout:

  + /some.bundle.id.xrnx/
  + manifest.xml -> XML file with information about the tool (author, id...)
  + main.lua -> entry point: loaded by Renoise to execute the tool

  You can import other Lua files into "main.lua" via Lua's "require" function
  if appropriate, and also include resource files (icons, bitmaps, text files,
  or executables) into your bundles as needed.

  For a detailed description of the bundle layout and the main.lua,
  manifest.lua specifications, have a look at the "com.renoise.Example.xrnx"
  tool please.

- Distributing XRNX tools:
  To share your tools with others, you can create Zip files out of your
  bundles, which can then simply be dragged and dropped into Renoise by the
  user.
  To do so, zip all the bundle's content (the !content!, not the bundle folder
  itself), and rename this Zip file to "SomeName.xrnx". Renoise will accept such
  XRNX zips as drag and drop targets, copy, install and activate the tool
  automatically.


--------------------------------------------------------------------------------
-- MIDI Controller Scripting with Duplex
--------------------------------------------------------------------------------

If you want to add support for your MIDI controller into Duplex, or help extend
the Duplex framework, have a look at the Duplex XRNX tool.

In the XRNX bundle you'll find some information about the Duplex API and
how to create new controller mappings.

The Duplex code can also be viewed online in the XRNX repository at:
<http://code.google.com/p/xrnx/source/browse/trunk/Tools#Tools/com.renoise.Duplex.xrnx>

More information can be found in Duplex manual, available here:
<http://oscillity.net/renoise/duplex/Duplex_manual.pdf>


--------------------------------------------------------------------------------
-- Debugging Renoise Scripts
--------------------------------------------------------------------------------

If tracing/debugging in the console with print, oprint and rprint isn't enough,
you can try attaching a command-line based debugger to your scripts. Have a look
at the Debugging document for more information and a small tutorial.


-- Enjoy extending, customizing and automating Renoise ;)

