Keywords: developer_docs

Subsections

- - - Maintaining a slave control list
    - Holding iterators
    - Just use the current data access functions

# Automation

As of revision 1490, automation is handled in two ways: User-generated (live) automation data (generated by the user moving sliders while playing) is fed into `fterfirstP`P=95 _ `P=58 : `P>64 `P<91 PPP <`<=95 _ `<=58 : `<>64 `<<91 <<< c@amelhyph<269>>luginI::_controlFifo`. Automation data is kept in `fterfirstA`A=95 _ `A=58 : `A>64 `A<91 AAA <`<=95 _ `<=58 : `<>64 `<<91 <<< c@amelhyph<269>>udioTrack::_controller`, which is a `fterfirstC`C=95 _ `C=58 : `C>64 `C<91 CCC <`<=95 _ `<=58 : `<>64 `<<91 <<< c@amelhyph<269>>trlListList`, that is, a list of `fterfirstC`C=95 _ `C=58 : `C>64 `C<91 CCC <`<=95 _ `<=58 : `<>64 `<<91 <<< c@amelhyph<269>>trlList`s, that is, a list of lists of controller-objects which hold the control points of the automation graph. The `fterfirstC`C=95 _ `C=58 : `C>64 `C<91 CCC <`<=95 _ `<=58 : `<>64 `<<91 <<< c@amelhyph<269>>trlList` also stores whether the list is meant discrete (a new control point results in a value-jump) or continuous (a new control point results in the value slowly sloping to the new value).

While `fterfirstP`P=95 _ `P=58 : `P>64 `P<91 PPP <`<=95 _ `<=58 : `<>64 `<<91 <<< c@amelhyph<269>>luginI::_controlFifo` can be queried very quickly and thus is processed with a very high resolution (only limited by the minimum control period setting), the automation value are expensive to query, and are only processed once in an audio driver period. This might lead to noticeable jumps in value.

This could possibly be solved in two ways:

#### Maintaining a slave control list

This approach would maintain a fully redundant slave control list, similar to `fterfirstP`P=95 _ `P=58 : `P>64 `P<91 PPP <`<=95 _ `<=58 : `<>64 `<<91 <<< c@amelhyph<269>>luginI::_controlFifo`. This list must be updated every time any automation-related thing is changed, and shall contain every controller change as a tuple of controller number and value. This could be processed in the same loop as `fterfirstP`P=95 _ `P=58 : `P>64 `P<91 PPP <`<=95 _ `<=58 : `<>64 `<<91 <<< c@amelhyph<269>>luginI::_controlFifo`, making it comfortable to implement; furthermore, it allows to cleanly offer automation-settings at other places in future (such as storing automation data in parts or similar).

#### Holding iterators

We also could hold a list of iterators of the single `fterfirstC`C=95 _ `C=58 : `C>64 `C<91 CCC <`<=95 _ `<=58 : `<>64 `<<91 <<< c@amelhyph<269>>trlList`s. This would also cause low CPU usage, because usually, the iterators only need to be incremented once. However, it is pretty complex to implement, because the iterators may become totally wrong (because of a seek in the song), and we must iterate through a whole list of iterators.

#### Just use the current data access functions

By just using the current functions for accessing automation data, we might get a quick-and-dirty solution, which however wastes way too much CPU resources. This is because on every single frame, we need to do a binary search on multiple controller lists.