Skip to content

Commit

Permalink
Use new recorderjs, remove feedback and fix libmp3lame bug
Browse files Browse the repository at this point in the history
  • Loading branch information
kehers committed Mar 23, 2015
1 parent 5579303 commit 7a6532a
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 88 deletions.
29 changes: 16 additions & 13 deletions index.html
Expand Up @@ -16,10 +16,10 @@ <h1>Record to MP3 Test</h1>

<button onclick="startRecording(this);">record</button>
<button onclick="stopRecording(this);" disabled>stop</button>

<h2>Recordings</h2>
<ul id="recordingslist"></ul>

<h2>Log</h2>
<pre id="log"></pre>

Expand All @@ -35,11 +35,14 @@ <h2>Log</h2>
var input = audio_context.createMediaStreamSource(stream);
__log('Media stream created.' );
__log("input sample rate " +input.context.sampleRate);

input.connect(audio_context.destination);

// Feedback!
//input.connect(audio_context.destination);
__log('Input connected to audio context destination.');

recorder = new Recorder(input);

recorder = new Recorder(input, {
numChannels: 1
});
__log('Recorder initialised.');
}

Expand All @@ -55,10 +58,10 @@ <h2>Log</h2>
button.disabled = true;
button.previousElementSibling.disabled = false;
__log('Stopped recording.');

// create WAV download link using audio data blob
createDownloadLink();

recorder.clear();
}

Expand All @@ -68,7 +71,7 @@ <h2>Log</h2>
var li = document.createElement('li');
var au = document.createElement('audio');
var hf = document.createElement('a');
au.controls = true;
au.src = url;
hf.href = url;
Expand All @@ -89,21 +92,21 @@ <h2>Log</h2>
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
window.URL = window.URL || window.webkitURL;

audio_context = new AudioContext;
__log('Audio context set up.');
__log('navigator.getUserMedia ' + (navigator.getUserMedia ? 'available.' : 'not present!'));
} catch (e) {
alert('No web audio support in this browser!');
}

navigator.getUserMedia({audio: true}, startUserMedia, function(e) {
__log('No live audio input: ' + e);
});
};
</script>
<script src="js/jquery-1.11.0.min.js"></script>

<script src="js/jquery-1.11.0.min.js"></script>
<script src="recordmp3.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion js/libmp3lame.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 35 additions & 49 deletions js/recorderWorker.js
@@ -1,8 +1,7 @@
var recLength = 0,
recBuffersL = [],
recBuffersR = [],
bits = 16,
sampleRate;
recBuffers = [],
sampleRate,
numChannels;

