Packages
wavex
0.4.9
0.14.1
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.4
0.9.3
0.9.1
0.9.0
0.8.1
0.8.0
0.7.3
0.7.2
0.7.1
0.5.5
0.5.4
0.5.3
0.5.2
0.5.0
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.0
0.3.0
0.2.16
0.2.13
0.2.11
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.2
0.2.1
0.2.0
0.1.8
0.1.0
Read WAVE LPCM data
Current section
Files
Jump to
Current section
Files
lib/wavex/riff_header.ex
defmodule Wavex.RIFFHeader do
@moduledoc """
Reading a RIFF header.
The RIFF header is the first chunk in a WAVE file, and normally consists of:
- the `"RIFF"` FourCC,
- the file size,
- the `"WAVE"` FourCC.
"""
alias Wavex.Error.{UnexpectedEOF, UnexpectedFourCC}
alias Wavex.Utils
defstruct [:size]
@type t :: %__MODULE__{size: pos_integer}
@expected_riff_four_cc "RIFF"
@expected_wave_four_cc "WAVE"
@doc ~S"""
Read a RIFF header.
## Examples
iex> Wavex.RIFFHeader.read(<<
...> 0x52, 0x49, 0x46, 0x46, # R I F F
...> 0x24, 0x08, 0x00, 0x00, # 2084
...> 0x57, 0x41, 0x56, 0x45 # W A V E
...> >>)
{:ok, %Wavex.RIFFHeader{size: 2084}, ""}
## Caveats
### "RIFF" FourCC
Bytes 1-4 must read `"RIFF"` to indicate the Resource Interchange File Format.
A different value results in an error.
iex> Wavex.RIFFHeader.read(<<"RIFX", 0, 0, 0, 0, "WAVE">>)
{:error, %Wavex.Error.UnexpectedFourCC{expected: "RIFF", actual: "RIFX"}}
### "WAVE" FourCC
Bytes 9-12 must read `"WAVE"` to indicate a waveform audio file. A different
value results in an error.
iex> Wavex.RIFFHeader.read(<<"RIFF", 0, 0, 0, 0, "AVI ">>)
{:error, %Wavex.Error.UnexpectedFourCC{expected: "WAVE", actual: "AVI "}}
### Header size
A binary must be at least 12 bytes to contain a RIFF header.
iex> Wavex.RIFFHeader.read(<<"RIFF", 0, 0>>)
{:error, %Wavex.Error.UnexpectedEOF{}}
Generally, the following holds for any `x`:
```elixir
not is_binary(x) or String.length(x) >= 12 or
Wavex.RIFFHeader.read(x) == %Wavex.Error.UnexpectedEOF{}
```
"""
@spec read(binary) :: {:ok, t, binary} | {:error, UnexpectedEOF.t() | UnexpectedFourCC.t()}
def read(binary) when is_binary(binary) do
with {:ok, etc} <- Utils.read_fourCC(binary, @expected_riff_four_cc),
<<size::32-little, etc::binary>> <- etc,
{:ok, etc} <- Utils.read_fourCC(etc, @expected_wave_four_cc) do
{:ok, %__MODULE__{size: size}, etc}
else
value when is_binary(value) -> {:error, %UnexpectedEOF{}}
{:error, _} = error -> error
end
end
end