.. This file is auto-generated by the Sphinx pre-build hook in
   ``docs/source/conf.py`` from ``docs/source/_data/patcher_objects.json``
   and the notes in ``docs/source/_data/patcher_notes/``.
   Do not edit by hand — run ``dart run tool/gen_patcher_snapshot.dart``
   to refresh the JSON from the bound engine and
   ``dart run tool/port_patcher_notes.dart`` to refresh the notes from the
   engine submodule, then rebuild the docs.

Collections
===========

Stores that hold numbers or messages for later recall.

6 objects. Every entry is
pulled directly from the engine registry, which reads the ``ADD_DESCRIPTION``
/ ``INLET_DOC`` / ``OUTLET_DOC`` / ``PARAM_DOC`` macros in the libYSE
source; the longer notes under each summary are ported from the libYSE
documentation. The ``~`` prefix marks DSP / audio-rate objects; ``.`` marks
control-rate objects. Links into the patcher guide (messages, time, data,
files, ...) lead to the libYSE documentation, which also has this
:yse-cpp:`category's page <patcher/objects/collections.html>`.

.. contents::
   :local:
   :depth: 1

``.bag``
--------

Holds a collection of numbers that a patch adds to and removes from, such as the notes currently held down. A bang sends every number, newest first.

:Dart: ``Obj.gBag``
:Kind: Control-rate

The left inlet takes the numbers, the right inlet says what to do with them:
while the flag is non-zero, numbers are added; while it is 0, they are
removed. The flag starts at 0, so set it before sending numbers. A float is truncated to an int on either inlet.

Adding and removing send nothing. A typical use is tracking held notes: add
the pitch on note-on, remove it on note-off, and bang to get the notes still
down.

**Messages**

- an int or float: add it or remove it, depending on the flag.
- ``<value> <flag>``: set the flag, then apply the value. ``60 1`` adds 60,
  ``60 0`` removes it. The flag stays set for later numbers.
- bang: send every stored number, newest first.
- ``cut``: send the oldest number and remove it.
- ``length``: send how many numbers are stored.
- ``clear``: remove everything.
- ``send <name>``: send what a bang would, but to every ``.r <name>`` (and the
  bus) instead of the outlet. It is a one-off: a later bang uses the outlet
  again. A bare ``send`` does nothing.

Without an argument each number is stored at most once, and adding one that
is already there changes nothing. With any argument (``.bag dup``) the same
number can be stored several times; a remove then takes the most recently
added copy.

**Limits**

At most 256 numbers; further adds are ignored. A ``send`` name is at most 63
characters. The contents are not saved with the patch (see
:yse-cpp:`What is saved with the patch <patcher/data.html#data-saved>`).

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - value
     - FLOAT, INT, BANG, LIST
     - any int
     - A number to add or remove, depending on the flag. Also bang, '<value> <flag>', 'cut', 'length', 'clear' and 'send <name>'.
   * - 1
     - flag
     - FLOAT, INT
     - 0 or non-zero
     - Non-zero: numbers on the left inlet are added. 0: they are removed. Starts at 0.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - INT
     - any int
     - Stored numbers, on bang or 'cut', and the count on 'length'.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - duplicates
     - —
     - any symbol
     - Any argument lets the same number be stored more than once. Without one, each number is held at most once.


``.capture``
------------

Records every value that reaches it, in arrival order, so a patch can be run and then asked what went past. When full, the oldest item makes room for the newest.

:Dart: ``Obj.gCapture``
:Kind: Control-rate

Every value that arrives is recorded. A list is recorded as separate items,
one per element, and each item keeps its type: an int stays an int, a float a
float, a word a word. Recording sends nothing.

When the record is full, each new item pushes out the oldest one, so it
always holds the most recent values. That makes it a debugging tool: run the
patch, then ``dump`` to see what went past.

**Messages**

- any value or list: record it.
- ``dump``: send every recorded item out of the left outlet, oldest first, one
  at a time. A word leaves as a one-word list.
