tutorial the play not examples abstracting javascript html5 webkit web-audio

javascript - the - web audio api tutorial



¿Hay alguna manera de utilizar la API de Web Audio para muestrear audio más rápido que en tiempo real? (2)

Existe un modo ''fuera de línea'' realmente sorprendente de Web Audio API que le permite procesar previamente un archivo completo a través de un contexto de audio y luego hacer algo con el resultado:

var context = new webkitOfflineAudioContext(); var source = context.createBufferSource(); source.buffer = buffer; source.connect(context.destination); source.noteOn(0); context.oncomplete = function(e) { var audioBuffer = e.renderedBuffer; }; context.startRendering();

Por lo tanto, la configuración se ve exactamente igual que el modo de procesamiento en tiempo real, excepto que configura la oncomplete llamada oncomplete y la llamada a startRendering() . Lo que obtienes en e.redneredBuffer es un AudioBuffer .

Estoy jugando con Web Audio API y estoy tratando de encontrar una forma de importar un mp3 (por lo tanto, esto solo está en Chrome) y generar una forma de onda en un lienzo. Puedo hacer esto en tiempo real, pero mi objetivo es hacerlo más rápido que en tiempo real.

Todos los ejemplos que he podido encontrar implican leer los datos de frecuencia de un objeto analizador, en una función adjunta al evento onaudioprocess:

processor = context.createJavascriptNode(2048,1,1); processor.onaudioprocess = processAudio; ... function processAudio{ var freqByteData = new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(freqByteData); //calculate magnitude & render to canvas }

Sin embargo, parece que analyser.frequencyBinCount solo se llena cuando se reproduce el sonido (algo sobre el búfer que se está llenando).

Lo que quiero es poder avanzar de forma manual / programática por el archivo lo más rápido posible para generar la imagen del lienzo.

Lo que tengo hasta ahora es esto:

$("#files").on(''change'',function(e){ var FileList = e.target.files, Reader = new FileReader(); var File = FileList[0]; Reader.onload = (function(theFile){ return function(e){ context.decodeAudioData(e.target.result,function(buffer){ source.buffer = buffer; source.connect(analyser); analyser.connect(jsNode); var freqData = new Uint8Array(buffer.getChannelData(0)); console.dir(analyser); console.dir(jsNode); jsNode.connect(context.destination); //source.noteOn(0); }); }; })(File); Reader.readAsArrayBuffer(File); });

Pero getChannelData () siempre devuelve una matriz tipada vacía.

Cualquier idea es apreciada, incluso si resulta que no se puede hacer. Creo que soy el único en Internet que no quiere hacer cosas en tiempo real.

Gracias.


Lo hice funcionar usando OfflineAudioContext usando el siguiente código. El ejemplo completo aquí muestra cómo usarlo para calcular las magnitudes de FFT para un chirrido lineal. Una vez que tenga el concepto de conectar los nodos, puede hacer casi cualquier cosa sin conexión.

function fsin(freq, phase, t) { return Math.sin(2 * Math.PI * freq * t + phase) } function linearChirp(startFreq, endFreq, duration, sampleRate) { if (duration === undefined) { duration = 1; // seconds } if (sampleRate === undefined) { sampleRate = 44100; // per second } var numSamples = Math.floor(duration * sampleRate); var chirp = new Array(numSamples); var df = (endFreq - startFreq) / numSamples; for (var i = 0; i < numSamples; i++) { chirp[i] = fsin(startFreq + df * i, 0, i / sampleRate); } return chirp; } function AnalyzeWithFFT() { var numChannels = 1; // mono var duration = 1; // seconds var sampleRate = 44100; // Any value in [22050, 96000] is allowed var chirp = linearChirp(10000, 20000, duration, sampleRate); var numSamples = chirp.length; // Now we create the offline context to render this with. var ctx = new OfflineAudioContext(numChannels, numSamples, sampleRate); // Our example wires up an analyzer node in between source and destination. // You may or may not want to do that, but if you can follow how things are // connected, it will at least give you an idea of what is possible. // // This is what computes the spectrum (FFT) information for us. var analyser = ctx.createAnalyser(); // There are abundant examples of how to get audio from a URL or the // microphone. This one shows you how to create it programmatically (we''ll // use the chirp array above). var source = ctx.createBufferSource(); var chirpBuffer = ctx.createBuffer(numChannels, numSamples, sampleRate); var data = chirpBuffer.getChannelData(0); // first and only channel for (var i = 0; i < numSamples; i++) { data[i] = 128 + Math.floor(chirp[i] * 127); // quantize to [0,256) } source.buffer = chirpBuffer; // Now we wire things up: source (data) -> analyser -> offline destination. source.connect(analyser); analyser.connect(ctx.destination); // When the audio buffer has been processed, this will be called. ctx.oncomplete = function(event) { console.log("audio processed"); // To get the spectrum data (e.g., if you want to plot it), you use this. var frequencyBins = new Uint8Array(analyser.frequencyBinCount); console.log(analyser.getByteFrequencyData(frequencyBins); // You can also get the result of any filtering or any other stage here: console.log(event.renderedBuffer); }; // Everything is now wired up - start the source so that it produces a // signal, and tell the context to start rendering. // // oncomplete above will be called when it is done. source.start(); ctx.startRendering(); }