# `Membrane.AudioMixer`
[🔗](https://github.com/membraneframework/membrane_audio_mix_plugin/blob/v0.16.7/lib/membrane_audio_mixer.ex#L1)

This element performs audio mixing.

Audio format can be set as an element option or received through stream_format from input pads. All
received stream_format have to be identical and match ones in element option (if that option is
different from `nil`).

Input pads can have offset - it tells how much silence should be added before first sample
from that pad. Offset has to be positive.

Mixer mixes only raw audio (PCM), so some parser may be needed to precede it in pipeline.

## Element options

Passed via struct `t:Membrane.AudioMixer.t/0`

- `stream_format`  

  ```
  RawAudio.t()
  ```
  
  Default value: `nil`  
  The value defines a raw audio format of pads connected to the
  element. It should be the same for all the pads.

- `frames_per_buffer`  

  ```
  pos_integer()
  ```
  
  Default value: `2048`  
  Assumed number of raw audio frames in each buffer.
  Used when converting demand from buffers into bytes.

- `prevent_clipping`  

  ```
  boolean()
  ```
  
  Default value: `true`  
  Defines how the mixer should act in the case when an overflow happens.
  - If true, the wave will be scaled down, so a peak will become the maximal
  value of the sample in the format. See `Membrane.AudioMixer.ClipPreventingAdder`.
  - If false, overflow will be clipped to the maximal value of the sample in
  the format. See `Membrane.AudioMixer.Adder`.

- `native_mixer`  

  ```
  boolean()
  ```
  
  Default value: `false`  
  The value determines if mixer should use NIFs for mixing audio. Only
  clip preventing version of native mixer is available.
  See `Membrane.AudioMixer.NativeAdder`.

- `synchronize_buffers?`  

  ```
  boolean()
  ```
  
  Default value: `false`  
  The value determines if mixer should synchronize buffers based on pts values.
  - If true, mixer will synchronize buffers based on its pts values. If buffer pts value is lower then the current
  mixing time (last_ts_sent) it will be dropped.
  - If false, mixer will take all incoming buffers no matter what pts they have and put it in the queue.

## Pads

### `:input`

Accepted formats:
```
%RawAudio{sample_format: sample_format}
when sample_format in [:s8, :s16le, :s16be, :s24le, :s24be, :s32le, :s32be]
```
```
RemoteStream
```

Direction: | `:input`
Availability: | `:on_request`
Flow control: | `:manual`
Demand unit: | `:bytes`
Pad options:

- `offset`  

  ```
  Time.non_neg()
  ```
  
  Default value: `0`  
  Offset of the input audio at the pad.

### `:output`

Accepted formats:
```
RawAudio
```

Direction: | `:output`
Availability: | `:always`
Flow control: | `:manual`
Demand unit: | `nil`

# `input_pad_opts`

```elixir
@type input_pad_opts() :: [{:offset, Membrane.Time.non_neg()}]
```

Options for pad `:input`

# `t`

```elixir
@type t() :: %Membrane.AudioMixer{
  frames_per_buffer: pos_integer(),
  native_mixer: boolean(),
  prevent_clipping: boolean(),
  stream_format: Membrane.RawAudio.t(),
  synchronize_buffers?: boolean()
}
```

Struct containing options for `Membrane.AudioMixer`

# `options`

```elixir
@spec options() :: keyword()
```

Returns description of options available for this module

---

*Consult [api-reference.md](api-reference.md) for complete listing*