- ``count``: send how many items have arrived since the last ``count`` out of
  the right outlet, and restart the count. ``count 1`` sends it without
  restarting. This counts arrivals, including items already pushed out, so it
  can be larger than the number of items held.
- ``clear``: erase the record. The ``count`` total is not reset.
- ``open``, ``wclose`` and ``write`` are accepted and do nothing: there is no
  editing window, and the record cannot be written to a file. Use
  ``.textfile`` for that.

A bang does nothing.

**Limits**

The argument sets the size, 1-512 items (default 512). A word longer than 64
characters is not recorded. The record is not saved with the patch.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - in
     - FLOAT, INT, LIST
     - any
     - Any value or list to record, one item per element. Also 'dump', 'clear' and 'count [keep]'.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - dump
     - ANY
     - any
     - The recorded items, oldest first, one at a time on 'dump'.
   * - 1
     - count
     - INT
     - any int
     - How many items arrived since the last 'count', on 'count'.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - maximum
     - 512
     - 1-512, optional display format
     - How many items the record holds, 1-512. A display-format letter may follow; it is ignored.


``.coll``
---------

Stores messages at number or symbol addresses and sends them back on request: presets, note tables, cue lists. All .coll objects with the same name share one collection.

:Dart: ``Obj.gColl``
:Kind: Control-rate

A collection of entries. Each entry is a message stored at an **address**,
which is a number or a word: the address ``1`` and the address ``one`` are
different entries. Numeric addresses don't have to be consecutive.

Entries are kept in the order they were stored, not sorted by address.
``dump``, ``next`` and ``prev`` walk that order; use ``sort`` to change it.

.. code-block:: text

   1 60 64 67          store "60 64 67" at address 1
   store intro 0 0 0   store "0 0 0" at address intro
   1                   send "60 64 67"
   intro               send "0 0 0"

**Storing and recalling**

- ``<number> <message>``: store the message at that numeric address,
  replacing what was there.
- ``store <address> <message>``: the same, for a number or a word address.
- an int or float: send the entry at that address (a float is truncated).
- a word on its own: send the entry at that word address. Anything after the
  word is ignored.
- ``insert <number> <message>``: store at that address, first moving every
  numeric address at or above it up by one.
- ``append <message>``: store at one past the highest numeric address (0 when
  there is none).
- ``merge <address> <data>``: add the data to the end of the entry's message,
  or create the entry.
- ``remove <address>``: delete the entry.
- ``delete <address>``: delete the entry and move every higher numeric
  address down by one.
- ``clear``: delete every entry.

An entry's message leaves the left outlet as an int or a float when it is one
number, and as a list otherwise (a single word is a one-word list). A plain
recall sends only the message; nothing is sent for an address that holds
nothing.

**Walking the collection**

Each ``.coll`` has a pointer into the stored order.

- bang: send the entry at the pointer.
- ``next`` / ``prev``: send the entry at the pointer, then move the pointer
  one forward or back. It wraps around at either end.
- ``goto <address>``: put the pointer on that entry, without sending.
- ``start`` / ``end``: put the pointer on the first or last entry.
- ``dump``: send every entry in order, then bang outlet 2.

These, and ``sub``, also send the entry's address out of outlet 1, just
before its message.

**Working inside entries**

Element positions count from 1.

- ``nth <address> <position>``: send one element of an entry.
- ``sub <address> <position> <data>``: replace one element, then send the
  entry. ``nsub`` does the same without sending.
- ``min [position]`` / ``max [position]``: send the lowest or highest number
  found at that position across all entries (default 1). Entries without a
  number there are skipped.
- ``length``: send the number of entries.

**Reordering and renumbering**

- ``sort [order] [position]``: reorder the entries. ``order`` -1 (the
  default) is ascending, 1 descending. The key is the element at
  ``position`` (default the first), or the address when ``position`` is -1.
  Numbers sort before words, and entries without that element come first.
  Equal keys keep their order.
- ``swap <address> <address>``: exchange the addresses of two entries; the
  messages stay where they are.
- ``renumber [start]``: give the numeric entries consecutive addresses from
  ``start`` (default 0), in stored order. Word addresses are not touched.
