# Libwing SDK Documentation
Libwing is a C++ library for interfacing with Behringer Wing digital mixing
consoles. It provides functionality for discovering Wing consoles on the
network, connecting to them, reading/writing console parameters, and receiving
any changes made on the mixer itself.
There is a C wrapper for this library. It generally follows the C++ API. You
can find it in `wing_c_api.h`.
## Basic Concepts
The Wing console exposes its functionality through a tree of nodes. Each node has:
- A unique numeric ID
- A hierarchical path name (like a filesystem path)
- A type (string, float, integer, enum, etc.)
- Optional min/max values and units
- Read/write or read-only access
## Getting Started
### Discovery
To find Wing consoles on your network:
```cpp
auto discovered = WingConsole::scan();
if (!discovered.empty()) {
// Found at least one console
auto firstConsole = discovered[0];
std::cout << "Found console: " << firstConsole.name
<< " at IP: " << firstConsole.ip << std::endl;
}
```
### Connecting
Once you have a console's IP address, you can connect to it:
```cpp
WingConsole console = WingConsole::connect("192.168.1.100");
```
### Communication Model
The Wing console uses an asynchronous communication model:
1. You make requests using methods like `requestNodeDefinition()` and `requestNodeData()`
2. Responses come back through callback functions you register
3. The Wing device also sends unsolicited updates when values change on the mixer
4. All messages are received through the `read()` method, which never returns
### Callbacks
Register callbacks to handle different types of messages. These callbacks will
be called on the thread from which the `read()` method was called.
```cpp
// Called when a node definition is received
console.onNodeDefinition = [](NodeDefinition node) {
std::cout << "Got definition for node: " << node.name << std::endl;
};
// Called when node data/values are received, in response to a request or
// unsolicited due to manipulation of the console
console.onNodeData = [](uint32_t id, NodeData data) {
std::cout
<< "Node "
<< NodeDefinition::nodeIdToName(id)
<< " ("
<< id
<< ") = "
<< data.getString()
<< std::endl;
};
// Called when a request is complete. You will get one of these for each time
// you call `requestNodeDefinition()` or `requestNodeData()`.
console.onRequestEnd = []() {
std::cout << "Request completed" << std::endl;
};
```
### IDs and Names
Nodes are identified by numeric IDs. You can convert between IDs and names:
```cpp
uint32_t id = WingConsole::nodeNameToId(name); // Returns the ID for this node
```
and
```cpp
std::string name = WingConsole::nodeIdToName(id); // Returns the ID for this node
```
The mapping of name to ID is generated by the `wingschema` utility and is
pulled into the lirbary at compile time. It is quite large (over 35k entries as
of firmware 3.0.5), and adds about 1MB to the library size. If you need this
trimmed and can give up this name/id mapping, just delete all (or some) of the
rows in `wing-schema.cpp`.
### Reading Data
To start receiving data:
```cpp
console.read(); // This blocks and processes incoming messages
```
You can request data from the console:
```cpp
// Request a node definition -- this is the schema of the node.
// You can pass zero (0) to get the root nodes.
console.requestNodeDefinition(id);
```
```cpp
// Request a node's data -- this is the parameter value.
console.requestNodeData(id);
```
These methods can be called on any thread.
### Writing Data
To change values on the console:
```cpp
// Set values by node ID
console.setString(nodeId, "value");
console.setFloat(nodeId, 0.5f);
console.setInt(nodeId, 42);
```
These methods can be called on any thread.
## Example Programs
### wingmon
The `wingmon` program demonstrates basic connection and monitoring:
- Discovers consoles on the network
- Connects to the first one found
- Monitors and displays value changes
### wingschema
The `wingschema` program shows how to:
- Traverse the entire node tree
- Request and process node definitions
- Generate documentation of the console's parameter space
- Handle asynchronous responses systematically