this.onmessage = function(e){
switch(e.data.command){
Expand All @@ -26,36 +25,51 @@ this.onmessage = function(e){

function init(config){
sampleRate = config.sampleRate;
numChannels = config.numChannels;
initBuffers();
}

function record(inputBuffer){
recBuffersL.push(inputBuffer[0]);
//recBuffersR.push(inputBuffer[1]);
for (var channel = 0; channel < numChannels; channel++){
recBuffers[channel].push(inputBuffer[channel]);
}
recLength += inputBuffer[0].length;
}

function exportWAV(type){
var bufferL = mergeBuffers(recBuffersL, recLength);
//var bufferR = mergeBuffers(recBuffersR, recLength);
//var interleaved = interleave(bufferL, bufferR);
//var dataview = encodeWAV(interleaved);
var dataview = encodeWAV(bufferL);
var buffers = [];
for (var channel = 0; channel < numChannels; channel++){
buffers.push(mergeBuffers(recBuffers[channel], recLength));
}
if (numChannels === 2){
var interleaved = interleave(buffers[0], buffers[1]);
} else {
var interleaved = buffers[0];
}
var dataview = encodeWAV(interleaved);
var audioBlob = new Blob([dataview], { type: type });

this.postMessage(audioBlob);
}

function getBuffer() {
function getBuffer(){
var buffers = [];
buffers.push( mergeBuffers(recBuffersL, recLength) );
buffers.push( mergeBuffers(recBuffersR, recLength) );
for (var channel = 0; channel < numChannels; channel++){
buffers.push(mergeBuffers(recBuffers[channel], recLength));
}
this.postMessage(buffers);
}

function clear(){
recLength = 0;
recBuffersL = [];
recBuffersR = [];
recBuffers = [];
initBuffers();
}

function initBuffers(){
for (var channel = 0; channel < numChannels; channel++){
recBuffers[channel] = [];
}
}

function mergeBuffers(recBuffers, recLength){
Expand Down Expand Up @@ -96,39 +110,14 @@ function writeString(view, offset, string){
}
}

/*function encodeLowWAV(samples) {
var block_align = (1 * bits) / 8
, byte_rate = sampleRate * block_align
, data_size = (samples.length * bits) / 8
, buffer = new ArrayBuffer(44 + data_size)
, view = new DataView(buffer);
writeString( view, 0, 'RIFF' );
view.setUint32( 4, 32 + data_size, true ); //!!!
writeString( view, 8, 'WAVE' );
writeString( view, 12, 'fmt' );
view.setUint32( 16, 16, true );
view.setUint16( 20, 1, true );
view.setUint16( 22, 1, true );
view.setUint32( 24, sampleRate, true );
view.setUint32( 28, byte_rate, true );
view.setUint16( 32, block_align, true );
view.setUint16( 34, bits, true );
writeString( view, 36, 'data' );
view.setUint32( 40, data_size, true ); //!!!
floatTo16BitPCM( view, 44, samples );
return view;
}*/

function encodeWAV(samples){
var buffer = new ArrayBuffer(44 + 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 chunk length */
view.setUint32(4, 36 + samples.length * 2, true);
/* RIFF type */
writeString(view, 8, 'WAVE');
/* format chunk identifier */
Expand All @@ -138,16 +127,13 @@ function encodeWAV(samples){
/* sample format (raw) */
view.setUint16(20, 1, true);
/* channel count */
//view.setUint16(22, 2, true); /*STEREO*/
view.setUint16(22, 1, true); /*MONO*/
view.setUint16(22, numChannels, true);
/* sample rate */
view.setUint32(24, sampleRate, true);
/* byte rate (sample rate * block align) */
//view.setUint32(28, sampleRate * 4, true); /*STEREO*/
view.setUint32(28, sampleRate * 2, true); /*MONO*/
view.setUint32(28, sampleRate * 4, true);
/* block align (channel count * bytes per sample) */
//view.setUint16(32, 4, true); /*STEREO*/
view.setUint16(32, 2, true); /*MONO*/
view.setUint16(32, numChannels * 2, true);
/* bits per sample */
view.setUint16(34, 16, true);
/* data chunk identifier */
Expand Down
53 changes: 28 additions & 25 deletions recordmp3.js
Expand Up @@ -6,28 +6,31 @@
var Recorder = function(source, cfg){
var config = cfg || {};
var bufferLen = config.bufferLen || 4096;
var numChannels = config.numChannels || 2;
this.context = source.context;
this.node = (this.context.createScriptProcessor ||
this.context.createJavaScriptNode).call(this.context,
bufferLen, 2, 2);
bufferLen, numChannels, numChannels);
var worker = new Worker(config.workerPath || WORKER_PATH);
worker.postMessage({
command: 'init',
config: {
sampleRate: this.context.sampleRate
sampleRate: this.context.sampleRate,
numChannels: numChannels
}
});
var recording = false,
currCallback;

this.node.onaudioprocess = function(e){
if (!recording) return;
var buffer = [];
for (var channel = 0; channel < numChannels; channel++){
buffer.push(e.inputBuffer.getChannelData(channel));
}
worker.postMessage({
command: 'record',
buffer: [
e.inputBuffer.getChannelData(0),
//e.inputBuffer.getChannelData(1)
]
buffer: buffer
});
}

Expand Down Expand Up @@ -65,20 +68,20 @@
type: type
});
}

//Mp3 conversion
worker.onmessage = function(e){
var blob = e.data;
//console.log("the blob " + blob + " " + blob.size + " " + blob.type);

var arrayBuffer;
var fileReader = new FileReader();

fileReader.onload = function(){
arrayBuffer = this.result;
var buffer = new Uint8Array(arrayBuffer),
data = parseWav(buffer);

console.log(data);
console.log("Converting to Mp3");
log.innerHTML += "\n" + "Converting to Mp3";
Expand All @@ -94,24 +97,24 @@
encoderWorker.postMessage({ cmd: 'finish'});
encoderWorker.onmessage = function(e) {
if (e.data.cmd == 'data') {

console.log("Done converting to Mp3");
log.innerHTML += "\n" + "Done converting to Mp3";

/*var audio = new Audio();
audio.src = 'data:audio/mp3;base64,'+encode64(e.data.buf);
audio.play();*/

//console.log ("The Mp3 data " + e.data.buf);

var mp3Blob = new Blob([new Uint8Array(e.data.buf)], {type: 'audio/mp3'});
uploadAudio(mp3Blob);

var url = 'data:audio/mp3;base64,'+encode64(e.data.buf);
var li = document.createElement('li');
var au = document.createElement('audio');
var hf = document.createElement('a');

au.controls = true;
au.src = url;
hf.href = url;
Expand All @@ -120,17 +123,17 @@
li.appendChild(au);
li.appendChild(hf);
recordingslist.appendChild(li);

}
};
};

fileReader.readAsArrayBuffer(blob);

currCallback(blob);
}


function encode64(buffer) {
var binary = '',
bytes = new Uint8Array( buffer ),
Expand Down Expand Up @@ -173,7 +176,7 @@
}
return f32Buffer;
}

function uploadAudio(mp3Data){
var reader = new FileReader();
reader.onload = function(event){
Expand All @@ -192,14 +195,14 @@
//console.log(data);
log.innerHTML += "\n" + data;
});
};
};
reader.readAsDataURL(mp3Data);
}

source.connect(this.node);
this.node.connect(this.context.destination); //this should not be necessary
};

/*Recorder.forceDownload = function(blob, filename){
console.log("Force download");
var url = (window.URL || window.webkitURL).createObjectURL(blob);
Expand Down

0 comments on commit 7a6532a

Please sign in to comment.