Digitale Schaltung zum Addieren mehrerer Frequenzen

Ziel ist es, eine Art Digitalpiano auf einem FPGA zu implementieren.

Bisher gelang es mir, einzelne Noten mit Zählern zu erzeugen. Grundsätzlich erzeuge ich eine Rechteckwelle einer bestimmten Frequenz, die einer Musiknote entspricht (natürlich verlasse ich mich dazu auf die Frequenz der Uhr, aber das ist kein Problem).

Wie kann ich eine Schaltung entwerfen, die die Überlappung mehrerer Noten erzeugen kann? Grundsätzlich möchte ich in der Lage sein, 2 Töne mit unterschiedlichen Frequenzen gleichzeitig zu erzeugen.

Antworten (5)

Als Teenager in den 1980er Jahren hatte ich einen Apple II+ Computer, der einen ähnlichen Lautsprecherausgang wie der IBM PC-Lautsprecher hatte. Der Zugriff auf eine speicherabgebildete I/O-Port-Position hatte den Effekt, dass ein mit dem Lautsprecher verbundener Ausgang umgeschaltet wurde.

Ich habe ein Programm in Maschinensprache geschrieben, das Dreiklänge spielte: drei simultane Töne. Eine Nachschlagetabelle konvertierte Notenwerte (indiziert durch Halbtöne) in Zählerwerte. Der Ansatz war einfach: Initialisieren Sie drei Zähler und durchlaufen Sie sie unabhängig voneinander in einer großen Schleife. Schalten Sie bei jeder Iteration, wenn mindestens einer der Zähler herumgerollt ist, den Lautsprecher um.

Diese Routine, gekoppelt mit einem BASIC-Programm, um sie mit Daten anzutreiben, spielte eine sehr gut klingende Wiedergabe der Synthesizer-Akkordfolge aus Van Halens Jump .

Es ist ein einzigartiger Klang. Es gibt Verzerrungen, aber die Notentrennung ist ziemlich klar.

Variationen in der Klangfarbe lassen sich übrigens mit Duty-Cycle-Variation erzeugen. Ich meine mich zu erinnern, dass dies die wahrgenommene Lautstärke bedeutet.

Es hängt viel von der Art der Hardware ab, die Sie haben.

Wenn Sie nur einen 1-Bit-Ausgang auf dem FPGA haben, können Sie das Audiosignal überabtasten (1 MHz oder mehr) und einen PWM- oder Delta-Sigma-Modulator verwenden, um effektiv ein Signal mit variabler Amplitude zu erzeugen (Sie können einen Tiefpassfilter hinzufügen, einen einfachen RC-Beschaltung ist ausreichend).

Sie können dann Ihre synthetisierten Signale (Sinus, Rechteck, Dreieck ...) hinzufügen und polyphone Klänge erzeugen. Stellen Sie beispielsweise bei einem 8-Bit-Addierer (vorzeichenbehaftet) die Amplitude der beiden Rechteckgeneratoren auf +50/-50 ein.

Der FPGA-Teil ist irgendwie irrelevant. Den eigentlichen Audioausgang verwende ich nicht. Stattdessen habe ich einen normalen Digitalausgang, an den ich einen Lautsprecher anschließe. Das einzige, was ich habe, ist eine Rechteckwelle, und ich muss diese Rechteckwelle so erzeugen, dass sie wie zwei überlappende Musiknoten klingt. Ich interessiere mich auch mehr für die eigentliche Schaltung als für die tatsächliche Implementierung.
"regulärer digitaler Ausgang". Was ist das? 8 Bit? 16 Bit? Unterzeichnet? Ohne Vorzeichen?
@Kaz, es hört sich für mich so an, als hätte er ein einzelnes digitales Ausgangssignal (1 Bit) und er verwendet es, um einen Lautsprecher anzusteuern.

Eine einfache Möglichkeit besteht darin, jeden Ausgang der Zähler zu nehmen, ihn durch einen Widerstand zu leiten und dann das andere Ende der Widerstände miteinander zu verbinden. Nun würden die einzelnen Zählerausgänge gedämpft, während der endgültige Ausgang die Summe der Zählerausgänge wäre.

Zwei Möglichkeiten (die mir einfallen):

  1. Mit DAC
    • Signale einzeln multiplizieren, um unterschiedliche individuelle Amplituden zu erhalten.
    • Summieren Sie die Signale, die Sie kombinieren möchten
    • Gib n Bits an den n-Bit-DAC aus
    • Sie können selbst einen einfachen R2R-DAC nur mit Widerständen herstellen.
  2. Ohne DAC, mit einem einzelnen Pin und einem Tiefpassfilter
    • Addieren Sie die beiden Signale
    • Modulieren Sie den Ausgang mit Delta-Sigma-Modulation
    • Ausgabe durch einen Tiefpassfilter (RC ist am einfachsten).

Wenn Sie nur mit einem einzigen digitalen Ausgang arbeiten und Rechteckwellen erzeugen, besteht die einfachste Möglichkeit darin, zwei (oder n) Zähler bei jeder gewünschten Frequenz zu haben und ihre Ausgänge mit XOR zu verknüpfen, bevor sie an den Pin ausgegeben werden. Dies erzeugt ein äquivalentes Ergebnis zu Kaz' Toggle-Ansatz.