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 field | default | description |
|---|---|---|
server | none | "pulse" for the sound server; any other value is refused |
card | 0 | ALSA card number |
device | 0 | PCM device number |
rate | 48000 | sample rate, Hz |
channels | 2 | channel count |
period | 1024 | frames per period: the latency step |
periods | 4 | periods in the ring |
format | "auto" | "f32", "s16", or "auto": f32 when the card takes it, else s16; any other value is refused |
| method | description |
|---|---|
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.