Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?



  • Also ich habe es geschafft, eine .wav-Datei einzulesen und diese wird auch abgespielt. Leider knackt es am Ende. Eine Recherche im Internet hat ergeben, dass ich den Ausgabewert am Ende auf 0 laufen lassen muss. Leider haben meine ersten schnellen Versuche nicht funktioniert, d.h. es knackt trotzdem.

    Wie macht man sowas praktisch? Beim VLC knackt es übrigens nicht.



  • @Peter-Viehweger

    Die wichtigsten Audioformate sind heutzutage AAC, MP3, FLAC. Auch, wenn diese lossy sind (bis auf FLAC), hört man doch keinen Unterschied.


  • Mod

    @Lupus-SLE sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

    @Peter-Viehweger Ich glaube, das ist nicht mehr zeitgemäß, weder deine Lib., noch das Audioformat.

    Die wichtigsten Audioformate sind heutzutage AAC, MP3, FLAC. Auch, wenn diese lossy sind (bis auf FLAC), hört man doch keinen Unterschied.

    Bitte rede weniger Unsinn.



  • Woher kommt denn die WAV-Datei? Hast du diese selbst erzeugt?
    Das Knacken kommt, wenn diese WAV-Datei auf einem hohen Wert endet und dann abrupt beendet wird (wir hören es dann als Klick bzw. Knacken).

    Für 16-bit PCM gibt mir ChatGPT folgenden Code zum Fade-Out:

    void applyFadeOut(int16_t* samples, int sampleCount, int sampleRate)
    {
        int fadeSamples = sampleRate / 100; // 10 ms Fade
        if (fadeSamples > sampleCount)
            fadeSamples = sampleCount;
    
        for (int i = 0; i < fadeSamples; ++i)
        {
            float factor = 1.0f - (float)i / fadeSamples;
            samples[sampleCount - fadeSamples + i] *= factor;
        }
    }
    

    (also die eingeladene WAV-Datei ändern, bevor sie abgespielt wird)



  • Muss Zeile 9 nicht

    float const factor = 1.0f - (static_cast<float>( i +1 ) / fadesamples);
    

    lauten, damit der Faktor für das letzte Sample 0 wird? TE hat ja geschrieben, dass der letzte Ausgabewert 0 sein soll.



  • Die 0 (Stille) kommt ja explizit durch das Beenden der WAV-Datei, d.h. der Übergang muß nur klein genug sein.

    Edit:
    Bei deinem Code würde der letzte Sample-Wert immer direkt auf 0 gesetzt werden, während der von mir gepostete Code den letzten Wert nur sehr stark abschwächt (ist aber schwer zu sagen, ob man dies wirklich hören würde, selbst wenn der letzte Sample-Wert vorher maximal war).



  • @SeppJ sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

    @Lupus-SLE sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

    @Peter-Viehweger Ich glaube, das ist nicht mehr zeitgemäß, weder deine Lib., noch das Audioformat.

    Die wichtigsten Audioformate sind heutzutage AAC, MP3, FLAC. Auch, wenn diese lossy sind (bis auf FLAC), hört man doch keinen Unterschied.

    Bitte rede weniger Unsinn.

    Heißt das, du hörst bei MP3s je nach Bitrate >128k einen Unterschied? Dann musst du wohl ein Wunderkind mit absolutem Gehör sein. 😅



  • @Lupus-SLE sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

    @Peter-Viehweger Ich glaube, das ist nicht mehr zeitgemäß, weder deine Lib., noch das Audioformat.

    Das ist der relevante Punkt.



  • @DocShoe Hab's wegeditiert.

    Aber der Sepp hätte auch einfach sagen können, auf was er sich bezieht, anstatt den kompletten Beitrag abzuwerten. Aber Genauigkeit und sprachliche Präzision ist wohl schon zu viel verlangt.



  • Und jetzt ist dein erster Beitrag off-topic 🤣



  • @DocShoe sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

    Und jetzt ist dein erster Beitrag off-topic 🤣

    Nur indirekt. Ich bezweifle, dass moderne Spiele noch wav als Soundformat einsetzen. Aber mag mich irren.



  • @Lupus-SLE sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

    @DocShoe sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

    Und jetzt ist dein erster Beitrag off-topic 🤣

    Nur indirekt. Ich bezweifle, dass moderne Spiele noch wav als Soundformat einsetzen. Aber mag mich irren.

    Wer spricht hier von Spielen?

    @Lupus-SLE
    Aber Genauigkeit und sprachliche Präzision ist wohl schon zu viel verlangt.



  • @DocShoe sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

    Wer spricht hier von Spielen?

    Übersicht / Weitere Fachbereiche / Spiele-/Grafikprogrammierung 😅

    Die KI sagt:

    Die am häufigsten verwendeten Formate in Spielen sind:

    WAV (.wav): Das Standardformat für kurze, häufig abgespielte Soundeffekte (z. B. Schüsse, Schritte, UI-Sounds). Es ist unkomprimiert (PCM), bietet höchste Qualität und verursacht eine geringere CPU-Last beim Abspielen.

    Ogg Vorbis (.ogg): Sehr beliebt für Hintergrundmusik und längere Audiospuren. Es bietet eine gute Komprimierung bei hoher Qualität und erlaubt nahtlose Übergänge (Looping), ohne Lücken zu erzeugen.

    MP3 (.mp3): Wird oft für Musik genutzt, ist aber wegen möglicher kurzer Pausen am Anfang/Ende weniger für nahtlose Loops geeignet. Auf mobilen Plattformen ist MP3 weit verbreitet.

    FLAC (.flac): Ein verlustfreies Format, das oft für hochwertige Musik verwendet wird, da es die Qualität von WAV bietet, aber weniger Speicherplatz benötigt.

    ADPCM / Bink Audio: Häufig in der Unreal Engine verwendet, um Audiodaten platzsparend zu komprimieren.

    Module-Dateien (.mod, .xm, .it, .s3m): Ältere oder spezielle Formate, die sehr ressourcenschonend sind, da sie Samples und Noteninformationen speichern.

    Engine-spezifische Hinweise:

    Unity: Importiert WAV, AIFF, MP3, OGG und konvertiert sie plattformabhängig oft in Ogg Vorbis (PC/Konsole) oder MP3 (Mobile).

    Unreal Engine: Unterstützt primär WAV, konvertiert diese beim "Cooking" (Verpacken) oft in Bink Audio, ADPCM oder lässt sie als PCM.



  • Es liegt aber nicht am Fade-Out ... (am besten selbst mal eine KI fragen...)

    Die "magische" Lösung von VLC gegen das Knacken liegt in der sauberen Implementierung der Drain- und Flush-Logik in seinem Audio-Output-System. Während einfache Implementierungen den Audiostrom oft hart abbrechen, sorgt VLC dafür, dass die Audio-Hardware alle verbleibenden Daten im Puffer kontrolliert ausspielt.

    Kernkonzepte der VLC-Implementierung

    VLC verwendet eine Abstraktionsschicht für Audio-Ausgänge (wie waveout.c für Windows oder alsa.c für Linux). Die entscheidenden Funktionen im Quellcode sind:

    • Drain (Entleeren): Dies ist der wichtigste Teil. Anstatt den Stream sofort zu stoppen, ruft VLC die Drain-Funktion des jeweiligen Betriebssystems auf (z. B. waveOutRestart oder das Warten auf Pufferleerung). Das Programm wartet aktiv, bis die Soundkarte meldet, dass das letzte Sample abgespielt wurde.

    • Flush (Leeren/Verwerfen): Wenn ein Benutzer manuell stoppt oder springt, nutzt VLC Flush, um den Puffer sofort zu leeren, setzt dabei aber oft die Hardware-Parameter so zurück, dass kein Pegelsprung entsteht.

    • PTS-Diskontinuitätshandling: VLC überwacht die Presentation Time Stamps (PTS). Wenn eine Lücke (Diskontinuität) im Zeitstempel erkannt wird, schaltet VLC nicht einfach hart um, sondern leitet einen geordneten Übergang ein, um Artefakte zu vermeiden.

    Beispielhafter Aufbau (Pseudo-Logik aus vlc_aout.h)

    Im VLC-Quellcode sieht die Struktur für Audio-Module etwa so aus:

    c

    struct audio_output {
        // ...
        int  (*start) (audio_output_t *, audio_sample_format_t *);
        void (*play)  (audio_output_t *, block_t *);
        void (*pause) (audio_output_t *, bool, vlc_tick_t);
        void (*flush) (audio_output_t *); // Verwirft Pufferdaten sauber
        void (*drain) (audio_output_t *); // Wartet, bis Puffer leergespielt ist
        void (*stop)  (audio_output_t *);
        // ...
    };
    

    Verwende Code mit Vorsicht.

    Warum knackt es bei Ihnen?

    Wenn Sie selbst eine Wiedergabe programmieren, fehlen wahrscheinlich diese Schritte:

    • Nulldurchgang: Sie beenden die Wiedergabe bei einem Sample-Wert ungleich Null.

    • Hardware-Puffer: Sie schließen das Audio-Device, während die Soundkarte noch Daten im internen Puffer hat.

    Empfehlung für Ihre Implementierung:

    Achten Sie darauf, am Ende Ihres Audiostreams entweder ein winziges Fade-Out (ca. 10ms) einzubauen oder explizit auf das Drain-Event Ihrer Audio-API zu warten, bevor Sie das Device schließen.



  • @Lupus-SLE sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

    Es liegt aber nicht am Fade-Out ... (am besten selbst mal eine KI fragen...)
    ...
    Achten Sie darauf, am Ende Ihres Audiostreams entweder ein winziges Fade-Out (ca. 10ms) einzubauen oder ...

    Du widersprichst dich...



  • @Th69 Nicht unbedingt, weil das eher ein Workaround ist, wenn man den Puffer nicht ordentlich schließt, also auf das Drain-Event horcht.



  • Man könnte die wav-Datei auch mit einem Hex-Editor öffnen und sich tatsächlich die letzten Bytes anschauen. Diese sollten 00 oder 80 sein, damit es keine Pegelsprünge am Ende der Audioausgabe gibt.

    Ein Knacken ist physikalisch gesehen nichts anderes als eine extrem schnelle Bewegung der Lautsprechermembran von einer ausgelenkten Position zurück in die Ruheposition.

    Hier ist der technische Hintergrund, warum 00 oder 80 entscheidend sind:

    Die zwei Arten, wie WAV-Daten gespeichert werden

    WAV-Dateien speichern Werte unterschiedlich, je nachdem, welche Bittiefe (Bit Depth) verwendet wird. Das beeinflusst, was "Stille" im Hex-Editor bedeutet:

    8-Bit WAV (Unsigned Integer):

    Die Werte gehen von 0 bis 255.

    Die Nulllinie (Stille) liegt in der Mitte bei 128.

    Im Hex-Editor ist das der Wert 80.

    Problem: Wenn die Datei bei FF (255) aufhört, springt die Membran sofort von "ganz vorne" auf die Mitte zurück -> Knack.

    16-Bit WAV (Signed Integer, Little Endian):

    Dies ist der Standard (CD-Qualität). Die Werte gehen von -32.768 bis +32.767.

    Die Nulllinie (Stille) liegt bei 0.

    Im Hex-Editor sieht das als 16-Bit-Paar so aus: 00 00.

    Problem: Wenn die Datei bei einem hohen Wert wie 7F FF aufhört, gibt es einen massiven Sprung auf Null -> Knack.

    Warum VLC das Problem "löst"

    Wenn VLC eine Datei abspielt, die bei einem hohen Wert (z.B. 7F FF) endet, "reißt" VLC die Verbindung zur Hardware nicht einfach ab.



  • OpenAL hat aber kein explizites Drain-Event (da es hardwareunabhängig ist), so daß man üblicherweise folgenden Ablauf verwendet:

    1. Fade-Out
    2. Warten auf AL_STOPPED
    3. 10–20 ms extra warten
    4. Dann Device schließen


  • @Th69 Ja, das würde es auch verhindern.


Anmelden zum Antworten