Générer une forme d'onde statique avec webaudio

J'essaie de générer une forme d'onde statique, comme dans les applications d'édition audio avec webaudio et toile. En ce moment, je charge un mp3, je crée un tampon, itérant sur les données renvoyées par getChannelData.

Le problème est … Je ne comprends pas vraiment ce qui est retourné.

  1. Ce qui est retourné par getChannelData – est-il approprié pour une forme d'onde?
  2. Comment ajuster (taille de l'échantillon?) Pour obtenir un pic == une seconde?
  3. Pourquoi ~ 50% des valeurs sont-elles négatives?

    ctx.decodeAudioData(req.response, function(buffer) { buf = buffer; src = ctx.createBufferSource(); src.buffer = buf; //create fft fft = ctx.createAnalyser(); var data = new Uint8Array(samples); fft.getByteFrequencyData(data); bufferL = buf.getChannelData(0) for(var i = 0; i<buf.length; i++){ n = bufferL[i*(1000)] gfx.beginPath(); gfx.moveTo(i +0.5, 300); gfx.lineTo(i +0.5, 300 + (-n*100)); gfx.stroke(); 

Ce que je génère:

Ce que je génère:

Ce que j'aimerais générer:

Ce que j'aimerais générer:

Merci

J'ai écrit un échantillon pour préciser ceci: https://github.com/cwilso/Audio-Buffer-Draw . C'est une démonstration assez simpliste – vous devrez faire le zoom vous-même, mais l'idée est là.

1) Oui, getChannelData renvoie les échantillons de tampon audio pour ce canal. 2) Eh bien, cela dépend de la fréquence des pics de votre échantillon et cela n'est pas nécessairement cohérent. L'exemple de tirage que j'ai effectué a fait un zoom arrière (c'est le bit "étape" de la méthode), mais vous voudrez probablement optimiser votre scénario. 3) La moitié des valeurs sont négatives car les échantillons sonores vont entre -1 et +1. Les ondes sonores sont une onde de pression positive et négative; C'est pourquoi le "silence" est une ligne plate au milieu, pas en bas.

Code:

 var audioContext = new AudioContext(); function drawBuffer( width, height, context, buffer ) { var data = buffer.getChannelData( 0 ); var step = Math.ceil( data.length / width ); var amp = height / 2; for(var i=0; i < width; i++){ var min = 1.0; var max = -1.0; for (var j=0; j<step; j++) { var datum = data[(i*step)+j]; if (datum < min) min = datum; if (datum > max) max = datum; } context.fillRect(i,(1+min)*amp,1,Math.max(1,(max-min)*amp)); } } function initAudio() { var audioRequest = new XMLHttpRequest(); audioRequest.open("GET", "sounds/fightclub.ogg", true); audioRequest.responseType = "arraybuffer"; audioRequest.onload = function() { audioContext.decodeAudioData( audioRequest.response, function(buffer) { var canvas = document.getElementById("view1"); drawBuffer( canvas.width, canvas.height, canvas.getContext('2d'), buffer ); } ); } audioRequest.send(); } window.addEventListener('load', initAudio );