Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
add experimental support for audio data api
  • Loading branch information
kripken committed Jan 13, 2012
1 parent f62f0be commit d3131b8
Showing 1 changed file with 67 additions and 22 deletions.
89 changes: 67 additions & 22 deletions speakClient.js
@@ -1,32 +1,77 @@
function speak(text, args) {
function encode64(data) {
var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var PAD = '=';
var ret = '';
var leftchar = 0;
var leftbits = 0;
for (var i = 0; i < data.length; i++) {
leftchar = (leftchar << 8) | data[i];
leftbits += 8;
while (leftbits >= 6) {
var curr = (leftchar >> (leftbits-6)) & 0x3f;
leftbits -= 6;
ret += BASE[curr];
function parseWav(wav) {
function readInt(i, bytes) {
var ret = 0;
var shft = 0;
while (bytes) {
ret += wav[i] << shft;
shft += 8;
i++;
bytes--;
}
return ret;
}
if (leftbits == 2) {
ret += BASE[(leftchar&3) << 4];
ret += PAD + PAD;
} else if (leftbits == 4) {
ret += BASE[(leftchar&0xf) << 2];
ret += PAD;
if (readInt(20, 2) != 1) throw 'Invalid compression code, not PCM';
if (readInt(22, 2) != 1) throw 'Invalid number of channels, not 1';
return {
sampleRate: readInt(24, 4),
bitsPerSample: readInt(34, 2),
samples: wav.subarray(44)
};
}

function playHTMLAudioElement(wav) {
function encode64(data) {
var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var PAD = '=';
var ret = '';
var leftchar = 0;
var leftbits = 0;
for (var i = 0; i < data.length; i++) {
leftchar = (leftchar << 8) | data[i];
leftbits += 8;
while (leftbits >= 6) {
var curr = (leftchar >> (leftbits-6)) & 0x3f;
leftbits -= 6;
ret += BASE[curr];
}
}
if (leftbits == 2) {
ret += BASE[(leftchar&3) << 4];
ret += PAD + PAD;
} else if (leftbits == 4) {
ret += BASE[(leftchar&0xf) << 2];
ret += PAD;
}
return ret;
}

document.getElementById("audio").innerHTML=("<audio id=\"player\" src=\"data:audio/x-wav;base64,"+encode64(wav)+"\">");
document.getElementById("player").play();
}

function playAudioDataAPI(data) {
try {
var output = new Audio();
output.mozSetup(1, data.sampleRate);
var num = data.samples.length;
var buffer = data.samples;
var f32Buffer = new Float32Array(num);
for (var i = 0; i < num; i++) {
f32Buffer[i] = ((buffer[i<<1] + (buffer[(i<<1)+1]<<8))/65535)-1;
}
output.mozWriteAudio(f32Buffer);
return true;
} catch(e) {
return false;
}
return ret;
}

var wav = generateSpeech(text, args);
var data = parseWav(wav); // validate the data and parse it

document.getElementById("audio").innerHTML=("<audio id=\"player\" src=\"data:audio/x-wav;base64,"+encode64(wav)+"\">");
document.getElementById("player").play();
if (1) { // !playAudioDataAPI(data)) {
playHTMLAudioElement(wav);
}
}

0 comments on commit d3131b8

Please sign in to comment.