wavex v0.4.9 Wavex.FormatChunk
Reading a format chunk.
A format chunk normally contains information about the data that follows:
- a
"fmt "
FourCC, - a format size,
- a format,
- the number of channels,
- a sample rate,
- a byte rate,
- block alignment,
- the bits per sample.
Link to this section Summary
Functions
Read and validate a format chunk. See Wavex.FormatChunk.validate/1
to see
what is validated
Validate a format chunk
Link to this section Types
t() :: %Wavex.FormatChunk{ bits_per_sample: pos_integer(), block_align: pos_integer(), byte_rate: pos_integer(), channels: pos_integer(), sample_rate: pos_integer() }
Link to this section Functions
read(binary()) :: {:ok, t(), binary()} | {:error, Wavex.Error.BlockAlignMismatch.t() | Wavex.Error.ByteRateMismatch.t() | Wavex.Error.UnexpectedEOF.t() | Wavex.Error.UnexpectedFormatSize.t() | Wavex.Error.UnexpectedFourCC.t() | Wavex.Error.UnsupportedBitsPerSample.t() | Wavex.Error.UnsupportedFormat.t() | Wavex.Error.ZeroChannels.t()}
Read and validate a format chunk. See Wavex.FormatChunk.validate/1
to see
what is validated.
Examples
iex Wavex.FormatChunk.read(<<
...> 0x66, 0x6d, 0x74, 0x20, # f m t \s
...> 0x10, 0x00, 0x00, 0x00, # 16
...> 0x01, 0x00, 0x02, 0x00, # 1 2
...> 0x22, 0x56, 0x00, 0x00, # 22050
...> 0x88, 0x58, 0x01, 0x00, # 88200
...> 0x04, 0x00, 0x10, 0x00 # 4 16
...> >>)
{:ok,
%Wavex.FormatChunk{
bits_per_sample: 16,
block_align: 4,
byte_rate: 88_200,
channels: 2,
sample_rate: 22_050
}, ""}
Caveats
“fmt “ FourCC
Bytes 1-4 must read "fmt "
to indicate a format chunk. A different value
results in an error. The following example gives an error because bytes 1-4
read "data"
instead of "fmt "
.
iex> Wavex.FormatChunk.read(<<
...> 0x64, 0x61, 0x74, 0x61, # d a t a
...> 0x10, 0x00, 0x00, 0x00, # 16
...> 0x01, 0x00, 0x02, 0x00, # 1 2
...> 0x22, 0x56, 0x00, 0x00, # 22050
...> 0x88, 0x58, 0x01, 0x00, # 88200
...> 0x04, 0x00, 0x10, 0x00 # 4 16
...> >>)
{:error, %Wavex.Error.UnexpectedFourCC{expected: "fmt ", actual: "data"}}
Format size
The format size at bytes 5-8 is expected to be 16
, the default format size
for the LPCM format. The following example gives an error because the format
size is 18
instead of 16
.
iex> Wavex.FormatChunk.read(<<
...> 0x66, 0x6d, 0x74, 0x20, # f m t \s
...> 0x12, 0x00, 0x00, 0x00, # 18
...> 0x01, 0x00, 0x02, 0x00, # 1 2
...> 0x22, 0x56, 0x00, 0x00, # 22050
...> 0x88, 0x58, 0x01, 0x00, # 88200
...> 0x04, 0x00, 0x10, 0x00 # 4 16
...> >>)
{:error, %Wavex.Error.UnexpectedFormatSize{size: 18}}
Format size
The format at bytes 9-12 must be 0x0001
(LPCM), as other formats are not
supported. The following example gives an error because the format is
0x0032
instead of 0x0001
.
iex> Wavex.FormatChunk.read(<<
...> 0x66, 0x6d, 0x74, 0x20, # f m t \s
...> 0x10, 0x00, 0x00, 0x00, # 16
...> 0x32, 0x00, 0x02, 0x00, # 50 2
...> 0x22, 0x56, 0x00, 0x00, # 22050
...> 0x88, 0x58, 0x01, 0x00, # 88200
...> 0x04, 0x00, 0x10, 0x00 # 4 16
...> >>)
{:error, %Wavex.Error.UnsupportedFormat{format: 0x0032}}
Internal consistency
The resulting %Wavex.FormatChunk{}
is checked for internal consistency
by Wavex.FormatChunk.validate/1
.
Validate a format chunk.
Examples
iex> Wavex.FormatChunk.validate(%Wavex.FormatChunk{
...> bits_per_sample: 16,
...> block_align: 4,
...> byte_rate: 88_200,
...> channels: 2,
...> sample_rate: 22_050
...> })
:ok
Channels
The number of channels
must be positive. The following example gives an
error because channels
is 0
.
iex> Wavex.FormatChunk.validate(%Wavex.FormatChunk{
...> bits_per_sample: 16,
...> block_align: 4,
...> byte_rate: 88_200,
...> channels: 0,
...> sample_rate: 22_050
...> })
{:error, %Wavex.Error.ZeroChannels{}}
Bits per sample
bits_per_sample
must be equal to 8
, 16
, or 24
. The following example
gives an error because bits_per_sample
is 32
.
iex> Wavex.FormatChunk.validate(%Wavex.FormatChunk{
...> bits_per_sample: 32,
...> block_align: 4,
...> byte_rate: 88_200,
...> channels: 2,
...> sample_rate: 22_050
...> })
{:error, %Wavex.Error.UnsupportedBitsPerSample{bits_per_sample: 32}}
Block alignment
block_align
must be equal to channels * bits_per_sample / 8
. The
following example gives an error because block_align
is 4
instead of
2 * 8 / 8 = 2
.
iex> Wavex.FormatChunk.validate(%Wavex.FormatChunk{
...> bits_per_sample: 8,
...> block_align: 4,
...> byte_rate: 88_200,
...> channels: 2,
...> sample_rate: 22_050
...> })
{:error, %Wavex.Error.BlockAlignMismatch{expected: 2, actual: 4}}
Byte rate
byte_rate
must be equal to sample_rate * block_align
. The following
example gives an error because byte_rate
is 88200
instead of
22050 * 2 = 44100
.
iex> Wavex.FormatChunk.validate(%Wavex.FormatChunk{
...> bits_per_sample: 8,
...> block_align: 2,
...> byte_rate: 88_200,
...> channels: 2,
...> sample_rate: 22_050
...> })
{:error, %Wavex.Error.ByteRateMismatch{expected: 44100, actual: 88200}}