- ``renumber2 [from]``: move every numeric address at or above ``from``
  (default 0) up by one.
- ``separate <number>``: the same as ``renumber2``, but the address is
  required. It opens a free address at ``number``.

**Word aliases**

A numeric entry can have a second address, a word. From then on the word
reaches that entry in every message: recall, ``store``, ``remove``, ``nth``
and so on. The outlet still reports the number.

- ``assoc <word> <number>``: give the existing entry at ``number`` the alias
  ``word``. If another entry already answered to that word, it is removed.
- ``deassoc <word> <number>``: take the alias away again. Both must match.
- ``nstore <number> <word> <message>``: store at the number and give it the
  alias, in one message. The word may also come first.
- ``subsym <new> <old>``: rename a word address or alias. Refused when
  ``new`` is already in use.

An entry has at most one alias, and the alias moves with the entry through
``insert``, ``delete``, ``sort``, ``swap`` and renumbering.

**Files**

``read <file>`` replaces the collection with the contents of a text file,
then bangs outlet 3. ``write <file>`` saves the collection. ``readagain`` and
``writeagain``, or a bare ``read`` or ``write``, reuse the last file name.
``filetype`` is accepted and does nothing. The file format, and how reading
and writing work, are described in :yse-cpp:`File input and output <patcher/files.html>`.

**Sharing and saving**

The argument is a name. Every ``.coll`` with the same name uses the same
collection, and each keeps its own pointer. Without a name the collection is
private. A second argument is accepted and ignored. The contents are saved
with the patch. See :yse-cpp:`Sharing a store by name <patcher/data.html#data-sharing>` and :yse-cpp:`What is saved with the patch <patcher/data.html#data-saved>`.

**Limits**

At most 256 entries. A message is at most 256 characters and an address at
most 64. A store that does not fit is ignored. There is no editing window, and
a ``.coll`` cannot be pointed at another name while the patch runs.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - in
     - FLOAT, INT, BANG, LIST
     - at most 256 entries
     - A number or symbol recalls that address; '<number> <message>' stores; a bang sends the entry at the pointer. Also the commands listed in the notes.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - data
     - ANY
     - —
     - The entry's message: one number as an int or float, anything else as a list. Also the results of 'length', 'nth', 'min' and 'max'.
   * - 1
     - address
     - ANY
     - —
     - The entry's address, sent just before its data on bang, 'dump', 'next', 'prev' and 'sub'. Not sent on a plain recall.
   * - 2
     - done
     - BANG
     - —
     - A bang when a 'dump' has finished.
   * - 3
     - file
     - BANG
     - —
     - A bang when a 'read' has loaded a file. Silent when the read fails.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - name
     - —
     - any identifier
     - Every .coll with this name in the patcher shares one collection. Without a name the collection is private.
   * - no-search
     - 0
     - any int
     - Accepted for compatibility and ignored.


``.funbuff``
------------

Stores (x, y) pairs of ints sorted by x, and sends the y for any x: the stored y, or the one at the nearest lower x. 'interp' interpolates between points; 'next' steps through them in order.

:Dart: ``Obj.gFunbuff``
:Kind: Control-rate

A function stored as points: (x, y) pairs of ints, kept sorted by x, with at
most one y per x. Use it for breakpoint curves, zone maps and timed event
lists.

The left inlet both stores and looks up. A number on the right inlet waits
for the next x: that x stores the pair. An x with nothing waiting is a
lookup. The waiting y is used once.

.. code-block:: text

   [.funbuff]   right <- 100, left <- 60   store (60, 100)
                60 100                     the same, as one list
                left <- 64                 send 100 (nearest lower x is 60)

A lookup sends the y stored at x. When there is no pair at x, it sends the y
of the nearest lower x, so the function is a staircase. An x below every
stored x sends nothing. Floats are truncated on both inlets.

**Messages**

- ``set <x> <y> [<x> <y> ...]``: store one or more pairs.
- ``delete <x>``: remove the pair at x. ``delete <x> <y>`` removes it only if
  its y matches.
