37

Ich versuche, einige Eigenschaften eines Yamaha YM3812 Sound-Chip zu implementieren (aka OPL2 http://en.wikipedia.org/wiki/YM3812) in JavaScript mit Audiolet (eine Synthesebibliothek, http://oampo.github.io/Audiolet/api.html)Was ist los mit diesem einfachen FM Synth Design?

Audiolet ermöglicht es Ihnen, einen Synthesizer als Graph von Knoten (Oszillatoren zu bauen , DSPs, Hüllkurvengeneratoren usw.).

Der OPL2 hat neun Kanäle mit je zwei Operatoren (Oszillatoren). Normalerweise moduliert ein Oszillator in jedem Kanal die Frequenz des anderen. Um dies zu simulieren, habe ich eine Kette von Knoten für jeden Kanal aufgebaut:

Synth Knotenkette (eine von neun Kanäle)

OPL2 channel as implemented

Node Kette Erstellung und Verbindungscode:

var FmChannel = function(audiolet) { 
    this.car = new ModifiedSine(audiolet); 
    this.carMult = 1; 
    this.setCarrierWaveform(this.SIN); 
    this.mod = new ModifiedSine(audiolet); 
    this.modMult = 1; 
    this.setModulatorWaveform(this.SIN); 
    this.modMulAdd = new MulAdd(audiolet); 
    this.carGain = new Gain(audiolet); 
    this.carEnv = new ADSREnvelope(audiolet, 0, 0.1, 0.1, 0.1, 0.1, 
     function() { 
      this.carEnv.reset(); 
     }.bind(this) 
    ); 
    this.carAtten = new Multiply(audiolet); 
    this.modGain = new Gain(audiolet); 
    this.modEnv = new ADSREnvelope(audiolet, 0, 0.1, 0.1, 0.1, 0.1, 
     function() { 
      this.modEnv.reset(); 
     }.bind(this) 
    ); 
    this.modAtten = new Multiply(audiolet); 

    this.modEnv.connect(this.modGain, 0, 1); 
    this.mod.connect(this.modGain); 
    this.modGain.connect(this.modAtten); 
    this.modAtten.connect(this.modMulAdd); 
    this.modMulAdd.connect(this.car); 
    this.carEnv.connect(this.carGain, 0, 1); 
    this.car.connect(this.carGain); 
    this.carGain.connect(this.carAtten); 
    // connect carAtten to the mixer from outside 
}; 

wenn ich jedoch die Parameter des Modulator- und Trägerknoten (Oszillator-Wellenformen, die relativen Häufigkeiten festgelegt, ATTEN (Use, ADSR-Parameter) und Trigger-Noten, die Ausgabe hat wenig Ähnlichkeit mit einem anständigen OPL2-Emulator mit ungefähr den gleichen Parametern. Einige Sounds sind im Stadion. Andere sind ziemlich unangenehm.

Ich habe ein paar Ideen, wie es weitergeht (Ich denke, die Ausgabe in verschiedenen Phasen wäre ein guter Ausgangspunkt), aber ich hoffe, jemand kann mich in die richtige Richtung zeigen oder etwas offensichtlich falsch zeigen mit dem was ich mache. Ich habe keine Signalverarbeitung oder einen starken mathematischen Hintergrund. Ich habe kein tiefes intuitives Verständnis von FM.

Einige Probleme Ich vermute, sind:

1) My FM-Implementierung (siehe oben) ist grundlegend falsch. Es kann auch ein Problem in der Funktion sein, wo eine Note spielen (den Oszillatorfrequenzen und Skalierung und Offset des Modulators vor der ADSR-Hüllkurven Triggerung):

FmChannel.prototype.noteOn = function (frq) { 
    var Fc = frq*this.carMult; 
    this.car.reset(Fc); 
    this.mod.reset(frq*this.modMult); 
    // scale and offset modulator from range (-1, 1) to (0, 2*Fc) 
    // (scale and offset is after ADSR gain and fixed attenuation is applied) 
    this.modMulAdd.mul.setValue(Fc); 
    this.modMulAdd.add.setValue(Fc); 
    this.carEnv.reset(); 
    this.modEnv.reset(); 
    this.carEnv.gate.setValue(1); 
    Thethis.modEnv.gate.setValue(1); 
}; 

2) Ausgabe von FM-Synthesizer können hochempfindliche zu kleinen Unterschieden in der Form der Modulator-ADSR-Hüllkurve (bitte sagen Sie mir, ob das stimmt!), und meine ADSR-Hüllkurven sind grobe Annäherungen bestenfalls der ADSRs in einer echten OPL2. In meiner Implementierung fehlen auch einige Funktionen, die relativ unbedeutend erscheinen (zB Key-Scaling), die aber den Sound eines FM-Synthesizers erheblich beeinflussen können (wieder bin ich mir nicht sicher).

