sound.open

sound

open(opts) -> dev, err

Open a playback device

With no server, opens /dev/snd/pcmC<card>D<device>p, sets the hardware and software parameters, and prepares the stream. Playback starts by itself once the ring fills. The device is held exclusively while open: no other program can play through it.

With server = "pulse", opens a stream on the desktop's sound server instead, through sound.pulse.open. That takes rate, channels, period and periods alike. Its own block lists its other fields and the methods that differ. The choice is the caller's. A socket that exists says nothing about who holds the card: a desktop's sound server starts on demand from its socket, even at a bare console.

opts fielddefaultdescription
servernone"pulse" for the sound server; any other value is refused
card0ALSA card number
device0PCM device number
rate48000sample rate, Hz
channels2channel count
period1024frames per period: the latency step
periods4periods in the ring
format"auto""f32", "s16", or "auto": f32 when the card takes it, else s16; any other value is refused
methoddescription
dev:fd()the PCM node's descriptor, for lev.core.wait_writable
dev:period()frames per period: what run writes at a time
dev:channels()the channel count the card took
dev:rate()the sample rate the card took
dev:format()"f32" or "s16": the format the card took
dev:avail()free frames in the ring; or nil and an error
dev:write(buf)frames written; nil and "EAGAIN" with the ring full; nil and "EPIPE" on an underrun
dev:recover()prepare the stream again after an underrun
dev:start()start playback before the ring is full
dev:drop()stop now and discard the queued frames
dev:close()release the card

write clamps samples to [-1, 1] and converts them to s16 when the card took s16.