- ``clear``: remove every pair.
- ``interp <x>``: send the y linearly interpolated between the pairs either
  side of x, as a float. ``x`` may be a float. Outside the stored range the
  first or last y is sent.
- ``min`` / ``max``: send the lowest or highest y.
- ``find <y>``: send, out of the left outlet, every x whose y equals ``y``.
- ``dump``: send every pair in x order: x out of the middle outlet, then y out
  of the left outlet.
- ``goto <x>``: move the pointer to x.
- ``next``: send the y at the pointer (or the next pair above it), with the
  distance from the previous x out of the middle outlet first, then move past
  it. When no pair is left, bang the right outlet instead. The pointer does
  not wrap; send ``goto`` to start again.
- ``embed 1``: save the pairs with the patch. ``embed 0`` (the default) does
  not.

The distance from ``next`` is what a sequencer needs: store event times as x,
and the middle outlet gives the wait before each event. After ``goto`` the
distance is measured from the ``goto`` position; on a fresh object, from 0.

**Limits**

At most 256 pairs; further pairs are ignored. The file-name argument is
accepted and ignored: ``.funbuff`` does not read or write files. Copy, paste
and the editing window are not supported.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - x
     - FLOAT, INT, LIST
     - at most 256 pairs
     - With a y waiting on the right inlet, stores the pair; otherwise sends the y for this x. '<x> <y>' stores a pair. Also the commands listed in the notes.
   * - 1
     - y
     - FLOAT, INT
     - any int
     - The y for the next x on the left inlet. Sends nothing.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - y
     - ANY
     - any
     - The y for a lookup, 'next', 'min', 'max' or 'dump'; the x values found by 'find'; a float for 'interp'.
   * - 1
     - x
     - INT
     - any int
     - On 'next', the distance from the previous x; on 'dump', each pair's x, before its y.
   * - 2
     - end
     - BANG
     - —
     - A bang when 'next' has passed the last pair.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - filename
     - —
     - any symbol
     - Accepted for compatibility and ignored: no file is read.


``.table``
----------

A fixed-size array of ints addressed by index, for wavetables, curves and step sequences. It can also be read as a probability distribution: a bang picks a weighted random address.

:Dart: ``Obj.gTable``
:Kind: Control-rate

An array of ints at addresses 0 to size-1, all set to 0 at the start. The
left inlet both reads and writes: a number on the right inlet waits for the
next address, which stores it. An address with nothing waiting sends the
value stored there. Floats are truncated on both inlets. An address outside
the table does nothing.

.. code-block:: text

   [.table 8]   right <- 50, left <- 3   store 50 at address 3
                3 50                     the same, as one list
                left <- 3                send 50

**Reading and writing**

- ``<address> <value>``: store directly.
- ``set <address> <value> [<value> ...]``: store values at successive
  addresses. Values past the end are dropped.
- ``const <value>``: set every address to the value.
- ``clear``: set every address to 0.
- ``load``: from now on, every number on the left inlet is stored at the next
  address, starting at 0, until the table is full. ``normal`` ends this.
- ``cancel``: drop a value waiting on the right inlet, so the next address
  reads instead of writing.
- ``getbits <address> <start> <count>``: send, as a number, the ``count``
  bits of one value from bit ``start`` downwards (bit 0 is the lowest).
  ``setbits <address> <start> <count> <value>`` writes those bits.

**Reading out**

- ``dump``: send every value, from address 0.
- ``goto <address>``: move the pointer (clamped into the table).
- ``next`` / ``prev``: send the value at the pointer, then move it one
  forward or back, wrapping at the ends.
- ``min``, ``max``, ``sum``, ``length``: send the lowest value, the highest,
  the total, or the size.
- ``inv <value>``: send the first address whose value is at least ``value``,
  or nothing.
- ``send <name> <address>``: send the value at that address to every
  ``.r <name>`` (and the bus) instead of the outlet.

**As a distribution**

The values can be read as weights. ``fquantile <f>``, with ``f`` from 0 to 1,
sends the first address where the running total of the values reaches that
fraction of the sum. ``quantile <n>`` is the same with ``n`` from 0 to 32768.
A bang does a ``quantile`` with a random number, so the table becomes a
weighted dice: an address with twice the value is picked twice as often.

