Packages
wavex
0.7.1
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.ex
defmodule Wavex do
@moduledoc """
Read LPCM WAVE data.
"""
alias Wavex.Chunk.{Data, Format, RIFF}
alias Wavex.Error
alias Wavex.Error.RIFFSizeMismatch
@enforce_keys [
:riff,
:format,
:data
]
defstruct [
:riff,
:format,
:data
]
@type t :: %__MODULE__{
riff: RIFF.t(),
format: Format.t(),
data: Data.t()
}
@spec verify_riff_size(non_neg_integer, binary) :: :ok | {:error, RIFFSizeMismatch.t()}
defp verify_riff_size(actual, binary) do
case byte_size(binary) - 8 do
^actual -> :ok
expected -> {:error, %RIFFSizeMismatch{expected: expected, actual: actual}}
end
end
@doc ~S"""
Read LPCM WAVE data.
For more details, see `Wavex.Chunk.RIFF.read/1`, `Wavex.Chunk.Format.read/1`,
and `Wavex.Chunk.Data.read/1`.
## Examples
Reading a 16-bit stereo 88200b/s LPCM file:
iex> Wavex.read(<<
...> 0x52, 0x49, 0x46, 0x46, # R I F F
...> 0x2C, 0x00, 0x00, 0x00, # 44
...> 0x57, 0x41, 0x56, 0x45, # W A V E
...> 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
...> 0x64, 0x61, 0x74, 0x61, # d a t a
...> 0x08, 0x00, 0x00, 0x00, # 8
...> 0x00, 0x00, 0x00, 0x00, # 0
...> 0x00, 0x00, 0x00, 0x00 # 0
...> >>)
{:ok,
%Wavex{
data: %Wavex.Chunk.Data{
data: <<0, 0, 0, 0, 0, 0, 0, 0>>,
size: 8
},
format: %Wavex.Chunk.Format{
bits_per_sample: 16,
block_align: 4,
byte_rate: 88_200,
channels: 2,
sample_rate: 22_050
},
riff: %Wavex.Chunk.RIFF{size: 44}
}}
Reading a 16-bit mono 22050/s LPCM file:
iex> Wavex.read(<<
...> 0x52, 0x49, 0x46, 0x46, # R I F F
...> 0x28, 0x00, 0x00, 0x00, # 40
...> 0x57, 0x41, 0x56, 0x45, # W A V E
...> 0x66, 0x6D, 0x74, 0x20, # f m t \s
...> 0x10, 0x00, 0x00, 0x00, # 16
...> 0x01, 0x00, 0x01, 0x00, # 1 1
...> 0x11, 0x2B, 0x00, 0x00, # 11025
...> 0x22, 0x56, 0x00, 0x00, # 22050
...> 0x02, 0x00, 0x10, 0x00, # 2 16
...> 0x64, 0x61, 0x74, 0x61, # d a t a
...> 0x04, 0x00, 0x00, 0x00, # 4
...> 0x00, 0x00, 0xFE, 0xFF # 0 0 254 255
...> >>)
{:ok,
%Wavex{
data: %Wavex.Chunk.Data{data: <<0, 0, 254, 255>>, size: 4},
format: %Wavex.Chunk.Format{
bits_per_sample: 16,
block_align: 2,
byte_rate: 22_050,
channels: 1,
sample_rate: 11_025
},
riff: %Wavex.Chunk.RIFF{size: 40}
}}
"""
@spec read(binary) :: {:ok, t} | {:error, Error.t()}
def read(binary) when is_binary(binary) do
with {:ok, %RIFF{size: riff_size} = riff, etc} <- RIFF.read(binary),
:ok <- verify_riff_size(riff_size, binary),
{:ok, %Format{} = format, etc} <- Format.read(etc),
{:ok, %Data{} = data} <- Data.read(etc) do
{:ok, %Wavex{riff: riff, format: format, data: data}}
end
end
end