<commit_before>% libmapper tutorial

Introduction
============

This tutorial introduces a new user to _libmapper_, providing steps to
construct _devices_ that are compatible with the _libmapper_ network
protocol.  Programs that implement a _device_ interface provide
_signals_, which can be inputs or outputs, which are announced on the
network.  A compatible GUI program can then be used to _map_ signals
between devices.

Conceptually, a device typically consists only of outputs, for example
in the case of a program that gets information from a human input
device like a joystick, or only of inputs, for example a
software-controlled synthesizer.  For convenience, we will call output
devices "controllers", or "senders", and input devices "synthesizers",
or "receivers".  This betrays the use case that was in mind when the
_libmapper_ system was conceived, but of course receivers could just
as well be programs that control motors, lights, or anything else that
might need control information.  Similarly, senders could easily be
programs that generate trajectory data based on algorithmic
composition, or whatever you can imagine.

It is also possible to create devices which have inputs and outputs,
and these can be mapped "in between" senders and receivers in order to
perform some intermediate processing for example.  However, this is a
more advanced topic that won't be covered in this tutorial.

First we will cover how to create a sender, and then how to create a
receiver.  This should be enough for you to try creating a mapping and
explore the possibilities afforded by dynamic mapping design.

Getting started
===============

Since _libmapper_ uses GNU autoconf, getting started with the library
is the same as any other library on Linux; use `./configure` and then
`make` to compile it.  You'll need `swig` available if you want to
compile the Python bindings.  On Mac OS X, we provide a precompiled
Framework bundle for 32- and 64-bit Intel platforms, so using it with
XCode should be a matter of including it in your project.

Overview of the API organization
================================

If you take a look at the API documentation, there is a section called
"modules".  This is divided into the following sections:

* Signals
* Devices
* Admins
* Device database
* Signal database
* Mappings database
* Links database
* Monitors

For this tutorial, the only sections to pay attention to are Devices
and Signals.  Admins is reserved for providing custom networking
configurations, but in general you don't need to worry about it.

Monitor and the various database modules are used to keep track of
what devices, signals and mappings are on the network.  Devices do not
need to worry about this.  It is used mainly for creating user
interfaces for mapping design and will also not be covered here.

Functions and types from each module are prefixed with
`mapper_<module>_`, in order to avoid namespace clashing.  However,
since this is a bit verbose, it is shortened to `mdev_` and `msig` for
device and signal functions respectively.

Devices
=======

Creating a device
-----------------

To create a _libmapper_ device, it is necessary to provide a few
parameters to `mdev_new`:

    mapper_device mdev_new( const char *name_prefix,
                            int initial_port,
                            mapper_admin admin )

Every device on the network needs a name and port.  In fact the
requested name and port are only "starting values".  There is an
initialization period after a device is created where a unique ordinal
is chosen to append to the device name.  This allows multiple devices
with the same name to exist on the network.

Similarly, each device gets a unique port to use for exchanging signal
data.  The provided port number is the "starting port", but the
allocation algorithm will possibly choose another port number close to
it if someone else on the network is already using it.  We usually use
a port number of 9000, and let the system decide if this is
appropriate.^[Strictly this is only necessary for devices on the same
computer, but port numbers are in abundance so we just allocate one
per device to keep things consistant.]

The third parameter of mdev_new is an optional admin instance.  It is
not necessary to provide this, but can be used to specify different
networking parameters, such as specifying the name of the network
interface to use.

An example of creating a device:

    mapper_device my_device = mdev_new("test", 9000, 0);

Polling the device
------------------

The device lifecycle looks like this, in terrible ASCII diagram art:

    mdev_new -> mdev_poll +-> mdev_free
                  |       |
                  +----<--+

In other words, after a device is created, it must be continuously
polled during its lifetime, and then explicitly freed when it is no
longer needed.

The polling is necessary for several reasons: to respond to requests
on the admin bus; to check for incoming signals; to update outgoing
signals.  Therefore even a device that does not have signals must be
polled.  The user program must organize to have a timer or idle
handler which can poll the device often enough.  Polling interval is
not extremely sensitive, but should be at least 100 ms or less.  The
faster it is polled, the faster it can handle incoming and outgoing
signals.

The `mdev_poll` function can be blocking or non-blocking, depending on
how you want your application to behave.  It takes a number of
milliseconds during which it should do some work, or 0 if it should
check for any immediate actions and then return without waiting:

    int mdev_poll( mapper_device md,
                   int block_ms )

An example of calling it with non-blocking behaviour:

    mdev_poll( my_device, 0 );

If your polling is in the middle of a processing function or in
response to a GUI event for example, non-blocking behaviour is
desired.  On the other hand if you put it in the middle of a loop
which reads incoming data at intervals or steps through a simulation
for example, you can use `mdev_poll` as your "sleep" function, so that
it will wait on network activity while

It returns the number of messages handled, so optionally you could<commit_msg>Fix unfinished sentence in tutorial.<commit_after>% libmapper tutorial

Introduction
============

