Automatische Pegelanpassung für Embedded-Systeme: Linux-ALSA-Implementierung
Der AGC-Algorithmus (Automatic Gain Control) gleicht Audiosignale in Echtzeit aus und macht manuelle Nachjustierungen überflüssig. In Linux-Kommunikationssystemen mit ALSA löst er das Problem ungleichmäßiger Lautstärken aus verschiedenen Quellen. Diese Implementierung zielt auf das S16_LE-Format, 8000 Hz, Mono ab, mit einer Latenz von bis zu 500 ms und einer CPU-Auslastung unter 3 %.
Ziel ist die Verarbeitung kurzer Sprachübertragungen ohne Averaging der gesamten Datei. Tests umfassen subjektive Kriterien (Sprachverständlichkeit) und objektive (Reduktion des Dynamikbereichs).
Analyse von fertigen Lösungen: KI und Plugins
Das Nvidia-Studiovoice-Modell normalisiert die Lautstärke und unterdrückt Rauschen, erfordert aber ein Resampling von 48 kHz auf 8 kHz, was Latenz hinzufügt. Lokaler Einsatz scheitert an Abhängigkeiten.
Das ALSA-Speex-Plugin (basierend auf speexdsp) aktiviert sich mit agc on und agc_level (1–32768). Konfiguration in /etc/asound.conf:
pcm.agc_pcm {
type speex
agc on
agc_level 23400
slave.pcm "dev_out"
}
pcm.test_agc {
type plug
slave.pcm agc_pcm
}
Test: arecord -D dev_in | aplay -D test_agc. Probleme: anfängliches Ausblenden, "Knacken" durch Underruns, undokumentierte frames und filter_length. Fazit: bedingt brauchbar.
FFmpeg dynaudnorm: Der Algorithmus im Detail
Der dynaudnorm-Filter passt perfekt: ffmpeg -f alsa -i dev_in -filter:a "dynaudnorm=f=20:g=33:m=100:c=1" output.wav.
Parameter:
f=20— 20 ms Frame für kurze Übertragungen;g=33— Gauß-Glättung (balanciert Latenz und Glätte);m=100— max. Verstärkung (abhängig von Lautstärkepegel);c=1— DC-Korrektur (entfernt Offset durch Störungen).
Algorithmus:
- Eingangsframe der Größe F;
- DC-Korrektur;
- Peak-Erkennung;
- Berechnung des Verstärkungsfaktors;
- Gauß-Filter zur Glättung;
- Anwenden der Verstärkung und Ausgabe.
Der Filter unterdrückt kein Rauschen. Alternativen: FFmpeg's afftdn, anlmdn, arnndn oder ALSA-Rnnoise mit RNN.
Eigene C++20-Implementierung
Python/Jupyter-Prototyp simuliert Echtzeitverarbeitung: 20-ms-Buffer ohne Laden der gesamten Datei. Oszilloskop-Ansichten bestätigen Dynamikbereichskompression.
Final: C++20 mit Klassen AutomaticGainControl und GaussianFilter. Projektstruktur:
libagc— statische Bibliothek;agc_pipe— Pipe-Utility;- ALSA-Plugin
libasound_module_pcm_agc.so.
agc_pipe-Optionen:
Erlaubte Optionen:
-h [ --help ] Hilfe anzeigen
-m [ --msec ] arg (=20) Framelänge in ms
-c [ --channel ] arg (=1) Zu filternde Kanäle
-r [ --rate ] arg (=8000) Abtastrate
-f [ --filter ] arg (=13) Gauß-Filtergröße
-p [ --peak ] arg (=0.950000) Max. Peak-Wert
-g [ --gain ] arg (=100) Max. Verstärkung
-v [ --verbose ] Detaillierte Logs aktivieren
Test: arecord -D <input> -f S16_LE -t raw | ./agc_pipe -f 7 -g 99 | aplay -D <output> -f S16_LE -t raw.
Leistung: +3 % CPU für eine Quelle, ~400 ms Latenz (FrameLenMs=20, FilterSize=13). Nutzt std::span für Sicherheit.
Wichtige Erkenntnisse
- AGC reduziert den Dynamikbereich, ohne die Sprachverständlichkeit zu beeinträchtigen;
- DC-Korrektur ist essenziell, um Hardware-Artefakte zu beseitigen;
- Gauß-Filterung sorgt für sanfte Übergänge und minimiert Clipping;
- C++20-OOP-Implementierung übertrifft FFmpeg in Wartbarkeit und Erweiterbarkeit;
- Ideal für Embedded-VoIP: geringe CPU-Last, minimale Latenz.
— Editorial Team
Noch keine Kommentare.