**Arguments and saving**

A number sets the size, 1-4096 (default 128). A word is a name. It is
accepted so that named tables load, but tables with the same name do not
share their values. Changing the arguments sets every value back to 0.

The values are saved with the patch unless the table is sent ``embed 0``
(``flags 0`` does the same). See :yse-cpp:`What is saved with the patch <patcher/data.html#data-saved>`.

**Limits**

There is no editing window, the size cannot be changed by a message, and
tables do not read or write files.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - address
     - FLOAT, INT, BANG, LIST
     - 0 to size-1
     - With a value waiting on the right inlet, stores it here; otherwise sends the value at this address. '<address> <value>' stores. A bang draws a weighted random address. Also the commands listed in the notes.
   * - 1
     - value
     - FLOAT, INT
     - any int
     - The value for the next address on the left inlet. Sends nothing.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - INT
     - any int
     - Stored values; the results of 'min', 'max', 'sum', 'length' and 'getbits'; an address for bang, 'quantile', 'fquantile' and 'inv'.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - name size
     - 128
     - optional name, optional size 1-4096
     - A number sets the size, clamped to 1-4096. A word is a name, kept for compatibility: tables with the same name do not share values.


``.textfile``
-------------

Collects incoming messages as lines of text: each message is added to the current line and 'cr' ends it. Lines can be sent back one at a time or all at once, and read from or written to a text file.

:Dart: ``Obj.gTextfile``
:Kind: Control-rate

Each message is added to the end of the current line, separated from the
previous one by a space. ``cr`` ends the line, so the next message starts a
new one. Numbers are written as text the way the rest of the patcher writes
them; a list is written as it arrived. Adding text sends nothing.

.. code-block:: text

   60 64 67
   cr
   intro
   0 0
   cr          =>   line 1: 60 64 67
                    line 2: intro 0 0

**Messages**

- any message: add it to the current line.
- ``cr``: end the current line. A ``cr`` when no line is open adds an empty
  line.
- ``tab``: add a tab character, with no space around it.
- ``symbol <word>``: add a word that would otherwise be read as one of these
  messages (``symbol clear`` adds the word ``clear``).
- ``dump``: send every line out of the left outlet, in order. A line that is
  one number leaves as an int or a float; any other line as a list, and an
  empty line as an empty list.
- ``line <n>``: send line ``n`` (counting from 1) preceded by ``set``, so it
  can set another object's contents. ``n`` below 1 means 1; a line that
  doesn't exist sends nothing.
- ``query``: send the number of lines out of the middle outlet.
- ``clear``: erase every line.

**Files**

``read <file>`` replaces the lines with those of a text file, then bangs the
right outlet. ``write <file>`` saves them, one line per line. A bare ``read``
or ``write`` reuses the last file name. A file name given as the argument is
read when the object is created, and is the default for a bare ``read`` or
``write``. See :yse-cpp:`File input and output <patcher/files.html>`.

The lines themselves are not saved with the patch: the file is where they are
kept.

**Limits**

At most 256 lines of at most 256 characters. A message that would make the
line too long, or a new line past the 256th, is ignored. There is no editing
window: ``open``, ``wclose``, ``settitle``, ``filetype``, ``precision`` and
``stringout`` are accepted and do nothing.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - in
     - FLOAT, INT, LIST
     - at most 256 lines of 256 characters
     - Any message is added to the current line. Also 'cr', 'tab', 'clear', 'dump', 'line <n>', 'query', 'symbol <word>', 'read [file]' and 'write [file]'.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - text
     - ANY
     - —
     - Lines: every line on 'dump'; one line preceded by 'set' on 'line <n>'.
   * - 1
     - lines
     - INT
     - 0-256
     - The number of lines, on 'query'.
   * - 2
     - file
     - BANG
     - —
     - A bang when a 'read' has loaded a file. Silent when the read fails.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - filename
     - —
     - any filename
     - A text file to read when the object is created. Also the default file for a bare 'read' or 'write'.


