Can Kosar

Kategorie: Embedded (page 1 of 2)

STM32 SAI Konfiguration

STM32 besitzt je nach Chipvariante eine serielle Audio-Schnittstelle SAI. Durch diese Schnittstelle kann über übliche Protokolle mit Audio-Codecs kommuniziert werden.

Audio-Clocks

Das Codec und die SAI-Schnittstelle müssen synchronisiert werden. Dabei gibt es konkrete Vorgaben bzw. Randbedingungen seitens Codecs.

  • Audio-Abtastfrequenz F_s wählen.
  • Den Multiplikator k_{MCLK} (Codecs haben oft Multiplikatortabellen z.B. 256 oder 512 bei 48kHz) wählen.
  • Daraus die erforderliche Master-Clock-Frequenz berechnen. (Oft F_{MCLK}F_s \cdot k_{MCLK})
  • Master-Clock-Quelle konfigurieren (Externer Quarz bzw. interne Clockquellen)

Übertragung

Unter dem Aspekt gibt es (wie für viele andere Hardwarekomponenten) hauptsächlich drei Möglichkeiten eine Codec-Schnittstelle zu steuern bzw. auszulesen:

  1. Normaler Modus (Blockierend)
  2. Interrupt-Modus (Nicht-blockierend)
  3. Per DMA auslesen (Nicht-blockierend)

Bei einer echtzeitkritischen Audio-DSP-Anwendung kommt nur DMA-Schnittstelle in Frage. Die Konfiguration der Software und Hardware ist hier beschrieben.

SAI und DMA Konfiguration

Beim Flex 500 ist feste 48kHz Abtastrate gewählt. Bei CS4272 kann der Multiplikator 256 oder 512 gewählt werden. Um auch zukünftig 96kHz zu unterstützen wurde hierbei 512 gewählt. Zu Stabilitätszwecken wurde für einen externen Quarz entschieden. Die Frequenz des Quarzes berechnet sich also als

(1)   \begin{equation*} F_{MCLK}=F_S \cdot k_{MCLK} = 48000 \cdot 512 = 24,576 MHz \end{equation*}

In dem Fall ist der Codec der Master und generiert den Bitclock. Der DSP ist Slave und erhält den Bitclock und dazugehörige Streams.

Die Konfiguration sieht folgendermaßen aus:

Low level Treiber: (*_hal_msp.c)

SAI Konfiguration

Starten vom Treiber

DMA Interrupts setzen die Flags. Die Software Architektur ist hier beschrieben.

Die CODEC-Treiber sind hier beschrieben:

CS4272 CODEC-Schnittstelle für Nucleo H743

WM8731 CODEC-Schnittstelle für Nucleo H743

Ressourcen

Der vollständige Code vom Communication Stack befindet sich auf den Repositories vom Controller und DSP unter den Ordnern „hw„.

DSP – Targetcode vom herunterladen

Controller- Targetcode vom   herunterladen

DSP<->Controller Kommunikation

Die Hardwarearchitektur vom Flex 500 ist hier beschrieben. Die Kommunikation zwischen DSP und Controller läuft über eine SPI-Schnittstelle. Auf der Controller-Seite werden Mitteilungen interrupt-gesteuert gesendet, da die Mitteilungen von mehreren Instanzen aus geschickt werden können und DMA zu ständigen Unterbrechungen auf der DSP Seite führen würde.

Auf der DSP-Seite wird die Mitteilung, die über SPI-Schnittstelle erhalten werden, mit DMA an den Programmspeicher kopiert. Danach wird ein Interrupt ausgelöst, wonach der DSP den Befehl verarbeiten kann.

Die Struktur der Mitteilung

Die Struktur der Mitteilung ist im folgenden dargestellt.

  • Bank Id: Die ID der Effekt-Bank.
  • Type: Der UI-Controller type, der sich geändert hat: Encoder oder Button
  • Id: Der ID des UI-Controllers (Button number oder Encoder number)
  • Data: Data in (Float, 32bit, 16bit, 8bit mit oder ohne Vorzeichen)

Die Übertragung der Mitteilung

Die Mitteilung liegt im Programm im Typ „union“, der die Typen

  • Float
  • 32bit unsigned
  • 16bit unsigned
  • 8bit unsigned

beinhaltet.

