2017-09-20 2 views
0

Ich versuche, einen komplexen periodischen Klang mit langen Zeitraum zu erstellen. Ich möchte Frequenzen so genau wie möglich definieren, also benutze ich Schritt sampleRate*0.5/tableLen. Aber ich habe einige Probleme mit großen Wellentabellen. Der Klang wird verzerrt und verliert hohe Frequenzen.Erstellen Sie benutzerdefinierte Oszillator mit langen periodischen Welle

Hier ist ein minimales Beispiel mit ~ 440 Hz Sinuswelle. Wenn ich Tabelle verwenden, mit einer Länge von 8192, ist die resultierende Sinuswelle recht erkennbar:

https://jsfiddle.net/zxqzntf0/

var gAudioCtx = new AudioContext(); 
var osc = gAudioCtx.createOscillator(); 
var tableSize = 8192; 
var real = new Float32Array(tableSize); 
var imag = new Float32Array(tableSize); 
var freq = 440; 
var step = gAudioCtx.sampleRate*0.5/tableSize; 
real[Math.floor(freq/step)] = 1; 
var wave = gAudioCtx.createPeriodicWave(real, imag, {disableNormalization: true}); 
osc.frequency.value = step; 
osc.setPeriodicWave(wave); 
osc.connect(gAudioCtx.destination); 
osc.start(); 

Aber wenn ich meine Tabellengröße erhöhen, ich bin immer etwas seltsam. Das Ergebnis ist keine Sinuswelle!

https://jsfiddle.net/0cc75nnm/

Dieses Problem reproduziert in allen Browsern (Chrome, Firefox, Rand), so scheint es nicht ein Browser Bug zu sein. Aber ich habe nichts in der Dokumentation gefunden.

Added

Ich fand, dass, wenn Oszillatorfrequenz eine ganze Zahl> = 2 Hz, ich habe keine keine Artefakte in resultierendem Sound mit Tabellengröße 16384 Ich denke, es ist jetzt für meine Bedürfnisse durchaus akzeptabel . Aber irgendwann möchte ich vielleicht längere Zeiträume schaffen. Wenn mir jemand erklärt, warum ich Tonartefakte bekomme, wenn der Schritt weniger als 2 Hz beträgt, werde ich seine Antwort akzeptieren.

Es ist ein Beispiel für eine komplexe Klangmelodie, die ich in JavaScript generieren: https://jsfiddle.net/h9rfzrnL/1/

Antwort

2

Sie Ihnen periodische Wellen falsch zu schaffen. Wenn Sie die Arrays für die periodische Welle füllen, nehmen Sie an, dass die Samplerate 1 ist. Wenn Sie einen Oszillator mit einer Frequenz von 440 Hz wünschen, stellen Sie die Oszillatorfrequenz auf 440 Hz ein.

Für eine Sinuswelle sollte das reelle Array also nur Nullen und das imaginäre Array [0, 1] sein. (Sie erstellen tatsächlich eine Kosinuswelle, aber das ist nicht wirklich wichtig.)

+0

Ich möchte 20 Sinus im Bereich 400-480 Hz, 40 Sinus im Bereich 800-960 Hz und so weiter. Ich kann es nicht tun, wenn ich 440 Hz Schritt habe. Eine einzelne Sinuswelle ist ein minimales Beispiel für mein Problem. – gammaker

+0

Vielleicht würde ein konkretes Beispiel für die Welle, die Sie erstellen möchten, dazu beitragen, das Problem besser zu erklären. Dennoch besteht die Grundidee darin, Ihre Welle so zu gestalten, als ob die Abtastrate 1 Hz wäre. Stellen Sie dann die Frequenz des Oszillators als Grundfrequenz des gewünschten Signals ein. –

+0

Ich brauche Oberschwingungen, die in einem Frequenzbereich verteilt sind. Wie kann ich Oszillator mit den Frequenzen 400, 401, ..., 480, 800, 801, ..., 960, 1200, 1201, ..., 1920, ..., 12800 erzeugen? 12801, ..., 15360? Ich kann es nicht tun, wenn ich Schritt 440 habe, brauche ich Schritt 1 Hz und sehr großen Tisch. Lesser Schritt ist besser. – gammaker

Verwandte Themen