wavex v0.9.3 Wavex.Chunk.Format
Read a format chunk.
Link to this section Summary
Functions
Read a format chunk
Link to this section Types
t() :: %Wavex.Chunk.Format{ 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 a format chunk.
Example
Reading the format chunk of a 16-bit stereo 88.2kb/s LPCM file:
iex> Wavex.Chunk.Format.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.Chunk.Format{
bits_per_sample: 16,
block_align: 4,
byte_rate: 88_200,
channels: 2,
sample_rate: 22_050
}, ""}
Caveats
Bytes 1-4 must read "fmt "
to indicate a format chunk. The following
example gives an error because bytes 1-4 read "data"
instead of "fmt "
:
iex> Wavex.Chunk.Format.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"}}
The format size at bytes 5-8 is expected to be 16
, the format size for the
LPCM format. The following example gives an error because the format size is
18
instead of 16
:
iex> Wavex.Chunk.Format.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{actual: 18}}
The format at bytes 9-10 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.Chunk.Format.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{actual: 0x0032}}
The format at bytes 11-12 must not be 0
, because there has to be at least
one channel. The following example gives an error because the number of
channels is 0
:
iex> Wavex.Chunk.Format.read(<<
...> 0x66, 0x6d, 0x74, 0x20, # f m t \s
...> 0x10, 0x00, 0x00, 0x00, # 16
...> 0x01, 0x00, 0x00, 0x00, # 1 0
...> 0x22, 0x56, 0x00, 0x00, # 22050
...> 0x88, 0x58, 0x01, 0x00, # 88200
...> 0x04, 0x00, 0x10, 0x00 # 4 16
...> >>)
{:error, %Wavex.Error.ZeroChannels{}}
The byte rate at bytes 17-20 must be equal to sample_rate * block_align
.
The following example gives an error because 44100
is not equal to
22050 * 4 = 88200
:
iex> Wavex.Chunk.Format.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
...> 0x44, 0xAC, 0x00, 0x00, # 44100
...> 0x04, 0x00, 0x10, 0x00 # 4 16
...> >>)
{:error, %Wavex.Error.ByteRateMismatch{expected: 88200, actual: 44100}}
The block alignment at bytes 21-22 must be equal to
channels * bits_per_sample / 8
. The following example gives an error
because 2
is not equal to 2 * 16 / 8 = 4
:
iex> Wavex.Chunk.Format.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
...> 0x02, 0x00, 0x10, 0x00 # 2 16
...> >>)
{:error, %Wavex.Error.BlockAlignMismatch{expected: 4, actual: 2}}
The bits per second at bytes 23-24 must be 8
, 16
, or 24
, as other bit
rates are not supported. The following example gives an error because the
bit rate is 32
:
iex> Wavex.Chunk.Format.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, 0x20, 0x00 # 4 32
...> >>)
{:error, %Wavex.Error.UnsupportedBitsPerSample{actual: 32}}