audio/aiff
Reading and writing AIFF and AIFF-C files.
import audio.aiff
AIFF is the big-endian cousin of WAVE: the same idea of a chunked container, written the other way round because it came from the Motorola side of the world. AIFF-C adds a compression tag, and this package reads the ones that matter: plain PCM, the little-endian sowt variant Apple tools write, IEEE floating point, and A-law and mu-law.
The one genuinely odd part is the sample rate, which AIFF stores as an 80 bit extended float. This package reads and writes it, so 44100 comes back as 44100 and not 44099.
Things to know
- 8, 16 and 24 bit PCM makes the round trip through a clip exactly. Unlike WAVE, 8 bit AIFF is signed.
ReadCommongives you the COMM and SSND chunks in one struct, because you always need both: one says the shape, the other says where the sound is.- A file whose COMM frame count disagrees with the bytes actually present decodes to whichever is shorter, rather than reading off the end.
- Writing always produces plain big-endian AIFF. The AIFC variants are read, not written.
Types
Common
struct Common| Name | Type | Description |
|---|---|---|
channels | int = 0 | How many channels. |
frames | int = 0 | How many frames the header claims. |
bits | int = 0 | Bits per sample. |
rate | int = 0 | Frames per second, read from the 80 bit float AIFF stores it in. |
compression | int = 0 | Which Comp number the file uses. Plain AIFF is always CompNone. |
data_offset | int = 0 | Where the samples start, past the SSND header and its offset field. |
data_size | int = 0 | How many bytes of samples there are. |
import audio
import audio.aiff
import compress
import filepath
import mem
import os
func main:
mut c := audio.New(44100, 2, 64)
audio.SetSample(c, 7, 1, 0.5)
buf := aiff.EncodeAIFFBits(c, 24)
println aiff.IsAIFF(buf.data, buf.len), aiff.IsAIFF(buf.data, 4)
println audio.FormatName(audio.DetectFormat(buf.data, buf.len))
mut cm := aiff.Common {}
println aiff.ReadCommon(buf.data, buf.len, cm)
println cm.channels, cm.frames, cm.bits, cm.rate
println cm.compression == aiff.CompNone, cm.data_size
mut ok := false
info := aiff.ProbeAIFF(buf.data, buf.len, ok)
println ok, info.rate, info.channels, info.bits, info.frames, info.lossless
mut dok := false
back := aiff.DecodeAIFF(buf.data, buf.len, dok)
println dok, back.frames, back.bits, audio.Sample(back, 7, 1)
each rate in [8000, 22050, 44100, 96000]:
mut one := audio.New(rate, 1, 2)
probe := aiff.EncodeAIFFBits(one, 16)
mut c2 := aiff.Common {}
aiff.ReadCommon(probe.data, probe.len, c2)
println rate, c2.rate == rate
compress.BufFree(probe)
audio.Free(one)
end
println compress.BufLen(aiff.EncodeAIFFBits(c, 12)), compress.BufLen(aiff.EncodeAIFF(audio.Clip {}))
path := filepath.Join(os.TempDir(), "salam_aiff_example.aiff")
defer mem.Free(path as void*)
println aiff.SaveAIFFBits(c, path, 16)
mut fok := false
disk := aiff.OpenAIFF(path, fok)
println fok, disk.bits, disk.frames
mut gone := false
missing := filepath.Join(os.TempDir(), "salam_aiff_none.aiff")
defer mem.Free(missing as void*)
aiff.OpenAIFF(missing, gone)
println gone
compress.BufFree(buf)
audio.Free(c)
audio.Free(back)
audio.Free(disk)
endConstants and variables
Compression numbers Comp…
| Name | Value |
|---|---|
CompNone | 0 |
CompSowt | 1 |
CompFloat32 | 2 |
CompFloat64 | 3 |
CompALaw | 4 |
CompMuLaw | 5 |
The example for this item is shown with the ones above: aiff-Read.salam
Functions
IsAIFF
func IsAIFF(p: void*, n: int): boolThe example for this item is shown with the ones above: aiff-Read.salam
ReadCommon
func ReadCommon(p: void*, n: int, out &: Common): boolThe example for this item is shown with the ones above: aiff-Read.salam
ProbeAIFF
func ProbeAIFF(p: void*, n: int, ok &: bool): audio.InfoThe example for this item is shown with the ones above: aiff-Read.salam
DecodeAIFF
func DecodeAIFF(p: void*, n: int, ok &: bool): audio.ClipThe example for this item is shown with the ones above: aiff-Read.salam
EncodeAIFFBits
func EncodeAIFFBits(c: audio.Clip, bits: int): compress.ByteBufThe example for this item is shown with the ones above: aiff-Read.salam
EncodeAIFF
func EncodeAIFF(c: audio.Clip): compress.ByteBufThe example for this item is shown with the ones above: aiff-Read.salam
OpenAIFF
func OpenAIFF(path: str, ok &: bool): audio.ClipThe example for this item is shown with the ones above: aiff-Read.salam
SaveAIFF
func SaveAIFF(c: audio.Clip, path: str): boolThe example for this item is shown with the ones above: aiff-Read.salam
SaveAIFFBits
func SaveAIFFBits(c: audio.Clip, path: str, bits: int): boolThe example for this item is shown with the ones above: aiff-Read.salam