wavex v0.4.6 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}}