Daten dieses Typs müssen über SPI übertragen werden. Dabei wird der Vorteil genutzt, dass sowohl Sender als auch der Empfänger gleiche Endianness benutzt. (Beide Cortex-M7) Das heißt, wir können einfach den Speicherbereich, wo die Mitteilung liegt, schicken. Dann castet der Empfänger auf dieselbe Union zurück und die Daten liegen in der erwünschten Struktur beim Empfänger an.

Code vom Sender

wobei ctrl_tx des Typs „Unions“ ist.

Code vom Empfänger

Ressourcen

Der vollständige Code vom Communication Stack befindet sich auf den Repositories vom Controller und DSP unter den Ordnern „com„.

DSP – Targetcode vom herunterladen

Controller- Targetcode vom   herunterladen

Hardware Architektur – Verteiltes System

Übliche Systemarchitektur eines Audioprozessorsystems wie das vom Flex 500 ist ein verteiltes System. Die Aufgaben werden dabei auf mehrere Prozessoren verteilt. Bei einer leistungs- und echtzeitkritischen Anwendung wie ein Audio-Prozessor ist das oft unverzichtbar.

Hardware-Architektur

Die Hardware-Architektur vom Flex 500 ist im folgenden Bild gezeigt:

Audio-DSP

Spezialisierte Audio-DSP-Chips

Der Kern eines typischen Audio-Prozessors ist ein DSP-Chip. Lange Zeit wurden dafür ausschließlich dafür konzipierte Audio-DSPs, wie z.B. die von Texas Instruments und Analog devices eingesetzt. Die Audio-DSPs haben Befehlsätze, die für Audiodatenverarbeitung typisch sind und eine effiziente hardwaregestütze Verarbeitung der Daten ermöglichen. Dazu gehören viele spezialisierte SIMD-Befehle. (Single Instruction Multiple data) wie MACs (Multiplier+Accumulator). Diese ermöglichen schnelle Verarbeitung von z.B. Biquad-Filtern, ein sehr verbreitetes digitales Filter oder aber auch viele andere Algorithmen, wo sequentielle Multiplikation und Addition-Folgen größerer Daten nötig ist.

MehrZweck-Mikroprozessoren (General purpose Microprocessors)

Mittlerweile sind die Leistung und die Befehlssätze der Mikroprozessoren rasant gestiegen. Heutzutage sind viele Prozessoren mehrere Hundert Megahertz schnell getaktet und bieten u. a. DSP-Einheiten für SIMDs und Gleitkommazahl-Einheiten (FPUs). Aufgrund ihrer breiten Verfügbarkeit und vielseitiger Einsatzmöglichkeiten jenseits der Audio-Verarbeitung, sind die Mehrzweck-Mikroprozessoren zu einer echten Alternative gegenüber der herkömmlichen Audio-DSPs geworden.

Ein Spitzenreiter unter denen ist die Prozessoren auf Basis von ARM Cortex-M7. Diese Prozessoren sind bis zu 600MHz getaktet, besitzen DSP und FPU Einheiten. Ein Vergleich von Cortex-basierten Prozessoren gegenüber der herkömmlichen, verbreiteten Produkte von Texas Instruments und Analog devices ist im folgenden Artikel detailliert aufgeführt:

Choosing the best processor for your DSP application

DSP capabilities of Cortex Processors

In diesen Studien ist sichtbar, dass die High-End Spezialprozessoren für manche spezialisierte Tasks wie MAC-Leistung immer noch die Nase vorne haben. Allerdings sind die Cortex Prozessoren auch sehr leistungsfähig und können ihre Stärken bei allgemeineren Tasks spielen, wofür die Spezialprozessoren keine HW-Unterstützung anbieten.

Aus den genannten Aspekten wurde für den Flex 500 ein STM32H743 mit 400MHz Taktrate, DSP und FPU-Einheiten gewählt.

Controller-Chip

Ein Controller-Chip übernimmt oft alle sonstigen Aufgaben wie die allgemeinen Verwaltungsaufgaben, GUI-Steuerung, Anzeige etc. Die Echtzeitansprüche an den Controller-Chip ist niedrig, dafür muss er viele Tasks abarbeiten. DSP und Controller-Chips unterscheiden sich voneinander vor allem in deren Softwarearchitektur.