This tutorial introduces a new user to _libmapper_, providing steps to
construct _devices_ that are compatible with the _libmapper_ network
protocol.  Programs that implement a _device_ interface provide
_signals_, which can be inputs or outputs, which are announced on the
network.  A compatible GUI program can then be used to _map_ signals
between devices.

Conceptually, a device typically consists only of outputs, for example
in the case of a program that gets information from a human input
device like a joystick, or only of inputs, for example a
software-controlled synthesizer.  For convenience, we will call output
devices "controllers", or "senders", and input devices "synthesizers",
or "receivers".  This betrays the use case that was in mind when the
_libmapper_ system was conceived, but of course receivers could just
as well be programs that control motors, lights, or anything else that
might need control information.  Similarly, senders could easily be
programs that generate trajectory data based on algorithmic
composition, or whatever you can imagine.

It is also possible to create devices which have inputs and outputs,
and these can be mapped "in between" senders and receivers in order to
perform some intermediate processing for example.  However, this is a
more advanced topic that won't be covered in this tutorial.

First we will cover how to create a sender, and then how to create a
receiver.  This should be enough for you to try creating a mapping and
explore the possibilities afforded by dynamic mapping design.

Getting started
===============

Since _libmapper_ uses GNU autoconf, getting started with the library
is the same as any other library on Linux; use `./configure` and then
`make` to compile it.  You'll need `swig` available if you want to
compile the Python bindings.  On Mac OS X, we provide a precompiled
Framework bundle for 32- and 64-bit Intel platforms, so using it with
XCode should be a matter of including it in your project.

Overview of the API organization
================================

If you take a look at the API documentation, there is a section called
"modules".  This is divided into the following sections:

* Signals
* Devices
* Admins
* Device database
* Signal database
* Mappings database
* Links database
* Monitors

For this tutorial, the only sections to pay attention to are Devices
and Signals.  Admins is reserved for providing custom networking
configurations, but in general you don't need to worry about it.

Monitor and the various database modules are used to keep track of
what devices, signals and mappings are on the network.  Devices do not
need to worry about this.  It is used mainly for creating user
interfaces for mapping design and will also not be covered here.

Functions and types from each module are prefixed with
`mapper_<module>_`, in order to avoid namespace clashing.  However,
since this is a bit verbose, it is shortened to `mdev_` and `msig` for
device and signal functions respectively.

Devices
=======

Creating a device
-----------------

To create a _libmapper_ device, it is necessary to provide a few
parameters to `mdev_new`:

    mapper_device mdev_new( const char *name_prefix,
                            int initial_port,
                            mapper_admin admin )

Every device on the network needs a name and port.  In fact the
requested name and port are only "starting values".  There is an
initialization period after a device is created where a unique ordinal
is chosen to append to the device name.  This allows multiple devices
with the same name to exist on the network.

Similarly, each device gets a unique port to use for exchanging signal
data.  The provided port number is the "starting port", but the
allocation algorithm will possibly choose another port number close to
it if someone else on the network is already using it.  We usually use
a port number of 9000, and let the system decide if this is
appropriate.^[Strictly this is only necessary for devices on the same
computer, but port numbers are in abundance so we just allocate one
per device to keep things consistant.]

The third parameter of mdev_new is an optional admin instance.  It is
not necessary to provide this, but can be used to specify different
networking parameters, such as specifying the name of the network
interface to use.

An example of creating a device:

    mapper_device my_device = mdev_new("test", 9000, 0);

Polling the device
------------------

The device lifecycle looks like this, in terrible ASCII diagram art:

    mdev_new -> mdev_poll +-> mdev_free
                  |       |
                  +----<--+

In other words, after a device is created, it must be continuously
polled during its lifetime, and then explicitly freed when it is no
longer needed.

The polling is necessary for several reasons: to respond to requests
on the admin bus; to check for incoming signals; to update outgoing
signals.  Therefore even a device that does not have signals must be
polled.  The user program must organize to have a timer or idle
handler which can poll the device often enough.  Polling interval is
not extremely sensitive, but should be at least 100 ms or less.  The
faster it is polled, the faster it can handle incoming and outgoing
signals.

The `mdev_poll` function can be blocking or non-blocking, depending on
how you want your application to behave.  It takes a number of
milliseconds during which it should do some work, or 0 if it should
check for any immediate actions and then return without waiting:

    int mdev_poll( mapper_device md,
                   int block_ms )

An example of calling it with non-blocking behaviour:

    mdev_poll( my_device, 0 );

If your polling is in the middle of a processing function or in
response to a GUI event for example, non-blocking behaviour is
desired.  On the other hand if you put it in the middle of a loop
which reads incoming data at intervals or steps through a simulation
for example, you can use `mdev_poll` as your "sleep" function, so that
it will react to network activity while waiting.

It returns the number of messages handled, so optionally you could
{'fraction_non_alphanumeric': 0.04804997197084968, 'fraction_numerical': 0.002882998318250981, 'mean_word_length': 3.901098901098901, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6168316', 'n_tokens_mistral': 3136, 'n_tokens_neox': 2976, 'n_words': 1926}