Frage

ich habe die Bittiefe eines digitalen Audiosignals von 24 auf 16 Bit zu reduzieren.

Betrachtet man nur die 16 höchstwertigen Bits (d.h. Abschneide) jeder Probe entspricht eine proportionale Berechnung zu tun (out = in * 0xFFFF / 0xFFFFFF)?

War es hilfreich?

Lösung

Ich nehme an, Sie mittlere (in * 0xFFFF) / 0xFFFFFF, wobei in diesem Fall, ja.

Andere Tipps

Sie erhalten bessere Ergebnisse klingen durch ein sorgfältig gestaltetes Rauschsignal zu dem ursprünglichen Signal hinzugefügt, knapp unterhalb der Schwelle Kürzen, vor Kürzen (auch bekannt als Dithering).

Dithering durch Hinzufügen von Rauschen im allgemeinen zu besseren Suchergebnissen. Der Schlüssel dazu ist die Form des Lärms. Die popula pow-r Dithering-Algorithmen haben eine spezifische Form, dass sehr beliebt ist in vielen digitalen Audio-Workstation-Anwendungen (Cakewalk SONAR, Logic, etc.).

Wenn Sie nicht brauchen, die voll auf die Treue von pow-r, können Sie einfach erzeugen einige Rauschen bei relativ niedriger Amplitude und in Ihr Signal mischen. Sie werden diese Masken einige der Quantisierung Effekte finden.

x * 0xffff / 0xffffff ist übermäßig von pedantisch, aber nicht in einer guten Art und Weise, wenn Ihre Proben unterzeichnet werden -. Und wahrscheinlich nicht in einem guten Weg im Allgemeinen

Ja, wollen Sie den Maximalwert in dem Quellbereich in Ihrem Zielbereich den maximalen Wert entsprechen, aber die Werte verwendet, da nur für unsigned Bereiche liegen, und die Verteilung von Quantisierungsschritten bedeutet, dass es wird sehr selten sein, dass Sie verwenden den größtmöglichen Ausgabewert.

Wenn die Proben signiert dann den positiven Spitzenwerte 0x7fff und 0x7fffff wären, während die negativen Spitzenwert -0x8000 und -0x800000 wären. Ihr erstes Problem ist zu entscheiden, ob ein gleich 0x7fff oder -1 ist gleich -0x8000. Wenn Sie sich für Letzteres entscheiden, dann ist es ein einfacher Schicht-Betrieb. Wenn Sie versuchen, beide zu haben, dann stoppt Null Null ist.

Nach dass Sie ein Problem, dass Division Runden gegen Null haben. Dies bedeutet, dass zu viele Werte gerundet auf Null erhalten im Vergleich mit anderen Werten. Dies führt zu Verzerrungen.

Wenn Sie nach den positiven Spitzenwerte skalieren möchten, wäre die richtige Form haben:

out = rint((float)in * 0x7fff / 0x7fffff);

Wenn Sie ein bisschen fischen um können Sie wahrscheinlich einen effizienten Weg finden, das zu tun mit Integer-Arithmetik und keine Teilung.

Diese Form sollte richtig rund auf den nächsten verfügbaren Ausgangswert für einen bestimmten Eingang, und es soll den größtmöglichen Eingangswert des größtmöglichen Ausgabewert zuzuordnen, aber es wird eine hässliche Verteilung von Quantisierungsschritten im gesamten Bereich verstreut hat .

Die meisten Menschen bevorzugen:

out = (in + 128) >> 8;
if (out > 0x7fff) out = 0x7fff;

Diese Form macht die Dinge das kleinste bisschen lauter, bis zu dem Punkt, dass positive Werte leicht befestigen können, aber die Quantisierungsstufen gleichmäßig verteilt sind.

Sie fügen 128 wegen Rechtsverschiebung Runden auf negative Unendlichkeit. Die Durchschnitt Quantisierungsfehler ist -128 und Sie fügen 128, dies zu korrigieren 0 zu halten genau 0. Der Test für Überlauf notwendig ist, weil ein Eingabewert von 0x7fffff sonst einem Ergebnis von 0x8000 geben würde, und wenn Sie speichern diese in einem Wort 16-Bit es umschlingen würde einen negativen Spitzenwert zu geben.

C Pedanten können Poke Löcher in den Annahmen über die Rechtsverschiebung und Teilungsverhalten, aber ich bin der für Klarheit mit Blick auf.

Wie jedoch andere haben aus Ihnen in der Regel nicht reduzieren die Bittiefe von Audio ohne Dithering spitz, und im Idealfall Noise Shaping. TPDF Zitter ist wie folgt:

out = (in + (rand() & 255) - (rand() & 255)) >> 8;
if (out < -0x8000) out = -0x8000;
if (out > 0x7fff) out = 0x7fff;

Auch hier große Probleme mit der Verwendung von rand(), die ich für Klarheit zu übersehen werde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top