std.audio.alsa

→ std.audio Übersicht · std.audio.playback · Guide: Audio & Video

ALSA (Advanced Linux Sound Architecture) ist die Standard-Soundschnittstelle unter Linux und direkter Nachfolger von OSS. Die Unit bietet Zugriff auf PCM-Geräte für Wiedergabe und Aufnahme von Audiosignalen mit konfigurierbarem Format (Samplerate, Kanalanzahl, Bittiefe). Der Zugriff erfolgt direkt auf Kernel-Ebene ohne zwischengeschaltete Abstraktionsschicht.

Typische Einsatzbereiche sind Audioanwendungen, Sprachausgabe (Text-to-Speech), Signalverarbeitung, Loopback-Tests und eingebettete Systeme mit Audioausgabe.

Quelle: std/audio/alsa.lyx

<WRAP center round important 90%> Behoben (#1930, nachgemessen mit lyxc 1.2.2B): ALSASetFormat(h, 44100, 2, 16) liefert 0, ALSAPrepare ebenfalls — die Wiedergabe arbeitet.

Die Ursache war eine andere als lange vermutet: nicht die FFI-Signatur, sondern die Fehlerprüfung. ALSA meldet Fehler negativ; ein Rückgabewert > 0 ist Erfolg mit Zusatzinformation. snd_pcm_hw_params_any liefert hier 1, und die gebundene Symbolversion von snd_pcm_hw_params_set_rate_near (ALSA_0.9.0rc4, Rate als Wert) gibt die tatsächlich gesetzte Rate zurück — also 44100. Beide Stufen galten mit der alten Prüfung != 0 als Fehlschlag. Geprüft wird jetzt überall < 0.

Zwei weitere Punkte kamen mit demselben Fix:

  • Die Formatkonstanten waren falsch. S8 stand auf 1 und U8 auf 2 — damit kollidierte U8 mit S16_LE, und 8-Bit-Material wurde still als 16 Bit ausgegeben. Gegen die C-Header gemessen gilt: S8=0, U8=1, S16_LE=2, S16_BE=3, U16_LE=4, U16_BE=5, S32_LE=10.
  • bitsPerSample wirkt jetzt. Vorher stand das Format fest auf S16_LE; heute wählt ALSASetFormat nach der Bittiefe: 8 → U8, 16 → S16_LE, 32 → S32_LE.

</WRAP>


Konstanten

Name Typ Wert Sichtbarkeit
ALSA_OK int64 0 pub
ALSA_ERROR int64 -1 pub
ALSA_TIMEOUT int64 -11 pub
SND_PCM_STREAM_PLAYBACK int64 0 pub
SND_PCM_STREAM_CAPTURE int64 1 pub
SND_PCM_ACCESS_MMAP_INTERLEAVED int64 0 pub
SND_PCM_ACCESS_RW_INTERLEAVED int64 3 pub
SND_PCM_FORMAT_S8 int64 0 pub
SND_PCM_FORMAT_U8 int64 1 pub
SND_PCM_FORMAT_S16_LE int64 2 pub
SND_PCM_FORMAT_S16_BE int64 3 pub
SND_PCM_FORMAT_U16_LE int64 4 pub
SND_PCM_FORMAT_U16_BE int64 5 pub
SND_PCM_OPEN_READ int64 1 pub
SND_PCM_OPEN_WRITE int64 2 pub

Externe Funktionen

Extern deklarierte Funktionen (aus C-Bibliotheken):

Signatur Beschreibung
snd_pcm_open(handlePtr: int64, device: pchar, stream: int64, mode: int64): int64 Öffnet ALSA-PCM-Gerät
snd_pcm_close(handle: int64): int64 Schließt ALSA-PCM-Gerät
snd_pcm_hw_params_malloc(paramsPtr: int64): int64 Allociert Hardware-Parameter-Struktur
snd_pcm_hw_params_free(params: int64): int64 Gibt Hardware-Parameter-Struktur frei
snd_pcm_hw_params_any(handle: int64, params: int64): int64 Füllt Parameter mit Gerätestandardwerten
snd_pcm_hw_params_set_access(handle: int64, params: int64, access: int64): int64 Setzt PCM-Zugriffsmodus
snd_pcm_hw_params_set_format(handle: int64, params: int64, format: int64): int64 Setzt PCM-Sampleformat
snd_pcm_hw_params_set_rate_near(handle: int64, params: int64, rate: int64, dir: int64): int64 Setzt Samplerate nächstmöglichem Wert
snd_pcm_hw_params_set_channels(handle: int64, params: int64, channels: int64): int64 Setzt Kanalanzahl
snd_pcm_hw_params(handle: int64, params: int64): int64 Überträgt Parameter an Hardware
snd_pcm_prepare(handle: int64): int64 Bereitet PCM-Stream zur Wiedergabe vor
snd_pcm_writei(handle: int64, buffer: int64, frames: int64): int64 Schreibt interleaved PCM-Frames
snd_pcm_drain(handle: int64): int64 Wartet auf Abspielung aller Frames

Typen

ALSAHandle = int64

Handle-Konvention für ALSA-Geräte:


Funktionen

Signatur Sichtbarkeit Beschreibung
ALSAAudioOpen(): ALSAHandle pub Öffnet Standard-PCM-Gerät für Wiedergabe
ALSASetFormat(handle: int64, sampleRate: int64, channels: int64, bitsPerSample: int64): int64 pub Konfiguriert Samplerate, Kanäle, Bittiefe
ALSAPrepare(handle: int64): int64 pub Bereitet PCM-Handle zur Ausgabe vor
ALSAWrite(handle: int64, buffer: int64, byteCount: int64): int64 pub Schreibt Bytes in den PCM-Ausgabepuffer. Rechnet fest mit 4 Byte je Frame (16 Bit, Stereo); Rückgabe: geschriebene Bytes oder negativer Fehlercode
ALSAWriteGeneric(handle: int64, buffer: int64, byteCount: int64, channels: int64, bitsPerSample: int64): int64 pub Wie ALSAWrite, aber mit beliebiger Kanalzahl und Bittiefe: bytesPerFrame = channels × (bitsPerSample / 8). Für Mono oder 8-Bit-Material die richtige Wahl
ALSAClose(handle: int64): int64 pub Draint und schließt PCM-Gerät

—-

Fallstricke

Thema Details
Format folgt der Bittiefe 8 → U8, 16 → S16_LE, 32 → S32_LE; andere Werte werden abgewiesen
ALSAWrite nur 16-Bit-Stereo Bei Mono oder 8 Bit rechnet die Frame-Umrechnung falsch; stattdessen ALSAWriteGeneric verwenden
Handle-Fehlerwert ALSAAudioOpen liefert 0 bei Fehler
Linux only Benötigt libasound.so.2 (PipeWire über die ALSA-Brücke funktioniert ebenfalls)

Letzte Aktualisierung: 2026-09-05 (#1930, nachgemessen mit lyxc 1.2.2B) — Defektkasten ersetzt: ALSASetFormat arbeitet, Ursache war die Fehlerprüfung (!= 0 statt < 0), nicht die FFI-Signatur; Formatkonstanten S8/U8 berichtigt; bitsPerSample wirkt jetzt.

Vorherige letzte Aktualisierung: 2026-09-02 — ALSAWriteGeneric ergänzt, Ursache des ALSASetFormat-Defekts (FFI-Signatur snd_pcm_hw_params_set_rate_near) dokumentiert.