Standard library · Encoding and data

audio/codec

Open and save a sound file without naming its format.

import audio.codec
On this page
  1. Functions

This package is the one call that does not care what format a file is in. Open reads the first bytes, works out the format and hands back a clip; Save looks at the extension and writes the right thing. Probe and ProbeFile do the same for a header alone.

It sits in its own package for a plain reason: audio cannot import the format packages, because they import it. So the sniffing lives in audio, where it needs nothing, and the dispatch lives here, where it can reach every codec.

Things to know

  • Knowing a format and being able to read it are different things. audio.DetectFormat names ten formats; CanDecode tells you which of them this build actually carries, and Formats lists them.
  • Today that list is WAV, AIFF and au. The rest of the family is being written, and nothing here changes when they land.
  • Save returns false for an extension it cannot write, rather than writing the wrong format.
  • Free the clip with audio.Free and any buffer with compress.BufFree.

Functions

CanDecode

func CanDecode(format: int): bool
True when this build can read that format. Today that is WAV, AIFF and au; the others are being written.
codec-Open.salam
import audio
import audio.codec
import compress
import filepath
import mem
import os

func main:
    println codec.CanDecode(audio.FormatWAV), codec.CanEncode(audio.FormatWAV)
    println codec.CanDecode(audio.FormatMP3), codec.CanEncode(audio.FormatFLAC)
    println codec.Formats().len(), codec.Formats().get(0) == audio.FormatWAV

    mut c := audio.New(22050, 2, 64)
    audio.SetSample(c, 5, 0, 0.5)
    audio.SetSample(c, 5, 1, -0.25)

    path := filepath.Join(os.TempDir(), "salam_codec_open.wav")
    defer mem.Free(path as void*)
    println codec.Save(c, path)
    mut ok := false
    back := codec.Open(path, ok)
    println ok, back.frames, back.channels, back.rate, back.bits
    println audio.Sample(back, 5, 0), audio.Sample(back, 5, 1)

    mut pok := false
    info := codec.ProbeFile(path, pok)
    println pok, audio.FormatName(info.format), info.frames, info.bits, info.lossless

    buf := codec.Encode(c, audio.FormatWAV)
    println compress.BufLen(buf) == 44 + 64 * 2 * 2
    mut mok := false
    mem_back := codec.Decode(buf.data, buf.len, mok)
    println mok, mem_back.frames
    mut iok := false
    mem_info := codec.Probe(buf.data, buf.len, iok)
    println iok, mem_info.channels

    mp3 := filepath.Join(os.TempDir(), "salam_codec_open.mp3")
    defer mem.Free(mp3 as void*)
    println codec.Save(c, mp3)
    println compress.BufLen(codec.Encode(c, audio.FormatMP3))
    mut bad := false
    mut junk := compress.NewByteBuf()
    mut i := 0
    until i < 16:
        compress.BufPush(junk, i)
        i += 1
    end
    codec.Decode(junk.data, junk.len, bad)
    println bad
    mut gone := false
    nope := filepath.Join(os.TempDir(), "salam_codec_nope.wav")
    defer mem.Free(nope as void*)
    codec.Open(nope, gone)
    println gone
    compress.BufFree(buf)
    compress.BufFree(junk)
    audio.Free(c)
    audio.Free(back)
    audio.Free(mem_back)
end
Outputtrue true false true 4 true true true 64 2 22050 16 0.5 -0.25 true wav 64 16 true true true 64 true 2 false 0 false false

CanEncode

func CanEncode(format: int): bool
True when this build can write that format.

The example for this item is shown with the ones above: codec-Open.salam

Formats

func Formats(): Vector<int>
Every format this package can work with, as a vector of Format numbers.

The example for this item is shown with the ones above: codec-Open.salam

Decode

func Decode(p: void*, n: int, ok &: bool): audio.Clip
Works out the format from the bytes and decodes them into a clip.

The example for this item is shown with the ones above: codec-Open.salam

Probe

func Probe(p: void*, n: int, ok &: bool): audio.Info
Works out the format from the bytes and reads its header, without decoding the sound.

The example for this item is shown with the ones above: codec-Open.salam

Open

func Open(path: str, ok &: bool): audio.Clip
Reads a file of any format this build knows into a clip.

The example for this item is shown with the ones above: codec-Open.salam

ProbeFile

func ProbeFile(path: str, ok &: bool): audio.Info
Reads only the header of a file of any format.

The example for this item is shown with the ones above: codec-Open.salam

Encode

func Encode(c: audio.Clip, format: int): compress.ByteBuf
Encodes a clip in the format you name.

The example for this item is shown with the ones above: codec-Open.salam

Save

func Save(c: audio.Clip, path: str): bool
Writes a clip to a file, picking the format from the extension.

The example for this item is shown with the ones above: codec-Open.salam