+4

Wenn Sie Ihr Bild betrachten, sollte der Modulator mit der Trägerfrequenz verknüpft werden und nicht gewinnen (wie folgt: https://en.wikipedia.org/wiki/Frequency_modulation#/media/File:Amfm3-en-de.gif). – Elric

+0

Normalerweise sollten Sie mit der Verstärkungsstufe des Modulators vorsichtig sein und nicht zu viel Verstärkung und damit Modulation aufwenden. Wenn die Modulation zu groß ist, erhalten Sie "unangenehme Geräusche", wobei die Modulation über den Träger dominiert. Ich bin mir nicht sicher, dass Sie das beschreiben. – noumenal

+0

Elric, basierend auf dem Diagramm sieht es aus wie der Modulator ist verbunden, um zu gewinnen. Es ist so lange her, dass ich daran gearbeitet habe oder Audiolet angeschaut habe, dass ich mir jetzt wirklich nicht sicher bin, ob das passiert! Ich werde graben. – bsa

Antwort

1

Die meisten Synthesizer, die mit "FM" beschriftet sind, tun tatsächlich eine Phasenmodulation (PM, siehe https://en.wikipedia.org/wiki/Phase_modulation). Es gibt einige Vorteile (die meist zu einem stabileren Klang in einem großen Tonbereich führen). Die OPL2 kann dies auch verwenden, ich fand keine eindeutigen Beweise, aber der Wikipedia-Artikel verwendet auch den Begriff "Phasenmodulation".

Kurz gesagt, viele Musik-Synthesizer mit der Bezeichnung "FM" waren in der Tat mit "PM" ausgestattet, also könnten Sie versuchen, damit zu gehen und prüfen, ob es besser zu den erwarteten OPL2-Sounds passt.

Von einem kurzen Blick auf die Audiolet-Quelle würde ich vermuten, dass der Sine Oszillator echte FM tut, also müssen Sie ihn möglicherweise ersetzen und einen Phaseneingang hinzufügen, um Phasenmodulation zu ermöglichen.

Grundsätzlich ist die Linie

output.samples[0] = Math.sin(this.phase); 

durch Sine des Trägers oscilator verwendet würde etwas zu lesen haben wie

output.samples[0] = Math.sin(this.phase+phase_offset); 

mit phase_offset vom mod oscilator gesteuert anstelle der Frequenz.

+0

Die berühmte Yamaha DX7-Tastatur, etwa zur selben Zeit vom selben Hersteller wie der OPL2, wurde trotz Phasenmodulation als "FM-Synthese" bezeichnet. – dronus

+0

Danke für die Antwort. Du hast recht, die OPL benutzt Phasenmodulation, und ich dachte, dass meine Implementierung "echtes" FM macht, aber es ist so lange her, seit ich es angeschaut habe, das kann ich jetzt wirklich nicht sagen :). Mein Verständnis war, dass für Sinuswellen, Phasenmodulation und Frequenzmodulation gleichwertig sind, also könnte ich einen ähnlichen Klang auf diese Weise erreichen. – bsa

+0

Nein, FM und PM sind ziemlich unterschiedlich und teilen viele Eigenschaften. Temporäre Frequenzänderungen integrieren sich jedoch im Laufe der Zeit, damit FM eine permanente Phasenverschiebung hinzufügen kann. Bei PM fügt eine temporäre Modulation eine temporäre Phasenverschiebung hinzu. – dronus