Suche C/C++-Lib für IIR oder FIR



  • Ich versuche gerade, einen virtuellen "digitalen Signalprozessor" zu schreiben.
    Die Laufzeitkorrektur funktioniert bereits, jetzt gehts an die Filter...

    Aber irgendwie finde ich nichts passendes, dabei hat doch jedes Audioprogramm der letzten 15 Jahre einen parametrischen EQ dabei...

    Kann mir da jemand eine Lib in C oder C++ empfehlen die folgendes kann:

    • Hoch-, Band- und Tiefpass aus den Parametern (Frequenz, Ordnung, beim Bandpass noch Bandbreite/Güte) erzeugen
    • "Häpchenweise" Anwendung, da Audiodaten ja auch so aus der Datei in den Buffer geschrieben werden. Kein Audiobuffer frisst 80MB große Wave-Dateien im ganzen.
    • Signed int mit 16Bit/Sample wäre perfekt, das ist nunmal der "Standard" bei PCM


  • Also ich hab' auf Anhieb mal die da gefunden (Google: digital filter library):

    http://spuc.sourceforge.net/ (GPL Lizenz)
    https://github.com/vinniefalco/DSPFilters/ (MIT Lizenz, nur IIR Filter)
    http://cnbi.epfl.ch/software/rtfilter.html (LGPL)

    Hab mir die aber nicht genauer angesehen, keine Ahnung wie schwer/einfach die einzubinden sind.

    Wirst du aber vermutlich alle nicht verwenden können ohne dich halbwegs gut in die Materie einzulesen.

    Die Implementierung der Filterfunktionen ist auch relativ einfach (zumindest wenn man bei FIR Filtern die "brute force" Methode macht, die halt langsam ist dafür aber auch ohne zusätzliches Delay auskommt). Das Schwierige ist eher das Berechnen der Filterkoeffizienten 😉



  • hustbaer schrieb:

    Das Schwierige ist eher das Berechnen der Filterkoeffizienten 😉

    Das ist mir bekannt, darum sollte die Lib das eben idialer Weise auch machen.

    Aktuell habe ich gerade Nr. 2 versucht, die kann aber nur float-Werte (obwohl bei Audio int16 standard wäre), die Channels müssen als Array von Arrays übergeben werden, obwohl eigentlich standard ist, die Samples zu verschachteln (siehe RIFF/Wave), aber die Samples muss ich wegen der Laufzeitkorrektur sowieso nach Kanälen sortieren...

    Außerdem glaube ich, dass ich bei dem Ding die ganze Datei durchschicken müsste, außer es ergeben sich keine unterschwiede wenn nach allen 1024 Bytes das Filter resettet wird, oder aber ich mache die "Häppchen" größer.

    Die anderen sehe ich mir morgen mal an...
    Danke für die Hilfe



  • Was soll den ein "virtueller digitaler Signalprozessor" sein? Was ist in dem Zusammenhang "Laufzeitkorrektur"?
    Typische DSPs haben keine eingebauten Filter und auch keine eingebauten Filterdesigntoolkits. Was Du normalerweise hast, sind irgendwelche Libs für SIMD-Operationen, zum Beispiel um einen Vektor mit Daten mit einem anderen Vektor zu falten. Das ist aber meistens ziemlich Low-Level.



  • @Tachyon:
    Er meint mit "DSP" vermutlich ein schwarzes Kastl mit Chip + Programm drinnen, mit dem man dann Audio-Signale zurechtbiegen kann.
    Mit Laufzeitkorrektur ist einfach ein (pro Kanal unterschiedliches) Delay gemeint, das man verwendet um die Signale so zu verzögern dass sie trotz unterschiedlicher Laufzeit (des Schalls in der Luft) beim Hörer wieder gleichzeitig ankommen.

    Hat jedes gute Autoradio drinnen, jeder brauchbare Surround-Receiver und auch jeder brauchbare Lautsprecher-Controller für den PA Bereich.



  • @der Papst:
    Mit 16 bittigen ints kannst du sowieso nicht 1:1 rechnen. Zumindest Zwischenergebnisse müssen grösser sein, und wenn du nicht nach jedem einzelnen Filter auf 16 Bit re-quantisieren willst (und damit Quantisierungsfehler akkumulieren), musst du auch die Daten zwischen den einzelnen Filtern in der Kette mit > 16 Bit übergeben.

    Und dann kannst du gleich float nehmen. Das machen soweit ich weiss auch die meisten besseren DSPs, also Input -> float wandeln -> alle DSP Stufen -> mit Dithering auf 16/20/24 Bit quantisieren -> Output.

    der Papst schrieb:

    Außerdem glaube ich, dass ich bei dem Ding die ganze Datei durchschicken müsste, außer es ergeben sich keine unterschwiede wenn nach allen 1024 Bytes das Filter resettet wird, oder aber ich mache die "Häppchen" größer.

    Also wenn der Filter nach jedem "häppchen" resettet wird wäre das sehr übel. Würde den Einsatz in jedem Tool das "live" arbeiten soll verhindern.
    Guck mal in die Implementierung rein ob der das wirklich macht.
    Und wenn ja, vielleicht kannst du den Code zumindest als Basis hernehmen und die nötigen Änderungen für "nicht-resetten" selbst vornehmen.

    Standard wäre eigentlich dass so ein Filter im Prinzip (zumindest) 3 Funktionen hat: setup (legt die Parameter fest), process/push/... (schiebt einen Block durch) und reset (resettet den internen Zustand auf Ausgangswerte). Und dass man eben mit process "streamen" kann, ohne dass dabei Artefakte entstehen.



  • hustbaer schrieb:

    Standard wäre eigentlich dass so ein Filter im Prinzip (zumindest) 3 Funktionen hat: setup (legt die Parameter fest), process/push/... (schiebt einen Block durch) und reset (resettet den internen Zustand auf Ausgangswerte).

    Die ersten beiden hat die lib, reset weiß ich noch nicht.
    Aber ich werde jetzt mal diesen Ansatz verfolgen:
    Ich lese ja immer 1024KB aus der Datei, dieses Array werde ich dann erstmal in die Kanäle sortieren und gleichzeitig in float umwandeln.

    Auf die float-arrays wende ich dann process an und dann fülle ich die Arrays in die beiden FIFOs.

    Mal sehen ob das dann klappt.
    Wenn ich process(array) aufrufe, müsste sich ja eigentlich das Filter um alles kümmern, und laut der Doku ist das auch so vorgesehen...



  • Und, wie steht's mit deinem Vorhaben?


Anmelden zum Antworten