├── docs
├── API
│ ├── builtins.md
│ ├── modules.md
│ ├── builtins
│ │ ├── any.md
│ │ ├── unknown.md
│ │ ├── integer.md
│ │ ├── function.md
│ │ ├── table.md
│ │ ├── number.md
│ │ ├── string.md
│ │ ├── userdata.md
│ │ ├── lightuserdata.md
│ │ ├── boolean.md
│ │ ├── nil.md
│ │ └── self.md
│ ├── renoise
│ │ ├── renoise.Views.md
│ │ ├── renoise.SongPos.md
│ │ ├── renoise.Document.Serializable.md
│ │ ├── renoise.Osc.Bundle.md
│ │ ├── renoise.Dialog.md
│ │ ├── renoise.Midi.MidiDevice.md
│ │ ├── renoise.Midi.MidiInputDevice.md
│ │ ├── renoise.ScriptingTool.MidiMessage.md
│ │ ├── renoise.Socket.SocketBase.md
│ │ ├── renoise.EffectColumn.md
│ │ ├── renoise.Midi.MidiOutputDevice.md
│ │ ├── renoise.InstrumentMacroMapping.md
│ │ ├── renoise.InstrumentMidiInputProperties.md
│ │ ├── renoise.Document.Observable.md
│ │ ├── renoise.InstrumentMacro.md
│ │ ├── renoise.Document.ObservableBang.md
│ │ ├── renoise.Socket.md
│ │ ├── renoise.InstrumentPluginDevice.md
│ │ ├── renoise.InstrumentDevice.md
│ │ ├── renoise.Document.ObservableNumber.md
│ │ ├── renoise.Document.ObservableString.md
│ │ ├── renoise.Document.ObservableBoolean.md
│ │ ├── renoise.PatternLine.md
│ │ ├── renoise.Document.ObservableList.md
│ │ ├── renoise.InstrumentPhraseMapping.md
│ │ ├── renoise.SampleMapping.md
│ │ ├── renoise.Osc.Message.md
│ │ ├── renoise.NoteColumn.md
│ │ ├── renoise.DeviceParameter.md
│ │ ├── renoise.InstrumentMidiOutputProperties.md
│ │ ├── renoise.AudioDevice.md
│ │ ├── renoise.SampleDeviceChain.md
│ │ ├── renoise.Midi.md
│ │ ├── renoise.Document.ObservableNumberList.md
│ │ ├── renoise.Document.ObservableStringList.md
│ │ ├── renoise.Document.ObservableBooleanList.md
│ │ ├── renoise.Osc.md
│ │ ├── renoise.PatternTrack.md
│ │ ├── renoise.InstrumentTriggerOptions.md
│ │ └── renoise.SampleOperandModulationDevice.md
│ ├── modules
│ │ ├── debug.md
│ │ ├── math.md
│ │ ├── io.md
│ │ ├── os.md
│ │ ├── table.md
│ │ └── global.md
│ ├── renoise.md
│ └── README.md
├── guide
│ ├── README.md
│ ├── sqlite.md
│ ├── files&bits.md
│ ├── observables.md
│ ├── classes.md
│ ├── midi.md
│ └── osc.md
├── styles.css
└── start
│ ├── README.md
│ ├── installing.md
│ ├── distribution.md
│ ├── development.md
│ └── possibilities.md
├── Cargo.toml
├── .gitmodules
├── .gitignore
├── .vscode
├── settings.json
├── tasks.json
└── launch.json
├── tools
├── com.renoise.ExampleToolGui.xrnx
│ ├── Bitmaps
│ │ ├── MiniPiano.bmp
│ │ ├── RenoiseLua.bmp
│ │ └── RenoiseLua.png
│ └── manifest.xml
├── DragOntoRenoiseToInstall.txt
├── com.renoise.ExampleToolSlicedProcess.xrnx
│ ├── manifest.xml
│ ├── process_slicer.lua
│ └── main.lua
└── com.renoise.ExampleTool.xrnx
│ └── manifest.xml
├── tests
├── README.md
├── all.lua
├── app_window.lua
├── class.lua
├── parameters.lua
├── osc.lua
├── notifiers.lua
├── track_device_chain.lua
├── transport.lua
└── sample_device_chain.lua
├── generate
├── Cargo.toml
├── src
│ └── main.rs
└── README.md
├── justfile
├── book.toml
├── BUILD.md
├── LICENSE
├── .github
└── workflows
│ ├── archive.yml
│ └── pages.yml
└── README.md
/docs/API/builtins.md:
--------------------------------------------------------------------------------
1 | # Lua Builtin Types
--------------------------------------------------------------------------------
/docs/API/modules.md:
--------------------------------------------------------------------------------
1 | # Lua Module Extensions
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | resolver = "2"
3 | members = [
4 | "generate",
5 | ]
6 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "definitions"]
2 | path = definitions
3 | url = git@github.com:renoise/definitions
4 | branch = master
5 |
--------------------------------------------------------------------------------
/docs/API/builtins/any.md:
--------------------------------------------------------------------------------
1 | # any
2 | > A type for a dynamic argument, it can be anything at run-time.
3 |
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | /book/
3 | /dist/
4 | /generate/Cargo.lock
5 | /generate/target/
6 | /generate/lua-language-server/
7 | /target/
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Lua.workspace.library": ["./definitions"],
3 | "Lua.runtime.plugin": "./definitions/plugin.lua"
4 | }
5 |
--------------------------------------------------------------------------------
/docs/API/builtins/unknown.md:
--------------------------------------------------------------------------------
1 | # unknown
2 | > A dummy type for something that cannot be inferred before run-time.
3 |
4 |
--------------------------------------------------------------------------------
/docs/API/builtins/integer.md:
--------------------------------------------------------------------------------
1 | # integer
2 | > A helper type that represents whole numbers, a subset of [number](number.md)
3 |
4 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Views.md:
--------------------------------------------------------------------------------
1 | # renoise.Views
2 | > Namespace for renoise view widgets.
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/tools/com.renoise.ExampleToolGui.xrnx/Bitmaps/MiniPiano.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/renoise/xrnx/HEAD/tools/com.renoise.ExampleToolGui.xrnx/Bitmaps/MiniPiano.bmp
--------------------------------------------------------------------------------
/tools/com.renoise.ExampleToolGui.xrnx/Bitmaps/RenoiseLua.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/renoise/xrnx/HEAD/tools/com.renoise.ExampleToolGui.xrnx/Bitmaps/RenoiseLua.bmp
--------------------------------------------------------------------------------
/tools/com.renoise.ExampleToolGui.xrnx/Bitmaps/RenoiseLua.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/renoise/xrnx/HEAD/tools/com.renoise.ExampleToolGui.xrnx/Bitmaps/RenoiseLua.png
--------------------------------------------------------------------------------
/docs/API/builtins/function.md:
--------------------------------------------------------------------------------
1 | # function
2 | > A built-in type representing functions, [see details](https://www.lua.org/pil/2.6.html)
3 |
4 |
--------------------------------------------------------------------------------
/docs/API/builtins/table.md:
--------------------------------------------------------------------------------
1 | # table
2 | > A built-in type representing associative arrays, [see details](https://www.lua.org/pil/2.5.html)
3 |
4 |
--------------------------------------------------------------------------------
/docs/API/builtins/number.md:
--------------------------------------------------------------------------------
1 | # number
2 | > A built-in type representing floating point numbers, [see details](https://www.lua.org/pil/2.3.html)
3 |
4 |
--------------------------------------------------------------------------------
/docs/API/builtins/string.md:
--------------------------------------------------------------------------------
1 | # string
2 | > A built-in type representing a string of characters, [see details](https://www.lua.org/pil/2.4.html)
3 |
4 |
--------------------------------------------------------------------------------
/docs/API/builtins/userdata.md:
--------------------------------------------------------------------------------
1 | # userdata
2 | > A built-in type representing array values, [see details](https://www.lua.org/pil/28.1.html).
3 |
4 |
--------------------------------------------------------------------------------
/docs/API/builtins/lightuserdata.md:
--------------------------------------------------------------------------------
1 | # lightuserdata
2 | > A built-in type representing a pointer, [see details](https://www.lua.org/pil/28.5.html)
3 |
4 |
--------------------------------------------------------------------------------
/docs/API/builtins/boolean.md:
--------------------------------------------------------------------------------
1 | # boolean
2 | > A built-in type representing a boolean (true or false) value, [see details](https://www.lua.org/pil/2.2.html)
3 |
4 |
--------------------------------------------------------------------------------
/tests/README.md:
--------------------------------------------------------------------------------
1 | ## Renoise API Tests
2 |
3 | This is a set of basic tests for the renoise Lua API, which need to be invoked within Renoise's scripting terminal.
4 |
5 | Use all.lua to run all of them in a batch.
6 |
--------------------------------------------------------------------------------
/docs/API/builtins/nil.md:
--------------------------------------------------------------------------------
1 | # nil
2 | > A built-in type representing a non-existant value, [see details](https://www.lua.org/pil/2.1.html). When you see `?` at the end of types, it means they can be nil.
3 |
4 |
--------------------------------------------------------------------------------
/generate/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "generate-api-docs"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [dependencies]
7 | # luals-docs-gen = { path = "../../Crates/luals-docs-gen" }
8 | luals-docs-gen = { git = "https://github.com/emuell/luals-docs-gen", tag = "v0.2.2" }
9 |
--------------------------------------------------------------------------------
/docs/API/builtins/self.md:
--------------------------------------------------------------------------------
1 | # self
2 | > A type that represents an instance that you call a function on. When you see a function signature starting with this type, you should use `:` to call the function on the instance, this way you can omit this first argument.
3 | > ```lua
4 | > local object = SomeClass()
5 | > object:do_something(123)
6 | > ```
7 |
8 |
--------------------------------------------------------------------------------
/docs/guide/README.md:
--------------------------------------------------------------------------------
1 | # Guides to the Renoise API
2 |
3 | Welcome to the guides for the Renoise Scripting API.
4 |
5 | In this section, you can learn about different aspects of the API through practical examples and explanations. These guides assume you have already read the chapters in our [introduction](../start/development.md) and are familiar with how to package and install tools.
6 |
--------------------------------------------------------------------------------
/tools/DragOntoRenoiseToInstall.txt:
--------------------------------------------------------------------------------
1 | To try out the example tools you have to install them first.
2 |
3 | This can be done by dragging the com.renoise.ExampleTool.xrnx and
4 | com.renoise.ExampleToolGui.xrnx folders onto the running Renoise window.
5 |
6 | The installed tools will create two menu entries in Renoises "Tool" menu:
7 | "Tools -> Example Tool" and
8 | "Tools -> Example Tool GUI"
9 |
--------------------------------------------------------------------------------
/justfile:
--------------------------------------------------------------------------------
1 | # These are just commands: https://github.com/casey/just
2 |
3 | default: docs-serve
4 |
5 | install-mdbook:
6 | cargo binstall -y mdbook mdbook-linkcheck mdbook-toc mdbook-alerts
7 |
8 | update-definitions:
9 | cd definitions && git checkout master
10 |
11 | docs-generate-api:
12 | cargo run
13 |
14 | docs-build: docs-generate-api
15 | mdbook build
16 |
17 | docs-serve: docs-generate-api
18 | mdbook serve
19 |
--------------------------------------------------------------------------------
/docs/API/modules/debug.md:
--------------------------------------------------------------------------------
1 | # debug
2 |
3 |
4 |
5 |
6 | ---
7 | ## Functions
8 | ### `start()`
9 | > Shortcut to remdebug.session.start(), which starts a debug session:
10 | > launches the debugger controller and breaks script execution. See
11 | > "Debugging.md" in the documentation root folder for more info.
12 | ### `stop()`
13 | > Shortcut to remdebug.session.stop: stops a running debug session
14 |
15 |
--------------------------------------------------------------------------------
/docs/styles.css:
--------------------------------------------------------------------------------
1 | blockquote {
2 | margin: 10px 0;
3 | padding-left: 10px;
4 | padding-right: 10px;
5 | background-color: transparent;
6 | border-block-start: .1em solid transparent;
7 | border-block-end: .1em solid transparent;
8 | }
9 |
10 | blockquote > p {
11 | color: var(--icons);
12 | padding: 0 0 10px 0;
13 | margin: 0 0 0 10px;
14 | }
15 |
16 | hr {
17 | height: 2px;
18 | background-color: var(--quote-border);
19 | border: none;
20 | }
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.SongPos.md:
--------------------------------------------------------------------------------
1 | # renoise.SongPos
2 | > Helper class used in Transport and Song, representing a position in the song.
3 |
4 |
5 |
6 |
7 | ---
8 | ## Properties
9 | ### sequence : [`integer`](../../API/builtins/integer.md)
10 | > Position in the pattern sequence.
11 |
12 | ### line : [`integer`](../../API/builtins/integer.md)
13 | > Position in the pattern at the given pattern sequence.
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/generate/src/main.rs:
--------------------------------------------------------------------------------
1 | use luals_docs_gen::*;
2 |
3 | fn main() -> Result<(), Error> {
4 | // run from the `generate` dir
5 | std::env::set_current_dir(env!("CARGO_MANIFEST_DIR"))?;
6 | // set option and generate...
7 | let options = Options {
8 | library: "../definitions/library".into(),
9 | output: "../docs".into(),
10 | excluded_classes: vec![],
11 | order: OutputOrder::ByClass,
12 | namespace: "renoise".into(),
13 | };
14 | generate_docs(&options)
15 | }
16 |
--------------------------------------------------------------------------------
/generate/README.md:
--------------------------------------------------------------------------------
1 | # Renoise API Documentation Generator
2 |
3 | This app generates the API definition chapters in the [Renoise XRNX book](https://renoise.github.io/xrnx/) from the [Renoise API definition](https://github.com/renoise/definitions) files using [luals-docs-gen](https://github.com/emuell/luals-docs-gen).
4 |
5 | ## Requirements
6 |
7 | [Rust](https://www.rust-lang.org/tools/install) v1.78 or higher
8 |
9 | ## Building
10 |
11 | To create or update the API definitions chapter, simply build and run the app via `cargo run`.
--------------------------------------------------------------------------------
/docs/start/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Welcome
4 | ... to the Renoise Lua Scripting Guide! This book is intended for developers who want to write their own scripts & tools for [Renoise](http://www.renoise.com/).
5 |
6 | If you are only interested in downloading tools for Renoise and not in developing your own tools, please have a look at the [Renoise Tools Page](http://www.renoise.com/tools).
7 |
8 | If you want to develop your own tools for Renoise, just keep reading.
9 |
--------------------------------------------------------------------------------
/book.toml:
--------------------------------------------------------------------------------
1 | [book]
2 | authors = ["renoise"]
3 | language = "en"
4 | multilingual = false
5 | src = "docs"
6 | title = "Renoise Scripting"
7 |
8 | [build]
9 | create-missing = false
10 |
11 | [output.html]
12 | default-theme = "dark"
13 | preferred-dark-theme = "ayu"
14 | git-repository-url = "https://github.com/renoise/xrnx"
15 | git-repository-icon = "fa-github"
16 | edit-url-template = "https://github.com/renoise/xrnx/edit/master/{path}"
17 | additional-css = [ "docs/styles.css" ]
18 |
19 | [output.linkcheck]
20 | warning-policy = "ignore"
21 |
22 | [preprocessor.toc]
23 | [preprocessor.alerts]
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "type": "cargo",
6 | "command": "run",
7 | "problemMatcher": [
8 | "$rustc"
9 | ],
10 | "group": "build",
11 | "label": "build: API docs"
12 | },
13 | {
14 | "type": "shell",
15 | "command": "mdbook",
16 | "args": [
17 | "build"
18 | ],
19 | "group": "build",
20 | "label": "build: book",
21 | },
22 | {
23 | "type": "shell",
24 | "command": "mdbook",
25 | "args": [
26 | "serve"
27 | ],
28 | "group": "build",
29 | "label": "serve: book",
30 | }
31 | ]
32 | }
--------------------------------------------------------------------------------
/tools/com.renoise.ExampleToolSlicedProcess.xrnx/manifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 6.2
4 | com.renoise.ExampleToolSlicedProcess
5 | 1.2
6 | taktik [taktik@renoise.com]
7 | Renoise Tool Processing Example
8 | Development
9 | Example tool that shows how to use coroutines to slice up processing functions.
10 | MIT
11 | http://scripting.renoise.com
12 |
13 |
--------------------------------------------------------------------------------
/docs/start/installing.md:
--------------------------------------------------------------------------------
1 | # Installing tools
2 |
3 | You can install any tool by dragging its folder (or a zip file with the `.xrnx` extension and the tool's contents) onto Renoise. You can also copy the folder manually into your Tools folder.
4 |
5 | > [!NOTE]
6 | > When creating a zip file you should only zip the **contents** of the folder, not the folder itself
7 |
8 |
9 |
10 |
11 | After you've installed a tool, it will be activated automatically. When in doubt, click the *Tools / Reload All Tools*.
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Document.Serializable.md:
--------------------------------------------------------------------------------
1 | # renoise.Document.Serializable
2 |
3 |
4 |
5 |
6 | ---
7 | ## Functions
8 | ### to_string([*self*](../../API/builtins/self.md))
9 | `->`[`string`](../../API/builtins/string.md)
10 |
11 | > Serialize an object to a string.
12 | ### from_string([*self*](../../API/builtins/self.md), string : [`any`](../../API/builtins/any.md))
13 | `->`[`string`](../../API/builtins/string.md)
14 |
15 | > Assign the object's value from a string - when possible. Errors are
16 | > silently ignored.
17 |
18 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "lldb",
9 | "request": "launch",
10 | "name": "Debug 'Generate API'",
11 | "cargo": {
12 | "args": [
13 | "build",
14 | ],
15 | "filter": {
16 | "kind": "bin"
17 | }
18 | },
19 | },
20 | ]
21 | }
--------------------------------------------------------------------------------
/BUILD.md:
--------------------------------------------------------------------------------
1 | ## Documentation Development
2 |
3 | ### Requirements
4 |
5 | The docs are generated using [mdBook](https://github.com/rust-lang/mdBook). To preview the pages locally you will need [cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html) to install mdbook, mdbook-linkcheck and mdbook-toc.
6 |
7 | ```sh
8 | # or `binstall`, to fetch latest binaries
9 | cargo install mdbook mdbook-linkcheck mdbook-toc mdbook-alerts
10 | ```
11 |
12 | ### Building
13 |
14 | Afterwards you can serve the docs at `localhost:3000` using mdbook, this will automatically refresh the browser tab whenever you change markdown files.
15 |
16 | ```sh
17 | mdbook serve --open
18 | ```
19 |
20 | ### Generate API reference
21 |
22 | See [generate/README.md](./generate/README.md)
--------------------------------------------------------------------------------
/tests/all.lua:
--------------------------------------------------------------------------------
1 | local failed_tests = 0
2 |
3 | -- run all tests except midi_actions which already executes a lot of sub tests
4 | local ignored_files = table.create{ "all.lua", "midi_actions.lua" }
5 |
6 | -- run all in current directory
7 | for _, file in pairs(os.filenames(os.currentdir(), { "*.lua" })) do
8 | if ignored_files:find(file) == nil then
9 | local file_chunk = assert(loadfile(os.currentdir() .. file, "t"))
10 | print("Running '" .. file .. "' tests...")
11 | local result, error = pcall(file_chunk)
12 | if result == false then
13 | print("\tTest FAILED:\n" .. error)
14 | failed_tests = failed_tests + 1
15 | end
16 | end
17 | end
18 |
19 | assert(failed_tests == 0,
20 | "One or more test failed. See output for details...")
21 |
22 |
--------------------------------------------------------------------------------
/tools/com.renoise.ExampleToolGui.xrnx/manifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 6.2
4 | com.renoise.ExampleToolGui
5 | 1.2
6 | taktik [taktik@renoise.com]
7 | Renoise ViewBuilder API Example
8 | Development
9 | Example tool which describes step by step how to create custom GUIs for your Renoise XRNX tools. Please have a look at the source files of this tool (manifest.xml and main.lua) for more info. Also creates a new menu 'Example Tool GUI' in the global 'Tools' menu.
10 | MIT
11 | http://scripting.renoise.com
12 |
13 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Osc.Bundle.md:
--------------------------------------------------------------------------------
1 | # renoise.Osc.Bundle
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### timetag : [`number`](../../API/builtins/number.md)
9 | > **READ-ONLY** Time value of the bundle.
10 |
11 | ### elements : [`renoise.Osc.Bundle`](../../API/renoise/renoise.Osc.Bundle.md) | [`renoise.Osc.Message`](../../API/renoise/renoise.Osc.Message.md)[]
12 | > **READ-ONLY** Access to the bundle elements (table of messages or bundles)
13 |
14 | ### binary_data : [`string`](../../API/builtins/string.md)
15 | > **READ-ONLY** Raw binary representation of the bundle, as needed when e.g.
16 | > sending the message over the network through sockets.
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tools/com.renoise.ExampleTool.xrnx/manifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 6.2
4 | com.renoise.ExampleTool
5 | 1.2
6 | taktik [taktik@renoise.com]
7 | Renoise Scripting Tool Example
8 | Development
9 | Example tool which describes step by step and in depth how to create Renoise XRNX tools. Please have a look at the source files of this tool (manifest.xml and main.lua) for more info. Also creates a new menu 'Example Tool' in the global 'Tools' menu.
10 | http://scripting.renoise.com
11 | MIT
12 | Windows, Mac, Linux
13 |
14 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Dialog.md:
--------------------------------------------------------------------------------
1 | # renoise.Dialog
2 | > A custom dialog created via the scripting API. Dialogs can be created
3 | > via `renoise.app():show_custom_dialog`.
4 | >
5 | > See `create custom views` on top of the renoise.ViewBuilder docs on how to
6 | > create views for the dialog.
7 |
8 |
9 |
10 |
11 | ---
12 | ## Properties
13 | ### visible : [`boolean`](../../API/builtins/boolean.md)
14 | > **READ-ONLY** Check if a dialog is alive and visible.
15 |
16 | ### focused : [`boolean`](../../API/builtins/boolean.md)
17 | > **READ-ONLY** Check if a dialog is visible and is the key window.
18 |
19 |
20 |
21 | ---
22 | ## Functions
23 | ### show([*self*](../../API/builtins/self.md))
24 | > Bring an already visible dialog to front and make it the key window.
25 | ### close([*self*](../../API/builtins/self.md))
26 | > Close a visible dialog.
27 |
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 by the renoise authors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Midi.MidiDevice.md:
--------------------------------------------------------------------------------
1 | # renoise.Midi.MidiDevice
2 | > Baseclass of renoise.Midi.MidiIn/OutDevice with common properties for MIDI
3 | > input and output devices.
4 |
5 |
6 |
7 |
8 | ---
9 | ## Properties
10 | ### is_open : [`boolean`](../../API/builtins/boolean.md)
11 | > Returns true while the device is open (ready to send or receive messages).
12 | > Your device refs will never be auto-closed, "is_open" will only be false if
13 | > you explicitly call "midi_device:close()" to release a device.
14 |
15 | ### name : [`string`](../../API/builtins/string.md)
16 | > The name of a device. This is the name you create a device with via
17 | > `renoise.Midi.create_input_device` or `renoise.Midi.create_output_device`.
18 |
19 |
20 |
21 | ---
22 | ## Functions
23 | ### close([*self*](../../API/builtins/self.md))
24 | > Close a running MIDI device. When no other client is using a device, Renoise
25 | > will also shut off the device driver so that, for example, Windows OS other
26 | > applications can use the device again. This is automatically done when
27 | > scripts are closed or your device objects are garbage collected.
28 |
29 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Midi.MidiInputDevice.md:
--------------------------------------------------------------------------------
1 | # renoise.Midi.MidiInputDevice
2 | > Midi device interface for receiving MIDI messages.
3 | > Instances are created via `renoise.Midi.create_input_device`
4 |
5 |
6 |
7 |
8 | ---
9 | ## Properties
10 | ### is_open : [`boolean`](../../API/builtins/boolean.md)
11 | > Returns true while the device is open (ready to send or receive messages).
12 | > Your device refs will never be auto-closed, "is_open" will only be false if
13 | > you explicitly call "midi_device:close()" to release a device.
14 |
15 | ### name : [`string`](../../API/builtins/string.md)
16 | > The name of a device. This is the name you create a device with via
17 | > `renoise.Midi.create_input_device` or `renoise.Midi.create_output_device`.
18 |
19 |
20 |
21 | ---
22 | ## Functions
23 | ### close([*self*](../../API/builtins/self.md))
24 | > Close a running MIDI device. When no other client is using a device, Renoise
25 | > will also shut off the device driver so that, for example, Windows OS other
26 | > applications can use the device again. This is automatically done when
27 | > scripts are closed or your device objects are garbage collected.
28 |
29 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.ScriptingTool.MidiMessage.md:
--------------------------------------------------------------------------------
1 | # renoise.ScriptingTool.MidiMessage
2 | > MIDI message as passed to the `invoke` callback in tool midi_mappings.
3 |
4 |
5 |
6 |
7 | ---
8 | ## Properties
9 | ### int_value : [`integer`](../../API/builtins/integer.md)[`?`](../../API/builtins/nil.md)
10 | > Range: (0S - 127) for abs values, Range: (-63 - 63) for relative values
11 | > valid when `is_rel_value()` or `is_abs_value()` returns true, else undefined
12 |
13 | ### boolean_value : [`boolean`](../../API/builtins/boolean.md)[`?`](../../API/builtins/nil.md)
14 | > valid [true OR false] when `is_switch()` returns true, else undefined
15 |
16 |
17 |
18 | ---
19 | ## Functions
20 | ### is_trigger([*self*](../../API/builtins/self.md))
21 | > returns if action should be invoked
22 | ### is_switch([*self*](../../API/builtins/self.md))
23 | > check if the boolean_value property is valid
24 | ### is_rel_value([*self*](../../API/builtins/self.md))
25 | `->`[`boolean`](../../API/builtins/boolean.md)
26 |
27 | > check if the int_value property is valid
28 | ### is_abs_value([*self*](../../API/builtins/self.md))
29 | `->`[`boolean`](../../API/builtins/boolean.md)
30 |
31 | > check if the int_value property is valid
32 |
33 |
--------------------------------------------------------------------------------
/docs/guide/sqlite.md:
--------------------------------------------------------------------------------
1 | # SQLite Databases
2 |
3 | The Renoise API allows you to create or load [SQLite databases](https://sqlite.org). This can be used to either efficiently deal with large data blobs within your tools or to read existing database files from other applications.
4 |
5 | See [`renoise.SQLite`](../API/renoise/renoise.SQLite.md) for more info.
6 |
7 | A quick example on how to open and read from an existing database file:
8 |
9 | ```lua
10 | -- create a new database (rwc = read/write/create)
11 | local db, status, error = renoise.SQLite.open("./some_test.db", "rwc")
12 | -- NB: use renoise.SQLite.open() to create a in-memory db instead
13 | print("Create:", db.is_open, db.error_code, db.error_message)
14 |
15 | local sql = [[
16 | CREATE TABLE numbers(num1,num2,str);
17 | INSERT INTO numbers VALUES(1,11,"ABC");
18 | INSERT INTO numbers VALUES(2,22,"DEF");
19 | INSERT INTO numbers VALUES(3,33,"UVW");
20 | INSERT INTO numbers VALUES(4,44,"XYZ");
21 | ]]
22 |
23 | print("Exec:", db:execute(sql))
24 | print("Changes:", db.changes, db.total_changes, db.error_message)
25 |
26 | -- read from an existing db using a prepared statement
27 | local db, status, error = renoise.SQLite.open("./test.db", "ro") -- read-only
28 | print("Open:", db.is_open, db.error_code, db.error_message)
29 |
30 | local stm = db:prepare("SELECT * from numbers")
31 | print("Read:", stm.columns, stm.unames)
32 |
33 | for k in stm:rows() do
34 | rprint(k)
35 | end
36 | ```
--------------------------------------------------------------------------------
/.github/workflows/archive.yml:
--------------------------------------------------------------------------------
1 | name: Build and Archive XRNX_Starter_Pack.zip
2 |
3 | on:
4 | pull_request:
5 | branches: [ "master" ]
6 | push:
7 | branches:
8 | - master
9 |
10 | env:
11 | CARGO_TERM_COLOR: always
12 |
13 | jobs:
14 | build:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v3
19 | with:
20 | submodules: recursive
21 |
22 | - name: Install Rust
23 | uses: actions-rust-lang/setup-rust-toolchain@v1
24 | with:
25 | cache-workspaces: "docs"
26 | cache-key: "renoise-xrnx"
27 |
28 | - name: Install mdbook
29 | run: cargo install mdbook@0.4.51 mdbook-linkcheck@0.7.5 mdbook-toc@0.14.2 mdbook-alerts@0.8.0
30 |
31 | - name: Build the API
32 | run: cargo run
33 |
34 | - name: Build the book
35 | run: mdbook build
36 |
37 | - name: Create XRNX_Starter_Pack
38 | run: |
39 | mkdir dist
40 | cp -rf definitions dist/definitions
41 | cp -rf book/html dist/docs
42 | cp -rf tools dist/tools
43 | rm -rf dist/*/.git dist/*/.gitignore
44 | echo -e '\n
\n\n\n' > dist/docs.html
45 |
46 | - name: Archive
47 | uses: actions/upload-artifact@v4
48 | with:
49 | name: XRNX_Starter_Pack
50 | path: dist
51 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Socket.SocketBase.md:
--------------------------------------------------------------------------------
1 | # renoise.Socket.SocketBase
2 | > SocketBase is the base class for socket clients and servers. All
3 | > SocketBase properties and functions are available for servers and clients.
4 |
5 |
6 |
7 |
8 | ---
9 | ## Properties
10 | ### is_open : [`boolean`](../../API/builtins/boolean.md)
11 | > **READ-ONLY** Returns true when the socket object is valid and connected.
12 | > Sockets can manually be closed (see socket:close()). Client sockets can also
13 | > actively be closed/refused by the server. In this case the client:receive()
14 | > calls will fail and return an error.
15 |
16 | ### local_address : [`string`](../../API/builtins/string.md)
17 | > **READ-ONLY** The socket's resolved local address (for example "127.0.0.1"
18 | > when a socket is bound to "localhost")
19 |
20 | ### local_port : [`integer`](../../API/builtins/integer.md)
21 | > **READ-ONLY** The socket's local port number, as specified when instantiated.
22 |
23 |
24 |
25 | ---
26 | ## Functions
27 | ### close([*self*](../../API/builtins/self.md))
28 | > Closes the socket connection and releases all resources. This will make
29 | > the socket useless, so any properties, calls to the socket will result in
30 | > errors. Can be useful to explicitly release a connection without waiting for
31 | > the dead object to be garbage collected, or if you want to actively refuse a
32 | > connection.
33 |
34 |
--------------------------------------------------------------------------------
/docs/start/distribution.md:
--------------------------------------------------------------------------------
1 | # Distribution
2 |
3 | Eventually you might want to share your work with others, in this case you will have to use the zipped format.
4 |
5 | * First, we recommend sharing your tool on the [Tools section of the forum](https://forum.renoise.com/c/renoise-tools) to get some feedback and early testing done. If you create a topic there, you can also use it to notify users about updates or discuss potential improvements.
6 | * Later on, you might want to [submit your tool](https://www.renoise.com/tools/submit) to the official [Tool library](https://www.renoise.com/tools) so that users can find it easier and have automatic updates.
7 |
8 |
9 | # Community channels
10 |
11 | If you have further questions or just want to discuss tools with fellow devs you can reach out over the following channels
12 |
13 | * [The official Renoise forum has a dedicated topic](https://forum.renoise.com/c/renoise-tool-development)
14 | * [The Discord server has a room for scripting](https://discord.com/invite/uDNJpQ8awR)
15 | * [Enter the Matrix at Renoise space](https://matrix.to/#/#renoise-space:hacklab.fi) on [Matrix](https://joinmatrix.org/)
16 | * [Post on Reddit](https://www.reddit.com/r/renoise/)
17 | * [Join the Facebook Group](https://www.facebook.com/groups/109911655710325/)
18 | * [Find community channels on the Renoise site](https://www.renoise.com/community)
19 |
20 | Now that you can write, package and test your tool, you are ready to explore the depths of the API and start implementing your ideas.
21 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.EffectColumn.md:
--------------------------------------------------------------------------------
1 | # renoise.EffectColumn
2 | > A single effect column in a pattern line.
3 | >
4 | > Access effect column properties either by values (numbers) or by strings.
5 | > The string representation uses exactly the same notation as you see
6 | > them in Renoise's pattern or phrase editor.
7 |
8 |
9 |
10 |
11 | ---
12 | ## Properties
13 | ### is_empty : [`boolean`](../../API/builtins/boolean.md)
14 | > **READ-ONLY** True, when all effect column properties are empty.
15 |
16 | ### is_selected : [`boolean`](../../API/builtins/boolean.md)
17 | > **READ-ONLY** True, when this column is selected in the pattern or phrase editor.
18 |
19 | ### number_value : [`integer`](../../API/builtins/integer.md)
20 | > 0-65535 in the form 0x0000xxyy where xx=effect char 1 and yy=effect char 2
21 |
22 | ### number_string : [`string`](../../API/builtins/string.md)
23 | > Range: ('00' - 'ZZ')
24 |
25 | ### amount_value : [`integer`](../../API/builtins/integer.md)
26 | > Range: (0 - 255)
27 |
28 | ### amount_string : [`string`](../../API/builtins/string.md)
29 | > Range: ('00' - 'FF')
30 |
31 |
32 |
33 | ---
34 | ## Functions
35 | ### clear([*self*](../../API/builtins/self.md))
36 | > Clear the effect column.
37 | ### copy_from([*self*](../../API/builtins/self.md), other : [`renoise.EffectColumn`](../../API/renoise/renoise.EffectColumn.md))
38 | > Copy the column's content from another column.
39 |
40 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Midi.MidiOutputDevice.md:
--------------------------------------------------------------------------------
1 | # renoise.Midi.MidiOutputDevice
2 | > Midi device interface for sending MIDI messages.
3 | > Instances are created via `renoise.Midi.create_output_device`
4 |
5 |
6 |
7 |
8 | ---
9 | ## Properties
10 | ### is_open : [`boolean`](../../API/builtins/boolean.md)
11 | > Returns true while the device is open (ready to send or receive messages).
12 | > Your device refs will never be auto-closed, "is_open" will only be false if
13 | > you explicitly call "midi_device:close()" to release a device.
14 |
15 | ### name : [`string`](../../API/builtins/string.md)
16 | > The name of a device. This is the name you create a device with via
17 | > `renoise.Midi.create_input_device` or `renoise.Midi.create_output_device`.
18 |
19 |
20 |
21 | ---
22 | ## Functions
23 | ### close([*self*](../../API/builtins/self.md))
24 | > Close a running MIDI device. When no other client is using a device, Renoise
25 | > will also shut off the device driver so that, for example, Windows OS other
26 | > applications can use the device again. This is automatically done when
27 | > scripts are closed or your device objects are garbage collected.
28 | ### send([*self*](../../API/builtins/self.md), message : [`integer`](../../API/builtins/integer.md)[])
29 | > Send raw 1-3 byte MIDI messages or sysex messages. Message is expected
30 | > to be an array of numbers. It must not be empty and can only contain
31 | > numbers >= 0 and <= 0xFF (bytes). Sysex messages must be sent in one block,
32 | > and must start with 0xF0, and end with 0xF7.
33 |
34 |
--------------------------------------------------------------------------------
/tests/app_window.lua:
--------------------------------------------------------------------------------
1 | --[[--------------------------------------------------------------------------
2 | TestAppWindow.lua
3 | --------------------------------------------------------------------------]]--
4 |
5 | do
6 |
7 | ----------------------------------------------------------------------------
8 | -- tools
9 |
10 | local function assert_error(statement)
11 | assert(pcall(statement) == false, "expected function error")
12 | end
13 |
14 |
15 | -- shortcuts
16 |
17 | local window = renoise.app().window
18 |
19 |
20 | ----------------------------------------------------------------------------
21 | -- upper frame
22 |
23 | local notification_count = 0
24 | function disk_browser_is_visible_changed()
25 | notification_count = notification_count + 1
26 | end
27 |
28 | window.disk_browser_is_visible = false
29 |
30 | window.disk_browser_is_visible_observable:add_notifier(
31 | disk_browser_is_visible_changed)
32 |
33 | window.disk_browser_is_visible = true
34 | assert(window.disk_browser_is_visible == true)
35 | assert(notification_count == 1)
36 |
37 | window.disk_browser_is_visible = false
38 | assert(window.disk_browser_is_visible == false)
39 | assert(notification_count == 2)
40 |
41 | window.disk_browser_is_visible_observable:remove_notifier(
42 | disk_browser_is_visible_changed)
43 |
44 | end
45 |
46 |
47 | ------------------------------------------------------------------------------
48 | -- test finalizers
49 |
50 | collectgarbage()
51 |
52 |
53 | --[[--------------------------------------------------------------------------
54 | --------------------------------------------------------------------------]]--
55 |
56 |
--------------------------------------------------------------------------------
/.github/workflows/pages.yml:
--------------------------------------------------------------------------------
1 | name: Build and Deploy mdBook
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v4
14 | with:
15 | submodules: recursive
16 |
17 | - name: Install Rust
18 | uses: actions-rust-lang/setup-rust-toolchain@v1
19 | with:
20 | cache-workspaces: "docs"
21 | cache-key: "renoise-xrnx"
22 |
23 | - name: Install mdbook
24 | run: cargo install mdbook@0.4.51 mdbook-linkcheck@0.7.5 mdbook-toc@0.14.2 mdbook-alerts@0.8.0
25 |
26 | - name: Build the API
27 | run: cargo run
28 |
29 | - name: Build the book
30 | run: mdbook build
31 |
32 | - name: Upload
33 | uses: actions/upload-pages-artifact@v3
34 | with:
35 | name: github-pages
36 | path: ./book/html
37 |
38 | deploy:
39 | # Add a dependency to the build job
40 | needs: build
41 |
42 | # Grant GITHUB_TOKEN the permissions required to make a Pages deployment
43 | permissions:
44 | pages: write # to deploy to Pages
45 | id-token: write # to verify the deployment originates from an appropriate source
46 |
47 | # Deploy to the github-pages environment
48 | environment:
49 | name: github-pages
50 | url: ${{ steps.deployment.outputs.page_url }}
51 |
52 | # Specify runner + deployment step
53 | runs-on: ubuntu-latest
54 | steps:
55 | - name: Deploy to GitHub Pages
56 | id: deployment
57 | uses: actions/deploy-pages@v4 # or specific "vX.X.X" version tag for this action
58 |
--------------------------------------------------------------------------------
/docs/guide/files&bits.md:
--------------------------------------------------------------------------------
1 | # File IO & Bits
2 |
3 | The Renoise API uses Lua's standard [io library](https://www.lua.org/pil/21.html) to read or write external files.
4 |
5 | To access the raw bits and bytes of some data, for example, to read or write binary file streams, you can use the `bit` library. It's built into the Renoise API, so there's no need to `require` it.
6 |
7 | See the [LuaJIT bit library documentation](https://bitop.luajit.org/api.html) for more info and examples.
8 |
9 | ```lua
10 | -- Reading integer numbers or raw bytes from a file
11 |
12 | local function read_word(file)
13 | local bytes = file:read(2)
14 | if (not bytes or #bytes < 2) then
15 | return nil
16 | else
17 | -- little-endian
18 | return bit.bor(bytes:byte(1),
19 | bit.lshift(bytes:byte(2), 8))
20 | end
21 | end
22 |
23 | local function read_dword(file)
24 | local bytes = file:read(4)
25 | if (not bytes or #bytes < 4) then
26 | return nil
27 | else
28 | -- little-endian
29 | return bit.bor(bytes:byte(1),
30 | bit.lshift(bytes:byte(2), 8),
31 | bit.lshift(bytes:byte(3), 16),
32 | bit.lshift(bytes:byte(4), 24))
33 | end
34 | end
35 |
36 | -- and so on (adapt as needed to deal with endianness!) ...
37 |
38 | local file, err = io.open("some_binary_file.bin", "rb")
39 | if not file then
40 | print("Could not open file: " .. tostring(err))
41 | return
42 | end
43 |
44 | local bytes = file:read(512)
45 |
46 | if (not bytes or #bytes < 512) then
47 | print("unexpected end of file")
48 | else
49 | for i = 1, #bytes do
50 | print(bytes:byte(i))
51 | end
52 | end
53 |
54 | print(read_word(file) or "unexpected end of file")
55 | print(read_dword(file) or "unexpected end of file")
56 |
57 | file:close()
58 | ```
59 |
--------------------------------------------------------------------------------
/docs/API/modules/math.md:
--------------------------------------------------------------------------------
1 | # math
2 |
3 |
4 |
5 |
6 | ---
7 | ## Functions
8 | ### lin2db(n : [`number`](../../API/builtins/number.md))
9 | `->`[`number`](../../API/builtins/number.md)
10 |
11 | > Converts a linear value to a db value. db values will be clipped to
12 | > math.infdb.
13 | > #### examples:
14 | > ```lua
15 | > print(math.lin2db(1.0)) --> 0
16 | > print(math.lin2db(0.0)) --> -200 (math.infdb)
17 | > ```
18 | ### db2lin(n : [`number`](../../API/builtins/number.md))
19 | `->`[`number`](../../API/builtins/number.md)
20 |
21 | > Converts a dB value to a linear value.
22 | > #### examples:
23 | > ```lua
24 | > print(math.db2lin(math.infdb)) --> 0
25 | > print(math.db2lin(6.0)) --> 1.9952623149689
26 | > ```
27 | ### db2fader(min_dB : [`number`](../../API/builtins/number.md), max_dB : [`number`](../../API/builtins/number.md), dB_to_convert : [`number`](../../API/builtins/number.md))
28 | `->`[`number`](../../API/builtins/number.md)
29 |
30 | > Converts a dB value to a normalized linear fader value between 0-1 within
31 | > the given dB range.
32 | > #### examples:
33 | > ```lua
34 | > print(math.db2fader(-96, 0, 1)) --> 0
35 | > print(math.db2fader(-48, 6, 0)) --> 0.73879611492157
36 | > ```
37 | ### fader2db(min_dB : [`number`](../../API/builtins/number.md), max_dB : [`number`](../../API/builtins/number.md), fader_value : [`number`](../../API/builtins/number.md))
38 | `->`[`number`](../../API/builtins/number.md)
39 |
40 | > Converts a normalized linear mixer fader value to a db value within
41 | > the given dB range.
42 | > #### examples:
43 | > ```lua
44 | > print(math.fader2db(-96, 0, 1)) --> 0
45 | > print(math.fader2db(-96, 0, 0)) --> -96
46 | > ```
47 |
48 |
--------------------------------------------------------------------------------
/docs/API/renoise.md:
--------------------------------------------------------------------------------
1 | # renoise
2 | > Holds all renoise related API functions and classes.
3 |
4 |
5 |
6 | ## Constants
7 |
8 | ### API_VERSION : [`number`](../API/builtins/number.md)
9 | > Currently 6.2. Any changes in the API which are not backwards compatible,
10 | > will increase the internal API's major version number (e.g. from 1.4 -> 2.0).
11 | > All other backwards compatible changes, like new functionality, new functions
12 | > and classes which do not break existing scripts, will increase only the minor
13 | > version number (e.g. 1.0 -> 1.1).
14 |
15 | ### RENOISE_VERSION : [`string`](../API/builtins/string.md)
16 | > Renoise Version "Major.Minor.Revision[AlphaBetaRcVersion][Demo]"
17 |
18 |
19 | ---
20 | ## Functions
21 | ### `ViewBuilder()`
22 | `->`[`renoise.ViewBuilder`](../API/renoise/renoise.ViewBuilder.md)
23 |
24 | > Construct a new viewbuilder instance you can use to create views.
25 | ### `app()`
26 | `->`[`renoise.Application`](../API/renoise/renoise.Application.md)
27 |
28 | > Global access to the Renoise Application.
29 | ### `song()`
30 | `->`[`renoise.Song`](../API/renoise/renoise.Song.md)[`?`](../API/builtins/nil.md)
31 |
32 | > Global access to the Renoise Song.
33 | >
34 | > NB: The song instance changes when a new song is loaded or created in Renoise,
35 | > so tools can not memorize the song instance globally once, but must instead
36 | > react on the application's `new_document_observable`
37 | > observable.
38 | ### `tool()`
39 | `->`[`renoise.ScriptingTool`](../API/renoise/renoise.ScriptingTool.md)
40 |
41 | > Global access to the Renoise Scripting Tool (your XRNX tool).
42 | >
43 | > This is only valid when getting called from a tool and not when e.g. using the
44 | > scripting terminal and editor in Renoise.
45 |
46 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.InstrumentMacroMapping.md:
--------------------------------------------------------------------------------
1 | # renoise.InstrumentMacroMapping
2 |
3 |
4 |
5 | ## Constants
6 | ### Scaling
7 | > ```lua
8 | > {
9 | > SCALING_LOG_FAST: integer = 1,
10 | > SCALING_LOG_SLOW: integer = 2,
11 | > SCALING_LINEAR: integer = 3,
12 | > SCALING_EXP_SLOW: integer = 4,
13 | > SCALING_EXP_FAST: integer = 5,
14 | > }
15 | > ```
16 |
17 |
18 | ---
19 | ## Properties
20 | ### parameter : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)
21 | > **READ-ONLY** Linked parameter.
22 | > Can be a sample FX- or modulation parameter. Never nil.
23 |
24 | ### parameter_min : [`number`](../../API/builtins/number.md)
25 | > Range: (0 - 1)
26 |
27 | ### parameter_min_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
28 | > Track changes to document properties or general states by attaching listener
29 | > functions to it.
30 |
31 | ### parameter_max : [`number`](../../API/builtins/number.md)
32 | > Range: (0 - 1)
33 |
34 | ### parameter_max_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
35 | > Track changes to document properties or general states by attaching listener
36 | > functions to it.
37 |
38 | ### parameter_scaling : [`renoise.InstrumentMacroMapping.Scaling`](renoise.InstrumentMacroMapping.md#Scaling)
39 | > Scaling which gets applied within the min/max range to set the dest value.
40 |
41 | ### parameter_scaling_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
42 | > Track changes to document properties or general states by attaching listener
43 | > functions to it.
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.InstrumentMidiInputProperties.md:
--------------------------------------------------------------------------------
1 | # renoise.InstrumentMidiInputProperties
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### device_name : [`string`](../../API/builtins/string.md)
9 | > When setting new devices, device names must be one of
10 | > `renoise.Midi.available_input_devices()` or "Renoise OSC Device".
11 | > To close a device and disconnect it from the instrument, assign
12 | > an empty string.
13 |
14 | ### device_name_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
15 | > Track changes to document properties or general states by attaching listener
16 | > functions to it.
17 |
18 | ### channel : [`integer`](../../API/builtins/integer.md)
19 | > Range: (1 - 16) 0 = Omni
20 |
21 | ### channel_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
22 | > Track changes to document properties or general states by attaching listener
23 | > functions to it.
24 |
25 | ### note_range : [`integer`](../../API/builtins/integer.md)[]
26 | > Table of two numbers in range (0-119) where C-4 is 48
27 |
28 | ### note_range_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
29 | > Track changes to document properties or general states by attaching listener
30 | > functions to it.
31 |
32 | ### assigned_track : [`integer`](../../API/builtins/integer.md)
33 | > Range: (1 - song.sequencer_track_count) 0 = Current track
34 |
35 | ### assigned_track_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
36 | > Track changes to document properties or general states by attaching listener
37 | > functions to it.
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Renoise Scripting Development
4 |
5 | Welcome to the Renoise Lua Scripting Repository! This site is for developers who want to write their own scripts & tools for [Renoise](http://www.renoise.com/). If you are only interested in downloading tools for Renoise and not in developing your own, please have a look at the [Renoise Tools Page](http://renoise.com/tools).
6 |
7 | ### Documentation & Guides
8 |
9 | Read the [Renoise Scripting Development Book](https://renoise.github.io/xrnx).
10 |
11 | This book is highly recommended for anyone who wants to get into all this Renoise scripting. Please read it first to get an overview of what's needed to develop tools for Renoise. It contains an introduction, some guides and the full API documentation.
12 |
13 | ### Example Tools
14 |
15 | In addition to the documentation, this repository also contains some sample tools in the [tools folder](./tools) that are intended for new tool developers only. You can download them, install them, and read them as an interactive tutorial. The example tools are also included in the XRNX Starter pack (see below).
16 |
17 | See [github.com/renoise/tools](https://github.com/renoise/tools) for tools created by the Renoise team that actually do something.
18 |
19 | ### Starter Pack
20 |
21 | The scripting development book, API definition and example tools, can also be downloaded as a "starter pack" bundle file from the [releases page](https://github.com/renoise/xrnx/releases).
22 |
23 | ### Need more help?
24 |
25 | For any questions regarding the Lua API or this repository, please have a look at the [Renoise Scripting Development Forum](https://forum.renoise.com/c/renoise-tool-development).
26 |
27 | *Have fun scripting and hacking Renoise!*
28 |
29 | ### Contribute
30 |
31 | Contributions such as typo fixes, new user guides, and other forms of documentation improvement are welcome!
32 |
33 | Please report issues [here](https://github.com/renoise/xrnx/issues) or fork the latest git repository and create a feature or bugfix branch.
34 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Document.Observable.md:
--------------------------------------------------------------------------------
1 | # renoise.Document.Observable
2 | > Track changes to document properties or general states by attaching listener
3 | > functions to it.
4 |
5 |
6 |
7 |
8 | ---
9 | ## Functions
10 | ### has_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction))
11 | `->`[`boolean`](../../API/builtins/boolean.md)
12 |
13 | > Checks if the given function, method was already registered as notifier.
14 | ### add_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction))
15 | > Register a function or method as a notifier, which will be called as soon as
16 | > the observable's value changed. The passed notifier can either be a function
17 | > or a table with a function and some context (an "object") -> method.
18 | > #### examples:
19 | > ```lua
20 | > renoise.song().transport.bpm_observable:add_notifier(function()
21 | > print("BPM changed")
22 | > end)
23 | >
24 | > local my_context = { bpm_changes = 0, something_else = "bla" }
25 | > renoise.song().transport.bpm_observable:add_notifier({
26 | > my_context,
27 | > function(context)
28 | > context.bpm_changes = context.bpm_changes + 1;
29 | > print(("#BPM changes: %s"):format(context.bpm_changes));
30 | > end
31 | > })
32 | > ```
33 | ### remove_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction) | [`NotifierMemberContext`](#NotifierMemberContext))
34 | > Unregister a previously registered notifier. When only passing an object,
35 | > all notifier functions that match the given object will be removed.
36 | > This will not fire errors when no methods for the given object are attached.
37 | > Trying to unregister a function or method which wasn't registered, will resolve
38 | > into an error.
39 |
40 |
41 |
42 | ---
43 | ## Aliases
44 | ### NotifierFunction
45 | fun()
46 |
47 |
48 | ### NotifierMemberContext
49 | [`table`](../../API/builtins/table.md) | [`userdata`](../../API/builtins/userdata.md)
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.InstrumentMacro.md:
--------------------------------------------------------------------------------
1 | # renoise.InstrumentMacro
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### name : [`string`](../../API/builtins/string.md)
9 | > Macro name as visible in the GUI when mappings are presents.
10 |
11 | ### name_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
12 | > Track changes to document properties or general states by attaching listener
13 | > functions to it.
14 |
15 | ### value : [`number`](../../API/builtins/number.md)
16 | > Range: (0 - 1)
17 |
18 | ### value_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
19 | > Track changes to document properties or general states by attaching listener
20 | > functions to it.
21 |
22 | ### value_string : [`string`](../../API/builtins/string.md)
23 | > Range: (0 - 100)
24 |
25 | ### value_string_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
26 | > Track changes to document properties or general states by attaching listener
27 | > functions to it.
28 |
29 | ### mappings : [`renoise.InstrumentMacroMapping`](../../API/renoise/renoise.InstrumentMacroMapping.md)[]
30 | > **READ-ONLY** Macro mappings, target parameters
31 |
32 | ### mappings_observable : [`renoise.Document.ObservableList`](../../API/renoise/renoise.Document.ObservableList.md)
33 | > Track changes to document lists by attaching listener functions to it.
34 | > NB: Notifiers will not broadcast changes made to list items, but only changes
35 | > to the lists **layout** (items got added, removed, swapped).
36 |
37 |
38 |
39 | ---
40 | ## Functions
41 | ### mapping([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
42 | `->`[`renoise.InstrumentMacroMapping`](../../API/renoise/renoise.InstrumentMacroMapping.md)
43 |
44 | > Access to a single attached parameter mapping by index. Use property
45 | > 'mappings' to query mapping count.
46 |
47 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Document.ObservableBang.md:
--------------------------------------------------------------------------------
1 | # renoise.Document.ObservableBang
2 | > Observable without a value which sends out notifications when "banging" it.
3 |
4 |
5 |
6 |
7 | ---
8 | ## Functions
9 | ### has_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction))
10 | `->`[`boolean`](../../API/builtins/boolean.md)
11 |
12 | > Checks if the given function, method was already registered as notifier.
13 | ### add_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction))
14 | > Register a function or method as a notifier, which will be called as soon as
15 | > the observable's value changed. The passed notifier can either be a function
16 | > or a table with a function and some context (an "object") -> method.
17 | > #### examples:
18 | > ```lua
19 | > renoise.song().transport.bpm_observable:add_notifier(function()
20 | > print("BPM changed")
21 | > end)
22 | >
23 | > local my_context = { bpm_changes = 0, something_else = "bla" }
24 | > renoise.song().transport.bpm_observable:add_notifier({
25 | > my_context,
26 | > function(context)
27 | > context.bpm_changes = context.bpm_changes + 1;
28 | > print(("#BPM changes: %s"):format(context.bpm_changes));
29 | > end
30 | > })
31 | > ```
32 | ### remove_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction) | [`NotifierMemberContext`](#NotifierMemberContext))
33 | > Unregister a previously registered notifier. When only passing an object,
34 | > all notifier functions that match the given object will be removed.
35 | > This will not fire errors when no methods for the given object are attached.
36 | > Trying to unregister a function or method which wasn't registered, will resolve
37 | > into an error.
38 | ### bang([*self*](../../API/builtins/self.md))
39 | > fire a notification, calling all registered notifiers.
40 |
41 |
42 |
43 | ---
44 | ## Aliases
45 | ### NotifierFunction
46 | fun()
47 |
48 |
49 | ### NotifierMemberContext
50 | [`table`](../../API/builtins/table.md) | [`userdata`](../../API/builtins/userdata.md)
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/docs/guide/observables.md:
--------------------------------------------------------------------------------
1 | # Observables
2 |
3 | The Renoise API makes extensive use of the [Observer pattern](https://en.wikipedia.org/wiki/Observer_pattern). In short, many values are wrapped in "Observable" objects. You can register "notifier" functions on these objects, which will be called whenever the underlying value changes. This is a powerful way to react to changes in the application state without constantly polling and comparing values.
4 |
5 | When browsing the [API documentation](../API/README.md), you will find many properties with an `_observable` suffix. Let's see how to use this feature by attaching a notifier that runs when the user loads a new song.
6 |
7 | ```lua
8 | local function on_new_document()
9 | renoise.app():show_message("Loaded a new song!")
10 | end
11 |
12 | -- Get the tool's new_document observable and add our function as a notifier.
13 | renoise.tool().app_new_document_observable:add_notifier(on_new_document)
14 | ```
15 |
16 | A common pattern is to attach notifiers to song-specific properties inside the `app_new_document_observable` notifier. This ensures that your notifiers are re-attached whenever a new song is loaded. To listen for changes on a specific value, you typically add `_observable` to the property name and add a notifier to it.
17 |
18 | Let's extend the previous snippet to also fire a message whenever the name of the song changes.
19 |
20 | ```lua
21 | local function on_song_name_changed()
22 | local song_name = renoise.song().name
23 | renoise.app():show_message("New name was set!\nName: " .. song_name)
24 | end
25 |
26 | local function on_new_document()
27 | renoise.app():show_message("Loaded a new song!")
28 | -- When a new song is loaded, attach a notifier to its name_observable
29 | renoise.song().name_observable:add_notifier(on_song_name_changed)
30 | end
31 |
32 | renoise.tool().app_new_document_observable:add_notifier(on_new_document)
33 | ```
34 |
35 | Now, try changing the song title in the "Song Settings" tab to see your message pop up.
36 |
37 | With this technique, you can listen to all sorts of events, which is very useful when you want your tool to react to user actions like selecting a new instrument, track, or sample.
38 |
39 | There are different Observables for each primitive type, such as `ObservableBoolean`, `ObservableNumber`, or `ObservableString`, as well as list types like `ObservableBooleanList`. You can explore the entire [Observables API](../API/renoise/renoise.Document.Observable.md) to see them all.
40 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Socket.md:
--------------------------------------------------------------------------------
1 | # renoise.Socket
2 | > Interfaces for built-in socket support for Lua scripts in Renoise.
3 | >
4 | > Right now UDP and TCP protocols are supported. The class interfaces for UDP
5 | > and TCP sockets behave exactly the same. That is, they don't depend on the
6 | > protocol, so both are easily interchangeable when needed.
7 |
8 |
9 |
10 | ## Constants
11 | ### Protocol
12 | > ```lua
13 | > {
14 | > PROTOCOL_TCP: integer = 1,
15 | > PROTOCOL_UDP: integer = 2,
16 | > }
17 | > ```
18 |
19 |
20 | ---
21 | ## Functions
22 | ### create_server(server_address : [`string`](../../API/builtins/string.md), server_port : [`integer`](../../API/builtins/integer.md), protocol : [`renoise.Socket.Protocol`](renoise.Socket.md#Protocol)[`?`](../../API/builtins/nil.md))
23 | `->`[`renoise.Socket.SocketServer`](../../API/renoise/renoise.Socket.SocketServer.md)[`?`](../../API/builtins/nil.md), [`string`](../../API/builtins/string.md)[`?`](../../API/builtins/nil.md)
24 |
25 | > Creates a connected UPD or TCP server object. Use "localhost" to use your
26 | > system's default network address. Protocol can be `renoise.Socket.PROTOCOL_TCP`
27 | > or `renoise.Socket.PROTOCOL_UDP` (by default TCP).
28 | > When instantiation and connection succeed, a valid server object is
29 | > returned, otherwise "error" is set and the server object is nil.
30 | > Using the create function with no server_address allows you to create a
31 | > server which allows connections to any address (for example localhost
32 | > and some IP)
33 | ### create_client(server_address : [`string`](../../API/builtins/string.md), server_port : [`integer`](../../API/builtins/integer.md), protocol : [`renoise.Socket.Protocol`](renoise.Socket.md#Protocol)[`?`](../../API/builtins/nil.md), timeout : [`integer`](../../API/builtins/integer.md)[`?`](../../API/builtins/nil.md))
34 | `->`client : [`renoise.Socket.SocketClient`](../../API/renoise/renoise.Socket.SocketClient.md)[`?`](../../API/builtins/nil.md), error : [`string`](../../API/builtins/string.md)[`?`](../../API/builtins/nil.md)
35 |
36 | > Create a connected UPD or TCP client.
37 | > `protocol` can be `renoise.Socket.PROTOCOL_TCP` or
38 | > `renoise.Socket.PROTOCOL_UDP` (by default TCP).
39 | > `timeout` is the time in ms to wait until the connection is established
40 | > (1000 ms by default). When instantiation and connection succeed, a valid client
41 | > object is returned, otherwise "error" is set and the client object is nil
42 |
43 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.InstrumentPluginDevice.md:
--------------------------------------------------------------------------------
1 | # renoise.InstrumentPluginDevice
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### name : [`string`](../../API/builtins/string.md)
9 | > **READ-ONLY** Device name.
10 |
11 | ### short_name : [`string`](../../API/builtins/string.md)
12 | > **READ-ONLY**
13 |
14 | ### presets : [`string`](../../API/builtins/string.md)[]
15 | > **READ-ONLY**
16 |
17 | ### active_preset : [`integer`](../../API/builtins/integer.md)
18 | > Preset handling. 0 when when none is active (or available)
19 |
20 | ### active_preset_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
21 | > Track changes to document properties or general states by attaching listener
22 | > functions to it.
23 |
24 | ### active_preset_data : [`string`](../../API/builtins/string.md)
25 | > raw XML data of the active preset
26 |
27 | ### parameters : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)[]
28 | > **READ-ONLY**
29 |
30 | ### external_editor_available : [`boolean`](../../API/builtins/boolean.md)
31 | > **READ-ONLY** Returns whether or not the plugin provides its own custom GUI.
32 |
33 | ### external_editor_visible : [`boolean`](../../API/builtins/boolean.md)
34 | > When the plugin has no custom GUI, Renoise will create a dummy editor for it which
35 | > lists the plugin parameters.
36 | > set to true to show the editor, false to close it
37 |
38 | ### device_path : [`string`](../../API/builtins/string.md)
39 | > **READ-ONLY** Returns a string that uniquely identifies the plugin
40 | > The string can be passed into: renoise.InstrumentPluginProperties:load_plugin()
41 |
42 |
43 |
44 | ---
45 | ## Functions
46 | ### preset([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
47 | `->`[`string`](../../API/builtins/string.md)
48 |
49 | > Access to a single preset name by index. Use properties 'presets' to iterate
50 | > over all presets and to query the presets count.
51 | ### parameter([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
52 | `->`[`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)
53 |
54 | > Access to a single parameter by index. Use properties 'parameters' to iterate
55 | > over all parameters and to query the parameter count.
56 |
57 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.InstrumentDevice.md:
--------------------------------------------------------------------------------
1 | # renoise.InstrumentDevice
2 | > **Deprecated.** Use `renoise.InstrumentPluginDevice` instead.
3 |
4 |
5 |
6 |
7 | ---
8 | ## Properties
9 | ### name : [`string`](../../API/builtins/string.md)
10 | > **READ-ONLY** Device name.
11 |
12 | ### short_name : [`string`](../../API/builtins/string.md)
13 | > **READ-ONLY**
14 |
15 | ### presets : [`string`](../../API/builtins/string.md)[]
16 | > **READ-ONLY**
17 |
18 | ### active_preset : [`integer`](../../API/builtins/integer.md)
19 | > Preset handling. 0 when when none is active (or available)
20 |
21 | ### active_preset_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
22 | > Track changes to document properties or general states by attaching listener
23 | > functions to it.
24 |
25 | ### active_preset_data : [`string`](../../API/builtins/string.md)
26 | > raw XML data of the active preset
27 |
28 | ### parameters : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)[]
29 | > **READ-ONLY**
30 |
31 | ### external_editor_available : [`boolean`](../../API/builtins/boolean.md)
32 | > **READ-ONLY** Returns whether or not the plugin provides its own custom GUI.
33 |
34 | ### external_editor_visible : [`boolean`](../../API/builtins/boolean.md)
35 | > When the plugin has no custom GUI, Renoise will create a dummy editor for it which
36 | > lists the plugin parameters.
37 | > set to true to show the editor, false to close it
38 |
39 | ### device_path : [`string`](../../API/builtins/string.md)
40 | > **READ-ONLY** Returns a string that uniquely identifies the plugin
41 | > The string can be passed into: renoise.InstrumentPluginProperties:load_plugin()
42 |
43 |
44 |
45 | ---
46 | ## Functions
47 | ### preset([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
48 | `->`[`string`](../../API/builtins/string.md)
49 |
50 | > Access to a single preset name by index. Use properties 'presets' to iterate
51 | > over all presets and to query the presets count.
52 | ### parameter([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
53 | `->`[`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)
54 |
55 | > Access to a single parameter by index. Use properties 'parameters' to iterate
56 | > over all parameters and to query the parameter count.
57 |
58 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Document.ObservableNumber.md:
--------------------------------------------------------------------------------
1 | # renoise.Document.ObservableNumber
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### value : [`number`](../../API/builtins/number.md)
9 | > Read/write access to the value of an Observable.
10 |
11 |
12 |
13 | ---
14 | ## Functions
15 | ### has_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction))
16 | `->`[`boolean`](../../API/builtins/boolean.md)
17 |
18 | > Checks if the given function, method was already registered as notifier.
19 | ### add_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction))
20 | > Register a function or method as a notifier, which will be called as soon as
21 | > the observable's value changed. The passed notifier can either be a function
22 | > or a table with a function and some context (an "object") -> method.
23 | > #### examples:
24 | > ```lua
25 | > renoise.song().transport.bpm_observable:add_notifier(function()
26 | > print("BPM changed")
27 | > end)
28 | >
29 | > local my_context = { bpm_changes = 0, something_else = "bla" }
30 | > renoise.song().transport.bpm_observable:add_notifier({
31 | > my_context,
32 | > function(context)
33 | > context.bpm_changes = context.bpm_changes + 1;
34 | > print(("#BPM changes: %s"):format(context.bpm_changes));
35 | > end
36 | > })
37 | > ```
38 | ### remove_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction) | [`NotifierMemberContext`](#NotifierMemberContext))
39 | > Unregister a previously registered notifier. When only passing an object,
40 | > all notifier functions that match the given object will be removed.
41 | > This will not fire errors when no methods for the given object are attached.
42 | > Trying to unregister a function or method which wasn't registered, will resolve
43 | > into an error.
44 | ### to_string([*self*](../../API/builtins/self.md))
45 | `->`[`string`](../../API/builtins/string.md)
46 |
47 | > Serialize an object to a string.
48 | ### from_string([*self*](../../API/builtins/self.md), string : [`any`](../../API/builtins/any.md))
49 | `->`[`string`](../../API/builtins/string.md)
50 |
51 | > Assign the object's value from a string - when possible. Errors are
52 | > silently ignored.
53 |
54 |
55 |
56 | ---
57 | ## Aliases
58 | ### NotifierFunction
59 | fun()
60 |
61 |
62 | ### NotifierMemberContext
63 | [`table`](../../API/builtins/table.md) | [`userdata`](../../API/builtins/userdata.md)
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Document.ObservableString.md:
--------------------------------------------------------------------------------
1 | # renoise.Document.ObservableString
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### value : [`string`](../../API/builtins/string.md)
9 | > Read/write access to the value of an Observable.
10 |
11 |
12 |
13 | ---
14 | ## Functions
15 | ### has_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction))
16 | `->`[`boolean`](../../API/builtins/boolean.md)
17 |
18 | > Checks if the given function, method was already registered as notifier.
19 | ### add_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction))
20 | > Register a function or method as a notifier, which will be called as soon as
21 | > the observable's value changed. The passed notifier can either be a function
22 | > or a table with a function and some context (an "object") -> method.
23 | > #### examples:
24 | > ```lua
25 | > renoise.song().transport.bpm_observable:add_notifier(function()
26 | > print("BPM changed")
27 | > end)
28 | >
29 | > local my_context = { bpm_changes = 0, something_else = "bla" }
30 | > renoise.song().transport.bpm_observable:add_notifier({
31 | > my_context,
32 | > function(context)
33 | > context.bpm_changes = context.bpm_changes + 1;
34 | > print(("#BPM changes: %s"):format(context.bpm_changes));
35 | > end
36 | > })
37 | > ```
38 | ### remove_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction) | [`NotifierMemberContext`](#NotifierMemberContext))
39 | > Unregister a previously registered notifier. When only passing an object,
40 | > all notifier functions that match the given object will be removed.
41 | > This will not fire errors when no methods for the given object are attached.
42 | > Trying to unregister a function or method which wasn't registered, will resolve
43 | > into an error.
44 | ### to_string([*self*](../../API/builtins/self.md))
45 | `->`[`string`](../../API/builtins/string.md)
46 |
47 | > Serialize an object to a string.
48 | ### from_string([*self*](../../API/builtins/self.md), string : [`any`](../../API/builtins/any.md))
49 | `->`[`string`](../../API/builtins/string.md)
50 |
51 | > Assign the object's value from a string - when possible. Errors are
52 | > silently ignored.
53 |
54 |
55 |
56 | ---
57 | ## Aliases
58 | ### NotifierFunction
59 | fun()
60 |
61 |
62 | ### NotifierMemberContext
63 | [`table`](../../API/builtins/table.md) | [`userdata`](../../API/builtins/userdata.md)
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Document.ObservableBoolean.md:
--------------------------------------------------------------------------------
1 | # renoise.Document.ObservableBoolean
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### value : [`boolean`](../../API/builtins/boolean.md)
9 | > Read/write access to the value of an observable.
10 |
11 |
12 |
13 | ---
14 | ## Functions
15 | ### has_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction))
16 | `->`[`boolean`](../../API/builtins/boolean.md)
17 |
18 | > Checks if the given function, method was already registered as notifier.
19 | ### add_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction))
20 | > Register a function or method as a notifier, which will be called as soon as
21 | > the observable's value changed. The passed notifier can either be a function
22 | > or a table with a function and some context (an "object") -> method.
23 | > #### examples:
24 | > ```lua
25 | > renoise.song().transport.bpm_observable:add_notifier(function()
26 | > print("BPM changed")
27 | > end)
28 | >
29 | > local my_context = { bpm_changes = 0, something_else = "bla" }
30 | > renoise.song().transport.bpm_observable:add_notifier({
31 | > my_context,
32 | > function(context)
33 | > context.bpm_changes = context.bpm_changes + 1;
34 | > print(("#BPM changes: %s"):format(context.bpm_changes));
35 | > end
36 | > })
37 | > ```
38 | ### remove_notifier([*self*](../../API/builtins/self.md), notifier : [`NotifierFunction`](#NotifierFunction) | [`NotifierMemberContext`](#NotifierMemberContext))
39 | > Unregister a previously registered notifier. When only passing an object,
40 | > all notifier functions that match the given object will be removed.
41 | > This will not fire errors when no methods for the given object are attached.
42 | > Trying to unregister a function or method which wasn't registered, will resolve
43 | > into an error.
44 | ### to_string([*self*](../../API/builtins/self.md))
45 | `->`[`string`](../../API/builtins/string.md)
46 |
47 | > Serialize an object to a string.
48 | ### from_string([*self*](../../API/builtins/self.md), string : [`any`](../../API/builtins/any.md))
49 | `->`[`string`](../../API/builtins/string.md)
50 |
51 | > Assign the object's value from a string - when possible. Errors are
52 | > silently ignored.
53 |
54 |
55 |
56 | ---
57 | ## Aliases
58 | ### NotifierFunction
59 | fun()
60 |
61 |
62 | ### NotifierMemberContext
63 | [`table`](../../API/builtins/table.md) | [`userdata`](../../API/builtins/userdata.md)
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.PatternLine.md:
--------------------------------------------------------------------------------
1 | # renoise.PatternLine
2 |
3 |
4 |
5 | ## Constants
6 |
7 | ### EMPTY_NOTE : [`integer`](../../API/builtins/integer.md)
8 | ### NOTE_OFF : [`integer`](../../API/builtins/integer.md)
9 | ### EMPTY_INSTRUMENT : [`integer`](../../API/builtins/integer.md)
10 | ### EMPTY_VOLUME : [`integer`](../../API/builtins/integer.md)
11 | ### EMPTY_PANNING : [`integer`](../../API/builtins/integer.md)
12 | ### EMPTY_DELAY : [`integer`](../../API/builtins/integer.md)
13 | ### EMPTY_EFFECT_NUMBER : [`integer`](../../API/builtins/integer.md)
14 | ### EMPTY_EFFECT_AMOUNT : [`integer`](../../API/builtins/integer.md)
15 |
16 | ---
17 | ## Properties
18 | ### is_empty : [`boolean`](../../API/builtins/boolean.md)
19 | > **READ-ONLY**
20 |
21 | ### note_columns : [`renoise.NoteColumn`](../../API/renoise/renoise.NoteColumn.md)[]
22 | > **READ-ONLY**
23 |
24 | ### effect_columns : [`renoise.EffectColumn`](../../API/renoise/renoise.EffectColumn.md)[]
25 | > **READ-ONLY**
26 |
27 |
28 |
29 | ---
30 | ## Functions
31 | ### clear([*self*](../../API/builtins/self.md))
32 | > Clear all note and effect columns.
33 | ### copy_from([*self*](../../API/builtins/self.md), other : [`renoise.PatternLine`](../../API/renoise/renoise.PatternLine.md))
34 | > Copy contents from other_line, trashing column content.
35 | ### note_column([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
36 | `->`[`renoise.NoteColumn`](../../API/renoise/renoise.NoteColumn.md)
37 |
38 | > Access to a single note column by index. Use properties 'note_columns'
39 | > to iterate over all note columns and to query the note_column count.
40 | > This is a !lot! more efficient than calling the property:
41 | > note_columns[index] to randomly access columns. When iterating over all
42 | > columns, use pairs(note_columns).
43 | ### effect_column([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
44 | `->`[`renoise.EffectColumn`](../../API/renoise/renoise.EffectColumn.md)
45 |
46 | > Access to a single effect column by index. Use properties 'effect_columns'
47 | > to iterate over all effect columns and to query the effect_column count.
48 | > This is a !lot! more efficient than calling the property:
49 | > effect_columns[index] to randomly access columns. When iterating over all
50 | > columns, use pairs(effect_columns).
51 |
52 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Document.ObservableList.md:
--------------------------------------------------------------------------------
1 | # renoise.Document.ObservableList
2 | > Track changes to document lists by attaching listener functions to it.
3 | > NB: Notifiers will not broadcast changes made to list items, but only changes
4 | > to the lists **layout** (items got added, removed, swapped).
5 |
6 |
7 |
8 |
9 | ---
10 | ## Functions
11 | ### size([*self*](../../API/builtins/self.md))
12 | `->`[`integer`](../../API/builtins/integer.md)
13 |
14 | > Returns the number of entries of the list.
15 | ### has_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction))
16 | > Checks if the given function, method was already registered as notifier.
17 | ### add_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction))
18 | > Register a function or method as a notifier, which will be called as soon as
19 | > the observable lists layout changed. The passed notifier can either be a function
20 | > or a table with a function and some context (an "object") -> method.
21 | ### remove_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction) | [`ListNotifierMemberContext`](#ListNotifierMemberContext))
22 | > Unregister a previously registered list notifier. When only passing an object,
23 | > all notifier functions that match the given object will be removed.
24 | > This will not fire errors when no methods for the given object are attached.
25 | > Trying to unregister a function or method which wasn't registered, will resolve
26 | > into an error.
27 |
28 |
29 |
30 | ---
31 | ## Aliases
32 | ### ListElementAdded
33 | { index : [`integer`](../../API/builtins/integer.md), type : `"insert"` }
34 |
35 |
36 | ### ListElementChange
37 | [`ListElementAdded`](#ListElementAdded) | [`ListElementRemoved`](#ListElementRemoved) | [`ListElementsSwapped`](#ListElementsSwapped)
38 |
39 |
40 | ### ListElementRemoved
41 | { index : [`integer`](../../API/builtins/integer.md), type : `"remove"` }
42 |
43 |
44 | ### ListElementsSwapped
45 | { index1 : [`integer`](../../API/builtins/integer.md), index2 : [`integer`](../../API/builtins/integer.md), type : `"swap"` }
46 |
47 |
48 | ### ListNotifierFunction
49 | (change : [`ListElementChange`](#ListElementChange))
50 |
51 |
52 | ### ListNotifierMemberContext
53 | [`table`](../../API/builtins/table.md) | [`userdata`](../../API/builtins/userdata.md)
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/docs/guide/classes.md:
--------------------------------------------------------------------------------
1 | # Classes
2 |
3 | The Lua language does not have a built-in `class` construct. However, the Renoise Lua API provides simple object-oriented programming support via a global `class()` function. All Renoise API objects use such classes, and you can use them in your tools as well.
4 |
5 | See the [luabind documentation](https://www.rasterbar.com/products/luabind/docs.html#defining-classes-in-lua) for more technical information, and the examples below for how to use them.
6 |
7 | ## Examples
8 |
9 | ```lua
10 | -- abstract class
11 | class 'Animal'
12 |
13 | function Animal:__init(name)
14 | self.name = name
15 | self.can_fly = nil
16 | end
17 |
18 | function Animal:__tostring()
19 | assert(self.can_fly ~= nil, "I don't know if I can fly or not")
20 |
21 | return ("I am a %s (%s) and I %s"):format(self.name, type(self),
22 | (self.can_fly and "can fly" or "cannot fly"))
23 | end
24 |
25 |
26 | -- derived classes
27 |
28 | -- MAMMAL
29 | class 'Mammal' (Animal)
30 |
31 | function Mammal:__init(str)
32 | Animal.__init(self, str)
33 | self.can_fly = false
34 | end
35 |
36 | -- BIRD
37 | class 'Bird' (Animal)
38 |
39 | function Bird:__init(str)
40 | Animal.__init(self, str)
41 | self.can_fly = true
42 | end
43 |
44 | -- FISH
45 | class 'Fish' (Animal)
46 |
47 | function Fish:__init(str)
48 | Animal.__init(self, str)
49 | self.can_fly = false
50 | end
51 |
52 |
53 | -- run
54 |
55 | local farm = {}
56 |
57 | table.insert(farm, Mammal("cow"))
58 | table.insert(farm, Bird("sparrow"))
59 | table.insert(farm, Fish("bass"))
60 |
61 | print(("type(Mammal('cow')) -> %s"):format(type(Mammal("cow"))))
62 | print(("type(Mammal) -> %s"):format(type(Mammal)))
63 |
64 | for _,animal in ipairs(farm) do
65 | print(animal)
66 | end
67 | ```
68 |
69 | Something to keep in mind:
70 |
71 | * A constructor, `function MyClass:__init(args)`, must be defined for each class, or the class cannot be used to instantiate objects.
72 | * Class definitions are always global, so even locally defined classes will be registered globally.
73 |
74 |
75 | ## Class operators
76 |
77 | You can overload most operators in Lua for your classes. You do this by simply declaring a member function with the same name as an operator's corresponding metamethod in Lua.
78 |
79 | The operators you can overload are:
80 |
81 | * `__add` (addition)
82 | * `__sub` (subtraction)
83 | * `__mul` (multiplication)
84 | * `__div` (division)
85 | * `__pow` (exponentiation)
86 | * `__lt` (less than)
87 | * `__le` (less than or equal to)
88 | * `__eq` (equality)
89 | * `__call` (function call)
90 | * `__unm` (unary minus)
91 | * `__tostring` (serialization)
92 | * `__len` (length operator `#`)
93 |
94 | Note: `__tostring` isn't really an operator, but it's the metamethod that is called by the standard library's `tostring()` function.
95 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.InstrumentPhraseMapping.md:
--------------------------------------------------------------------------------
1 | # renoise.InstrumentPhraseMapping
2 |
3 |
4 |
5 | ## Constants
6 | ### KeyTrackingMode
7 | > ```lua
8 | > {
9 | > KEY_TRACKING_NONE: integer = 1,
10 | > KEY_TRACKING_TRANSPOSE: integer = 2,
11 | > KEY_TRACKING_OFFSET: integer = 3,
12 | > }
13 | > ```
14 |
15 |
16 | ---
17 | ## Properties
18 | ### phrase : [`renoise.InstrumentPhrase`](../../API/renoise/renoise.InstrumentPhrase.md)
19 | > Linked phrase.
20 |
21 | ### key_tracking : [`renoise.InstrumentPhraseMapping.KeyTrackingMode`](renoise.InstrumentPhraseMapping.md#KeyTrackingMode)
22 | > Phrase's key-tracking mode.
23 |
24 | ### key_tracking_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
25 | > Track changes to document properties or general states by attaching listener
26 | > functions to it.
27 |
28 | ### base_note : [`integer`](../../API/builtins/integer.md)
29 | > Range: (0 - 119) where C-4 is 48
30 |
31 | ### base_note_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
32 | > Track changes to document properties or general states by attaching listener
33 | > functions to it.
34 |
35 | ### note_range : [`integer`](../../API/builtins/integer.md)[]
36 | > Range: (0 - 119) where C-4 is 48
37 |
38 | ### note_range_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
39 | > Track changes to document properties or general states by attaching listener
40 | > functions to it.
41 |
42 | ### looping : [`boolean`](../../API/builtins/boolean.md)
43 | > Loop mode. The phrase plays as one-shot when disabled.
44 |
45 | ### looping_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
46 | > Track changes to document properties or general states by attaching listener
47 | > functions to it.
48 |
49 | ### loop_start : [`integer`](../../API/builtins/integer.md)
50 | ### loop_start_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
51 | > Track changes to document properties or general states by attaching listener
52 | > functions to it.
53 |
54 | ### loop_end : [`integer`](../../API/builtins/integer.md)
55 | ### loop_end_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
56 | > Track changes to document properties or general states by attaching listener
57 | > functions to it.
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/tests/class.lua:
--------------------------------------------------------------------------------
1 | --[[--------------------------------------------------------------------------
2 | TestClass.lua
3 | --------------------------------------------------------------------------]]--
4 |
5 | -- GlobalBaseClass
6 |
7 | class "GlobalBaseClass"
8 |
9 | function GlobalBaseClass:__init(str)
10 | self.__str = str
11 | end
12 |
13 | function GlobalBaseClass:__tostring()
14 | return self.__str
15 | end
16 |
17 |
18 | -- GlobalMyClass
19 |
20 | class "GlobalMyClass"(GlobalBaseClass)
21 |
22 | function GlobalMyClass:__init(str)
23 | GlobalBaseClass.__init(self, str)
24 | end
25 |
26 |
27 | -- namespace
28 |
29 | namespace = { }
30 |
31 |
32 | -- namespace.BaseClass
33 |
34 | class (namespace, "BaseClass")
35 |
36 | function namespace.BaseClass:__init(str)
37 | self.__str = str
38 | end
39 |
40 | function namespace.BaseClass:__tostring()
41 | return self.__str
42 | end
43 |
44 |
45 | -- namespace.MyClass(BaseClass)
46 |
47 | class (namespace, "MyClass")(namespace.BaseClass)
48 |
49 | function namespace.MyClass:__init(str)
50 | namespace.BaseClass.__init(self, str)
51 | end
52 |
53 |
54 | ------------------------------------------------------------------------------
55 | -- test
56 |
57 | do
58 |
59 | -- tools
60 |
61 | local function assert_error(statement)
62 | assert(pcall(statement) == false, "expected function error")
63 | end
64 |
65 |
66 | -- test class namespaces
67 |
68 | assert_error(function()
69 | assert(tostring(MyClass("Olla")) == "Olla")
70 | end)
71 |
72 | assert(tostring(namespace.MyClass("Olla")) == "Olla")
73 |
74 | assert(type(GlobalBaseClass) == "GlobalBaseClass class")
75 | assert(type(GlobalBaseClass()) == "GlobalBaseClass")
76 |
77 | assert(type(GlobalMyClass) == "GlobalMyClass class")
78 | assert(type(GlobalMyClass()) == "GlobalMyClass")
79 |
80 | assert(type(namespace.BaseClass) == "BaseClass class")
81 | assert(type(namespace.BaseClass()) == "BaseClass")
82 |
83 | assert(type(namespace.MyClass) == "MyClass class")
84 | assert(type(namespace.MyClass()) == "MyClass")
85 |
86 | assert(type(renoise.song()) == "Song")
87 | assert(type(renoise.Song) == "Song class")
88 |
89 | -- rprint(namespace)
90 | -- oprint(GlobalMyClass())
91 | -- oprint(namespace.MyClass())
92 |
93 |
94 | -- test class object comparison
95 |
96 | local obj1 = GlobalMyClass()
97 | local obj2 = GlobalMyClass()
98 |
99 | assert(rawequal(obj1, obj1))
100 | assert(not rawequal(obj1, obj2))
101 |
102 | assert(rawequal(renoise.song(), renoise.song()))
103 | assert(rawequal(renoise.song().tracks[1], renoise.song().tracks[1]))
104 | assert(not rawequal(renoise.song().tracks[1], renoise.song().tracks[2]))
105 | assert(not rawequal(renoise.song().tracks[1], renoise.song().instruments[1]))
106 | assert(not rawequal(renoise.song().tracks[1], obj1))
107 |
108 | end
109 |
110 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.SampleMapping.md:
--------------------------------------------------------------------------------
1 | # renoise.SampleMapping
2 | > General remarks: Sample mappings of sliced samples are read-only: can not be
3 | > modified. See `sample_mappings[].read_only`
4 |
5 |
6 |
7 |
8 | ---
9 | ## Properties
10 | ### read_only : [`boolean`](../../API/builtins/boolean.md)
11 | > **READ-ONLY** True for sliced instruments. No sample mapping properties are
12 | > allowed to be modified, but can be read.
13 |
14 | ### sample : [`renoise.Sample`](../../API/renoise/renoise.Sample.md)
15 | > Linked sample.
16 |
17 | ### layer : [`renoise.Instrument.Layer`](renoise.Instrument.md#Layer)
18 | > Mapping's layer (triggered via Note-Ons or Note-Offs?).
19 |
20 | ### layer_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
21 | > Track changes to document properties or general states by attaching listener
22 | > functions to it.
23 |
24 | ### map_velocity_to_volume : [`boolean`](../../API/builtins/boolean.md)
25 | > Mappings velocity->volume and key->pitch options.
26 |
27 | ### map_velocity_to_volume_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
28 | > Track changes to document properties or general states by attaching listener
29 | > functions to it.
30 |
31 | ### map_key_to_pitch : [`boolean`](../../API/builtins/boolean.md)
32 | ### map_key_to_pitch_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
33 | > Track changes to document properties or general states by attaching listener
34 | > functions to it.
35 |
36 | ### base_note : [`integer`](../../API/builtins/integer.md)
37 | > Range: (0-119, c-4=48)]
38 |
39 | ### base_note_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
40 | > Track changes to document properties or general states by attaching listener
41 | > functions to it.
42 |
43 | ### note_range : [`integer`](../../API/builtins/integer.md)[]
44 | > Range: (0 - 119) where C-4 is 48
45 |
46 | ### note_range_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
47 | > Track changes to document properties or general states by attaching listener
48 | > functions to it.
49 |
50 | ### velocity_range : [`integer`](../../API/builtins/integer.md)[]
51 | > Range: (0 - 127)
52 |
53 | ### velocity_range_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
54 | > Track changes to document properties or general states by attaching listener
55 | > functions to it.
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/docs/API/modules/io.md:
--------------------------------------------------------------------------------
1 | # io
2 |
3 |
4 |
5 |
6 | ---
7 | ## Functions
8 | ### exists(filename : [`string`](../../API/builtins/string.md))
9 | `->`[`boolean`](../../API/builtins/boolean.md)
10 |
11 | > Returns true when a file, folder or link at the given path and name exists
12 | ### stat(filename : [`string`](../../API/builtins/string.md))
13 | `->`result : [`Stat`](#stat)[`?`](../../API/builtins/nil.md), error : [`string`](../../API/builtins/string.md)[`?`](../../API/builtins/nil.md), error_code : [`integer`](../../API/builtins/integer.md)[`?`](../../API/builtins/nil.md)
14 |
15 | > Returns a table with status info about the file, folder or link at the given
16 | > path and name, else nil the error and the error code is returned.
17 | ### chmod(filename : [`string`](../../API/builtins/string.md), mode : [`integer`](../../API/builtins/integer.md))
18 | `->`result : [`boolean`](../../API/builtins/boolean.md), error : [`string`](../../API/builtins/string.md)[`?`](../../API/builtins/nil.md), error_code : [`integer`](../../API/builtins/integer.md)[`?`](../../API/builtins/nil.md)
19 |
20 | > Change permissions of a file, folder or link. mode is a unix permission
21 | > styled octal number (like 755 - WITHOUT a leading octal 0). Executable,
22 | > group and others flags are ignored on windows and won't fire errors
23 |
24 |
25 |
26 | ---
27 | ## Structs
28 | # Stat
29 | > return value for io.stat
30 |
31 | ---
32 | ## Properties
33 | ### dev : [`integer`](../../API/builtins/integer.md)
34 | > device number of filesystem
35 |
36 | ### ino : [`integer`](../../API/builtins/integer.md)
37 | > inode number
38 |
39 | ### mode : [`integer`](../../API/builtins/integer.md)
40 | > unix styled file permissions
41 |
42 | ### type : `"file"` | `"directory"` | `"link"` | `"socket"` | `"named pipe"` | `"char device"` | `"block device"`
43 | ### nlink : [`integer`](../../API/builtins/integer.md)
44 | > number of (hard) links to the file
45 |
46 | ### uid : [`integer`](../../API/builtins/integer.md)
47 | > numeric user ID of file's owner
48 |
49 | ### gid : [`integer`](../../API/builtins/integer.md)
50 | > numeric group ID of file's owner
51 |
52 | ### rdev : [`integer`](../../API/builtins/integer.md)
53 | > the device identifier (special files only)
54 |
55 | ### size : [`integer`](../../API/builtins/integer.md)
56 | > total size of file, in bytes
57 |
58 | ### atime : [`integer`](../../API/builtins/integer.md)
59 | > last access time in seconds since the epoch
60 |
61 | ### mtime : [`integer`](../../API/builtins/integer.md)
62 | > last modify time in seconds since the epoch
63 |
64 | ### ctime : [`integer`](../../API/builtins/integer.md)
65 | > inode change time (NOT creation time!) in seconds
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/tests/parameters.lua:
--------------------------------------------------------------------------------
1 | --[[--------------------------------------------------------------------------
2 | TestParameters.lua
3 | --------------------------------------------------------------------------]]--
4 |
5 | do
6 |
7 | ----------------------------------------------------------------------------
8 | -- shortcuts
9 |
10 | local song = renoise.song()
11 | local selected_track = song.tracks[song.selected_track_index]
12 |
13 |
14 | ----------------------------------------------------------------------------
15 | -- default track parameters & device parameter iteration
16 |
17 | local found_prefx_volume_parameter = false
18 | local found_prefx_panning_parameter = false
19 | local found_prefx_width_parameter = false
20 | local found_postfx_volume_parameter = false
21 | local found_postfx_panning_parameter = false
22 |
23 | local track_device_parameters = selected_track.devices[1].parameters
24 |
25 | for _,param in ipairs(track_device_parameters) do
26 |
27 | if param.name == selected_track.prefx_volume.name then
28 | found_prefx_volume_parameter = true
29 |
30 | elseif param.name == selected_track.prefx_panning.name then
31 | found_prefx_panning_parameter = true
32 |
33 | elseif param.name == selected_track.prefx_width.name then
34 | found_prefx_width_parameter = true
35 |
36 | elseif param.name == selected_track.postfx_volume.name then
37 | found_postfx_volume_parameter = true
38 |
39 | elseif param.name == selected_track.postfx_panning.name then
40 | found_postfx_panning_parameter = true
41 | end
42 |
43 | end
44 |
45 | assert(found_prefx_volume_parameter)
46 | assert(found_prefx_panning_parameter)
47 | assert(found_prefx_width_parameter)
48 | assert(found_postfx_volume_parameter)
49 | assert(found_postfx_panning_parameter)
50 |
51 |
52 | ----------------------------------------------------------------------------
53 | -- parameter ranges & values
54 |
55 | assert(selected_track.prefx_volume.value_min <
56 | selected_track.prefx_volume.value_max)
57 |
58 | local new_value = math.random(selected_track.prefx_width.value_min,
59 | selected_track.prefx_width.value_max)
60 |
61 | selected_track.prefx_width.value = new_value
62 | assert(selected_track.prefx_width.value == new_value)
63 |
64 | selected_track.prefx_volume.value_string = "1.0 dB"
65 | assert(selected_track.prefx_volume.value_string == "1.000 dB")
66 |
67 | selected_track.postfx_volume.value_string = "3.0 dB"
68 |
69 |
70 | ----------------------------------------------------------------------------
71 | -- parameter automation flags
72 |
73 | assert(selected_track.prefx_volume.is_automatable)
74 | assert(not selected_track.postfx_volume.is_automatable)
75 |
76 | end
77 |
78 |
79 | ------------------------------------------------------------------------------
80 | -- test finalizers
81 |
82 | collectgarbage()
83 |
84 |
85 | --[[--------------------------------------------------------------------------
86 | --------------------------------------------------------------------------]]--
87 |
--------------------------------------------------------------------------------
/tests/osc.lua:
--------------------------------------------------------------------------------
1 | --[[--------------------------------------------------------------------------
2 | TestOsc.lua
3 | --------------------------------------------------------------------------]]--
4 |
5 | do
6 |
7 | ----------------------------------------------------------------------------
8 | -- tools
9 |
10 | local function assert_error(statement)
11 | assert(pcall(statement) == false, "expected function error")
12 | end
13 |
14 | local OscMessage = renoise.Osc.Message
15 | local OscBundle = renoise.Osc.Bundle
16 |
17 |
18 | -- create & access messages
19 |
20 | local message = OscMessage("/test/message")
21 |
22 | message = OscMessage("/test/message", {
23 | {tag="s", value="string"},
24 | {tag="i", value=12},
25 | {tag="b", value="blob"}
26 | })
27 |
28 | assert(message.pattern == "/test/message")
29 | assert(message.binary_data:find("/test/message") == 1)
30 | assert(#message.binary_data > #message.pattern)
31 |
32 | assert(#message.arguments == 3)
33 | assert(message.arguments[1].tag == "s")
34 | assert(message.arguments[1].value == "string")
35 | assert(message.arguments[2].tag == "i")
36 | assert(message.arguments[2].value == 12)
37 | assert(message.arguments[3].tag == "b")
38 | assert(message.arguments[3].value == "blob")
39 |
40 | -- unknown tag
41 | assert_error(function()
42 | OscMessage("/test/message", { {tag="X"} })
43 | end)
44 | -- missing tag value
45 | assert_error(function()
46 | OscMessage("/test/message", { {tag="i"} })
47 | end)
48 | -- bogus tag value
49 | assert_error(function()
50 | OscMessage("/test/message", { {tag="i", value="string"} })
51 | end)
52 |
53 |
54 | -- create & access bundles
55 |
56 | local timetag = 99
57 | local bundle = OscBundle(timetag, message)
58 | assert(#bundle.elements == 1)
59 |
60 | bundle = OscBundle(timetag, {OscMessage("/bla"), message})
61 | assert(#bundle.elements == 2)
62 | assert(type(bundle.elements[1]) == "Message")
63 | assert(type(bundle.elements[2]) == "Message")
64 | assert(bundle.elements[2].arguments[2].tag == "i")
65 | assert(bundle.elements[2].arguments[2].value == 12)
66 |
67 |
68 | -- binary data -> bundles or messages
69 |
70 | local result, error = renoise.Osc.from_binary_data("garbage")
71 | assert(not result and error)
72 |
73 | result, error = renoise.Osc.from_binary_data(bundle.binary_data)
74 | assert(result and not error)
75 | assert(type(result) == "Bundle")
76 | assert(result.timetag == bundle.timetag)
77 | assert(result.elements[2].arguments[2].tag == "i")
78 | assert(result.elements[2].arguments[2].value == 12)
79 |
80 |
81 | result, error = renoise.Osc.from_binary_data(message.binary_data)
82 | assert(result and not error)
83 | assert(type(result) == "Message")
84 | assert(result.arguments[2].tag == "i")
85 | assert(result.arguments[2].value == 12)
86 |
87 | end
88 |
89 |
90 | ------------------------------------------------------------------------------
91 | -- test finalizers
92 |
93 | collectgarbage()
94 |
95 |
96 | --[[--------------------------------------------------------------------------
97 | --------------------------------------------------------------------------]]--
98 |
99 |
--------------------------------------------------------------------------------
/docs/start/development.md:
--------------------------------------------------------------------------------
1 | # Setting up your development environment
2 |
3 | To start developing Scripts in Renoise, use the following two menu entries inside the `Tools` menu on the top bar.
4 |
5 | * `Scripting Terminal & Editor` - This will open the debugging console used to test things and see your tool's output
6 | * `Reload All Tools` - This will force a reload of all installed and running tools. It can be useful when adding new tools by hand or when changing them.
7 |
8 | > [!NOTE]
9 | > In previous versions of Renoise it was necessary to launch the Renoise executable with the `--scripting-dev` argument to see the above mentioned menue entries.
10 |
11 | ## Lua
12 |
13 | Tools in Renoise are written using the [Lua programming language](https://www.lua.org/). Lua is a dynamic language with a friendly syntax and good performance. While Renoise itself is written in C++, it has an [API](https://en.wikipedia.org/wiki/API) layer that exposes all sorts of aspects of the tracker so that tools can implement new functionality without the dangers of crashing Renoise itself or having to worry about low level programming challenges.
14 |
15 | > [!NOTE]
16 | > Teaching you programming is out of the scope of this guide but you can check out the book [Programming in Lua](https://www.lua.org/pil/contents.html) to get a complete overview of the language. That said, you will probably be able to pick up a lot of things just by reading through this guide and checking out the examples. If you are the kind of person who learns best by doing stuff, getting straight into tinkering might be right up your alley.
17 |
18 | ### Language Server
19 |
20 | Luckily Lua has a language server called [LuaLS](https://github.com/LuaLS/lua-language-server) which - when paired with the [definitions for the Renoise API](https://github.com/renoise/definitions/) - can help you write code by providing useful hints about functions and variables, autocompletion and code diagnostics. You can even annotate your own code to keep things more explicit and well documented. While you can absolutely write Lua and create tools without any of this, we highly recommend setting it up.
21 |
22 | If you are using [VSCode](https://code.visualstudio.com/) you will have to do three things
23 |
24 | * Install the [Lua extension by sumneko](https://marketplace.visualstudio.com/items?itemName=sumneko.lua)
25 | * Download the [Renoise API definitions from Github](https://github.com/renoise/definitions/)
26 | * Configure VSCode so that LuaLS knows where to find the definition files. For this you will have to either put this into your [workspace's settings](https://code.visualstudio.com/docs/editor/workspaces#_singlefolder-workspace-settings) in your project folder (as `.vscode/settings.json`), or the global *User Settings JSON* file. Make sure to fill the paths below according to where you've extracted the previously downloaded definitions.
27 |
28 | ```json
29 | {
30 | "Lua.workspace.library": [ "PATH/TO/RENOISE_DEFINITION_FOLDER" ],
31 | "Lua.runtime.plugin": "PATH/TO/RENOISE_DEFINITION_FOLDER/plugin.lua"
32 | }
33 | ```
34 |
35 | > For configuring other editors, you can check out the [official docs about installation](https://luals.github.io/#install)
36 |
--------------------------------------------------------------------------------
/docs/API/modules/os.md:
--------------------------------------------------------------------------------
1 | # os
2 |
3 |
4 |
5 |
6 | ---
7 | ## Functions
8 | ### `platform()`
9 | `->``"LINUX"` | `"MACINTOSH"` | `"WINDOWS"`
10 |
11 | > Returns the platform the script is running on:
12 | >
13 | > ```lua
14 | > return #1:
15 | > | "WINDOWS"
16 | > | "MACINTOSH"
17 | > | "LINUX"
18 | > ```
19 | ### `currentdir()`
20 | `->`path : [`string`](../../API/builtins/string.md)
21 |
22 | > Returns the current working dir. Will always be the scripts directory
23 | > when executing a script from a file
24 | ### dirnames(path : [`any`](../../API/builtins/any.md))
25 | `->`paths : [`string`](../../API/builtins/string.md)[]
26 |
27 | > Returns a list of directory names (names, not full paths) for the given
28 | > parent directory. Passed directory must be valid, or an error will be thrown.
29 | ### filenames(path : [`string`](../../API/builtins/string.md), file_extensions : [`string`](../../API/builtins/string.md)[][`?`](../../API/builtins/nil.md))
30 | `->`paths : [`string`](../../API/builtins/string.md)[]
31 |
32 | > Returns a list file names (names, not full paths) for the given
33 | > parent directory. Second optional argument is a list of file extensions that
34 | > should be searched for, like {"*.wav", "*.txt"}. By default all files are
35 | > matched. The passed directory must be valid, or an error will be thrown.
36 | ### mkdir(path : [`string`](../../API/builtins/string.md))
37 | `->`[`boolean`](../../API/builtins/boolean.md)[`?`](../../API/builtins/nil.md), [`string`](../../API/builtins/string.md)[`?`](../../API/builtins/nil.md)
38 |
39 | > Creates a new directory. mkdir can only create one new sub directory at the
40 | > same time. If you need to create more than one sub dir, call mkdir multiple
41 | > times. Returns true if the operation was successful; in case of error, it
42 | > returns nil plus an error string.
43 | ### move(src : [`string`](../../API/builtins/string.md), dest : [`string`](../../API/builtins/string.md))
44 | `->`[`boolean`](../../API/builtins/boolean.md)[`?`](../../API/builtins/nil.md), [`string`](../../API/builtins/string.md)[`?`](../../API/builtins/nil.md)
45 |
46 | > Moves a file or a directory from path 'src' to 'dest'. Unlike 'os.rename'
47 | > this also supports moving a file from one file system to another one. Returns
48 | > true if the operation was successful; in case of error, it returns nil plus
49 | > an error string.
50 | ### tmpname(extension : [`string`](../../API/builtins/string.md)[`?`](../../API/builtins/nil.md))
51 | `->`[`string`](../../API/builtins/string.md)
52 |
53 | > Returns a string with a file name that can be used for a temporary file.
54 | >
55 | > [View documents](http://www.lua.org/manual/5.4/manual.html#pdf-os.tmpname)
56 | ### `clock()`
57 | `->`[`number`](../../API/builtins/number.md)
58 |
59 | > Returns an approximation of the amount in seconds of CPU time used by the program.
60 | >
61 | > [View documents](http://www.lua.org/manual/5.4/manual.html#pdf-os.clock)
62 | ### `exit()`
63 | > Calls the ISO C function `exit` to terminate the host program.
64 | >
65 | > [View documents](http://www.lua.org/manual/5.4/manual.html#pdf-os.exit)
66 |
67 |
--------------------------------------------------------------------------------
/docs/API/modules/table.md:
--------------------------------------------------------------------------------
1 | # table
2 |
3 |
4 |
5 |
6 | ---
7 | ## Functions
8 | ### create(t : [`table`](../../API/builtins/table.md)[`?`](../../API/builtins/nil.md))
9 | `->`[`table`](../../API/builtins/table.md) | tablelib
10 |
11 | > Create a new, or convert an exiting table to an object that uses the global
12 | > 'table.XXX' functions as methods, just like strings in Lua do.
13 | > #### examples:
14 | > ```lua
15 | > t = table.create(); t:insert("a"); rprint(t) -> [1] = a;
16 | > t = table.create{1,2,3}; print(t:concat("|")); -> "1|2|3";
17 | > ```
18 | ### is_empty(t : [`table`](../../API/builtins/table.md))
19 | `->`[`boolean`](../../API/builtins/boolean.md)
20 |
21 | > Returns true when the table is empty, else false and will also work
22 | > for non indexed tables
23 | > #### examples:
24 | > ```lua
25 | > t = {}; print(table.is_empty(t)); -> true;
26 | > t = {66}; print(table.is_empty(t)); -> false;
27 | > t = {["a"] = 1}; print(table.is_empty(t)); -> false;
28 | ### count(t : [`table`](../../API/builtins/table.md))
29 | > Count the number of items of a table, also works for non index
30 | > based tables (using pairs).
31 | > #### examples:
32 | > ```lua
33 | > t = {["a"]=1, ["b"]=1}; print(table.count(t)) --> 2
34 | > ```
35 | ### find(t : [`table`](../../API/builtins/table.md), value : [`any`](../../API/builtins/any.md), start_index : [`integer`](../../API/builtins/integer.md)[`?`](../../API/builtins/nil.md))
36 | `->`key_or_nil : [`string`](../../API/builtins/string.md) | [`number`](../../API/builtins/number.md)[`?`](../../API/builtins/nil.md)
37 |
38 | > Find first match of *value* in the given table, starting from element
39 | > number *start_index*.
40 | > Returns the first *key* that matches the value or nil
41 | > #### examples:
42 | > ```lua
43 | > t = {"a", "b"}; table.find(t, "a") --> 1
44 | > t = {a=1, b=2}; table.find(t, 2) --> "b"
45 | > t = {"a", "b", "a"}; table.find(t, "a", 2) --> "3"
46 | > t = {"a", "b"}; table.find(t, "c") --> nil
47 | > ```
48 | ### keys(t : [`table`](../../API/builtins/table.md))
49 | `->`[`table`](../../API/builtins/table.md)
50 |
51 | > Return an indexed table of all keys that are used in the table.
52 | > #### examples:
53 | > ```lua
54 | > t = {a="aa", b="bb"}; rprint(table.keys(t)); --> "a", "b"
55 | > t = {"a", "b"}; rprint(table.keys(t)); --> 1, 2
56 | > ```
57 | ### values(t : [`table`](../../API/builtins/table.md))
58 | `->`[`table`](../../API/builtins/table.md)
59 |
60 | > Return an indexed table of all values that are used in the table
61 | > #### examples:
62 | > ```lua
63 | > t = {a="aa", b="bb"}; rprint(table.values(t)); --> "aa", "bb"
64 | > t = {"a", "b"}; rprint(table.values(t)); --> "a", "b"
65 | > ```
66 | ### copy(t : [`table`](../../API/builtins/table.md))
67 | `->`[`table`](../../API/builtins/table.md)
68 |
69 | > Copy the metatable and all first level elements of the given table into a
70 | > new table. Use table.rcopy to do a recursive copy of all elements
71 | ### rcopy(t : [`table`](../../API/builtins/table.md))
72 | `->`[`table`](../../API/builtins/table.md)
73 |
74 | > Deeply copy the metatable and all elements of the given table recursively
75 | > into a new table - create a clone with unique references.
76 | ### clear(t : [`table`](../../API/builtins/table.md))
77 | > Recursively clears and removes all table elements.
78 |
79 |
--------------------------------------------------------------------------------
/docs/guide/midi.md:
--------------------------------------------------------------------------------
1 | # MIDI
2 |
3 | The Renoise API allows you to access raw MIDI input and output devices from within your tool. You can use this to add features like bi-directional MIDI controller support.
4 |
5 | See the [`renoise.Midi`](../API/renoise/renoise.Midi.md) API for more details.
6 |
7 | ## MIDI Input Listener (Function Callback)
8 |
9 | ```lua
10 | -- NOTE: The MIDI device will be closed when this local variable gets garbage
11 | -- collected. Make it global or assign it to a table that is held globally
12 | -- to keep it active.
13 | local midi_device = nil
14 |
15 | local inputs = renoise.Midi.available_input_devices()
16 | if not table.is_empty(inputs) then
17 | -- Use the first available device in this example
18 | local device_name = inputs[1]
19 |
20 | local function midi_callback(message)
21 | assert(#message == 3)
22 | assert(message[1] >= 0 and message[1] <= 0xff)
23 | assert(message[2] >= 0 and message[2] <= 0xff)
24 | assert(message[3] >= 0 and message[3] <= 0xff)
25 |
26 | print(("%s: got MIDI %X %X %X"):format(device_name,
27 | message[1], message[2], message[3]))
28 | end
29 |
30 | -- The sysex callback is an optional second argument.
31 | midi_device = renoise.Midi.create_input_device(
32 | device_name, midi_callback)
33 |
34 | -- To stop listening, call: midi_device:close()
35 | end
36 | ```
37 |
38 | ## MIDI Input and SysEx Listener (Class Callbacks)
39 |
40 | ```lua
41 | class "MidiDumper"
42 | function MidiDumper:__init(device_name)
43 | self.device_name = device_name
44 | self.device = nil
45 | end
46 |
47 | function MidiDumper:start()
48 | self.device = renoise.Midi.create_input_device(
49 | self.device_name,
50 | { self, self.midi_callback },
51 | { self, self.sysex_callback }
52 | )
53 | end
54 |
55 | function MidiDumper:stop()
56 | if self.device then
57 | self.device:close()
58 | self.device = nil
59 | end
60 | end
61 |
62 | function MidiDumper:midi_callback(message)
63 | print(("%s: MidiDumper got MIDI %X %X %X"):format(
64 | self.device_name, message[1], message[2], message[3]))
65 | end
66 |
67 | function MidiDumper:sysex_callback(message)
68 | print(("%s: MidiDumper got SYSEX with %d bytes"):format(
69 | self.device_name, #message))
70 | end
71 |
72 | -- NOTE: The MIDI device will be closed when this dumper object gets garbage
73 | -- collected. Make it global or assign it to a table that is held globally
74 | -- to keep it active.
75 | local midi_dumper = nil
76 |
77 | local inputs = renoise.Midi.available_input_devices()
78 |
79 | if not table.is_empty(inputs) then
80 | -- Use the first available device in this example
81 | local device_name = inputs[1]
82 |
83 | midi_dumper = MidiDumper(device_name)
84 | -- This will dump MIDI messages until midi_dumper:stop() is called
85 | -- or the MidiDumper object is garbage collected.
86 | midi_dumper:start()
87 | end
88 | ```
89 |
90 | ## MIDI Output
91 |
92 | ```lua
93 | local outputs = renoise.Midi.available_output_devices()
94 | if not table.is_empty(outputs) then
95 | local device_name = outputs[1]
96 | local midi_device = renoise.Midi.create_output_device(device_name)
97 |
98 | -- Note On
99 | midi_device:send({ 0x90, 0x10, 0x7F })
100 | -- SysEx (MMC Start)
101 | midi_device:send({ 0xF0, 0x7F, 0x00, 0x06, 0x02, 0xF7 })
102 |
103 | -- We no longer need the device in this example, so close it.
104 | midi_device:close()
105 | end
106 | ```
107 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Osc.Message.md:
--------------------------------------------------------------------------------
1 | # renoise.Osc.Message
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### pattern : [`string`](../../API/builtins/string.md)
9 | > **READ-ONLY** The message pattern (e.g. "/renoise/transport/start")
10 |
11 | ### arguments : [`OscValue`](#oscvalue)[]
12 | > **READ-ONLY** Table of `{tag="X", value=SomeValue}` that represents the
13 | > message arguments. See `renoise.Osc.Message.create` for more info.
14 |
15 | ### binary_data : [`string`](../../API/builtins/string.md)
16 | > **READ-ONLY** Raw binary representation of the message, as needed when e.g.
17 | > sending the message over the network through sockets.
18 |
19 |
20 |
21 |
22 |
23 | ---
24 | ## Structs
25 | # OscValue
26 | > `tag` is a standard OSC type tag. `value` is the arguments value expressed
27 | > by a Lua type. The value must be convertible to the specified tag, which
28 | > means, you cannot for example specify an "i" (integer) as type and then pass
29 | > a string as the value. Use a number value instead. Not all tags require a
30 | > value, like the T,F boolean tags. Then a `value` field should not be
31 | > specified. For more info, see: http://opensoundcontrol.org/spec-1_0
32 |
33 | ---
34 | ## Properties
35 | ### tag : [`OscTag`](#OscTag)
36 | ### value : [`boolean`](../../API/builtins/boolean.md) | [`string`](../../API/builtins/string.md) | [`number`](../../API/builtins/number.md)
37 |
38 |
39 |
40 |
41 | ---
42 | ## Aliases
43 | ### OscTag
44 | `"F"` | `"I"` | `"N"` | `"S"` | `"T"` | `"b"` | `"c"` | `"d"` | `"f"` | `"h"` | `"i"` | `"m"` | `"r"` | `"s"` | `"t"`
45 | > ```lua
46 | > OscTag:
47 | > | "i" -- int32
48 | > | "f" -- float32
49 | > | "s" -- OSC-string
50 | > | "b" -- OSC-blob (raw string)
51 | > | "h" -- 64 bit big-endian two's complement integer
52 | > | "t" -- OSC-timetag
53 | > | "d" -- 64 bit ("double") IEEE 754 floating point number
54 | > | "S" -- Alternate type represented as an OSC-string
55 | > | "c" -- An ascii character, sent as 32 bits
56 | > | "r" -- 32 bit RGBA color
57 | > | "m" -- 4 byte MIDI message. Bytes from MSB to LSB are: port id, status byte, data1, data2
58 | > | "T" -- True. No value needs to be specified.
59 | > | "F" -- False. No value needs to be specified.
60 | > | "N" -- Nil. No value needs to be specified.
61 | > | "I" -- Infinitum. No value needs to be specified.
62 | > ```
63 |
64 |
65 |
66 |
67 |
68 |
69 | ---
70 | ## Aliases
71 | ### OscTag
72 | `"F"` | `"I"` | `"N"` | `"S"` | `"T"` | `"b"` | `"c"` | `"d"` | `"f"` | `"h"` | `"i"` | `"m"` | `"r"` | `"s"` | `"t"`
73 | > ```lua
74 | > OscTag:
75 | > | "i" -- int32
76 | > | "f" -- float32
77 | > | "s" -- OSC-string
78 | > | "b" -- OSC-blob (raw string)
79 | > | "h" -- 64 bit big-endian two's complement integer
80 | > | "t" -- OSC-timetag
81 | > | "d" -- 64 bit ("double") IEEE 754 floating point number
82 | > | "S" -- Alternate type represented as an OSC-string
83 | > | "c" -- An ascii character, sent as 32 bits
84 | > | "r" -- 32 bit RGBA color
85 | > | "m" -- 4 byte MIDI message. Bytes from MSB to LSB are: port id, status byte, data1, data2
86 | > | "T" -- True. No value needs to be specified.
87 | > | "F" -- False. No value needs to be specified.
88 | > | "N" -- Nil. No value needs to be specified.
89 | > | "I" -- Infinitum. No value needs to be specified.
90 | > ```
91 |
92 |
93 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.NoteColumn.md:
--------------------------------------------------------------------------------
1 | # renoise.NoteColumn
2 | > A single note column in a pattern line.
3 | >
4 | > General remarks: instrument columns are available for lines in phrases
5 | > but are ignored. See renoise.InstrumentPhrase for detail.
6 | >
7 | > Access note column properties either by values (numbers) or by strings.
8 | > The string representation uses exactly the same notation as you see
9 | > them in Renoise's pattern or phrase editor.
10 |
11 |
12 |
13 |
14 | ---
15 | ## Properties
16 | ### is_empty : [`boolean`](../../API/builtins/boolean.md)
17 | > **READ-ONLY** True, when all note column properties are empty.
18 |
19 | ### is_selected : [`boolean`](../../API/builtins/boolean.md)
20 | > **READ-ONLY** True, when this column is selected in the pattern or phrase
21 | > editors current pattern.
22 |
23 | ### note_value : [`integer`](../../API/builtins/integer.md)
24 | > Range: (0-119) or 120=Off or 121=Empty
25 |
26 | ### note_string : [`string`](../../API/builtins/string.md)
27 | > Range: (\'C-0\'-\'G-9\') or \'OFF\' or \'---\'
28 |
29 | ### instrument_value : [`integer`](../../API/builtins/integer.md)
30 | > Range: (0-254), 255==Empty
31 |
32 | ### instrument_string : [`string`](../../API/builtins/string.md)
33 | > Range: (\'00\'-\'FE\') or \'..\'
34 |
35 | ### volume_value : [`integer`](../../API/builtins/integer.md)
36 | > Range: (0-127) or 255==Empty when column value is <= 0x80 or is 0xFF,
37 | > i.e. to specify a volume value.
38 | >
39 | > Range: (0-65535) in the form 0x0000xxyy where xx=effect char 1 and yy=effect char 2,
40 | > when column value is > 0x80, i.e. to specify an effect.
41 |
42 | ### volume_string : [`string`](../../API/builtins/string.md)
43 | > Range(\'00\'-\'ZF\') or \'..\'
44 |
45 | ### panning_value : [`integer`](../../API/builtins/integer.md)
46 | > Range: (0-127) or 255==Empty when column value is <= 0x80 or is 0xFF,
47 | > i.e. to specify a pan value.
48 | >
49 | > Range: (0-65535) in the form 0x0000xxyy where xx=effect char 1 and yy=effect char 2,
50 | > when column value is > 0x80, i.e. to specify an effect.
51 |
52 | ### panning_string : [`string`](../../API/builtins/string.md)
53 | > Range: (\'00'-\'ZF\') or \'..\'
54 |
55 | ### delay_value : [`integer`](../../API/builtins/integer.md)
56 | > Range: (0-255)
57 |
58 | ### delay_string : [`string`](../../API/builtins/string.md)
59 | > Range: (\'00'-\'FF\') or \'..\'
60 |
61 | ### effect_number_value : [`integer`](../../API/builtins/integer.md)
62 | > Range: (0-65535) in the form 0x0000xxyy where xx=effect char 1 and yy=effect char 2
63 |
64 | ### effect_number_string : [`string`](../../API/builtins/string.md)
65 | > Range: (\'00\'-\'ZZ\')
66 |
67 | ### effect_amount_value : [`integer`](../../API/builtins/integer.md)
68 | > Range: (0-255)
69 |
70 | ### effect_amount_string : [`string`](../../API/builtins/string.md)
71 | > Range: (\'00\' - \'FF\')
72 |
73 |
74 |
75 | ---
76 | ## Functions
77 | ### clear([*self*](../../API/builtins/self.md))
78 | > Clear the note column.
79 | ### copy_from([*self*](../../API/builtins/self.md), other : [`renoise.NoteColumn`](../../API/renoise/renoise.NoteColumn.md))
80 | > Copy the column's content from another column.
81 |
82 |
--------------------------------------------------------------------------------
/tests/notifiers.lua:
--------------------------------------------------------------------------------
1 | --[[--------------------------------------------------------------------------
2 | TestNotifiers.lua
3 | --------------------------------------------------------------------------]]--
4 |
5 | do
6 |
7 | ----------------------------------------------------------------------------
8 | -- tools
9 |
10 | local function assert_error(statement)
11 | assert(pcall(statement) == false, "expected function error")
12 | end
13 |
14 |
15 | ----------------------------------------------------------------------------
16 | -- setup
17 |
18 | -- SomeClass
19 |
20 | class "SomeClass"
21 | function SomeClass:__init(name)
22 | self.name = name
23 | end
24 |
25 | function SomeClass:BpmNotifier()
26 | local bpm = renoise.song().transport.bpm
27 | notifier_print("BPM changed to " .. bpm ..
28 | " in Object: '" .. self.name .. "'")
29 | end
30 |
31 |
32 | -- function
33 |
34 | local function BpmNotifierFunction()
35 | local bpm = renoise.song().transport.bpm
36 | notifier_print("BPM changed to " .. bpm ..
37 | " in global Function")
38 | end
39 |
40 |
41 | -- setup
42 |
43 | local bpm_observable = renoise.song().transport.bpm_observable
44 | local tpl_observable = renoise.song().transport.tpl_observable
45 |
46 | local obj1 = SomeClass("Obj1")
47 | local obj2 = SomeClass("Obj2")
48 |
49 |
50 | ----------------------------------------------------------------------------
51 | -- expect notifications
52 |
53 | notifier_print = function (message) --[[ do nothing --]] end
54 |
55 | bpm_observable:add_notifier(SomeClass.BpmNotifier, obj1)
56 | bpm_observable:add_notifier(SomeClass.BpmNotifier, obj2)
57 | bpm_observable:add_notifier(BpmNotifierFunction)
58 |
59 | assert(bpm_observable:has_notifier(SomeClass.BpmNotifier, obj1))
60 | assert(bpm_observable:has_notifier(obj2, SomeClass.BpmNotifier))
61 | assert(bpm_observable:has_notifier(BpmNotifierFunction))
62 | assert(not bpm_observable:has_notifier(function() end))
63 |
64 | tpl_observable:add_notifier(BpmNotifierFunction)
65 | tpl_observable:remove_notifier(BpmNotifierFunction)
66 |
67 | -- already added notifier
68 | assert_error(function()
69 | bpm_observable:add_notifier(SomeClass.BpmNotifier, obj1)
70 | end)
71 | assert_error(function()
72 | bpm_observable:add_notifier(BpmNotifierFunction)
73 | end)
74 |
75 | local transport = renoise.song().transport
76 | local old_bpm = transport.bpm
77 | if transport.bpm == 999 then
78 | transport.bpm = transport.bpm - 1
79 | else
80 | transport.bpm = transport.bpm + 1
81 | end
82 |
83 |
84 | ----------------------------------------------------------------------------
85 | -- expect no notifications
86 |
87 | notifier_print = function (message) error(message) end
88 |
89 | bpm_observable:remove_notifier(SomeClass.BpmNotifier, obj1)
90 | bpm_observable:remove_notifier(SomeClass.BpmNotifier, obj2)
91 | bpm_observable:remove_notifier(BpmNotifierFunction)
92 |
93 | -- already removed notifiers
94 | assert_error(function()
95 | bpm_observable:remove_notifier(SomeClass.BpmNotifier, obj1)
96 | end)
97 | assert_error(function()
98 | bpm_observable:remove_notifier(BpmNotifierFunction)
99 | end)
100 |
101 | transport.bpm = old_bpm
102 |
103 | end
104 |
105 |
106 | ------------------------------------------------------------------------------
107 | -- test finalizers
108 |
109 | collectgarbage()
110 |
111 |
112 | --[[--------------------------------------------------------------------------
113 | --------------------------------------------------------------------------]]--
114 |
115 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.DeviceParameter.md:
--------------------------------------------------------------------------------
1 | # renoise.DeviceParameter
2 | > A single parameter within an audio DSP effect (renoise.AudioDevice)
3 |
4 |
5 |
6 | ## Constants
7 | ### Polarity
8 | > ```lua
9 | > {
10 | > POLARITY_UNIPOLAR: integer = 1,
11 | > POLARITY_BIPOLAR: integer = 2,
12 | > }
13 | > ```
14 |
15 |
16 | ---
17 | ## Properties
18 | ### name : [`string`](../../API/builtins/string.md)
19 | > **READ-ONLY**
20 |
21 | ### name_observable : [`renoise.Document.ObservableString`](../../API/renoise/renoise.Document.ObservableString.md)
22 | ### polarity : [`renoise.DeviceParameter.Polarity`](renoise.DeviceParameter.md#Polarity)
23 | > **READ-ONLY**
24 |
25 | ### value_min : [`number`](../../API/builtins/number.md)
26 | > **READ-ONLY**
27 |
28 | ### value_max : [`number`](../../API/builtins/number.md)
29 | > **READ-ONLY**
30 |
31 | ### value_quantum : [`number`](../../API/builtins/number.md)
32 | > **READ-ONLY**
33 |
34 | ### value_default : [`number`](../../API/builtins/number.md)
35 | > **READ-ONLY**
36 |
37 | ### time_quantum : [`number`](../../API/builtins/number.md)
38 | > **READ-ONLY**
39 |
40 | ### is_automatable : [`boolean`](../../API/builtins/boolean.md)
41 | > **READ-ONLY**
42 |
43 | ### is_automated : [`boolean`](../../API/builtins/boolean.md)
44 | > **READ-ONLY** Is automated. Not valid for parameters of instrument devices.
45 |
46 | ### is_automated_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
47 | > Track changes to document properties or general states by attaching listener
48 | > functions to it.
49 |
50 | ### is_midi_mapped : [`boolean`](../../API/builtins/boolean.md)
51 | > **READ-ONLY** Parameter has a custom MIDI mapping in the current song.
52 |
53 | ### is_midi_mapped_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
54 | > Track changes to document properties or general states by attaching listener
55 | > functions to it.
56 |
57 | ### show_in_mixer : [`boolean`](../../API/builtins/boolean.md)
58 | > Show in mixer. Not valid for parameters of instrument devices.
59 |
60 | ### show_in_mixer_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
61 | > Track changes to document properties or general states by attaching listener
62 | > functions to it.
63 |
64 | ### value : [`number`](../../API/builtins/number.md)
65 | > value in Range: (value_min - value_max)
66 |
67 | ### value_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
68 | > Track changes to document properties or general states by attaching listener
69 | > functions to it.
70 |
71 | ### value_string : [`string`](../../API/builtins/string.md)
72 | ### value_string_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
73 | > Track changes to document properties or general states by attaching listener
74 | > functions to it.
75 |
76 |
77 |
78 | ---
79 | ## Functions
80 | ### record_value([*self*](../../API/builtins/self.md), value : [`number`](../../API/builtins/number.md))
81 | > Set a new value and write automation when the MIDI mapping
82 | > "record to automation" option is set. Only works for parameters
83 | > of track devices, not for instrument devices.
84 |
85 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.InstrumentMidiOutputProperties.md:
--------------------------------------------------------------------------------
1 | # renoise.InstrumentMidiOutputProperties
2 |
3 |
4 |
5 | ## Constants
6 | ### Type
7 | > ```lua
8 | > {
9 | > TYPE_EXTERNAL: integer = 1,
10 | > TYPE_LINE_IN_RET: integer = 2,
11 | > TYPE_INTERNAL: integer = 3,
12 | > }
13 | > ```
14 |
15 |
16 | ---
17 | ## Properties
18 | ### instrument_type : [`renoise.InstrumentMidiOutputProperties.Type`](renoise.InstrumentMidiOutputProperties.md#Type)
19 | > Note: ReWire device always start with "ReWire: " in the device_name and
20 | > will always ignore the instrument_type and channel properties. MIDI
21 | > channels are not configurable for ReWire MIDI, and instrument_type will
22 | > always be "TYPE_INTERNAL" for ReWire devices.
23 |
24 | ### instrument_type_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
25 | > Track changes to document properties or general states by attaching listener
26 | > functions to it.
27 |
28 | ### device_name : [`string`](../../API/builtins/string.md)
29 | > When setting new devices, device names must be one of:
30 | > renoise.Midi.available_output_devices.
31 | > Devices are automatically opened when needed. To close a device, set its name
32 | > to "", e.g. an empty string.
33 |
34 | ### device_name_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
35 | > Track changes to document properties or general states by attaching listener
36 | > functions to it.
37 |
38 | ### channel : [`integer`](../../API/builtins/integer.md)
39 | > Range: (1 - 16)
40 |
41 | ### channel_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
42 | > Track changes to document properties or general states by attaching listener
43 | > functions to it.
44 |
45 | ### transpose : [`integer`](../../API/builtins/integer.md)
46 | > Range: (-120 - 120)
47 |
48 | ### transpose_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
49 | > Track changes to document properties or general states by attaching listener
50 | > functions to it.
51 |
52 | ### program : [`integer`](../../API/builtins/integer.md)
53 | > Range: (1 - 128) 0 = OFF
54 |
55 | ### program_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
56 | > Track changes to document properties or general states by attaching listener
57 | > functions to it.
58 |
59 | ### bank : [`integer`](../../API/builtins/integer.md)
60 | > Range: (1 - 65536) 0 = OFF
61 |
62 | ### bank_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
63 | > Track changes to document properties or general states by attaching listener
64 | > functions to it.
65 |
66 | ### delay : [`integer`](../../API/builtins/integer.md)
67 | > Range: (0 - 100)
68 |
69 | ### delay_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
70 | > Track changes to document properties or general states by attaching listener
71 | > functions to it.
72 |
73 | ### duration : [`integer`](../../API/builtins/integer.md)
74 | > Range: (1 - 8000) 8000 = INF
75 |
76 | ### duration_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
77 | > Track changes to document properties or general states by attaching listener
78 | > functions to it.
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/docs/API/README.md:
--------------------------------------------------------------------------------
1 | # Renoise Lua API Overview
2 |
3 | The 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.
4 |
5 | A note about the general API design:
6 |
7 | - 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.
8 |
9 | - 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...
10 |
11 | Some notes about the documentation, and a couple of tips:
12 |
13 | - 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()`
14 |
15 | - 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.
16 |
17 | - 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. ;)
18 |
19 | - 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**`.
20 |
21 | - 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.
22 |
23 | - *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.
24 |
25 | A small example using bpm:
26 | ```lua
27 | renoise.song().transport.bpm_observable:add_notifier(function()
28 | print("bpm changed")
29 | end)
30 |
31 | -- will print "bpm changed", but only if the bpm was not 120 before
32 | renoise.song().transport.bpm = 120
33 | ```
34 |
35 | 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...)
36 |
37 | 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.
38 |
39 | - 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)`.
--------------------------------------------------------------------------------
/docs/guide/osc.md:
--------------------------------------------------------------------------------
1 | # OSC
2 |
3 | The Renoise API allows you to create sockets and provides tools to send and receive Open Sound Control (OSC) data. This enables you to connect your tools to other OSC servers and clients, offering an alternative to MIDI for controlling and interacting with devices like a [monome](https://monome.org/docs/serialosc/osc).
4 |
5 | See the [`renoise.Osc`](../API/renoise/renoise.Osc.md) and [`renoise.Socket`](../API/renoise/renoise.Socket.md) APIs for more details.
6 |
7 | > [!NOTE]
8 | > Using TCP instead of UDP as the socket protocol would likely require manual [SLIP encoding/decoding](https://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol) of OSC message data. This is not handled automatically, so the examples below will only work with UDP servers/clients.
9 |
10 | ## OSC Server (Receiving OSC)
11 |
12 | This example creates a UDP server that listens for OSC messages on port 8008.
13 |
14 | ```lua
15 | -- Create some shortcuts
16 | local OscMessage = renoise.Osc.Message
17 | local OscBundle = renoise.Osc.Bundle
18 |
19 | -- Open a socket connection to listen for messages
20 | local server, socket_error = renoise.Socket.create_server(
21 | "localhost", 8008, renoise.Socket.PROTOCOL_UDP)
22 |
23 | if (socket_error) then
24 | renoise.app():show_warning(("Failed to start the " ..
25 | "OSC server. Error: '%s'"):format(socket_error))
26 | return
27 | end
28 |
29 | server:run {
30 | socket_message = function(socket, data)
31 | -- Decode the binary data to an OSC message or bundle
32 | local message_or_bundle, osc_error = renoise.Osc.from_binary_data(data)
33 |
34 | -- Show what we've got
35 | if (message_or_bundle) then
36 | if (type(message_or_bundle) == "Message") then
37 | print(("Got OSC message: '%s'"):format(tostring(message_or_bundle)))
38 |
39 | elseif (type(message_or_bundle) == "Bundle") then
40 | print(("Got OSC bundle: '%s'"):format(tostring(message_or_bundle)))
41 | end
42 |
43 | -- Send a reply back to the client
44 | local reply_message = OscMessage("/renoise/reply", {
45 | { tag = "s", value = "Thank you for the message!" }
46 | })
47 | socket:send(reply_message:to_binary_data())
48 |
49 | else
50 | print(("Got invalid OSC data, or data which is not " ..
51 | "OSC data at all. Error: '%s'"):format(osc_error))
52 | end
53 | end
54 | }
55 |
56 | -- To shut down the server at any time, call:
57 | -- server:close()
58 | ```
59 |
60 | ## OSC Client (Sending OSC)
61 |
62 | This example creates a UDP client to send OSC messages to a server on port 8008.
63 |
64 | ```lua
65 | -- Create some shortcuts
66 | local OscMessage = renoise.Osc.Message
67 | local OscBundle = renoise.Osc.Bundle
68 |
69 | -- Create a client to send messages to the server
70 | local client, socket_error = renoise.Socket.create_client(
71 | "localhost", 8008, renoise.Socket.PROTOCOL_UDP)
72 |
73 | if (socket_error) then
74 | renoise.app():show_warning(("Failed to start the " ..
75 | "OSC client. Error: '%s'"):format(socket_error))
76 | return
77 | end
78 |
79 | -- Construct and send a simple message
80 | client:send(
81 | OscMessage("/transport/start"):to_binary_data()
82 | )
83 |
84 | -- Construct and send a message with arguments
85 | client:send(
86 | OscMessage("/transport/bpm", {
87 | { tag = "f", value = 127.5 }
88 | }):to_binary_data()
89 | )
90 |
91 | -- Construct and send a bundle of messages
92 | local message1 = OscMessage("/some/message")
93 | local message2 = OscMessage("/another/one", {
94 | { tag = "b", value = "with some blob data" },
95 | { tag = "s", value = "and a string" }
96 | })
97 |
98 | client:send(
99 | OscBundle(os.clock(), { message1, message2 }):to_binary_data()
100 | )
101 |
102 | -- Close the client when done
103 | client:close()
104 | ```
105 |
--------------------------------------------------------------------------------
/docs/start/possibilities.md:
--------------------------------------------------------------------------------
1 | # Possibilities
2 |
3 | Before you delve into writing your own scripts and tools, it worth considering what is even possible to do with them. In general, you can automate and manage different aspects Renoise, add or modify song data using algorithms or create interfaces to connect with other software or hardware. You can see some examples below about what you can access inside Renoise, for a complete reference, check out the [API Definitions](../API/README.md).
4 |
5 | ### Process song data
6 | * Generate, modify or filter notes, patterns or phrases
7 | * Access volume, delays and panning values
8 | * Write effect commands and automation
9 | * Rearrange the pattern matrix and more
10 |
11 | ### Manage tracks and instruments
12 | * Create and modify instruments or tracks
13 | * Add built-in DSP devices to tracks or FX chains and set their parameters
14 | * Generate modulation chains on instruments
15 | * Load samples and configure them
16 | * Manage slices and keyzones
17 |
18 | ### Sample generation and mangling
19 | * Generate new samples and change existing ones
20 | * Chop samples and create slices and intruments based on custom rules
21 | * Implement offline audio effects
22 |
23 | ### Custom graphical interfaces
24 | * Use built-in sliders, buttons, switches and more to compose a GUI
25 | * Listen to keyboard and mouse events to define custom behaviour
26 | * Use bitmaps to create unique buttons
27 | * Hook up the interface to the rest of your tool
28 |
29 | ### Controller support
30 | * Write logic for bidirectional communication between Renoise and MIDI controllers
31 | * Implement custom functionality for MIDI control surfaces
32 | * Control Renoise via customized [OSC](https://en.wikipedia.org/wiki/Open_Sound_Control) messages
33 | * Exchange information with other software like VJ tools or web services
34 |
35 | ### Interactions
36 |
37 | There are a few ways tool creators can make the functionality they provide available for users, below is a brief summary of the most used methods.
38 |
39 | * [Define keybindings](../guide/tool.md#keybindings) that can be assigned to shortcuts and executed from certain contexts in Renoise
40 | * [Add new entries to menus](../guide/tool.md#menu-entries) like the *Tools* menu or one of the right-click context menus
41 | * [Create custom views](../guide/tool.md#custom-guis) that do things on button presses, slider drags and so on
42 | * Listen to [MIDI](../guide/midi.md), [OSC](../guide/osc.md) or [WebSocket messages](../guide/sockets.md) to execute actions
43 | * [React to events inside Renoise](../guide/observables.md) like "do something any time a new song is loaded"
44 |
45 |
46 | ## Limitations
47 |
48 | Finally, let's look at what is **not** possible via tools.
49 |
50 | * You cannot override the existing behaviour of Renoise. You can add functionality *on top* of what's already there, but you can't disable or change how the built-in features work.
51 | For example, you can create a completely custom GUI to compose patterns in a novel way but you cannot change how the built-in pattern editor works or looks like. Similarly, you can add a new shortcut that does something extra to the selected sample block or places new slices but you can't modify how the built-in autoslicing works.
52 |
53 | * You cannot write real-time DSP code like synths, effects or modulators (except for scripts inside the [Formula device](https://tutorials.renoise.com/wiki/Meta_Devices#*Formula)), which is not using the Renoise Tool API. If you want to design your own synths and effects you should look into plugin development (using [DISTRHO](https://distrho.kx.studio/), [nih-plug](https://github.com/robbert-vdh/nih-plug) etc.), you could also use existing plugins that allow you to build your own DSP patches (like [plugdata](https://plugdata.org/) or [Cardinal](https://cardinal.kx.studio/)). Of course you can [generate and modify samples](../guide/song.md#samples) using your tool, but it will have to be implemented as offline rendering instead of real-time processing.
54 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.AudioDevice.md:
--------------------------------------------------------------------------------
1 | # renoise.AudioDevice
2 | > Audio DSP device in tracks or sample device chains.
3 |
4 |
5 |
6 |
7 | ---
8 | ## Properties
9 | ### name : [`string`](../../API/builtins/string.md)
10 | > **READ-ONLY**
11 |
12 | ### short_name : [`string`](../../API/builtins/string.md)
13 | > **READ-ONLY**
14 |
15 | ### display_name : [`string`](../../API/builtins/string.md)
16 | > Configurable device display name. When empty `name` is displayed.
17 |
18 | ### display_name_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
19 | > Track changes to document properties or general states by attaching listener
20 | > functions to it.
21 |
22 | ### is_active : [`boolean`](../../API/builtins/boolean.md)
23 | > !active = bypassed
24 |
25 | ### is_active_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
26 | > Track changes to document properties or general states by attaching listener
27 | > functions to it.
28 |
29 | ### is_maximized : [`boolean`](../../API/builtins/boolean.md)
30 | > Maximize state in DSP chain.
31 |
32 | ### is_maximized_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
33 | > Track changes to document properties or general states by attaching listener
34 | > functions to it.
35 |
36 | ### active_preset : [`integer`](../../API/builtins/integer.md)
37 | > 0 when none is active or available
38 |
39 | ### active_preset_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
40 | > Track changes to document properties or general states by attaching listener
41 | > functions to it.
42 |
43 | ### active_preset_data : [`string`](../../API/builtins/string.md)
44 | > raw serialized data in XML format of the active preset
45 |
46 | ### presets : [`string`](../../API/builtins/string.md)[]
47 | > **READ-ONLY** preset names
48 |
49 | ### is_active_parameter : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)
50 | > **READ-ONLY**
51 |
52 | ### parameters : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)[]
53 | > **READ-ONLY**
54 |
55 | ### external_editor_available : [`boolean`](../../API/builtins/boolean.md)
56 | > **READ-ONLY** Returns whether or not the device provides its own custom GUI
57 | > (only available for some plugin devices)
58 |
59 | ### external_editor_visible : [`boolean`](../../API/builtins/boolean.md)
60 | > true to show the editor, false to close it
61 |
62 | ### device_path : [`string`](../../API/builtins/string.md)
63 | > **READ-ONLY** Returns a string that uniquely identifies the device, from
64 | > `available_devices`. The string can be passed into:
65 | > `renoise.song().tracks[]:insert_device_at()`
66 |
67 |
68 |
69 | ---
70 | ## Functions
71 | ### preset([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
72 | `->`preset_name : [`string`](../../API/builtins/string.md)
73 |
74 | > Access to a single preset name by index. Use properties 'presets' to iterate
75 | > over all presets and to query the presets count.
76 | > comment
77 | ### parameter([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
78 | `->`[`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)
79 |
80 | > Access to a single parameter by index. Use properties 'parameters' to iterate
81 | > over all parameters and to query the parameter count.
82 |
83 |
--------------------------------------------------------------------------------
/tools/com.renoise.ExampleToolSlicedProcess.xrnx/process_slicer.lua:
--------------------------------------------------------------------------------
1 | --[[============================================================================
2 | process_slicer.lua
3 | ============================================================================]]--
4 |
5 | --[[
6 |
7 | ProcessSlicer allows you to slice up a function which takes a lot of
8 | processing time into multiple calls via Lua coroutines.
9 |
10 | * Example usage:
11 |
12 | local slicer = ProcessSlicer(my_process_func, argument1, argumentX)
13 |
14 | -- This starts calling 'my_process_func' in idle, passing all arguments
15 | -- you've specified in the ProcessSlicer constructor.
16 | slicer:start()
17 |
18 | -- To abort a running sliced process, you can call "stop" at any time
19 | -- from within your processing function of outside of it in the main thread.
20 | -- As soon as your process function returns, the slicer is automatically
21 | -- stopped.
22 | slicer:stop()
23 |
24 | -- To give processing time back to Renoise, call 'coroutine.yield()'
25 | -- anywhere in your process function to temporarily yield back to Renoise:
26 | function my_process_func()
27 | for j=1,100 do
28 | -- do something that needs a lot of time, and periodically call
29 | -- "coroutine.yield()" to give processing time back to Renoise. Renoise
30 | -- will switch back to this point of the function as soon as has done
31 | -- "its" job:
32 | coroutine.yield()
33 | end
34 | end
35 |
36 |
37 | * Drawbacks:
38 |
39 | By slicing your processing function, you will also slice any changes that are
40 | done to the Renoise song into multiple undo actions (one action per slice/yield).
41 |
42 | Modal dialogs will block the slicer, cause on_idle notifications are not fired then.
43 | It will even block your own process GUI when trying to show it modal.
44 |
45 | ]]
46 |
47 | class "ProcessSlicer"
48 |
49 | function ProcessSlicer:__init(process_func, ...)
50 | assert(type(process_func) == "function",
51 | "expected a function as first argument")
52 |
53 | self.__process_func = process_func
54 | self.__process_func_args = { ... }
55 | self.__process_thread = nil
56 | end
57 |
58 | --------------------------------------------------------------------------------
59 | -- returns true when the current process currently is running
60 |
61 | function ProcessSlicer:running()
62 | return (self.__process_thread ~= nil)
63 | end
64 |
65 | --------------------------------------------------------------------------------
66 | -- start a process
67 |
68 | function ProcessSlicer:start()
69 | assert(not self:running(), "process already running")
70 |
71 | self.__process_thread = coroutine.create(self.__process_func)
72 |
73 | renoise.tool().app_idle_observable:add_notifier(
74 | { ProcessSlicer.__on_idle, self })
75 | end
76 |
77 | --------------------------------------------------------------------------------
78 | -- stop a running process
79 |
80 | function ProcessSlicer:stop()
81 | assert(self:running(), "process not running")
82 |
83 | renoise.tool().app_idle_observable:remove_notifier(
84 | { ProcessSlicer.__on_idle, self })
85 |
86 | self.__process_thread = nil
87 | end
88 |
89 | --------------------------------------------------------------------------------
90 |
91 | -- function that gets called from Renoise to do idle stuff. switches back
92 | -- into the processing function or detaches the thread
93 |
94 | function ProcessSlicer:__on_idle()
95 | assert(self.__process_thread ~= nil, "ProcessSlicer internal error: " ..
96 | "expected no idle call with no thread running")
97 |
98 | -- continue or start the process while its still active
99 | if (coroutine.status(self.__process_thread) == 'suspended') then
100 | local succeeded, error_message = coroutine.resume(
101 | self.__process_thread, table.unpack(self.__process_func_args))
102 |
103 | if (not succeeded) then
104 | -- stop the process on errors
105 | self:stop()
106 | -- and forward the error to the main thread
107 | error(error_message)
108 | end
109 |
110 | -- stop when the process function completed
111 | elseif (coroutine.status(self.__process_thread) == 'dead') then
112 | self:stop()
113 | end
114 | end
115 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.SampleDeviceChain.md:
--------------------------------------------------------------------------------
1 | # renoise.SampleDeviceChain
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### name : [`string`](../../API/builtins/string.md)
9 | > Name of the audio effect chain.
10 |
11 | ### name_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
12 | > Track changes to document properties or general states by attaching listener
13 | > functions to it.
14 |
15 | ### available_devices : [`string`](../../API/builtins/string.md)[]
16 | > **READ-ONLY** Allowed, available devices for 'insert_device_at'.
17 |
18 | ### available_device_infos : [`AudioDeviceInfo`](#audiodeviceinfo)[]
19 | > **READ-ONLY** Returns a list of tables containing more information about
20 | > the devices.
21 |
22 | ### devices : [`renoise.AudioDevice`](../../API/renoise/renoise.AudioDevice.md)[]
23 | > **READ-ONLY** Device access.
24 |
25 | ### devices_observable : [`renoise.Document.ObservableList`](../../API/renoise/renoise.Document.ObservableList.md)
26 | > Track changes to document lists by attaching listener functions to it.
27 | > NB: Notifiers will not broadcast changes made to list items, but only changes
28 | > to the lists **layout** (items got added, removed, swapped).
29 |
30 | ### available_output_routings : [`string`](../../API/builtins/string.md)[]
31 | > **READ-ONLY** Output routing.
32 |
33 | ### output_routing : [`string`](../../API/builtins/string.md)
34 | > One of 'available_output_routings'
35 |
36 | ### output_routing_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
37 | > Track changes to document properties or general states by attaching listener
38 | > functions to it.
39 |
40 |
41 |
42 | ---
43 | ## Functions
44 | ### insert_device_at([*self*](../../API/builtins/self.md), device_path : [`string`](../../API/builtins/string.md), index : [`integer`](../../API/builtins/integer.md))
45 | `->`new_device : [`renoise.AudioDevice`](../../API/renoise/renoise.AudioDevice.md)
46 |
47 | > Insert a new device at the given position. "device_path" must be an available device
48 | > See: `renoise.SampleDeviceChain.available_devices`
49 | ### delete_device_at([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
50 | > Delete an existing device from a chain. The mixer device at index 1 can not
51 | > be deleted.
52 | ### swap_devices_at([*self*](../../API/builtins/self.md), index1 : [`integer`](../../API/builtins/integer.md), index2 : [`integer`](../../API/builtins/integer.md))
53 | > Swap the positions of two devices in the device chain. The mixer device at
54 | > index 1 can not be swapped or moved.
55 | ### device([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
56 | `->`[`renoise.AudioDevice`](../../API/renoise/renoise.AudioDevice.md)
57 |
58 | > Access to a single device in the chain.
59 |
60 |
61 |
62 | ---
63 | ## Structs
64 | # AudioDeviceInfo
65 | > Audio device info
66 |
67 | ---
68 | ## Properties
69 | ### path : [`string`](../../API/builtins/string.md)
70 | > The device's path used by `renoise.Track:insert_device_at`
71 |
72 | ### name : [`string`](../../API/builtins/string.md)
73 | > The device's name
74 |
75 | ### short_name : [`string`](../../API/builtins/string.md)
76 | > The device's name as displayed in shortened lists
77 |
78 | ### favorite_name : [`string`](../../API/builtins/string.md)
79 | > The device's name as displayed in favorites
80 |
81 | ### is_favorite : [`boolean`](../../API/builtins/boolean.md)
82 | > true if the device is a favorite
83 |
84 | ### is_bridged : [`boolean`](../../API/builtins/boolean.md)
85 | > true if the device is a bridged plugin
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/docs/API/modules/global.md:
--------------------------------------------------------------------------------
1 | # Global
2 |
3 |
4 |
5 |
6 | ---
7 | ## Functions
8 | ### tostring(pattern_line : [`renoise.PatternLine`](../../API/renoise/renoise.PatternLine.md))
9 | `->`[`string`](../../API/builtins/string.md)
10 |
11 | > Receives a value of any type and converts it to a string in a human-readable format.
12 | >
13 | > If the metatable of `v` has a `__tostring` field, then `tostring` calls the corresponding value with `v` as argument, and uses the result of the call as its result. Otherwise, if the metatable of `v` has a `__name` field with a string value, `tostring` may use that string in its final result.
14 | >
15 | > For complete control of how numbers are converted, use [string.format](http://www.lua.org/manual/5.4/manual.html#pdf-string.format).
16 | >
17 | >
18 | > [View documents](http://www.lua.org/manual/5.4/manual.html#pdf-tostring)
19 | ### ripairs(table : )
20 | `->`fun(table: [], i?: integer):integer, , , i : [`integer`](../../API/builtins/integer.md)
21 |
22 | > An iterator like ipairs, but in reverse order.
23 | > #### examples:
24 | > ```lua
25 | > t = {"a", "b", "c"}
26 | > for k,v in ripairs(t) do print(k, v) end -> "3 c, 2 b, 1 a"
27 | > ```
28 | ### objinfo(object : [`userdata`](../../API/builtins/userdata.md))
29 | `->`[`string`](../../API/builtins/string.md)[]
30 |
31 | > Return a string which lists properties and methods of class objects.
32 | ### oprint(object : [`userdata`](../../API/builtins/userdata.md))
33 | > Dumps properties and methods of class objects (like renoise.app()).
34 | ### rprint(value : [`any`](../../API/builtins/any.md))
35 | > Recursively dumps a table and all its members to the std out (console).
36 | > This works for standard Lua types and class objects as well.
37 | ### class(name : [`string`](../../API/builtins/string.md))
38 | `->`[`function`](../../API/builtins/function.md)
39 |
40 | > Luabind "class" registration. Registers a global class object and returns a
41 | > closure to optionally set the base class.
42 | >
43 | > See also [Luabind class](https://luabind.sourceforge.net/docs.html#class_lua)
44 | >
45 | > #### examples
46 | > ```lua
47 | > ---@class Animal
48 | > -- Construct a new animal with the given name.
49 | > ---@overload fun(string): Animal
50 | > Animal = {}
51 | > class 'Animal'
52 | > ---@param name string
53 | > function Animal:__init(name)
54 | > self.name = name
55 | > self.can_fly = nil
56 | > end
57 | > function Animal:show()
58 | > return ("I am a %s (%s) and I %s fly"):format(self.name, type(self),
59 | > (self.can_fly and "can fly" or "can not fly"))
60 | > end
61 | >
62 | > -- Mammal class (inherits Animal functions and members)
63 | > ---@class Mammal : Animal
64 | > -- Construct a new mamal with the given name.
65 | > ---@overload fun(string): Mammal
66 | > Mammal = {}
67 | > class 'Mammal' (Animal)
68 | > ---@param name string
69 | > function Mammal:__init(name)
70 | > Animal.__init(self, name)
71 | > self.can_fly = false
72 | > end
73 | >
74 | > -- show() function and base member are available for Mammal too
75 | > local mamal = Mammal("Cow")
76 | > mamal:show()
77 | > ```
78 | ### type(value : [`any`](../../API/builtins/any.md))
79 | `->`[`string`](../../API/builtins/string.md)
80 |
81 | > Returns the type of its only argument, coded as a string. The possible results of this function are `"nil"` (a string, not the value `nil`), `"number"`, `"string"`, `"boolean"`, `"table"`, `"function"`, `"thread"`, and `"userdata"`.
82 | >
83 | >
84 | > [View documents](http://www.lua.org/manual/5.4/manual.html#pdf-type)
85 | >
86 | >
87 | > ```lua
88 | > type:
89 | > | "nil"
90 | > | "number"
91 | > | "string"
92 | > | "boolean"
93 | > | "table"
94 | > | "function"
95 | > | "thread"
96 | > | "userdata"
97 | > ```
98 | ### rawequal(obj1 : [`any`](../../API/builtins/any.md), obj2 : [`any`](../../API/builtins/any.md))
99 | > Checks whether v1 is equal to v2, without invoking the `__eq` metamethod.
100 | >
101 | > [View documents](http://www.lua.org/manual/5.4/manual.html#pdf-rawequal)
102 |
103 |
--------------------------------------------------------------------------------
/tests/track_device_chain.lua:
--------------------------------------------------------------------------------
1 | --[[--------------------------------------------------------------------------
2 | TestTrackDeviceChain.lua
3 | --------------------------------------------------------------------------]]--
4 |
5 | do
6 |
7 | ----------------------------------------------------------------------------
8 | -- tools
9 |
10 | local function assert_error(statement)
11 | assert(pcall(statement) == false, "expected function error")
12 | end
13 |
14 |
15 | -- shortcuts
16 |
17 | local song = renoise.song()
18 |
19 | song.selected_track_index = 1 -- make sure its a player track
20 | local selected_track = song.tracks[song.selected_track_index]
21 |
22 |
23 | ----------------------------------------------------------------------------
24 | -- insert/delete/swap
25 |
26 | local avail_devices = selected_track.available_devices
27 |
28 | local new_device_path, new_device_path2
29 |
30 | repeat
31 | new_device_path = avail_devices[math.random(1, #avail_devices)]
32 | new_device_path2 = avail_devices[math.random(1, #avail_devices)]
33 | until
34 | -- avoid plugins, cause they may fail to load and pop up dialogs
35 | not string.find(new_device_path, "VST") and
36 | not string.find(new_device_path, "AU") and
37 | not string.find(new_device_path2, "VST") and
38 | not string.find(new_device_path2, "AU")
39 |
40 | assert_error(function()
41 | selected_track:insert_device_at("InvalidDeviceName#234", #selected_track.devices + 1)
42 | end)
43 |
44 | assert_error(function()
45 | selected_track:insert_device_at(new_device_path, 1)
46 | end)
47 |
48 | assert_error(function()
49 | selected_track:delete_device_at(1)
50 | end)
51 |
52 | local device_count = #selected_track.devices
53 |
54 | local new_device = selected_track:insert_device_at(new_device_path, 2)
55 | device_count = device_count + 1
56 | assert(device_count == #selected_track.devices)
57 |
58 | local found_device = false
59 |
60 | local found_device_path = false
61 |
62 | for _,device in ipairs(selected_track.devices) do
63 | if device.name == new_device.name then
64 | found_device = true
65 | end
66 | if device.device_path == new_device_path then
67 | found_device_path = true
68 | end
69 | end
70 |
71 | assert(found_device)
72 |
73 | assert(found_device_path)
74 |
75 | selected_track:delete_device_at(2)
76 | device_count = device_count - 1
77 | assert(device_count == #selected_track.devices)
78 |
79 | selected_track:insert_device_at(new_device_path,
80 | #selected_track.devices + 1)
81 |
82 | selected_track:insert_device_at(new_device_path2,
83 | #selected_track.devices + 1)
84 |
85 | device_count = device_count + 2
86 | assert(device_count == #selected_track.devices)
87 |
88 |
89 | selected_track:swap_devices_at(
90 | #selected_track.devices,
91 | #selected_track.devices - 1)
92 |
93 | assert(device_count == #selected_track.devices)
94 |
95 |
96 | selected_track:delete_device_at(2)
97 | selected_track:delete_device_at(2)
98 |
99 | device_count = device_count - 2
100 | assert(device_count == #selected_track.devices)
101 |
102 |
103 | -- preset handing
104 |
105 | local trackvolpan = selected_track.devices[1]
106 | assert(#trackvolpan.presets == 1) -- init
107 |
108 | selected_track:insert_device_at(new_device_path,
109 | #selected_track.devices + 1)
110 |
111 | local new_device = selected_track.devices[#selected_track.devices]
112 |
113 | assert(#new_device.presets >= 1)
114 | assert(new_device.active_preset >= 1)
115 |
116 | local new_preset = math.random(#new_device.presets)
117 | new_device.active_preset = new_preset
118 | assert(new_device.active_preset == new_preset)
119 |
120 | assert_error(function()
121 | new_device.active_preset = 0
122 | end)
123 | assert_error(function()
124 | new_device.active_preset = #new_device.presets + 1
125 | end)
126 |
127 | end
128 |
129 |
130 | ------------------------------------------------------------------------------
131 | -- test finalizers
132 |
133 | collectgarbage()
134 |
135 |
136 | --[[--------------------------------------------------------------------------
137 | --------------------------------------------------------------------------]]--
138 |
--------------------------------------------------------------------------------
/tests/transport.lua:
--------------------------------------------------------------------------------
1 | --[[--------------------------------------------------------------------------
2 | TestTransport.lua
3 | --------------------------------------------------------------------------]]--
4 |
5 | do
6 |
7 | ----------------------------------------------------------------------------
8 | -- tools
9 |
10 | local function assert_error(statement)
11 | assert(pcall(statement) == false, "expected function error")
12 | end
13 |
14 |
15 | -- shortcuts
16 |
17 | local transport = renoise.song().transport
18 |
19 |
20 | ----------------------------------------------------------------------------
21 | -- SongPos
22 |
23 | local some_str = tostring(transport.edit_pos)
24 | transport.edit_pos = renoise.SongPos(1, 1)
25 | local new_pos = transport.edit_pos
26 |
27 | assert_error(function()
28 | new_pos.does_not_exist = "Foo!"
29 | end)
30 |
31 | --[[ TODO:
32 | assert_error(function()
33 | new_pos.sequence = 2
34 | end)
35 | assert_error(function()
36 | new_pos.line = 1
37 | end)
38 | --]]
39 |
40 | transport.loop_range = {renoise.SongPos(1, 1), renoise.SongPos(1, 17)}
41 |
42 | assert(transport.loop_start == transport.loop_range[1])
43 | assert(transport.loop_end == transport.loop_range[2])
44 |
45 | assert(transport.loop_start < transport.loop_end)
46 | assert(transport.loop_start <= transport.loop_end)
47 | assert(transport.loop_end > transport.loop_start)
48 | assert(transport.loop_end >= transport.loop_start)
49 |
50 | assert(transport.loop_start == renoise.SongPos(1, 1))
51 | assert(transport.loop_start ~= renoise.SongPos(2, 1))
52 |
53 |
54 |
55 | ----------------------------------------------------------------------------
56 | -- Track Headroom
57 |
58 | function track_headroom_changed()
59 | print("track headroom changed: " .. transport.track_headroom)
60 | end
61 |
62 | transport.track_headroom_observable:add_notifier(track_headroom_changed)
63 |
64 | transport.track_headroom = math.db2lin(-6.0)
65 |
66 | assert_error(function()
67 | transport.track_headroom = math.db2lin(1.5)
68 | end)
69 |
70 | transport.track_headroom_observable:remove_notifier(track_headroom_changed)
71 |
72 |
73 | ----------------------------------------------------------------------------
74 | -- Computer Keyboard Velocity
75 |
76 | transport.keyboard_velocity_enabled = false
77 | transport.keyboard_velocity = 127
78 |
79 | local num_keyboard_velocity_changes = 0
80 | function keyboard_velocity_changed()
81 | num_keyboard_velocity_changes = num_keyboard_velocity_changes + 1
82 | end
83 |
84 | local num_keyboard_velocity_enabled_changes = 0
85 | function keyboard_velocity_enabled_changed()
86 | num_keyboard_velocity_enabled_changes =
87 | num_keyboard_velocity_enabled_changes + 1
88 | end
89 |
90 | transport.keyboard_velocity_observable:add_notifier(
91 | keyboard_velocity_changed)
92 | transport.keyboard_velocity_enabled_observable:add_notifier(
93 | keyboard_velocity_enabled_changed)
94 |
95 | transport.keyboard_velocity_enabled = true
96 | assert(transport.keyboard_velocity_enabled == true)
97 |
98 | transport.keyboard_velocity = 1
99 | assert(transport.keyboard_velocity == 1)
100 |
101 | transport.keyboard_velocity = 64
102 | assert(transport.keyboard_velocity == 64)
103 |
104 | assert_error(function()
105 | transport.keyboard_velocity = 128
106 | end)
107 |
108 | transport.keyboard_velocity_enabled = false
109 | assert(transport.keyboard_velocity_enabled ~= true)
110 |
111 | -- Should always return max 127 when disabled
112 | assert(transport.keyboard_velocity == 127)
113 |
114 | assert(num_keyboard_velocity_changes == 2)
115 | assert(num_keyboard_velocity_enabled_changes == 2)
116 |
117 | transport.keyboard_velocity_observable:remove_notifier(
118 | keyboard_velocity_changed)
119 |
120 | transport.keyboard_velocity_enabled_observable:remove_notifier(
121 | keyboard_velocity_enabled_changed)
122 |
123 | end
124 |
125 |
126 | ------------------------------------------------------------------------------
127 | -- test finalizers
128 |
129 | collectgarbage()
130 |
131 |
132 | --[[--------------------------------------------------------------------------
133 | --------------------------------------------------------------------------]]--
134 |
135 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Midi.md:
--------------------------------------------------------------------------------
1 | # renoise.Midi
2 | > Raw MIDI IO support for scripts in Renoise; the ability to send and receive
3 | > MIDI data.
4 |
5 |
6 |
7 |
8 | ---
9 | ## Functions
10 | ### `available_input_devices()`
11 | `->`[`string`](../../API/builtins/string.md)[]
12 |
13 | > Return a list of strings with currently available MIDI input devices.
14 | > This list can change when devices are hot-plugged.
15 | > See `renoise.Midi.devices_changed_observable`
16 | ### `available_output_devices()`
17 | `->`[`string`](../../API/builtins/string.md)[]
18 |
19 | > Return a list of strings with currently available MIDI output devices.
20 | > This list can change when devices are hot-plugged.
21 | > See `renoise.Midi.devices_changed_observable`
22 | ### `devices_changed_observable()`
23 | `->`[`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
24 |
25 | > Fire notifications as soon as new devices become active or a previously
26 | > added device gets removed/unplugged.
27 | > This will only happen on Linux and OSX with real devices. On Windows this
28 | > may happen when using ReWire slaves. ReWire adds virtual MIDI devices to
29 | > Renoise.
30 | > Already opened references to devices which are no longer available will
31 | > do nothing: you can use them as before and they will not fire any errors.
32 | > The messages will simply go into the void...
33 | ### create_input_device(device_name : [`string`](../../API/builtins/string.md), callback : [`MidiMessageFunction`](#MidiMessageFunction) | [`MidiMessageMethod1`](#MidiMessageMethod1) | [`MidiMessageMethod2`](#MidiMessageMethod2)[`?`](../../API/builtins/nil.md), sysex_callback : [`MidiMessageFunction`](#MidiMessageFunction) | [`MidiMessageMethod1`](#MidiMessageMethod1) | [`MidiMessageMethod2`](#MidiMessageMethod2)[`?`](../../API/builtins/nil.md))
34 | `->`[`renoise.Midi.MidiInputDevice`](../../API/renoise/renoise.Midi.MidiInputDevice.md)
35 |
36 | > Listen to incoming MIDI data: opens access to a MIDI input device by
37 | > specifying a device name.
38 | > Name must be one of `renoise.Midi.available_input_devices()`.
39 | >
40 | > One or both callbacks should be valid, and should either point to a function
41 | > with one parameter `function (message: number[]) end`, or a table with an object
42 | > and class `{context, function(context, message: number[]) end}` -> a method.
43 | >
44 | > All MIDI messages except active sensing will be forwarded to the callbacks.
45 | > When Renoise is already listening to this device, your callback *and* Renoise
46 | > (or even other scripts) will handle the message.
47 | >
48 | > Messages are received until the device reference is manually closed (see
49 | > renoise.Midi.MidiDevice:close()) or until the MidiInputDevice object gets garbage
50 | > collected.
51 | ### create_output_device(device_name : [`string`](../../API/builtins/string.md))
52 | `->`[`renoise.Midi.MidiOutputDevice`](../../API/renoise/renoise.Midi.MidiOutputDevice.md)
53 |
54 | > Open access to a MIDI device by specifying the device name.
55 | > Name must be one of `renoise.Midi.available_input_devices()`.
56 | > All other device names will fire an error.
57 | >
58 | > The real device driver gets automatically closed when the MidiOutputDevice
59 | > object gets garbage collected or when the device is explicitly closed
60 | > via midi_device:close() and nothing else references it.
61 |
62 |
63 |
64 | ---
65 | ## Aliases
66 | ### MidiMessage
67 | [`integer`](../../API/builtins/integer.md)[]
68 |
69 |
70 | ### MidiMessageFunction
71 | (message : [`MidiMessage`](#MidiMessage))
72 |
73 |
74 | ### MidiMessageMemberContext
75 | [`table`](../../API/builtins/table.md) | [`userdata`](../../API/builtins/userdata.md)
76 |
77 |
78 | ### MidiMessageMemberFunction
79 | (self : [`MidiMessageMemberContext`](#MidiMessageMemberContext), message : [`MidiMessage`](#MidiMessage))
80 |
81 |
82 | ### MidiMessageMethod1
83 | { 1 : [`MidiMessageMemberContext`](#MidiMessageMemberContext), 2 : [`MidiMessageMemberFunction`](#MidiMessageMemberFunction) }
84 |
85 |
86 | ### MidiMessageMethod2
87 | { 1 : [`MidiMessageMemberFunction`](#MidiMessageMemberFunction), 2 : [`MidiMessageMemberContext`](#MidiMessageMemberContext) }
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/tools/com.renoise.ExampleToolSlicedProcess.xrnx/main.lua:
--------------------------------------------------------------------------------
1 | --[[============================================================================
2 | main.lua
3 | ============================================================================]]--
4 |
5 | --[[
6 |
7 | This tool shows how to slice up a function which takes a lot of processing
8 | time into multiple calls via Lua coroutines.
9 |
10 | This mainly is useful to:
11 | - show the current progress of your processing function
12 | - allow users to abort the progress at any time
13 | - avoids that Renoise asks to kill your process function cause it assumes
14 | its frozen when taking more than 10 seconds
15 |
16 | Please have a look at "process_slicer.lua" for more info. This file basically
17 | just shows how to create a GUI for the ProcessSlicer class.
18 |
19 | ]]
20 |
21 | require "process_slicer"
22 |
23 |
24 | --------------------------------------------------------------------------------
25 |
26 | -- main: dummy example for sliced working function which needs a lot of time
27 |
28 | function main(update_progress_func)
29 | local i = 0
30 |
31 | local num_iterations = 1000
32 | for j=1,num_iterations do
33 | i = i + 1
34 |
35 | -- waste time (your tool would do something useful here)
36 | for k=1,1000000 do
37 | local a = 12/12*3434
38 | end
39 |
40 | -- show the progress in the GUI
41 | update_progress_func(i / num_iterations)
42 |
43 | -- and periodically give time back to renoise
44 | coroutine.yield()
45 | end
46 | end
47 |
48 |
49 | --------------------------------------------------------------------------------
50 |
51 | -- creates a dialog which starts stops and visualizes a sliced progress
52 |
53 | local function create_gui()
54 |
55 | local dialog, process
56 | local vb = renoise.ViewBuilder()
57 |
58 | -- Note: we allow multiple dialogs and processes in this example. If you
59 | -- only want one dialog to be shown and only one process running, make
60 | -- 'dialog' and 'process' global, and check if if the dialog is visible
61 | -- here. If your dialog and viewbuilder is global, you also don't have to
62 | -- pass an "update_progress_func" to the processing function, but can call
63 | -- it directly.
64 |
65 | ----- process GUI functions (callbacks):
66 |
67 | local function update_progress(progress)
68 | if (not dialog or not dialog.visible) then
69 | -- abort processing when the dialog was closed
70 | process:stop()
71 | return
72 | end
73 |
74 | -- else update the progress text
75 | if (progress == 1.0) then
76 | vb.views.start_button.text = "Start"
77 | vb.views.progress_text.text = "Done!"
78 | else
79 | vb.views.progress_text.text = string.format(
80 | "Working hard (%d%% done)...", progress * 100)
81 | end
82 | end
83 |
84 | local function start_stop_process()
85 | if (not process or not process:running()) then
86 | -- start running
87 | vb.views.start_button.text = "Stop"
88 | process = ProcessSlicer(main, update_progress)
89 | process:start()
90 |
91 | elseif (process and process:running()) then
92 | -- stop running
93 | vb.views.start_button.text = "Start"
94 | vb.views.progress_text.text = "Process Aborted!"
95 | process:stop()
96 | end
97 | end
98 |
99 |
100 | ---- process GUI
101 |
102 | local DEFAULT_DIALOG_MARGIN =
103 | renoise.ViewBuilder.DEFAULT_DIALOG_MARGIN
104 |
105 | local DEFAULT_CONTROL_SPACING =
106 | renoise.ViewBuilder.DEFAULT_CONTROL_SPACING
107 |
108 | local DEFAULT_DIALOG_BUTTON_HEIGHT =
109 | renoise.ViewBuilder.DEFAULT_DIALOG_BUTTON_HEIGHT
110 |
111 | local dialog_content = vb:column {
112 | uniform = false,
113 | margin = DEFAULT_DIALOG_MARGIN,
114 | spacing = DEFAULT_CONTROL_SPACING,
115 |
116 | -- (add some content here)
117 |
118 | vb:text {
119 | id = "progress_text",
120 | text = "Hit 'Start' to begin a sliced process:"
121 | },
122 |
123 | vb:button {
124 | id = "start_button",
125 | text = "Start",
126 | height = DEFAULT_DIALOG_BUTTON_HEIGHT,
127 | width = 80,
128 | notifier = start_stop_process
129 | }
130 | }
131 |
132 | dialog = renoise.app():show_custom_dialog(
133 | "Sliced Process Example", dialog_content)
134 | end
135 |
136 |
137 | --------------------------------------------------------------------------------
138 |
139 | renoise.tool():add_menu_entry{
140 | name = "Main Menu:Tools:Example Tool Sliced Process...",
141 | invoke = function()
142 | create_gui()
143 | end
144 | }
145 |
146 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Document.ObservableNumberList.md:
--------------------------------------------------------------------------------
1 | # renoise.Document.ObservableNumberList
2 | > A observable list of number values.
3 |
4 |
5 |
6 |
7 | ---
8 | ## Functions
9 | ### to_string([*self*](../../API/builtins/self.md))
10 | `->`[`string`](../../API/builtins/string.md)
11 |
12 | > Serialize an object to a string.
13 | ### from_string([*self*](../../API/builtins/self.md), string : [`any`](../../API/builtins/any.md))
14 | `->`[`string`](../../API/builtins/string.md)
15 |
16 | > Assign the object's value from a string - when possible. Errors are
17 | > silently ignored.
18 | ### size([*self*](../../API/builtins/self.md))
19 | `->`[`integer`](../../API/builtins/integer.md)
20 |
21 | > Returns the number of entries of the list.
22 | ### has_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction))
23 | > Checks if the given function, method was already registered as notifier.
24 | ### add_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction))
25 | > Register a function or method as a notifier, which will be called as soon as
26 | > the observable lists layout changed. The passed notifier can either be a function
27 | > or a table with a function and some context (an "object") -> method.
28 | ### remove_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction) | [`ListNotifierMemberContext`](#ListNotifierMemberContext))
29 | > Unregister a previously registered list notifier. When only passing an object,
30 | > all notifier functions that match the given object will be removed.
31 | > This will not fire errors when no methods for the given object are attached.
32 | > Trying to unregister a function or method which wasn't registered, will resolve
33 | > into an error.
34 | ### property([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
35 | `->`[`renoise.Document.ObservableNumber`](../../API/renoise/renoise.Document.ObservableNumber.md)[`?`](../../API/builtins/nil.md)
36 |
37 | > List item access by index. returns nil for non existing items.
38 | ### find([*self*](../../API/builtins/self.md), start_pos : [`integer`](../../API/builtins/integer.md), value : [`number`](../../API/builtins/number.md))
39 | `->`[`integer`](../../API/builtins/integer.md)[`?`](../../API/builtins/nil.md)
40 |
41 | > Find a value in the list by comparing the list values with the passed
42 | > value. The first successful match is returned. When no match is found, nil
43 | > is returned.
44 | ### insert([*self*](../../API/builtins/self.md), pos : [`integer`](../../API/builtins/integer.md), value : [`number`](../../API/builtins/number.md))
45 | `->`[`renoise.Document.ObservableNumber`](../../API/renoise/renoise.Document.ObservableNumber.md)
46 |
47 | > Insert a new item to the end of the list when no position is specified, or
48 | > at the specified position. Returns the newly created and inserted Observable.
49 | ### remove([*self*](../../API/builtins/self.md), pos : [`integer`](../../API/builtins/integer.md))
50 | > Removes an item (or the last one if no index is specified) from the list.
51 | ### swap([*self*](../../API/builtins/self.md), pos1 : [`integer`](../../API/builtins/integer.md), pos2 : [`integer`](../../API/builtins/integer.md))
52 | > Swaps the positions of two items without adding/removing the items.
53 | > With a series of swaps you can move the item from/to any position.
54 |
55 |
56 |
57 | ---
58 | ## Aliases
59 | ### ListElementAdded
60 | { index : [`integer`](../../API/builtins/integer.md), type : `"insert"` }
61 |
62 |
63 | ### ListElementChange
64 | [`ListElementAdded`](#ListElementAdded) | [`ListElementRemoved`](#ListElementRemoved) | [`ListElementsSwapped`](#ListElementsSwapped)
65 |
66 |
67 | ### ListElementRemoved
68 | { index : [`integer`](../../API/builtins/integer.md), type : `"remove"` }
69 |
70 |
71 | ### ListElementsSwapped
72 | { index1 : [`integer`](../../API/builtins/integer.md), index2 : [`integer`](../../API/builtins/integer.md), type : `"swap"` }
73 |
74 |
75 | ### ListNotifierFunction
76 | (change : [`ListElementChange`](#ListElementChange))
77 |
78 |
79 | ### ListNotifierMemberContext
80 | [`table`](../../API/builtins/table.md) | [`userdata`](../../API/builtins/userdata.md)
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Document.ObservableStringList.md:
--------------------------------------------------------------------------------
1 | # renoise.Document.ObservableStringList
2 | > A observable list of string values.
3 |
4 |
5 |
6 |
7 | ---
8 | ## Functions
9 | ### to_string([*self*](../../API/builtins/self.md))
10 | `->`[`string`](../../API/builtins/string.md)
11 |
12 | > Serialize an object to a string.
13 | ### from_string([*self*](../../API/builtins/self.md), string : [`any`](../../API/builtins/any.md))
14 | `->`[`string`](../../API/builtins/string.md)
15 |
16 | > Assign the object's value from a string - when possible. Errors are
17 | > silently ignored.
18 | ### size([*self*](../../API/builtins/self.md))
19 | `->`[`integer`](../../API/builtins/integer.md)
20 |
21 | > Returns the number of entries of the list.
22 | ### has_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction))
23 | > Checks if the given function, method was already registered as notifier.
24 | ### add_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction))
25 | > Register a function or method as a notifier, which will be called as soon as
26 | > the observable lists layout changed. The passed notifier can either be a function
27 | > or a table with a function and some context (an "object") -> method.
28 | ### remove_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction) | [`ListNotifierMemberContext`](#ListNotifierMemberContext))
29 | > Unregister a previously registered list notifier. When only passing an object,
30 | > all notifier functions that match the given object will be removed.
31 | > This will not fire errors when no methods for the given object are attached.
32 | > Trying to unregister a function or method which wasn't registered, will resolve
33 | > into an error.
34 | ### property([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
35 | `->`[`renoise.Document.ObservableString`](../../API/renoise/renoise.Document.ObservableString.md)[`?`](../../API/builtins/nil.md)
36 |
37 | > List item access by index. returns nil for non existing items.
38 | ### find([*self*](../../API/builtins/self.md), start_pos : [`integer`](../../API/builtins/integer.md), value : [`number`](../../API/builtins/number.md))
39 | `->`[`integer`](../../API/builtins/integer.md)[`?`](../../API/builtins/nil.md)
40 |
41 | > Find a value in the list by comparing the list values with the passed
42 | > value. The first successful match is returned. When no match is found, nil
43 | > is returned.
44 | ### insert([*self*](../../API/builtins/self.md), pos : [`integer`](../../API/builtins/integer.md), value : [`number`](../../API/builtins/number.md))
45 | `->`[`renoise.Document.ObservableString`](../../API/renoise/renoise.Document.ObservableString.md)
46 |
47 | > Insert a new item to the end of the list when no position is specified, or
48 | > at the specified position. Returns the newly created and inserted Observable.
49 | ### remove([*self*](../../API/builtins/self.md), pos : [`integer`](../../API/builtins/integer.md))
50 | > Removes an item (or the last one if no index is specified) from the list.
51 | ### swap([*self*](../../API/builtins/self.md), pos1 : [`integer`](../../API/builtins/integer.md), pos2 : [`integer`](../../API/builtins/integer.md))
52 | > Swaps the positions of two items without adding/removing the items.
53 | > With a series of swaps you can move the item from/to any position.
54 |
55 |
56 |
57 | ---
58 | ## Aliases
59 | ### ListElementAdded
60 | { index : [`integer`](../../API/builtins/integer.md), type : `"insert"` }
61 |
62 |
63 | ### ListElementChange
64 | [`ListElementAdded`](#ListElementAdded) | [`ListElementRemoved`](#ListElementRemoved) | [`ListElementsSwapped`](#ListElementsSwapped)
65 |
66 |
67 | ### ListElementRemoved
68 | { index : [`integer`](../../API/builtins/integer.md), type : `"remove"` }
69 |
70 |
71 | ### ListElementsSwapped
72 | { index1 : [`integer`](../../API/builtins/integer.md), index2 : [`integer`](../../API/builtins/integer.md), type : `"swap"` }
73 |
74 |
75 | ### ListNotifierFunction
76 | (change : [`ListElementChange`](#ListElementChange))
77 |
78 |
79 | ### ListNotifierMemberContext
80 | [`table`](../../API/builtins/table.md) | [`userdata`](../../API/builtins/userdata.md)
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Document.ObservableBooleanList.md:
--------------------------------------------------------------------------------
1 | # renoise.Document.ObservableBooleanList
2 | > A observable list of boolean values.
3 |
4 |
5 |
6 |
7 | ---
8 | ## Functions
9 | ### to_string([*self*](../../API/builtins/self.md))
10 | `->`[`string`](../../API/builtins/string.md)
11 |
12 | > Serialize an object to a string.
13 | ### from_string([*self*](../../API/builtins/self.md), string : [`any`](../../API/builtins/any.md))
14 | `->`[`string`](../../API/builtins/string.md)
15 |
16 | > Assign the object's value from a string - when possible. Errors are
17 | > silently ignored.
18 | ### size([*self*](../../API/builtins/self.md))
19 | `->`[`integer`](../../API/builtins/integer.md)
20 |
21 | > Returns the number of entries of the list.
22 | ### has_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction))
23 | > Checks if the given function, method was already registered as notifier.
24 | ### add_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction))
25 | > Register a function or method as a notifier, which will be called as soon as
26 | > the observable lists layout changed. The passed notifier can either be a function
27 | > or a table with a function and some context (an "object") -> method.
28 | ### remove_notifier([*self*](../../API/builtins/self.md), notifier : [`ListNotifierFunction`](#ListNotifierFunction) | [`ListNotifierMemberContext`](#ListNotifierMemberContext))
29 | > Unregister a previously registered list notifier. When only passing an object,
30 | > all notifier functions that match the given object will be removed.
31 | > This will not fire errors when no methods for the given object are attached.
32 | > Trying to unregister a function or method which wasn't registered, will resolve
33 | > into an error.
34 | ### property([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
35 | `->`[`renoise.Document.ObservableBoolean`](../../API/renoise/renoise.Document.ObservableBoolean.md)[`?`](../../API/builtins/nil.md)
36 |
37 | > List item access by index. returns nil for non existing items.
38 | ### find([*self*](../../API/builtins/self.md), start_pos : [`integer`](../../API/builtins/integer.md), value : [`boolean`](../../API/builtins/boolean.md))
39 | `->`[`integer`](../../API/builtins/integer.md)[`?`](../../API/builtins/nil.md)
40 |
41 | > Find a value in the list by comparing the list values with the passed
42 | > value. The first successful match is returned. When no match is found, nil
43 | > is returned.
44 | ### insert([*self*](../../API/builtins/self.md), pos : [`integer`](../../API/builtins/integer.md), value : [`boolean`](../../API/builtins/boolean.md))
45 | `->`[`renoise.Document.ObservableBoolean`](../../API/renoise/renoise.Document.ObservableBoolean.md)
46 |
47 | > Insert a new item to the end of the list when no position is specified, or
48 | > at the specified position. Returns the newly created and inserted Observable.
49 | ### remove([*self*](../../API/builtins/self.md), pos : [`integer`](../../API/builtins/integer.md))
50 | > Removes an item (or the last one if no index is specified) from the list.
51 | ### swap([*self*](../../API/builtins/self.md), pos1 : [`integer`](../../API/builtins/integer.md), pos2 : [`integer`](../../API/builtins/integer.md))
52 | > Swaps the positions of two items without adding/removing the items.
53 | >
54 | > With a series of swaps you can move the item from/to any position.
55 |
56 |
57 |
58 | ---
59 | ## Aliases
60 | ### ListElementAdded
61 | { index : [`integer`](../../API/builtins/integer.md), type : `"insert"` }
62 |
63 |
64 | ### ListElementChange
65 | [`ListElementAdded`](#ListElementAdded) | [`ListElementRemoved`](#ListElementRemoved) | [`ListElementsSwapped`](#ListElementsSwapped)
66 |
67 |
68 | ### ListElementRemoved
69 | { index : [`integer`](../../API/builtins/integer.md), type : `"remove"` }
70 |
71 |
72 | ### ListElementsSwapped
73 | { index1 : [`integer`](../../API/builtins/integer.md), index2 : [`integer`](../../API/builtins/integer.md), type : `"swap"` }
74 |
75 |
76 | ### ListNotifierFunction
77 | (change : [`ListElementChange`](#ListElementChange))
78 |
79 |
80 | ### ListNotifierMemberContext
81 | [`table`](../../API/builtins/table.md) | [`userdata`](../../API/builtins/userdata.md)
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.Osc.md:
--------------------------------------------------------------------------------
1 | # renoise.Osc
2 | > OSC (Open Sound Control) support for Lua scripts in Renoise.
3 |
4 |
5 |
6 |
7 | ---
8 | ## Functions
9 | ### from_binary_data(binary_data : [`string`](../../API/builtins/string.md))
10 | `->`[`renoise.Osc.Bundle`](../../API/renoise/renoise.Osc.Bundle.md) | [`renoise.Osc.Message`](../../API/renoise/renoise.Osc.Message.md)[`?`](../../API/builtins/nil.md), [`string`](../../API/builtins/string.md)[`?`](../../API/builtins/nil.md)
11 |
12 | > De-packetizing raw (socket) data to OSC messages or bundles:
13 | > Converts the binary data to an OSC message or bundle. If the data does not
14 | > look like an OSC message, or the message contains errors, nil is returned
15 | > as first argument and the second return value will contain the error.
16 | > If de-packetizing was successful, either a renoise.Osc.Bundle or Message
17 | > object is returned. Bundles may contain multiple messages or nested bundles.
18 | ### Message(pattern : [`string`](../../API/builtins/string.md), arguments : [`OscValue`](#oscvalue)[][`?`](../../API/builtins/nil.md))
19 | `->`[`renoise.Osc.Message`](../../API/renoise/renoise.Osc.Message.md)
20 |
21 | > Create a new OSC message with the given pattern and optional arguments.
22 | ### Bundle(time : [`integer`](../../API/builtins/integer.md), arguments : [`renoise.Osc.Message`](../../API/renoise/renoise.Osc.Message.md) | [`renoise.Osc.Message`](../../API/renoise/renoise.Osc.Message.md)[])
23 | `->`[`renoise.Osc.Bundle`](../../API/renoise/renoise.Osc.Bundle.md)
24 |
25 | > Create a new bundle by specifying a time-tag and one or more messages.
26 | > If you do not know what to do with the time-tag, use `os.clock()`,
27 | > which simply means "now". Messages must be renoise.Osc.Message objects.
28 | > Nested bundles (bundles in bundles) are right now not supported.
29 |
30 |
31 |
32 | ---
33 | ## Structs
34 | # OscValue
35 | > `tag` is a standard OSC type tag. `value` is the arguments value expressed
36 | > by a Lua type. The value must be convertible to the specified tag, which
37 | > means, you cannot for example specify an "i" (integer) as type and then pass
38 | > a string as the value. Use a number value instead. Not all tags require a
39 | > value, like the T,F boolean tags. Then a `value` field should not be
40 | > specified. For more info, see: http://opensoundcontrol.org/spec-1_0
41 |
42 | ---
43 | ## Properties
44 | ### tag : [`OscTag`](#OscTag)
45 | ### value : [`boolean`](../../API/builtins/boolean.md) | [`string`](../../API/builtins/string.md) | [`number`](../../API/builtins/number.md)
46 |
47 |
48 |
49 |
50 | ---
51 | ## Aliases
52 | ### OscTag
53 | `"F"` | `"I"` | `"N"` | `"S"` | `"T"` | `"b"` | `"c"` | `"d"` | `"f"` | `"h"` | `"i"` | `"m"` | `"r"` | `"s"` | `"t"`
54 | > ```lua
55 | > OscTag:
56 | > | "i" -- int32
57 | > | "f" -- float32
58 | > | "s" -- OSC-string
59 | > | "b" -- OSC-blob (raw string)
60 | > | "h" -- 64 bit big-endian two's complement integer
61 | > | "t" -- OSC-timetag
62 | > | "d" -- 64 bit ("double") IEEE 754 floating point number
63 | > | "S" -- Alternate type represented as an OSC-string
64 | > | "c" -- An ascii character, sent as 32 bits
65 | > | "r" -- 32 bit RGBA color
66 | > | "m" -- 4 byte MIDI message. Bytes from MSB to LSB are: port id, status byte, data1, data2
67 | > | "T" -- True. No value needs to be specified.
68 | > | "F" -- False. No value needs to be specified.
69 | > | "N" -- Nil. No value needs to be specified.
70 | > | "I" -- Infinitum. No value needs to be specified.
71 | > ```
72 |
73 |
74 |
75 |
76 |
77 |
78 | ---
79 | ## Aliases
80 | ### OscTag
81 | `"F"` | `"I"` | `"N"` | `"S"` | `"T"` | `"b"` | `"c"` | `"d"` | `"f"` | `"h"` | `"i"` | `"m"` | `"r"` | `"s"` | `"t"`
82 | > ```lua
83 | > OscTag:
84 | > | "i" -- int32
85 | > | "f" -- float32
86 | > | "s" -- OSC-string
87 | > | "b" -- OSC-blob (raw string)
88 | > | "h" -- 64 bit big-endian two's complement integer
89 | > | "t" -- OSC-timetag
90 | > | "d" -- 64 bit ("double") IEEE 754 floating point number
91 | > | "S" -- Alternate type represented as an OSC-string
92 | > | "c" -- An ascii character, sent as 32 bits
93 | > | "r" -- 32 bit RGBA color
94 | > | "m" -- 4 byte MIDI message. Bytes from MSB to LSB are: port id, status byte, data1, data2
95 | > | "T" -- True. No value needs to be specified.
96 | > | "F" -- False. No value needs to be specified.
97 | > | "N" -- Nil. No value needs to be specified.
98 | > | "I" -- Infinitum. No value needs to be specified.
99 | > ```
100 |
101 |
102 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.PatternTrack.md:
--------------------------------------------------------------------------------
1 | # renoise.PatternTrack
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### is_alias : [`boolean`](../../API/builtins/boolean.md)
9 | > **READ-ONLY**
10 |
11 | ### alias_pattern_index : [`integer`](../../API/builtins/integer.md)
12 | > index or 0 when no alias is present
13 |
14 | ### alias_pattern_index_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
15 | > Track changes to document properties or general states by attaching listener
16 | > functions to it.
17 |
18 | ### color : [`RGBColor`](#RGBColor)[`?`](../../API/builtins/nil.md)
19 | > slot color of the pattern in the matrix, nil when no slot color is set
20 |
21 | ### color_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
22 | > Track changes to document properties or general states by attaching listener
23 | > functions to it.
24 |
25 | ### is_empty : [`boolean`](../../API/builtins/boolean.md)
26 | > Returns true when all the track lines are empty. Does not look at automation.
27 |
28 | ### is_empty_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
29 | > Track changes to document properties or general states by attaching listener
30 | > functions to it.
31 |
32 | ### lines : [`renoise.PatternLine`](../../API/renoise/renoise.PatternLine.md)[]
33 | > **READ-ONLY** Get all lines in range [1, number_of_lines_in_pattern].
34 | > Use `renoise.Pattern:add/remove_line_notifier` for change notifications.
35 |
36 | ### automation : [`renoise.PatternTrackAutomation`](../../API/renoise/renoise.PatternTrackAutomation.md)[]
37 | > Automation.
38 |
39 | ### automation_observable : [`renoise.Document.ObservableList`](../../API/renoise/renoise.Document.ObservableList.md)
40 | > Track changes to document lists by attaching listener functions to it.
41 | > NB: Notifiers will not broadcast changes made to list items, but only changes
42 | > to the lists **layout** (items got added, removed, swapped).
43 |
44 |
45 |
46 | ---
47 | ## Functions
48 | ### clear([*self*](../../API/builtins/self.md))
49 | > Deletes all lines & automation.
50 | ### copy_from([*self*](../../API/builtins/self.md), other : [`renoise.PatternTrack`](../../API/renoise/renoise.PatternTrack.md))
51 | > Copy contents from other pattern tracks, including automation when possible.
52 | ### line([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
53 | `->`[`renoise.PatternLine`](../../API/renoise/renoise.PatternLine.md)
54 |
55 | > Access to a single line by index. Line must be in Range: (1 - MAX_NUMBER_OF_LINES).
56 | > This is a !lot! more efficient than calling the property: lines[index] to
57 | > randomly access lines.
58 | ### lines_in_range([*self*](../../API/builtins/self.md), index_from : [`integer`](../../API/builtins/integer.md), index_to : [`integer`](../../API/builtins/integer.md))
59 | `->`[`renoise.PatternLine`](../../API/renoise/renoise.PatternLine.md)[]
60 |
61 | > Get a specific line range. Index must be Range: (1 - Pattern.MAX_NUMBER_OF_LINES)
62 | ### find_automation([*self*](../../API/builtins/self.md), parameter : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md))
63 | `->`[`renoise.PatternTrackAutomation`](../../API/renoise/renoise.PatternTrackAutomation.md)[`?`](../../API/builtins/nil.md)
64 |
65 | > Returns the automation for the given device parameter or nil when there is
66 | > none.
67 | ### create_automation([*self*](../../API/builtins/self.md), parameter : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md))
68 | `->`[`renoise.PatternTrackAutomation`](../../API/renoise/renoise.PatternTrackAutomation.md)
69 |
70 | > Creates a new automation for the given device parameter.
71 | > Fires an error when an automation for the given parameter already exists.
72 | > Returns the newly created automation. Passed parameter must be automatable,
73 | > which can be tested with 'parameter.is_automatable'.
74 | ### delete_automation([*self*](../../API/builtins/self.md), parameter : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md))
75 | > Remove an existing automation the given device parameter. Automation
76 | > must exist.
77 |
78 |
79 |
80 | ---
81 | ## Aliases
82 | ### RGBColor
83 | { 1 : [`integer`](../../API/builtins/integer.md), 2 : [`integer`](../../API/builtins/integer.md), 3 : [`integer`](../../API/builtins/integer.md) }
84 | > A table of 3 bytes (ranging from 0 to 255)
85 | > representing the red, green and blue channels of a color.
86 | > {0xFF, 0xFF, 0xFF} is white
87 | > {165, 73, 35} is the red from the Renoise logo
88 |
89 |
90 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.InstrumentTriggerOptions.md:
--------------------------------------------------------------------------------
1 | # renoise.InstrumentTriggerOptions
2 |
3 |
4 |
5 | ## Constants
6 | ### QuantizeMode
7 | > ```lua
8 | > {
9 | > QUANTIZE_NONE: integer = 1,
10 | > QUANTIZE_LINE: integer = 2,
11 | > QUANTIZE_BEAT: integer = 3,
12 | > QUANTIZE_BAR: integer = 4,
13 | > }
14 | > ```
15 |
16 |
17 | ---
18 | ## Properties
19 | ### available_scale_modes : [`string`](../../API/builtins/string.md)[]
20 | > **READ-ONLY** List of all available scale modes.
21 |
22 | ### scale_mode : [`string`](../../API/builtins/string.md)
23 | > one of 'available_scales']
24 |
25 | ### scale_mode_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
26 | > Track changes to document properties or general states by attaching listener
27 | > functions to it.
28 |
29 | ### scale_key : [`integer`](../../API/builtins/integer.md)
30 | > Scale-key to use when transposing (1=C, 2=C#, 3=D, ...)
31 |
32 | ### scale_key_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
33 | > Track changes to document properties or general states by attaching listener
34 | > functions to it.
35 |
36 | ### mts_esp_tuning : [`boolean`](../../API/builtins/boolean.md)
37 | > When true, act as MTS ESP client. Disables custom tunings.
38 |
39 | ### mts_esp_tuning_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
40 | > Track changes to document properties or general states by attaching listener
41 | > functions to it.
42 |
43 | ### tuning : [`number`](../../API/builtins/number.md)[]
44 | > Array of custom pitch values relative to 1/1, used as custom tuning values for
45 | > instrument sample playback. The root key is assumed to be middle C (48 in Renoise),
46 | > The scale will be repeated, so only one octave of values should be defined. An
47 | > octave may contain more or less than 12 notes.
48 | >
49 | > When set mts_esp_tuning is disabled. Set an empty table to disable custom tuning
50 | > using default 12-TET tuning instead.
51 | >
52 | > Use property `tuning_name` to give your custom tuning a name.
53 | >
54 | > #### examples:
55 | > ```lua
56 | > -- Andreas Werckmeister's temperament III (the most famous one, 1681)
57 | > local well_tempered_tuning = {
58 | > 256/243, 1.117403, 32/27, 1.252827, 4/3, 1024/729,
59 | > 1.494927, 128/81, 1.670436, 16/9, 1.879241, 2/1
60 | > }
61 | > instrument.tuning = well_tempered_tuning
62 | > ```
63 |
64 | ### tuning_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
65 | > Track changes to document properties or general states by attaching listener
66 | > functions to it.
67 |
68 | ### tuning_name : [`string`](../../API/builtins/string.md)
69 | > Name, as displayed in the UI for a custom tuning or a tuning loaded from a file.
70 |
71 | ### tuning_name_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
72 | > Track changes to document properties or general states by attaching listener
73 | > functions to it.
74 |
75 | ### quantize : [`renoise.InstrumentTriggerOptions.QuantizeMode`](renoise.InstrumentTriggerOptions.md#QuantizeMode)
76 | > Trigger quantization mode.
77 |
78 | ### quantize_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
79 | > Track changes to document properties or general states by attaching listener
80 | > functions to it.
81 |
82 | ### monophonic : [`boolean`](../../API/builtins/boolean.md)
83 | > Mono/Poly mode.
84 |
85 | ### monophonic_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
86 | > Track changes to document properties or general states by attaching listener
87 | > functions to it.
88 |
89 | ### monophonic_glide : [`integer`](../../API/builtins/integer.md)
90 | > Glide amount when monophonic. 0 == off, 255 = instant
91 |
92 | ### monophonic_glide_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
93 | > Track changes to document properties or general states by attaching listener
94 | > functions to it.
95 |
96 |
97 |
98 | ---
99 | ## Functions
100 | ### load_tuning([*self*](../../API/builtins/self.md), filename : [`string`](../../API/builtins/string.md))
101 | `->`success : [`boolean`](../../API/builtins/boolean.md)
102 |
103 | > Load and apply a scala tuning file as custom tuning. Disables `mts_esp_tuning`.
104 | > Any errors during the export are shown to the user.
105 |
106 |
--------------------------------------------------------------------------------
/tests/sample_device_chain.lua:
--------------------------------------------------------------------------------
1 | --[[--------------------------------------------------------------------------
2 | TestSampleDeviceChain.lua
3 | --------------------------------------------------------------------------]]--
4 |
5 | do
6 |
7 | ----------------------------------------------------------------------------
8 | -- tools
9 |
10 | local function assert_error(statement)
11 | assert(pcall(statement) == false, "expected function error")
12 | end
13 |
14 |
15 | -- shortcuts
16 |
17 | local song = renoise.song()
18 | local selected_instrument = song.selected_instrument
19 |
20 |
21 | ----------------------------------------------------------------------------
22 | -- device chain insert/delete/swap
23 | ----------------------------------------------------------------------------
24 |
25 | selected_instrument:insert_sample_device_chain_at(1)
26 |
27 | while (#selected_instrument.sample_device_chains > 0) do
28 | selected_instrument:delete_sample_device_chain_at(1)
29 | end
30 |
31 | assert(#selected_instrument.sample_device_chains == 0)
32 |
33 | new_chain1 = selected_instrument:insert_sample_device_chain_at(1)
34 | assert(type(new_chain1) == "SampleDeviceChain")
35 | new_chain1.name = "Wurst"
36 |
37 | new_chain2 = selected_instrument:insert_sample_device_chain_at(2)
38 | assert(type(new_chain2) == "SampleDeviceChain")
39 | new_chain2.name = "Hose"
40 |
41 | selected_instrument:swap_sample_device_chains_at(1, 2)
42 | assert(selected_instrument.sample_device_chains[1].name == "Hose")
43 | assert(selected_instrument.sample_device_chains[2].name == "Wurst")
44 |
45 |
46 | ----------------------------------------------------------------------------
47 | -- device insert/delete/swap
48 | ----------------------------------------------------------------------------
49 |
50 | local avail_devices =
51 | selected_instrument.sample_device_chains[1].available_devices
52 |
53 | local new_device_path
54 | repeat
55 | new_device_path = avail_devices[math.random(1, #avail_devices)]
56 | until
57 | -- avoid plugins, cause they may fail to load and pop up dialogs
58 | not string.find(new_device_path, "VST") and
59 | not string.find(new_device_path, "AU")
60 |
61 |
62 | assert_error(function()
63 | new_chain1:insert_device_at("InvalidDeviceName#234",
64 | #new_chain1.devices + 1)
65 | end)
66 |
67 | -- mixer device tests
68 | assert_error(function()
69 | new_chain1:insert_device_at(new_device_path, 1)
70 | end)
71 |
72 | assert_error(function()
73 | new_chain1:delete_device_at(1)
74 | end)
75 |
76 | local device_count = #new_chain1.devices
77 |
78 | local new_device = new_chain1:insert_device_at(
79 | new_device_path, device_count + 1)
80 | device_count = device_count + 1
81 | assert(device_count == #new_chain1.devices)
82 |
83 | local found_device = false
84 | local found_device_path = false
85 |
86 | for _,device in ipairs(new_chain1.devices) do
87 | if device.name == new_device.name then
88 | found_device = true
89 | end
90 | if device.device_path == new_device_path then
91 | found_device_path = true
92 | end
93 | end
94 |
95 | assert(found_device)
96 | assert(found_device_path)
97 |
98 | new_chain1:delete_device_at(#new_chain1.devices)
99 | device_count = device_count - 1
100 | assert(device_count == #new_chain1.devices)
101 |
102 | new_chain1:insert_device_at(new_device_path,
103 | #new_chain1.devices + 1)
104 | new_chain1:insert_device_at(new_device_path,
105 | #new_chain1.devices + 1)
106 |
107 | device_count = device_count + 2
108 | assert(device_count == #new_chain1.devices)
109 |
110 | new_chain1:swap_devices_at(
111 | #new_chain1.devices,
112 | #new_chain1.devices - 1)
113 |
114 | assert(device_count == #new_chain1.devices)
115 |
116 | new_chain1:delete_device_at(#new_chain1.devices)
117 | new_chain1:delete_device_at(#new_chain1.devices)
118 |
119 | device_count = device_count - 2
120 | assert(device_count == #new_chain1.devices)
121 |
122 |
123 | -- preset handing
124 |
125 | local mixer_device = new_chain1.devices[1]
126 | assert(#mixer_device.presets == 1) -- init
127 |
128 | new_chain1:insert_device_at(new_device_path,
129 | #new_chain1.devices + 1)
130 |
131 | local new_device = new_chain1.devices[
132 | #new_chain1.devices]
133 |
134 | assert(#new_device.presets >= 1)
135 | assert(new_device.active_preset >= 1)
136 |
137 | local new_preset = math.random(#new_device.presets)
138 | new_device.active_preset = new_preset
139 | assert(new_device.active_preset == new_preset)
140 |
141 | assert_error(function()
142 | new_device.active_preset = 0
143 | end)
144 | assert_error(function()
145 | new_device.active_preset = #new_device.presets + 1
146 | end)
147 | end
148 |
149 |
150 | ------------------------------------------------------------------------------
151 | -- test finalizers
152 |
153 | collectgarbage()
154 |
155 |
156 | --[[--------------------------------------------------------------------------
157 | --------------------------------------------------------------------------]]--
158 |
--------------------------------------------------------------------------------
/docs/API/renoise/renoise.SampleOperandModulationDevice.md:
--------------------------------------------------------------------------------
1 | # renoise.SampleOperandModulationDevice
2 |
3 |
4 |
5 |
6 | ---
7 | ## Properties
8 | ### name : [`string`](../../API/builtins/string.md)
9 | > **READ-ONLY** Fixed name of the device.
10 |
11 | ### short_name : [`string`](../../API/builtins/string.md)
12 | > **READ-ONLY**
13 |
14 | ### display_name : [`string`](../../API/builtins/string.md)
15 | > Configurable device display name.
16 |
17 | ### display_name_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
18 | > Track changes to document properties or general states by attaching listener
19 | > functions to it.
20 |
21 | ### enabled : [`boolean`](../../API/builtins/boolean.md)
22 | > **Deprecated.** Use `is_active` instead.
23 |
24 | ### enabled_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
25 | > Track changes to document properties or general states by attaching listener
26 | > functions to it.
27 |
28 | ### is_active : [`boolean`](../../API/builtins/boolean.md)
29 | > not active = bypassed
30 |
31 | ### is_active_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
32 | > Track changes to document properties or general states by attaching listener
33 | > functions to it.
34 |
35 | ### is_maximized : [`boolean`](../../API/builtins/boolean.md)
36 | > Maximize state in modulation chain.
37 |
38 | ### is_maximized_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
39 | > Track changes to document properties or general states by attaching listener
40 | > functions to it.
41 |
42 | ### target : [`renoise.SampleModulationDevice.TargetType`](renoise.SampleModulationDevice.md#TargetType)
43 | > **READ-ONLY** Where the modulation gets applied (Volume,
44 | > Pan, Pitch, Cutoff, Resonance).
45 |
46 | ### operator : [`renoise.SampleModulationDevice.OperatorType`](renoise.SampleModulationDevice.md#OperatorType)
47 | > Modulation operator: how the device applies.
48 |
49 | ### operator_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
50 | > Track changes to document properties or general states by attaching listener
51 | > functions to it.
52 |
53 | ### bipolar : [`boolean`](../../API/builtins/boolean.md)
54 | > Modulation polarity:
55 | > when bipolar, the device applies it's values in a -1 to 1 range,
56 | > when unipolar in a 0 to 1 range.
57 |
58 | ### bipolar_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
59 | > Track changes to document properties or general states by attaching listener
60 | > functions to it.
61 |
62 | ### tempo_sync_switching_allowed : [`boolean`](../../API/builtins/boolean.md)
63 | > **READ-ONLY** When true, the device has one of more time parameters,
64 | > which can be switched to operate in synced or unsynced mode.
65 | > see also field tempo_synced.
66 |
67 | ### tempo_synced : [`boolean`](../../API/builtins/boolean.md)
68 | > When true and the device supports sync switching the device operates
69 | > in wall-clock (ms) instead of beat times.
70 | > see also property 'tempo_sync_switching_allowed'
71 |
72 | ### tempo_synced_observable : [`renoise.Document.Observable`](../../API/renoise/renoise.Document.Observable.md)
73 | > Track changes to document properties or general states by attaching listener
74 | > functions to it.
75 |
76 | ### is_active_parameter : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)
77 | > **READ-ONLY** Generic access to all parameters of this device.
78 |
79 | ### parameters : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)[]
80 | > **READ-ONLY**
81 |
82 | ### value : [`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)
83 | > Operand value.
84 |
85 |
86 |
87 | ---
88 | ## Functions
89 | ### init([*self*](../../API/builtins/self.md))
90 | > Reset the device to its default state.
91 | ### copy_from([*self*](../../API/builtins/self.md), other_device : [`renoise.SampleModulationDevice`](../../API/renoise/renoise.SampleModulationDevice.md))
92 | > Copy a device's state from another device. 'other_device' must be of the
93 | > same type.
94 | ### parameter([*self*](../../API/builtins/self.md), index : [`integer`](../../API/builtins/integer.md))
95 | `->`[`renoise.DeviceParameter`](../../API/renoise/renoise.DeviceParameter.md)
96 |
97 | > Access to a single parameter by index. Use properties 'parameters' to iterate
98 | > over all parameters and to query the parameter count.
99 |
100 |
--------------------------------------------------------------------------------