Der DSP-Chip muss mehrere Tasks schedulen und abarbeiten. Eine Middleware wie FreeRTOS ist dafür sehr gut geeignet, wenn die Komplexität und die Tasks steigt. Man kann auch „Bare-metal“ programmieren und eigenen Scheduler schreiben.

Je nach benötigter Leistung und Peripherien kann man einen Mikroprozessor wählen, der diese Aufgaben erledigt. Auch hierbei  ist ARM Cortex-M sehr gut geeignet und verbreitet.

Beim Flex 500 muss der Mikrocontroller

  • GUI Inputs und Outpus managen
  • Eine kleine Grafikbibliothek treiben
  • Kommunikation zum DSP aufbauen.
  • Expression-Pedal und Fußschalter treiben
  • Sonstige HW steuern (Leistungsstufe etc.)

Als Controller von Flex 500 ist der STM32F767 von ST gewählt, der mit 216MHz Taktfrequenz und zahlreiche Schnittstellen all diese Aufgaben erledigen kann. Für diesen Zweck ist vermutlich auch ein kleinerer Cortex-M4 vollständig ausreichend.

Display-Treiber

Der Controller-Chip ist von der Prozessorleistung her sehr stark und besitzt  auch ein Display-Treiber. Allerdings ist die verfügbare interne RAM mit 512 sehr knapp für Grafikanwendungen. Um die interne RAM für sonstige Aufgaben freizuhalten, ist ein externer Display-Treiber gewählt.

Die Lösung für Display hängt stark von Anforderungen an. Eine sehr gute Übersicht ist im folgenden Paper von ST verfügbar:

LCD-TFT display controller (LTDC) on STM32 MCUs

Beim Flex 500 ist ein Display mit integriertem Chip ILI9341 eingesetzt.

 

DSP Architektur

Ein DSP-FX benötigt jitter-freie Verarbeitung der Audiodaten in Echtzeit.  Echtzeit ist ein theoretischer und dehnbarer Begriff, der die erforderliche Systemlatenz beschreibt. Beim Audio beruht diese Feststellung auf die Latenzwahrnehmung des Menschen. Wir nehmen die Latenzen unter 10ms als Echtzeit wahr. Die Latenz der gesamten Kette (Roundtriplatenz) ist die Zeit zwischen dem Eintreten des Signals in die Codec-Eingänge bis zur Bereitstehung des verarbeiteten Signals an Codec-Ausgängen. Diese Zeit darf 10ms nicht überschreiten. Am besten soll diese Zeit sogar noch unter 10ms liegen, da auch der Schall zwischen den Lautsprechern und dem Ohr zusätzlich große Latenz erzeugt und Echtzeiterlebnis schnell beeinflusst werden kann.

Systemarchitektur

Die Übersicht der Systemarchitektur des DSPs vom Flex 500 ist im folgenden Diagramm gezeigt:

Codec

Ein Audio- Codec (Coder, decoder) ist die Komponente, die die analogen Audio-Signale ins Digitale wandelt und die digitalen Audio-Signale ins Analoge wandelt. (Sampling) Er besteht aus einem oder mehreren Analog-Digital-Wandlern (ADC) und ein Digital-Analog-Wandlern (DAC). Nach diesem Schritt liegen die Audio-Signale in einem digitalen Audio-Format vor, im vorliegenden Fall als I2S-Format (Intersound).

Die Codecs müssen konfiguriert und initialisiert werden. Das erfolgt über eine andere serielle Schnittstelle, üblicherweise SPI oder I2C. Das heißt, der Codec hat auch eine Steuerschnittstelle zum DSP. Beim Flex 500 stehen beide Schnittstellen zur Verfügung.

SAI

SAI (Serial Audio Interface) ist eine Schnittstelle, über die digitale Audio-Daten ausgetauscht werden können. Der Codec kommuniziert mit der SAI-Schnittstelle vom DSP-Chip, in dem Fall STM32H743. Diese Schnittstelle serialisiert und deserialisiert die Audiodaten, D.h. er schreibt/liest die in den bzw. von dem Arbeitsspeicher.

 

DMA

