= AGC

include::../../common.adoc[]

== Overview

image:agc.svg[alt="AGC", width=400, role=right]The AGC, or automatic gain control, compares the envelope, `env`, to an external reference, `ref`, and increases or decreases the gain to maintain a constant output level. A class named `agc` implements AGC.

Envelope tracking is done externally using an external envelope follower to make it possible to use different types of envelope tracking schemes, the output of which is the supplied argument to the function call operator.

The `agc` is an envelope processor that operates on the envelope of the audio signal, performs computations in the logarithmic domain, and returns a processed envelope.

NOTE: See xref:reference/dynamic.adoc[Dynamic] for further details.

`agc` is a feedforward type AGC." In contrast to feedback AGCs, feedforward AGCs derive their control signal only from the input signal and an external reference set-point.

== Include

```c++
#include <q/fx/dynamic.hpp>
```

== Declaration

```c++
struct agc
{
                agc(decibel max);

    decibel     operator()(decibel env, decibel ref) const;
    void        max(decibel max_);
    decibel     max() const;
};
```

== Expressions

=== Notation

`g`, `a`, `b`       :: Objects of type `agc`
`max`, `ref`        :: Objects of type `decibel`

=== Constructors and Assignment

[cols="1,1"]
|===
| Expression    | Semantics

| `agc(max)`    | Construct an `agc` from `max` (maximum) gain.
| `agc(g)`      | Copy construct from `agc g`.
| `a = b`       | Assign `b` to `a`.
|===

NOTE: C++ brace initialization may also be used.

As previously stated, the `agc` compares the envelope, `env`, to an external reference, `ref`, and adjusts the gain accordingly to maintain a constant output level. However, there is a maximum gain that can be applied when the signal falls below the reference. The `max` constructor parameter specified this "maximum" gain.

=== Function Call

[cols="1,1,1"]
|===
| Expression        | Semantics                             | Return Type

| `g(env, ref)`     | Process the input envelope `env`
                      by increasing or decreasing the gain
                      if `env` goes above, or falls below
                      `ref` to maintain a constant output
                      level.                                | `decibel`
|===

The output is the adjusted gain, also in `decibels`. Simply multiply the signal by the result converted to `float` using `as_float` (or `double` using `as_double`). For example:

```c++
auto gain = as_float(g(env, ref));      <1>
auto out = signal * gain;               <2>
```

<1> `env` is the computed envelope (e.g.) using an envelope follower.
    `gain` is obtained from the `env` processed by `agc` and converted to `float`.
<2> The `signal` multiplied by `gain`.

=== Mutators

[cols="1,1,1"]
|===
| Expression        | Semantics                         | Return Type

| `g.max(max)`      | Set the `agc` maximum gain.       | `void`
|===

=== Accessors

[cols="1,1,1"]
|===
| Expression        | Semantics                         | Return Type

| `g.max()`         | Get the `agc` maximum gain.       | `float`
|===

