/* AUDIO CAPTURE FUNCTIONS */ var jsnode; var mStreamNode; var glob_stream = null; var con = null; var source; var sampleRate = 22050; var recording = false; var speech_audio; function createContext() { var context; try { context = new webkitAudioContext(); return context; } catch(err) { alert("WebkitAudioContext failed. " + err); } } function startRecording() { clear(); if(glob_stream == null) { console.log("GLOB_NULL "); navigator.webkitGetUserMedia({audio:true}, gotStream, function(e) { console.log("ERROR: webkit error - ", e); }); } else { gotStream(glob_stream); } } function gotStream(stream) { /* Setup the variables */ console.log("INFO: recording..."); recording = true; if(con == null) con = createContext(); glob_stream = stream; mStreamSource = con.createMediaStreamSource(stream); jsnode = con.createJavaScriptNode(256,1,1); // We could change this to stereo source = new Float32Array(); console.log("INFO: ", source.length); var i = 0; jsnode.onaudioprocess = function(e) { if(!recording) return; /* get the input and assign it to source */ var input = e.inputBuffer.getChannelData(0); source = Float32Concat(source, input); /* Now update the waveform */ i++; updateWaveform(i, input); } mStreamSource.connect(jsnode); jsnode.connect(con.destination); } function playSpeech() { var buffer = source; var dataview = encodeWAV(buffer); var audioBlob = new Blob([dataview], {type:'audio/wav'}); var bloburl = webkitURL.createObjectURL(audioBlob); speech_audio = document.querySelector("audio"); speech_audio.addEventListener("ended", playonended,false); speech_audio.src = bloburl; speech_audio.play(); } function pausePlayback() { // speech_audio = document.querySelector("audio"); speech_audio.pause(); } function stopRecording() { console.log("INFO: stopRecording"); recording = false; glob_stream.stop(); jsnode.disconnect(con.destination); } function clear() { speech.src = null; source = null; } function writeString(view, offset, string){ for (var i = 0; i < string.length; i++){ view.setUint8(offset + i, string.charCodeAt(i)); } } function encodeWAV(samples) { var buffer = new ArrayBuffer(48 + samples.length * 2); var view = new DataView(buffer); /* RIFF identifier */ writeString(view, 0, 'RIFF'); /* file length */ view.setUint32(4, 32 + samples.length * 2, true); /* RIFF type */ writeString(view, 8, 'WAVE'); /* format chunk identifier */ writeString(view, 12, 'fmt '); /* format chunk length */ view.setUint32(16, 16, true); /* sample format (raw) */ view.setUint16(20, 1, true); /* channel count */ view.setUint16(22, 2, true); /* sample rate */ view.setUint32(24, sampleRate, true); /* byte rate (sample rate * block align) */ view.setUint32(28, sampleRate * 4, true); /* block align (channel count * bytes per sample) */ view.setUint16(32, 4, true); /* bits per sample */ view.setUint16(34, 16, true); /* data chunk identifier */ writeString(view, 36, 'data'); /* data chunk length */ view.setUint32(40, samples.length * 2, true); /* TODO: this WILL need altered. */ floatTo16BitPCM(view, 44, samples); return view; } function Float32Concat(first, second) { var firstLength = first.length; var result = new Float32Array(firstLength + second.length); result.set(first); result.set(second, firstLength); return result; } function floatTo16BitPCM(output, offset, input){ for (var i = 0; i < input.length; i++, offset+=2){ var s = Math.max(-1, Math.min(1, input[i])); output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true); } } function processAudio() { console.log("processing the audio..."); f32 = source; result = ""; var hex_array = new Array(); for(i = 0; i < f32.length; i++) { hex = floatToIntBits(f32[i]).toString(16); hex_array.push(hex); if(hex != "") result = result + (hex + ":"); } /* Now hand the hex string to Flash */ var ogg_lib = swfobject.getObjectById("ogg_lib"); if(ogg_lib == null) { // TODO: maybe some sort of error handling. i.e an alert maybe? console.log("ERROR-JS: getOggLib is null!!"); } ogg_lib.passHex(result); clear(); } function updateWaveform(index, inBuf) { if((index % 20) == 0){ j = 0; for(x in inBuf) { if((j % 6) == 0){ n = parseFloat(inBuf[x]); if(n == 256 || n == 1024 || n == 4) // These keep popping out somehow?? n = 0; if((n < 1) || (n > -1)) { if(typeof n === 'number' && !isNaN(n)) usr_audio_data.push(n*4); } } j++; } usr_waveform.update({data:usr_audio_data}); } }