Das Schreiben bzw. Lesen muss über eine DMA (DIrect memory access)-Hardware-Komponente erfolgen. DMA ist eine einfache Hardware, die die Aufgabe hat, ein Register in das andere zu kopieren. Die Startaddresse, FIFO, IRQs und die Länge müssen dabei konfiguriert werden. Dadurch dass DMA die Datenübertragungsaufgabe übernimmt, kann sich DSP auf die Datenverarbeitung konzentrieren.

DMA muss so konfiguriert werden, dass er ein Interrupt auslöst, wenn die Puffer

  • halb voll und
  • ganz voll

sind. Dadurch können die Flags der Zustandsmaschine (State machine) gesetzt werden.

Puffer

Das vom Audio-Codec ins digitale I2S-Format gewandelte Audio-Signal muss in einem Eingangspuffer zwischengespeichert werden. Dann wird dieses Puffer vom DSP verarbeitet und das Ergebnis in ein Ausgangspuffer geschrieben. Die Größe der Puffer ergibt sich aus dem Kompromiss aus zwei Anforderungen:

  1. Die Puffer muss so klein wie möglich sein, um eine nicht-wahrnehmbare Latenz zu erreichen.
  2. Die Puffer müssen so groß wie möglich sein, um eine effiziente blockweise Datenverarbeitung zu ermöglichen (Overhead muss reduziert werden)

Bei den Anforderungen

  • Roundtrip-Latenz = 10ms
  • Abtastrate f_S= 48kHz
  • Bittiefe = 32bit

ergibt sich eine Puffergröße von 240 für jeweils Eingangs- und Ausgangspuffer mit 32bit Registern, da Eingangslatenz und Ausgangslatenz 5ms betragen müssen.

Für die Verarbeitung mit DMA-Interrupts wird ein Doppelpuffer der Größe 480 verwendet. Für genaue Erkläreung, siehe unten.

Zustandsmaschine

Die Zustandsmaschine ist die Hauptsteuerungskomponente  in der Software. Durch die Interrupts von DMA wird der Software mitgeteilt, dass das Puffer halb oder ganz voll ist. Nun kann die Zustandsmaschine, die in Endlosschleife läuft, entscheiden, ob der Prozess getriggert werden soll.

 

Die auf STM32 eingesetzter DMA unterstützt Double-buffering. Das heißt, er kann auf der Hälfte und am Ende der Übertragung ein Interrupt auslösen. Deshalb müssen wir das Doppelpuffer nicht selbst managen.

Der Ablauf sieht folgendermaßen aus:

  1. Erste Hälfte vom RX fertig ( Ab nun beschreibt DMA die zweite Hälfte)
  2. Erste Hälfte vom TX fertig ( Ab nun beschreibt DMA die zweite Hälfte)
  3. Zustandsmaschine löst die Verarbeitung der ersten Hälfte aus. Jetzt liest DSP von der ersten Hälfte von RX und beschreibt die erste Hälfte von TX.
  4. Zweite Hälfte vom RX fertig ( Ab nun beschreibt DMA die erste Hälfte)
  5. Zweite Hälfte vom TX fertig ( Ab nun beschreibt DMA die erste Hälfte)
  6. Zustandsmaschine löst die Verarbeitung der zweiten Hälfte aus. Jetzt liest DSP von der zweiten Hälfte von RX und beschreibt die zweite Hälfte von TX.
  7. Zurück zu 1.

Man erkennt, dass zwischen den RX und TX interrupts ein kleiner Versatz ist. Zwar synchronisiert der Codec die ADCs und DACs aber trotzdem entstehen ein kleines Offset von ein paar Samples. Um den Jitter zu verhindern, müssen beide Interrupts ausgewertet werden, um sicherzugehen, dass in der zu verarbeitenden Hälfte wirklich nichts mehr beschrieben bzw. gelesen wird.

Implementierung

Zuerst müssen die Stati initialisiert werden.

 

Die Hauptroutine, die Endlosschleife der Verarbeitung wird folgendermaßen implementiert:

Die Flags tx_status und rx_status wurden in Interrupt Routinen gesetzt und hier (nach der Verarbeitung) wieder geresettet.

Wichtig: Die Interruptroutine muss so schnell wie möglich ablaufen, da diese höchste Priorität hat und alles pausiert. Hier nichts verarbeiten, sondern nur Flags setzen, die dann in der Hauptschleife verarbeitet werden.

 

 

