2016-01-22 14 views
6

Zuerst werde ich mein Problem beschreiben, ich bin eine automatische Wiedergabeliste aus zufälligen Songs erstellen, einige der Lieder 10-15 Sekunden Stille am Ende des Songs haben, was ich versuche zu erreichen ist von erkennen der Analysator, wenn ein Lied für 5 Sekunden still war und darauf reagieren.Wie kann ich einen aus einem audioContext erstellten Analysator verwenden, um zu erkennen, ob ein Spielgeräusch hörbar ist?

Bisher habe ich dies bekommt:

var context, analyser, source, audio; 
context = new (window.AudioContext || window.webkitAudioContext)(); 
analyser = context.createAnalyser(); 
audio = new Audio(); 

source = context.createMediaElementSource(audio) 
source.connect(analyser); 
analyser.connect(context.destination); 

var playNext = function() { 
    var pickedSong; 
    // chooses a song from an api with several 
    // thousands of songs and store it in pickedSong 
    audio.src = pickedSong; 
    audio.play(); 
} 

audio.addEventListener('ended', playNext); 

playNext(); 

Ich weiß die Antwort irgendwo im Analysator ist, aber ich habe keine Kohärenz in den zurückgegebenen Daten aus Ihm gefunden.

ich etwas tun kann:

var frequencies = new Float32Array(analyser.frequencyBinCount); 
analyser.getFloatFrequencyData(frequencies); 

und die Frequenzen var 2048 Tasten jeweils mit einem zufälligen (für mich) Zahl enthalten würde (-48,11, -55, -67, etc ...) Bedeuten diese Zahlen etwas, das mit dem wahrgenommenen Klang zusammenhängt? Wie kann ich erkennen, ob es so niedrig ist, dass die Leute denken, dass nichts spielt?

Für den Nachweis möchte ich in erster Linie etwas wie folgt aus:

var isInSilence = function(){ 
    return !audible; 
} 

var tries = 0; 

var checker = function() { 
    tries = isInSilence() ? tries + 1 : 0; 
    if(tries >= 5) playNext(); 
    setTimeout(checker, 1000); 
} 

checker(); 

Der einzige fehlende Teil Erfassen, wenn der Song zur Zeit still ist oder nicht, jede mögliche Hilfe würde geschätzt.

Edit:

basierend auf william Antwort ich es geschafft, es zu lösen, indem es auf diese Weise tun:

var context, compressor, gain, source, audio; 
context = new (window.AudioContext || window.webkitAudioContext)(); 
compressor = context.createDynamicsCompressor(); 
gain = context.createGain(); 
audio = new Audio(); 

source = context.createMediaElementSource(audio) 

// Connecting source directly 
source.connect(context.destination); 

// Connecting source the the compresor -> muted gain 
source.connect(compressor); 
compressor.connect(gain); 
gain.connect(context.destination); 

gain.gain.value = 0; // muting the gain 
compressor.threshold.value = -100; 

var playNext = function() { 
    var pickedSong; 
    // chooses a song from an api with several 
    // thousands of songs and store it in pickedSong 
    audio.src = pickedSong; 
    audio.play(); 
} 

audio.addEventListener('ended', playNext); 

playNext(); 

var isInSilence = function(){ 
    return compressor.reduction.value >= -50; 
} 

var tries = 0; 

var checker = function() { 
    tries = isInSilence() ? tries + 1 : 0; 
    if(tries >= 5) playNext(); 
    setTimeout(checker, 1000); 
} 

checker(); 
+0

Sie können ctx.source.stop (0) oder so ähnlich verwenden – Akxe

+0

context.source ist undefined –

+0

Sie können http://toys.eise.cz/Equaliser versuchen, gibt es Funktionsstopp, der die Musik stoppt versuche es dort zu finden, wenn du versagst Ich werde versuchen, es mir selbst zu besorgen – Akxe

Antwort

4

Dies ist eine mögliche Lösung, die einen anderen Ansatz - den Kompressor Knoten. Es ist eine kurze Beschreibung sollte aber ausreichen, um Sie in den Details für Ihren Anwendungsfall lassen füllen:

einen Kompressor Knoten erstellen und Ihre Eingangsquelle anschließen. Verbinden Sie dann den Kompressor mit einem Verstärkerknoten und schalten Sie den Verstärkungsknoten stumm (stellen Sie ihn auf Null). Verbinden Sie den Verstärkerknoten mit dem audioContext.destination

Nehmen Sie Ihre Eingabequelle und verbinden Sie sie mit audioContext.destination.

Set die Kompressoreigenschaftswerte das Signal zu erfassen (so, dass sie den Reduktionswert auslöst).

Wrap compressor.reduction.value in einem setInterval oder requestAnimationFrame auf Änderungen überprüfen.

-Code der Logik erforderlich zu tun, was Sie wollen, wenn dieser Wert ändert (oder ändert sich nicht).

+0

Stummschalten des Gains unterdrückt den Zielsound, auch der Compressor-Reduzierungswert misst die Reduzierung des Kompressors, nicht das Audio selbst. vermisse ich etwas? –

+0

Stummschalten der Verstärkung in diesem Fall stummt den Klang durch den Kompressor, aber dies ist wünschenswert, weil Sie in diesem Fall nicht das Geräusch hören möchten, das vom Kompressor betroffen ist, verwenden Sie nur den Kompressor als ein Werkzeug, um das Signal zu erkennen . Sie hören immer noch den ersten Ton, weil er direkt mit dem Audio-Kontext verbunden ist. Sie haben Recht, dass der Kompressor nicht "das Audio selbst misst", aber Sie können immer noch verwenden, um zu erkennen, ob eine Signalamplitude einen bestimmten Wert über- oder unterschreitet Schwelle, was du willst. – William

+0

Also sollte ich das Audio direkt mit dem Ziel verbinden und es dann auch an den Kompressor zum Messen anschließen? –

1

Für die Zukunft - die Werte der Analysator kehrt für getFloatFrequencyValues ​​Dezibel des jeweiligen Signals ist - so „0“ würde ein hypothetischer volles Signal sein, „-96“ deutlich unter normalen Dynamikbereich für einen Menschen.

Es ist wahrscheinlich einfacher für Sie, nur getByteFrequencyValues ​​zu verwenden, die vorge munges Werte in 0-255; 0 ist ein vernünftiges Grundrauschen. Wenn Sie wirklich Stille suchen, suchen Sie einfach nach Nullen in allen Analysator-Bins - wenn Sie nach einem leisen Signal suchen, ist der Standardwert -100 für minDecibels wahrscheinlich zu niedrig. Suchen Sie also nach einer niedrigen Zahl (10 oder weniger) Du müsstest experimentieren. Oder ändern Sie minDecibels - siehe die Spezifikation.