Current section
Files
Jump to
Current section
Files
lib/membrane_caps_audio_mpeg.ex
defmodule Membrane.Caps.Audio.MPEG do
@moduledoc """
This module implements struct for caps representing MPEG audio stream.
See [MPEG Frame header documentation](https://www.mp3-tech.org/programmer/frame_header.html)
"""
@compile {:inline,
[
samples_per_frame: 2,
sound_of_silence: 0
]}
# MPEG version
@type version_t :: :v1 | :v2 | :v2_5
# MPEG layer
@type layer_t :: :layer1 | :layer2 | :layer3
# CRC enabled
@type crc_enabled_t :: boolean
# Bitrate
@type bitrate_t :: pos_integer | :free
# Sample rate of the audio.
@type sample_rate_t :: pos_integer
# Padding enabled
@type padding_enabled_t :: boolean
# Private bit set?
@type private_t :: boolean
# Channel mode
@type channel_mode_t :: :stereo | :joint_stereo | :dual_channel | :single_channel
# Mode extension (in Joint Stereo)
@type mode_extension_t :: :mode0 | :mode1 | :mode2 | :mode3 | nil
# Copyright bit set?
@type copyright_t :: boolean
# Original bit set?
@type original_t :: boolean
# Emphasis mode
@type emphasis_mode_t :: :none | :emphasis_50_15 | :reserved | :ccit_j_17
@type t :: %Membrane.Caps.Audio.MPEG{
version: version_t,
layer: layer_t,
crc_enabled: crc_enabled_t,
bitrate: bitrate_t,
sample_rate: sample_rate_t,
padding_enabled: padding_enabled_t,
private: private_t,
channel_mode: channel_mode_t,
mode_extension: mode_extension_t,
copyright: copyright_t,
original: original_t,
emphasis_mode: emphasis_mode_t
}
defstruct version: nil,
layer: nil,
crc_enabled: nil,
bitrate: nil,
channels: nil,
sample_rate: nil,
padding_enabled: nil,
private: nil,
channel_mode: nil,
mode_extension: nil,
copyright: nil,
original: nil,
emphasis_mode: nil
@doc """
Returns amount of raw audio samples that are in the frame for given
version/layer combination.
Inlined by the compiler.
"""
@spec samples_per_frame(version_t, layer_t) :: pos_integer
def samples_per_frame(:v1, :layer1), do: 384
def samples_per_frame(:v1, :layer2), do: 1152
def samples_per_frame(:v1, :layer3), do: 1152
def samples_per_frame(:v2, :layer1), do: 384
def samples_per_frame(:v2, :layer2), do: 1152
def samples_per_frame(:v2, :layer3), do: 576
def samples_per_frame(:v2_5, :layer1), do: 384
def samples_per_frame(:v2_5, :layer2), do: 1152
def samples_per_frame(:v2_5, :layer3), do: 576
@doc """
Returns one 'silent' frame along with its caps.
Inlined by the compiler.
"""
@spec sound_of_silence :: {binary, t}
def sound_of_silence do
payload =
<<255, 251, 16, 100, 0, 15, 240, 0, 0, 105, 0, 0, 0, 8, 0, 0, 13, 32, 0, 0, 1, 0, 0, 1, 164,
0, 0, 0, 32, 0, 0, 52, 128, 0, 0, 4, 76, 65, 77, 69, 51, 46, 49, 48,
48>> <>
<<85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85>>
caps = %__MODULE__{
bitrate: 32,
channel_mode: :joint_stereo,
channels: 2,
copyright: false,
crc_enabled: true,
emphasis_mode: :none,
layer: :layer3,
mode_extension: :mode2,
original: true,
padding_enabled: false,
private: false,
sample_rate: 44_100,
version: :v1
}
{payload, caps}
end
end