WM8731 CODEC-Schnittstelle für Nucleo H743

Die WM8731 ist ein Budget-Klasse-Stereo Audio-CODEC von Cirrus Logic für mobile Applikationen. Es unterstützt 24bit Bittiefe, bis zu 96kHzAbtastrate und besitzt einen dynamischen Bereich vom 90db für ADC und 100dB für DAC .

Für Flex 500 wurde ein Breakout-Board für WM8731 entwickelt, das man direkt auf ein Nucleo Board stecken kann.

Board-Design

Folgendes auf Referenzdesign basiertes Design wurde für das Breakout board entwickelt.

Analoge Ein- und Ausgänge

Da WM8731 für mobile Anwendungen mit knappem Platz entwickelt ist, kommt es ohne zusätzlichen Eingangs- und Ausgangsstufen klar. Dafür unterstützt es nur unsymmetrische Ein- und Ausgänge.

Dafür hat es einen integrierten Kopfhörerverstärker. Auf dem Board befinden sich Line-In/Out und Kopfhörer-Anschlüsse.

Oszillator

Ein 24,576 MHz Oszillator ist eingebaut und gibt den Takt an den Master-Clock.

Ressourcen

Die KiCad Schaltung- und PCB-Designdaten herunterladen

Kompletter Programmcode für H743-Target

CS4272 CODEC-Schnittstelle für Nucleo H743

Die CS4272 ist ein hochwertiges Stereo Audio-CODEC von Cirrus Logic für anspruchsvolle Implementierungen. Es unterstützt 24bit Bittiefe, bis zu 192kHz Abtastrate und besitzt einen dynamischen Bereich vom 114dB.

Für Flex 500 wurde ein Breakout-Board für CS4272 entwickelt, das man direkt auf ein Nucleo Board stecken kann.

PCB Design

CS4272 CODEC- Breakout board im Betrieb

Board-Design

CS4272 unterstützt 2x symmetrische Eingänge und hat 2x symmetrische Ausgänge.

Symmetrische Eingänge

Die Nutzsignale vom analogen Preamp-Board sind Wechselspannungen, da Preamp-Board symmetrische Spannungsversorgung von +-15V hat. Für die symmetrischen Eingänge muss das Signal vom Preamp-Board in einen Pegel von V_{pp}<5V gebracht werden. Danach muss eine Gleichspannung V_{alias}=2,5V addiert werden, damit das Eingangssignal in den erlaubten Bereich vom CS4272 0V\leq V_{i} \leq5V gebracht werden. Das wird in der untenstehenden Schaltung realisiert:

Bei diesem Design handelt es sich um das Referenzdesign von CS4272. Hierbei wird die Alias-Spannung V_{com}=2,5V auf die durch die Kondensatoren C_INAx entkoppelte Eingangsspannung addiert und ein Eingangspuffer hinzugefügt.

Symmetrische Ausgänge

Die analogen Ausgänge vom CS4272 symmetrisch und für weitere Verarbeitung desymmetriert werden. Das wurde mit folgender Schaltung realisiert.

Hierbei werden die symmetrischen Signale V_{OUT,A+} und V_{OUT,A-} in einer Stufe voneinander abgezogen. Danach wird mit dem Ausgangskondesator C_OUTA6 der Gleichstrom herausgefiltert. Schließlich arbeitet die ganze Schaltung auf einen Lastwiderstand von R_L=47k\Omega. Hierbei handelt es sich um das Referenz Design von CS4272.

Digitale Schnittstellen

Das Breakout-Board unterstützt SPI und I2C Schnittstellen zum Controller.

Initialisierungssequenz

Die Initialisierungssequenz von CS4272 ist im folgenden Code gezeigt.

Nach der Initialisierung kann das CODEC aktiviert und deaktiviert werden.

Der SAI von H743 muss folgendermaßen konfiguriert sein:

Oszillator

Ein 24,576 MHz Oszillator ist eingebaut und gibt den Takt an den Master-Clock.

Ressourcen

SPICE-Simulationsdateien zu analogen Schnittstellen für CS4272 herunterladen

Die KiCad Schaltung- und PCB-Designdaten herunterladen

Kompletter Programmcode für H743-Target

Digitaler Distortion-Effekt

