Skip to content

Instantly share code, notes, and snippets.

@luciferous
Created November 6, 2011 11:13
Show Gist options
  • Save luciferous/1342758 to your computer and use it in GitHub Desktop.
Save luciferous/1342758 to your computer and use it in GitHub Desktop.
WebSocket Radio!
<!doctype html>
<html><head>
<script type="text/javascript" src="Microphone/swfobject.js"></script>
<script type="text/javascript" src="ulaw.js"></script>
<script type="text/javascript" src="Microphone/microphone.js"></script>
<script type="text/javascript" src="sockjs-0.1.min.js"></script>
<script type="text/javascript">
Microphone.debug = true;
bsock = new SockJS("/broadcast");
Microphone.initialize({ swfLocation: "Microphone/MicrophoneMain.swf" });
Microphone.onready(function(){
Microphone.enable();
Microphone.ondata(function(frame){
var encoded = [];
for (var i = 0; i < frame.length; i++) {
if (i % 4 !== 0) continue;
var sample = 1.18 * (frame.charCodeAt(i) - 27647);
encoded.push(String.fromCharCode(MuLaw.encode(sample)));
}
var toSend = encoded.join("");
bsock.send(toSend);
//console.log("Sent: " + toSend.length);
});
});
</script>
</head><body></body></html>
<!doctype html>
<html><head>
<script type="text/javascript" src="Sound/swfobject.js"></script>
<script type="text/javascript" src="Sound/sound.js"></script>
<script type="text/javascript" src="ulaw.js"></script>
<script type="text/javascript" src="sockjs-0.1.min.js"></script>
<script type="text/javascript">
Sound.debug = true;
Sound.initialize({ swfLocation: "Sound/SoundMain.swf" });
function listen() {
lsock = new SockJS("/music");
sound = new Sound();
sound.play();
lsock.onmessage = function(m) {
//console.log("Received: " + m.data.length);
var decoded = [];
for (var i = 0; i < m.data.length; i++) {
var sample = MuLaw.decode(m.data.charCodeAt(i));
var code = String.fromCharCode(sample + 32767);
decoded.push(code);
decoded.push(code);
decoded.push(code);
decoded.push(code);
}
var toBuffer = decoded.join("");
sound.buffer(toBuffer);
}
}
setTimeout(listen, 2000);
</script>
</head><body></body></html>
var http = require('http');
var sockjs = require('sockjs');
var node_static = require('node-static');
var listeners = [];
// 1. Echo sockjs server
var sockjs_opts = {sockjs_url: "http://cdn.sockjs.org/sockjs-0.1.min.js"};
var sockjs_listen = sockjs.createServer(sockjs_opts);
sockjs_listen.on('connection', function(conn) {
console.log("Connected listener");
listeners.push(conn);
});
sockjs_listen.on('close', function(conn) {
if ((index = listeners.indexOf(conn)) > -1) {
listeners.splice(index, 1);
}
});
var sockjs_broadcast = sockjs.createServer(sockjs_opts);
sockjs_broadcast.on('connection', function(conn) {
console.log("Connected broadcaster");
conn.on('data', function(message) {
//console.log("Broadcasting " + message.length + " bytes");
for (var i = 0; i < listeners.length; i++) {
var listener = listeners[i];
listener.write(message);
}
});
});
// 2. Static files server
var static_directory = new node_static.Server(__dirname);
// 3. Usual http stuff
var server = http.createServer();
server.addListener('request', function(req, res) { static_directory.serve(req, res); });
server.addListener('upgrade', function(req,res){ res.end(); });
sockjs_broadcast.installHandlers(server, {prefix:'[/]broadcast'});
sockjs_listen.installHandlers(server, {prefix:'[/]music'});
console.log(' [*] Listening on 0.0.0.0:9999' );
server.listen(9999, '0.0.0.0');
/**!
* Source: http://hazelware.luggle.com/tutorials/mulawcompression.html.
*/
var MuLaw = (function(){
var cBias = 0x84,
cClip = 32635,
exponents = [ 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3
, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
],
translate = [ -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
-23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
-15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
-11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
-7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
-5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
-3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
-2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
-1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
-1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
-876, -844, -812, -780, -748, -716, -684, -652,
-620, -588, -556, -524, -492, -460, -428, -396,
-372, -356, -340, -324, -308, -292, -276, -260,
-244, -228, -212, -196, -180, -164, -148, -132,
-120, -112, -104, -96, -88, -80, -72, -64,
-56, -48, -40, -32, -24, -16, -8, -1,
32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
876, 844, 812, 780, 748, 716, 684, 652,
620, 588, 556, 524, 492, 460, 428, 396,
372, 356, 340, 324, 308, 292, 276, 260,
244, 228, 212, 196, 180, 164, 148, 132,
120, 112, 104, 96, 88, 80, 72, 64,
56, 48, 40, 32, 24, 16, 8, 0
],
encode = function(sample) {
var sign = (sample >> 8) & 0x80;
if (sign) {
sample = -sample;
}
if (sample > cClip) {
sample = cClip;
}
sample = (sample + cBias) & 65535;
var exponent = exponents[(sample >> 7) & 0xFF],
mantissa = (sample >> (exponent + 3 )) & 0x0F,
compressedByte = ~ (sign | (exponent << 4) | mantissa);
return String.fromCharCode(compressedByte).charCodeAt(0) & 255;
},
decode = function(byte) {
return translate[byte];
};
return {
encode: encode,
decode: decode
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment