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.
S8stand auf 1 undU8auf 2 — damit kollidierteU8mitS16_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. bitsPerSamplewirkt jetzt. Vorher stand das Format fest aufS16_LE; heute wähltALSASetFormatnach 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.