Der Distortion (dt. Verzerrung)-Effekt basiert auf starkem Übersteuern und/oder Limitieren eines Signals. Er ist ein sehr beliebter und verbreiteter E-Gitarreneffekt. Mit dem Effekt kann man sowohl mildere „Overdrive“ als auch starke „Metal“-Sounds erreichen.

Technisch basiert es in analoger Ausführung auf hartem Limitieren des Signals (Clipping) mit Hilfe von Dioden oder Übersteuern von Röhren. Davor und danach werden Filter und sonstige Effekte eingebaut, um einen guten Klang zu erzielen.

In digitaler Ausführung kann hingegen mit verschiedenen mathematischen Ansätzen gearbeitet werden, die analog schwer bis unmöglich umzusetzen sind., wie z.B. Parabeln und exponentiellen Funktionen.

Das harte Limitieren eines 1kHz Sinussignals kann man sich folgendermaßen vorstellen.

Rendered by QuickLaTeX.com

Mathematisch lässt sich das als

(1)   \begin{equation*} \begin{aligned} y=-y_{th} \quad &wenn\quad \sin(x)<-y_{th} \\ y=\sin(x) \quad &wenn\quad -y_{th}< \sin(x)< y_{th} \\ y=y_{th} \quad &wenn\quad \sin(x)>y_{th} \end{aligned} \end{equation*}

beschreiben, wobei y_{th} der Threshold-Wert ist, ab dem das Clipping erfolgt.

Auf dieser Grafik fallen zwei Sachen auf:

  1. Ab dem Clipping stellt man den Pegel auf einen konstanten Wert : Gleichstrom!
  2. Die Übergänge haben einen Knick =>Sehr hohe Frequenzen

Die Verzerrung tiefe Verzerrung wird als sehr unangenehm empfungen. Der Gleichstrom (f=0) ist sogar schädlich für die Lautsprecher (wobei der üblicherweise von der Leistungselektronik herausgefiltert wird)

Das heißt, das einfache Clipping erzeugt zwar einen Distortion-Sound aber keinen Guten. Eine bessere Möglichkeit zum Verzerren ist die Anwendung von Soft-Clipping mit mathematischen Funktionen.  Ein weicher Übergang zum Clipping und danach ein leichtes Überschwingen ist wünschenswert, um Gleichstrom zu vermeiden. Das kann mit folgender exponentiellen Funktion erreicht werden.

 

(2)   \begin{equation*} y=sgn(x) [1-e^{-k x sgn(x)}] \end{equation*}

oder als teilweise Funktion

(3)   \begin{equation*} \begin{aligned} y=1-e^{-k x} \quad& \text{wenn} \quad x\geq0 \\ y=-1+e^{k x} \quad& \text{wenn} \quad x<0 \end{aligned} \end{equation*}

,wobei der Skalierungsfaktor k als Vorverstärkung gesehen werden kann.

Im folgenden ist diese Signalform mit den Verstärkungsfaktoren k=1 und k=5 dargestellt.

Rendered by QuickLaTeX.com

Es gibt auch andere mathematische Ansätze, die ein Soft-Clipping modellieren und oft Zusammensetzung gestückelter Polynome sind.

Das Herzstück der Verzerrung ist also das Clipping, wobei dies noch lange nicht alles bei einem guten Distortion-Sound ist. Es gibt noch etwas unvernachlässigbares bei einem Distortion-Algorithmus: Die Frequenzfilter.

Hochpassfilter/Kuhschwanzfilter für Tiefen

Verzerrung von tiefen Frequenzen werden als sehr unangenehm empfunden. Daher möchte man oft einen Hochpassfilter vor dem Clipping-Block einschalten, um die tiefen Frequenzen herauszufiltern. Zudem entsteht bei Clipping sogar noch zusätzlich tiefe Frequnzen, Diese müssen dann nach dem Clipping herausgefiltert werden.

Tiefpassfilter / Kuhschwanzfilter für Höhen

Nach dem Clipping erhalten wir oft einen Sound, der je nach Clipping sehr kratzig klingen kann, weil erstens verzerrte Hochfrequenzen unangenehm empfunden werden als auch wir durch Clipping zusätzlich Hochfrequenzen erzeugen. Deshalb können wir nach dem Clipping auch einen Tiefpassfilter schalten und alle hohe Frequenzen dämpfen, um einen „runderen“ und weniger „kratzigen“ Klang zu erzielen.

