====== std.audio — Audio-Verarbeitung und Wiedergabe ======
→ [[lyx_-_programmiersprache:units|Zurück zur Unit-Übersicht]] · [[lyx_-_programmiersprache:guides:audio-und-video|Guide: Audio & Video]] · [[lyx_-_programmiersprache:units:video|std.video]]
Übersicht über den Audio-Namensraum von Lyx: vier Units für **Analyse, Konvertierung, Dekodierung und Wiedergabe** von Audiodaten. ''std.audio'' selbst ist die Basis-Unit und kommt ohne externe Bibliotheken aus; die drei Unterunits binden Systembibliotheken per FFI ein.
Was Lyx kann: WAV lesen und schreiben, PCM-Formate umrechnen, MP3 dekodieren, PCM über ALSA ausgeben. Was Lyx **nicht** kann: MP3 oder andere Formate kodieren — der einzige Encoder ist WAV.
**Autor:** Andreas Röne\\
**Copyright:** 2024-2025 Andreas Röne\\
**Quelle:** ''std/audio.lyx'', ''std/audio/''
----
===== Units im Überblick =====
^ Unit ^ Import ^ Externe Bibliothek ^ Beschreibung ^
| [[lyx_-_programmiersprache:units:audio|std.audio]] | ''import std.audio;'' | keine | Basis: ''AudioInfo''-Struct, WAV-Parser, WAV schreiben, PCM-Konvertierung (8→16 Bit, Stereo→Mono) |
| [[lyx_-_programmiersprache:units:audio:mpg123|std.audio.mpg123]] | ''import std.audio.mpg123;'' | ''libmpg123'' | MP3 → PCM, stream-basiert, Formatabfrage (Samplerate, Kanäle, Encoding) |
| [[lyx_-_programmiersprache:units:audio:alsa|std.audio.alsa]] | ''import std.audio.alsa;'' | ''libasound.so.2'' | ALSA-Direktzugriff: PCM-Gerät öffnen, Format setzen, Puffer ausgeben, Aufnahme |
| [[lyx_-_programmiersprache:units:audio:playback|std.audio.playback]] | ''import std.audio.playback;'' | ''libasound.so.2'' (+ ''libmpg123'' für MP3) | Fassade: ''AudioOpen''/''AudioPlayWAV''/''AudioPlayPCM''/''AudioPlayMP3''/''AudioClose'', dazu die Einzeiler ''PlayWAV'' und ''PlayMP3'' |
Es gibt **keinen Wildcard-Import**: ''%%import std.audio.*;%%'' ist ein Parse-Fehler. Jeder Punktpfad bezeichnet genau eine Datei — ''std.audio.alsa'' → ''std/audio/alsa.lyx''.
----
===== Wann welche Unit =====
^ Aufgabe ^ Unit ^ Kernfunktionen ^
| WAV-Datei analysieren (Samplerate, Kanäle, Dauer) | ''std.audio'' | ''WAVParse'', ''AudioInfo'' |
| PCM-Rohdaten aus WAV holen | ''std.audio'' | ''WAVReadData'', ''WAVGetBuffer'' |
| Eigenes Signal als WAV speichern | ''std.audio'' | ''WAVWriteHeader'', ''WAVSaveFile'' |
| 8-Bit-Material auf 16 Bit bringen | ''std.audio'' | ''WAVConvert8To16'' |
| Stereo auf Mono mischen | ''std.audio'' | ''WAVStereoToMono'' |
| MP3-Metadaten und PCM-Daten lesen | ''std.audio.mpg123'' | ''MP3Init'', ''MP3OpenFile'', ''MP3Read'', ''MP3GetFormat'' |
| Eigener Ausgabepfad mit voller Kontrolle | ''std.audio.alsa'' | ''ALSAAudioOpen'', ''ALSASetFormat'', ''ALSAWrite'' |
| Kurzer Systemton, Alarm, schneller Test | ''std.audio.playback'' | ''PlayWAV'', ''PlayMP3'' |
| Mehrere Dateien auf einem offenen Gerät | ''std.audio.playback'' | ''AudioOpen'', ''AudioPlayWAV'', ''AudioPlayMP3'', ''AudioClose'' |
| Testton erzeugen (Rechteck, 16 Bit) | ''std.audio'' | ''AudioGenTone'' |
----
===== Signalweg =====
WAV-Datei ──WAVParse/WAVReadData──┐
├──► PCM im Speicher ──ALSAWrite──► Soundkarte
MP3-Datei ──MP3OpenFile/MP3Read───┘ └──WAVSaveFile──► WAV-Datei
Alle Units arbeiten mit **interleaved PCM**: bei Stereo folgen die Samples abwechselnd links/rechts. Die Bittiefe steht in ''AudioInfo.bitsPerSample''; ALSA erwartet dazu passend ''SND_PCM_FORMAT_S16_LE'' bzw. ''SND_PCM_FORMAT_U8''.
----
===== Bekannte Defekte =====
Geprüft mit lyxc 1.0.21A:
* ''MP3Parse'' aus ''std.audio'' liefert **immer** ''AUDIO_ERROR'' (−1). Für MP3 stattdessen ''std.audio.mpg123'' verwenden.
* ''ALSASetFormat'' schlägt mit ''ALSA_ERROR'' fehl, auch bei vorhandener Soundkarte — damit funktioniert **die gesamte Wiedergabe** (''PlayWAV'', ALSA-Direktausgabe) derzeit nicht. Analyse, Konvertierung und Datei-Ausgabe sind nicht betroffen.
----
===== Einstiegsbeispiel =====
unit main;
import std.audio;
import std.io;
import std.string;
fn main(): int64 {
var info: AudioInfo;
if (WAVParse("ton.wav"c, info) != AUDIO_OK) {
PrintLn("WAV konnte nicht gelesen werden");
return 1;
}
PrintLn(StrConcat("Samplerate: ", IntToStr(info.sampleRate)));
PrintLn(StrConcat("Kanaele: ", IntToStr(info.channels)));
PrintLn(StrConcat("Bits: ", IntToStr(info.bitsPerSample)));
PrintLn(StrConcat("Dauer (ms): ", IntToStr(info.durationMs)));
return 0;
}
Ausführliche Beispiele — PCM erzeugen, MP3 dekodieren, ALSA-Ausgabe, Video-Metadaten — stehen im [[lyx_-_programmiersprache:guides:audio-und-video|Guide „Audio & Video"]].
----
===== Referenz: std.audio =====
Gemeinsame Audio-Typen und Dateiformat-Parser als Basis für die Audio-Unterpakete. ''AudioInfo'' beschreibt einen Audio-Stream mit Format, Sample-Rate, Kanalanzahl, Bittiefe, Datenoffset und Gesamtdauer. Parser für WAV-Dateien (''WAVParse'', ''WAVReadData'', ''WAVGetBuffer'') und MP3 (''MP3Parse'' für Metadaten). Format-Konvertierung: 8-Bit nach 16-Bit PCM (''WAVConvert8To16'') und Stereo nach Mono (''WAVStereoToMono''). WAV-Dateien schreiben (''WAVWriteHeader'', ''WAVSaveFile'').
Einsatzbereiche: Basis-Unit für ''std.audio.alsa'', ''std.audio.mpg123'' und ''std.audio.playback''; Audio-Verarbeitung, TTS-Ausgabe, Signalanalyse, Aufnahme und Wiedergabe von PCM-Daten.
----
===== Konstanten =====
^ Name ^ Typ ^ Wert ^ Sichtbarkeit ^
| ''AUDIO_OK'' | ''int64'' | ''0'' | pub |
| ''AUDIO_ERROR'' | ''int64'' | ''-1'' | pub |
| ''AUDIO_NOT_SUPPORTED'' | ''int64'' | ''-3'' | pub |
| ''AF_PCM8'' | ''int64'' | ''1'' | pub |
| ''AF_PCM16'' | ''int64'' | ''2'' | pub |
| ''AF_MP3'' | ''int64'' | ''10'' | pub |
----
===== Typen =====
==== AudioInfo (struct) ====
^ Feld ^ Typ ^
| ''format'' | ''int64'' |
| ''sampleRate'' | ''int64'' |
| ''channels'' | ''int64'' |
| ''bitsPerSample'' | ''int64'' |
| ''dataOffset'' | ''int64'' |
| ''dataSize'' | ''int64'' |
| ''durationMs'' | ''int64'' |
----
===== Funktionen =====
^ Signatur ^ Sichtbarkeit ^ Beschreibung ^
| ''MP3Parse(path: pchar, ref info: AudioInfo): int64'' | pub | Liest MP3-Metadaten in AudioInfo — **liefert derzeit immer ''AUDIO_ERROR''** |
| ''WAVParse(path: pchar, ref info: AudioInfo): int64'' | pub | Liest WAV-Header in AudioInfo |
| ''WAVReadData(path: pchar, info: AudioInfo): int64'' | pub | Liest PCM-Nutzdaten aus WAV-Datei |
| ''WAVGetBuffer(path: pchar, info: AudioInfo): int64'' | pub | Gibt Zeiger auf WAV-Datenpuffer |
| ''WAVConvert8To16(src: int64, dst: int64, count: int64): int64'' | pub | Konvertiert 8-Bit-PCM nach 16-Bit |
| ''WAVStereoToMono(src: int64, dst: int64, frames: int64): int64'' | pub | Mischt Stereo-PCM zu Mono |
| ''AudioErrorString(code: int64): pchar'' | pub | Gibt Fehlermeldung als C-String |
| ''WAVWriteHeader(fd: int64, dataSize: int64, sampleRate: int64, channels: int64, bitsPerSample: int64): int64'' | pub | Schreibt WAV-Header in Dateideskriptor |
| ''WAVSaveFile(path: pchar, buffer: int64, dataSize: int64, sampleRate: int64, channels: int64, bitsPerSample: int64): int64'' | pub | Speichert PCM-Puffer als WAV-Datei |
| ''AudioGenTone(freq: int64, durationMs: int64, sampleRate: int64, channels: int64, amplitude: int64, sizeOut: int64): int64'' | pub | Erzeugt einen Rechteck-Ton als 16-Bit-PCM-Puffer (ohne Fließkomma). Rückgabe: ''mmap''-Zeiger, 0 bei Fehler; die Bytegröße wird nach ''sizeOut'' geschrieben. Freigabe durch den Aufrufer per ''munmap(buf, size)'' |
----
===== Konstanten =====
^ Name ^ Typ ^ Wert ^ Sichtbarkeit ^
| ''SEEK_SET'' | ''int64'' | ''0'' | pub |
| ''SEEK_CUR'' | ''int64'' | ''1'' | pub |
| ''SEEK_END'' | ''int64'' | ''2'' | pub |
| ''PROT_READ'' | ''int64'' | ''1'' | pub |
| ''PROT_WRITE'' | ''int64'' | ''2'' | pub |
| ''PROT_RW'' | ''int64'' | ''3'' | pub |
| ''MAP_ANON'' | ''int64'' | ''32'' | pub |
| ''MAP_PRIVATE'' | ''int64'' | ''2'' | pub |
| ''O_RDONLY'' | ''int64'' | ''0'' | pub |
| ''O_WRONLY'' | ''int64'' | ''1'' | pub |
| ''O_RDWR'' | ''int64'' | ''2'' | pub |
| ''O_CREAT'' | ''int64'' | ''64'' | pub |
| ''O_TRUNC'' | ''int64'' | ''512'' | pub |
| ''FD_NONE'' | ''int64'' | ''-1'' | pub |
Letzte Aktualisierung: 2026-09-02 — Übersichtsteil ergänzt; ''AudioGenTone'' nachgetragen, ''ref''-Parameter bei ''WAVParse''/''MP3Parse'' korrigiert, Playback-Fassade richtiggestellt.