summaryrefslogtreecommitdiff
path: root/public/js
diff options
context:
space:
mode:
Diffstat (limited to 'public/js')
-rw-r--r--public/js/chat.js93
-rw-r--r--public/js/sample.js94
2 files changed, 187 insertions, 0 deletions
diff --git a/public/js/chat.js b/public/js/chat.js
new file mode 100644
index 0000000..27b0c8e
--- /dev/null
+++ b/public/js/chat.js
@@ -0,0 +1,93 @@
+/* -*- mode:javascript; coding:utf-8; -*- */
+
+'use strict';
+
+(function (window) {
+ function on_ended(context) {
+ if (this.link && this.link.buffer) {
+ console.log('playing next sound');
+ queue.link = this.link;
+ this.link.onended = _.partial(on_ended, context);
+ this.link.play(context);
+ }
+ else {
+ console.log('playing again');
+ this.play(context);
+ }
+ };
+
+ function Queue() {
+ this.last = this;
+ }
+
+ Queue.prototype.append = function (x) {
+ if (!this.seen || x.gt(this.seen)) {
+ this.last.link = x;
+ this.last = x;
+ this.seen = {
+ seq: x.seq,
+ timestamp: x.timestamp
+ };
+ return x;
+ }
+ else {
+ return null;
+ }
+ };
+
+ var queue = new Queue();
+
+ window.AudioContext = window.AudioContext || window.webkitAudioContext;
+
+ window.onload = function () {
+ var context = new AudioContext();
+ var field = document.getElementById("field");
+ var history = document.getElementById("history");
+ var send = document.getElementById('send');
+
+ var messages = [];
+ var socket = io.connect('/');
+
+ socket.on('message', function (data) {
+ if (data.message) {
+ messages.push(data.message);
+
+ var html = '';
+
+ for (var i = 0; i < messages.length; i++) {
+ html += messages[i] + '<br />';
+ }
+ history.innerHTML = html;
+
+ if (data.queue) {
+ _.each(data.queue, function (s) {
+ try {
+ var sample = new Sample(s);
+
+ if (queue.append(sample)) {
+ if (queue.link === sample) {
+ sample.onended = _.partial(on_ended, context);
+ sample.onload = function () {
+ this.play(context);
+ };
+ }
+ sample.load(context);
+ }
+ }
+ catch (e) {
+ console.error((e.message || 'error') + ' in "' + s + '"');
+ }
+ });
+ }
+ }
+ else {
+ console.error('error: ', data);
+ }
+ });
+
+ send.onclick = function () {
+ var text = field.value;
+ socket.emit('send', { message: text });
+ };
+ };
+})(window);
diff --git a/public/js/sample.js b/public/js/sample.js
new file mode 100644
index 0000000..d54be71
--- /dev/null
+++ b/public/js/sample.js
@@ -0,0 +1,94 @@
+/* -*- mode:javascript; coding:utf-8; -*- */
+
+'use strict';
+
+(function (window) {
+ var LOOP_COUNT = 4;
+
+ function sample(json) {
+ var x = JSON.parse(json);
+
+ this.seq = x.seq || 0;
+ this.timestamp = x.timestamp || 0;
+ this.url = x.url;
+ }
+
+ sample.prototype.gt = function (x) {
+ return this.timestamp > x.timestamp || this.timestamp === x.timestamp && this.seq > x.seq;
+ };
+
+ sample.prototype.load = function (context) {
+ var self = this;
+
+ if (self.url) {
+ var request = new XMLHttpRequest();
+
+ request.open('GET', self.url, true);
+ request.responseType = 'arraybuffer';
+
+ request.onload = function (v) {
+ if (v && v.target && v.target.status == 200) {
+ context.decodeAudioData(request.response, function (buffer) {
+ if (buffer) {
+ self.buffer = buffer;
+
+ if (self.onload) {
+ self.onload();
+ }
+ console.log('sample.load: finished ', self.url);
+ }
+ else {
+ console.error('sample.load: no decoded data', self);
+ }
+ }, function (e) {
+ console.error('sample.load: decodeAudioData error', e, self);
+ });
+ }
+ };
+
+ request.onerror = function (e) {
+ var s = (e && e.target && e.target.status && e.target.statusText
+ ? (e.target.status + ' ' + e.target.statusText)
+ : 'error');
+ console.error('sample.load: ' + s + ' while loading', self);
+ };
+
+ request.send();
+ }
+ else {
+ console.error('sample.load: no URL');
+ }
+ };
+
+ sample.prototype.play = function (context) {
+ var self = this;
+
+ if (self.buffer) {
+ var delay = self.buffer.duration * LOOP_COUNT
+ var source = context.createBufferSource();
+
+ source.buffer = self.buffer;
+ source.loop = true;
+
+ source.connect(context.destination);
+ source.start(context.currentTime);
+ source.stop(context.currentTime + delay);
+
+ window.setTimeout(function () {
+ if (self.onended) {
+ self.onended();
+ }
+ }, delay * 1000);
+
+ // does not work
+ //source.onended = function (e) {
+ // console.log(e);
+ //};
+ }
+ else {
+ console.error('sample.play: no buffer', self);
+ }
+ };
+
+ window['Sample'] = sample;
+})(window);