Sonstige Bestandteile der Verzerrung

Oft haben schöne Distortion-Sounds viel mehr Komponenten als nur Clipping. Diese sind v.a.

  • Kompressoren vor und/oder nach dem Clipping
  • Zusätzliche Frequenzfilter für die Betonung
  • Zusätzliche Polynomfilter (Röhrensimulation)
  • Phaser / Doubler (Frequenzauslöschungen)
  • Asymmetrische Clipper (Röhren-ähnliche Distortion / Overdrive Sounds)

Die Zusammensetzung des Distortion Sounds hängt also neben dem Clipping-Algorithmus auch von anderen Komponenten, die für einen angenehmen verzerrten Sound sorgen.

Parameter

Folgende Kontrollparameter sind für einen Flanger-Effekt üblich:

Vorverstärkung (Gain)

Die Stärke des Clippings hängt hauptsächlich vor unserer Vorskalierung k ab. Das ist der Hauptparameter einer Distortion. Alles andere ist im Grunde optional. In der Benutzeroberfläche befinden sich nicht die Parameter einzelner Komponenten, sondern verschiedene künstliche Parameter wie „Presence“ oder gar Verstärkertypen „Brit, Vox, Marshall, etc.“, wobei diese empirisch ermittelter Parametersätze für die verwendeten Blöcke sind.

Nachverstärkung/Korrektur (Post-gain/Volume)

Dieser Parameter ist dafür da, um wieder auf den Pegel zurückzukommen von dem man sich durch das Clipping ggf. entfernt hat. Manchmal ist dieser Parameter nicht an den Endbenutzer weitergegeben, sondern durch Vorverstärkung berechnet.

Implementierung

Im folgenden ist ein grundlegender Distortion/Overdrive mit einem vorgeschalteten Hochpassfilter und nachgeschaltetem Tiefpassfilter implementiert.

 

Klangbeispiele

Anbei ist dieser Algorithmus mit ein paar verschiedenen Parametern zu hören.

 

Flex 500 – Controller

  • GUI
    • Display
      • Steuerung eines Display-Moduls mit ILI9341
      • Ein einfacher Grafikprozessor
    • Benutzereingaben
      • Architektur einer bare-metal-GUI
      • Auslesen der Drehgeber
        • Gray code
      • Auslesen der Buttons
        • Tastenentprellung
    • Kommunikationsarchitektur zweier Prozessoren
      • Serielle Kommunikation
      • SPI DMA
      • Startup / Handshake
      • (Pipelining)
    • Externe Controller
      • Expressionpedal über STM32-ADC einlesen
      • Fußschalterinterface

Digitaler Dynamikkompressor

Die Dynamikkompression (engl. Dynamic range compression) ist ein Prozess, der die Dynamik komprimiert bzw. reduziert. Das wird gemacht, indem die lauten Bereiche, die einen Schwellwert überschreiten, leiser gemacht werden, während die leiseren Bereiche unreduziert passieren. Die Charakteristik der Kompression lässt sich am Besten in einer Dynamikkurve darstellen, die die Beziehung zwischen der Einganglautstärke und Ausgangslautstärke beschreibt.

Die Steigung \frac{b}{a} beschreibt die Kompressionsrate, mit der das Signal abgeschwächt wird. Dies greift ab dem Überschreiten eines Threshold-Werts.

Digitale Realisierung

Das Herzstück eines Kompressors ist ein  spannungskontrollierter Verstärker (VCA). Im analogen Design, wird das mit komplexen Schaltungen realisiert. In der Digitaltechnik ist dies ein simpler Verstärkungsfaktor, mit dem das Signal multipliziert wird. Dieser Verstärkungsfaktor wird in einem parallelen Pfad berechnet. Der parallele Pfad besteht aus einem Lautstärkendetektor (in der Regel realisiert mit Effektivleistung, RMS) und einer Logik, die die Reduktion aus der Lautstärke berechnet (Gain computer).

 

Loudness detector

Einer der wichtigsten Bestandteile einer Kompression ist die Berechnung der Lautstärke, Hier wird kontinuierlich ermittelt, wie hoch die empfundene Lautstärke ist. Gängigste Methode dafür ist der Effektivwert als quadratischer Mittelwert des relevanten Sampleabschnitts.

