2014-06-10 31 views
9

Sto usando il seguente metodo per riprodurre un array di byte contenente dati wav. La funzione viene chiamata da un progetto GWT.Come si gioca a wav audio byte array tramite javascript/html5?

Questa funzione riproduce il suono, ma suona come una sorta di mostro infernale. La frequenza di campionamento è sicuramente corretta (il suono viene generato da neospeech) e ho provato tutti i tipi di valori per numberOfSamples, che sembra rappresentare la durata dei dati audio.

Un valore superiore a 30000 per numberOfSamples riproduce l'intera lunghezza del file audio ma è confuso e orribile.

Quindi, cosa sto sbagliando?

function playByteArray(byteArray, numberOfSamples) { 
    sampleRate = 8000; 

    if (!window.AudioContext) { 
     if (!window.webkitAudioContext) { 
      alert("Your browser does not support any AudioContext and cannot play back this audio."); 
      return; 
     } 
     window.AudioContext = window.webkitAudioContext; 
    } 

    var audioContext = new AudioContext(); 

    var buffer = audioContext.createBuffer(1, numberOfSamples, sampleRate); 
    var buf = buffer.getChannelData(0); 
    for (i = 0; i < byteArray.length; ++i) { 
     buf[i] = byteArray[i]; 
    } 

    var source = audioContext.createBufferSource(); 
    source.buffer = buffer; 
    source.connect(audioContext.destination); 
    source.start(0); 
} 

risposta

17

ho capito come fare quello che ho descritto nella mia domanda e pensato che avrei dovuto pubblicarlo per il beneficio degli altri. Il codice è sotto Chiamo playByteArray e gli passiamo un array di byte contenente dati pcm wav.

window.onload = init; 
var context; // Audio context 
var buf;  // Audio buffer 

function init() { 
if (!window.AudioContext) { 
    if (!window.webkitAudioContext) { 
     alert("Your browser does not support any AudioContext and cannot play back this audio."); 
     return; 
    } 
     window.AudioContext = window.webkitAudioContext; 
    } 

    context = new AudioContext(); 
} 

function playByteArray(byteArray) { 

    var arrayBuffer = new ArrayBuffer(byteArray.length); 
    var bufferView = new Uint8Array(arrayBuffer); 
    for (i = 0; i < byteArray.length; i++) { 
     bufferView[i] = byteArray[i]; 
    } 

    context.decodeAudioData(arrayBuffer, function(buffer) { 
     buf = buffer; 
     play(); 
    }); 
} 

// Play the loaded file 
function play() { 
    // Create a source node from the buffer 
    var source = context.createBufferSource(); 
    source.buffer = buf; 
    // Connect to the final output node (the speakers) 
    source.connect(context.destination); 
    // Play immediately 
    source.start(0); 
} 
+0

Grande roba, ho cercato per una concisa, ad esempio bollito-down come questo –

2

Clean up suggerimento:

function playByteArray(bytes) { 
    var buffer = new Uint8Array(bytes.length); 
    buffer.set(new Uint8Array(bytes), 0); 

    context.decodeAudioData(buffer.buffer, play); 
} 

function play(audioBuffer) { 
    var source = context.createBufferSource(); 
    source.buffer = audioBuffer; 
    source.connect(context.destination); 
    source.start(0); 
}