(1)   \begin{equation*} RMS=\sqrt{\frac{1}{n}\sum_{i=1}^{n}x_i^2} \end{equation*}

Der RMS-Wert dient als Eingang für den Gain-Computer. Der Gain-Computer berechnet daraus die Verstärkung, die dem Signal appliziert werden soll. Es appliziert die Dynamikkurve, s. oben.

Parameter

Folgende Kontrollparameter sind für einen Kompressor Effekt üblich:

Input gain

Die Eingangsverstärkung wird auf das Eingangssignal appliziert, um das Signalniveau in einen gewünschten Platz in der Dynamikkurve zu platzieren.  Alternativ kann man auch Threshold verschieben.

Threshold

Der Threshold (dt. für Schranke/Grenze) ist der Grenzwert, ab dessen Überschreitung eine Gain-Reduktion erfolgt, s. Diagramm.

Kompressionsrate

Sie beschreibt die Stärke der Gain-Reduktion nach Threshold, in der Dynamikkurve ist dies als Tangenzwert \frac{b}{a} gezeigt.

Ab einem Wert von 60:1 wird von einem Limiter gesprochen.

Make-Up Gain

Der Gain-Computer appliziert eine Gain-Reduktion.  Das bedeutet, die gesamte Lautstärke des Signals sinkt. Um das ältere Lautstärkenniveau zu erreichen, wird ein Make-Up Gain am Ausgang appliziert.

Soft-Knee / Hard-Knee

Ab dem Threshold ändert sich die Verstärkung, die man appliziert. Dieser Übergang, der in der Dynamikkurve oben scharf gezeichnet wurde, kann auch mild erfolgen. So dass die Gain-Reduktion langsam eintritt.

Attack

Der Attack-Wert bestimmt, wann die Gain-Reduktion nach einer Überschreitung eintreten soll. Sie liegt im Bereich von 5 bis 250 ms.

Release

Der Release-Wert bestimmt, wann nach einer Unterschreitung des Tresholds die Gain-Reduktion wieder  aussetzen soll. Sie liegt üblicherweise im Bereich von 5 bis 100ms.

Implementierung

Im folgenden ist die Prozessroutine eines Kompressors gezeigt:

Quadratwurzel (Root square) Implementierung

Eine der wichtigsten Komponenten des Kompressors ist der RMS-Rechner. Der Aufwand der Berechnung der Quadratsumme ist eine Multiplikation und eine Addition. Hingegen ist die Quadratwurzelberechnung eine sehr aufwändige Berechnung, die den Flaschenhals darstellt. Hierzu gibt es effiziente Algorithmen, die dies übernehmen. Ein davon (hier eingesetzter) Algorithmus ist der berühmte „fastsqroot„-Algorithmus. Dieser Algorithmus ist ursprünglich für Videoverarbeitung entwickelt und mittlerweile gut analysiert und breit eingesetzt.

 

Potenzimplementierung

Der berechnete RMS-Wert wird in einen logarithmischen Wert umgerechnet, woraus sich die wahrgenommene Lautstärke \overline{RMS} ergibt. Jeder Mensch empfindet die Lautstärke anders. Mann kann den Logarithmus auf 2 Basis, 10 Basis oder natürlichen Logarithmus nehmen.

(2)   \begin{equation*} \overline{RMS}={Base}^{RMS} \end{equation*}

Die Potenzberechnung der Gleitkommazahlen ist auch eine teure Operation. Die Funktion pow() der Mathe-Bibliothek ist selbst auf FPUs sehr langsam, da es für alle Zahlen eine gute Genauigkeit liefern muss. Wir brauchen aber keine sehr Hohe Genauigkeit, da wir nur ein Verstärkungsfaktor berechnen. Dafür gibt es schnellere Funktion, wie z.B. fastPow

Klangbeispiele

Den Klang eines Kompressors sollte man im Optimalfall nicht hören. Dennoch hier ein paar Beispiele der sehr starken Komprimierung, wo die Kompression im Vergleich zum trockenen Signal erkennbar ist.

 

ältestenposts

Rechte © 2024 Can Kosar

Mit Unterstützung von Wordpress, QuickLaTeX und Design von Anders NorenSeitenanfang ↑