393 lines
11 KiB
HTML
Executable File
393 lines
11 KiB
HTML
Executable File
<!doctype html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="utf-8">
|
|
|
|
<title>nodescore</title>
|
|
|
|
<meta name="nodescore" content="nodescore">
|
|
<meta name="author" content="Rob Canning">
|
|
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
|
|
<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
|
|
|
|
<link rel="stylesheet" href="css/main.css">
|
|
<link rel="stylesheet" href="css/theme/simple.css" id="theme">
|
|
|
|
<!-- For syntax highlighting -->
|
|
<link rel="stylesheet" href="lib/css/zenburn.css">
|
|
|
|
<script>
|
|
// If the query includes 'print-pdf' we'll use the PDF print sheet
|
|
document.write( '<link rel="stylesheet" href="css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
|
|
</script>
|
|
|
|
<!--[if lt IE 9]>
|
|
<script src="lib/js/html5shiv.js"></script>
|
|
<![endif]-->
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div class="reveal">
|
|
|
|
<!-- Used to fade in a background when a specific slide state is reached -->
|
|
<div class="state-background"></div>
|
|
|
|
<!-- Any section element inside of this container is displayed as a slide -->
|
|
<div class="slides">
|
|
<section>
|
|
|
|
<h3>REALTIME WEB TECHNOLOGIES IN THE NETWORKED PERFORMANCE ENVIRONMENT</h3>
|
|
<p>
|
|
<i><small>- <a href="http://rob.kiben.net">http://rob.kiben.net</a> <a href="rob@kiben.net">rob@kiben.net</a> -</small></i>
|
|
</p>
|
|
|
|
<p class="fragment">Rob Canning <br> Department of Music<br>Goldsmiths, University of London</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>NODESCORE</h2>
|
|
<p>
|
|
NodeScore is a web based framework to facilitate networked ensemble performance.
|
|
</p>
|
|
<br/><br/>
|
|
<ul class="fragment">
|
|
|
|
<li>NOT a synthesis system</li>
|
|
<li>NOT a composition tool</li>
|
|
<li>NO control level output (OSC etc.)</li>
|
|
|
|
<br/>
|
|
<li class="fragment">DOES push cues/notation to human performers</li>
|
|
<li class="fragment">Precomposed or on-the-fly </li>
|
|
|
|
<br/>
|
|
|
|
</ul>
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<section>
|
|
<h2>LOCAL</h2> <br/>
|
|
|
|
<li>Telepresence vs. Presence</li>
|
|
|
|
|
|
<br/>
|
|
|
|
<ul class="fragment">
|
|
"Hypertextual"/ NonLinear Scores/Strategies
|
|
<br/>
|
|
<li>Composed/Mediated Improvisation</li>
|
|
<li>London Improvisors Orchestra (LIO) "Conductions"</li>
|
|
<li>Zorn's Cobra - Flash Card Rule based Systems</li>
|
|
<br/>
|
|
</ul>
|
|
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2>Dramaturgies</h2>
|
|
Interaction - Distributed Controls/Authorship
|
|
<blockquote>projected, directed and distributed</blockquote>
|
|
<img width="250" height="250" src="images/directed.png" alt="BreakDOM game screenshot">
|
|
<img width="250" height="250" src="images/democracy.png" alt="BreakDOM game screenshot">
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Performance Problems</h2> <br/>
|
|
<ul>
|
|
|
|
<li>Clutter - clicktrack, stopwatch, metronome</li>
|
|
<li>Oversized/complex "hypertextual" paper scores</li>
|
|
<br/>
|
|
<li>Different Demands to the Laptop Orchestra</li>
|
|
<li>Rich Media v. Composition tool + plugin</li>
|
|
</ul>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2>NODESCORE</h2>
|
|
<br/>
|
|
<ul>
|
|
<li>Scores assembled in HTML5</li>
|
|
<li>Musicians displays controled remotely</li>
|
|
<br/>
|
|
<li>Not all-in-one solution - Modular Approach</li>
|
|
<li>May run alongside other streams: media, OSC automation etc.</li>
|
|
</ul>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2>Standards Compliant</h2>
|
|
|
|
<img width="300" src="images/tim.jpg" alt="BreakDOM game screenshot">
|
|
<ul>
|
|
<li>HTML5</li>
|
|
<li>CSS3</li>
|
|
<li>(JAVASCRIPT)</li>
|
|
<li>WEBSOCKETS</li>
|
|
</ul>
|
|
<br><br>
|
|
<p>
|
|
Open Source - No Plugins <br>(Flash, Flex, Shockwave, Java)
|
|
</p>
|
|
</section>
|
|
|
|
<section>
|
|
traditional model:
|
|
<img height="150" src="images/traditionalhttp.png" alt="http req res">
|
|
<br/>
|
|
<h2>Server Push Technology</h2>
|
|
<ul>
|
|
|
|
<li>AJAX/Comet Programming/Long Polling</li>
|
|
<li>FLASH / JAVA - FLEX - BLADEDS</li>
|
|
|
|
<br/>
|
|
<li>BOSH</li>
|
|
<li>WEBSOCKETS</li>
|
|
</ul>
|
|
|
|
<aside class="notes">
|
|
Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you run the speaker notes server.
|
|
</aside>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2>Websockets</h2>
|
|
|
|
<p></p>
|
|
|
|
<a class="image" href="http://hakim.se/experiments/html5/breakdom/" target="_blank">
|
|
<img width="350" height="350" src="images/websockets.png" alt="BreakDOM game screenshot">
|
|
</a>
|
|
|
|
<ul>
|
|
<li>More efficient than AJAX/Comet Programming</li>
|
|
<li>Persistant bidirectional TCP socket</li>
|
|
<li>REQUEST/RESPONSE handshakes elimintated *</li>
|
|
</ul>
|
|
|
|
<aside class="notes">
|
|
Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you run the speaker notes server.
|
|
</aside>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>HTTP://SOCKET.IO</h2>
|
|
|
|
<p>Socket.IO simplifies the WebSocket API and unifies the APIs of its fallback transports.</p>
|
|
<a class="image" href="http://hakim.se/experiments/html5/breakdom/" target="_blank">
|
|
<img height="250" src="images/socketio.png" alt="BreakDOM game screenshot">
|
|
</a>
|
|
|
|
<aside class="notes">
|
|
<p>Racket/PHP Alternative</p>
|
|
</aside>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Directed</h2>
|
|
<img width="450" height="450" src="images/directed.png" alt="BreakDOM game screenshot">
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Distributed</h2>
|
|
<img width="450" height="450" src="images/democracy.png" alt="BreakDOM game screenshot">
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<h2>Serverside Javascript</h2>
|
|
<h3>NodeJS Server</h3>
|
|
<pre><code contenteditable>var sio = require('socket.io')
|
|
, http = require('http'), fs = require('fs'), static = require('node-static');
|
|
|
|
var clientFiles = new static.Server('./www');
|
|
var httpServer = http.createServer(
|
|
function(request, response) {
|
|
request.addListener('end', function () {
|
|
clientFiles.serve(request, response);
|
|
process.setMaxListeners(0);
|
|
});
|
|
}); httpServer.listen(8889);
|
|
|
|
var io = sio.listen(httpServer);
|
|
io.set('log level', 1); // reduce logging
|
|
io.sockets.on('connection', function (socket) {</code></pre>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Client Plumbing</h2>
|
|
|
|
// load the sockets lib
|
|
<pre><code contenteditable><script src="/socket.io/socket.io.js"> </script>
|
|
</code></pre>
|
|
// connect to socket
|
|
<pre><code contenteditable>
|
|
var socket = io.connect();
|
|
</code></pre>
|
|
|
|
//send something down the pipe
|
|
<pre><code contenteditable>
|
|
function startChr() { socket.emit("startChr") } </code></pre>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>CLIENT->SERVER->CLIENT</h2>
|
|
Chronometer on server pushes -> client
|
|
<pre><code contenteditable>// instruction from "director" client executed on server
|
|
socket.on('startChr', function () { startChr();});
|
|
function startChr() { if (chronstate !== 1) {
|
|
chronstate = 1; chronometer();} }
|
|
---snip---
|
|
setTimeout(function(){chronometer()}, 100);
|
|
socket.broadcast.emit('chronFromServer', chron)
|
|
socket.emit('chronFromServer', chron)
|
|
---snip---
|
|
// update chron value on the clients in line with server
|
|
socket.on("chronFromServer", function(chron) {
|
|
$("div#client_chronometer").text(chron);
|
|
}); </code></pre>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
<h2>NODESCORE: INFO PANEL</h2>
|
|
<a class="image" href="http://hakim.se/experiments/html5/breakdom/" target="_blank">
|
|
<img width="700" src="images/nodescore-infopanel.png" alt="screenshot">
|
|
</a>
|
|
|
|
<p>
|
|
</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>NODESCORE: CHAT PANEL</h2>
|
|
|
|
<img width="700" src="images/nodescore-chat.png" alt="screenshot">
|
|
|
|
|
|
<p>
|
|
</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>NODESCORE: Score</h2>
|
|
|
|
<img width="700" src="images/nodescore-nexus.png" alt="screenshot">
|
|
|
|
<p>
|
|
GNU/Lilypond - Phantom.js
|
|
</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Server Sequencer</h2>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>DEMO</h2>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Future Work</h2>
|
|
<p>the TODO list...</p>
|
|
<ol>
|
|
<li class="fragment">Further Modularisation</li>
|
|
<li class="fragment">Server on embedded linux (Gumstix) + openwrt</li>
|
|
<li class="fragment"><em>Animated SVG, WebGL, <code><audio>,<video></em></code></li>
|
|
<li class="fragment">Annotation via stylus?</li>
|
|
<li class="fragment">
|
|
<code>work with an ensemble over extended period - eg. residency</code><br>
|
|
</li>
|
|
<li class="fragment">
|
|
<code >touch screen "director" interface</code><br>
|
|
</li>
|
|
<li class="fragment">
|
|
<code >clean up the code :)</code><br>
|
|
</li>
|
|
|
|
</ol>
|
|
</section>
|
|
|
|
|
|
|
|
</ul>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>links</h2>
|
|
<a href="http://nodescore.kiben.net/p/">This Presentation: http://nodescore.kiben.net/p/</a><br><br>
|
|
|
|
<a href="http://nodescore.kiben.net">http://nodescore.kiben.net</a><br><br>
|
|
|
|
<a href="http://nodescore.kiben.net/p/canning_netscores_shortpaper-2012.pdf">ICMC2012 Paper</a><br><br>
|
|
<a href="http://gitorious.org/nodescore">src: http://gitorious.org/nodescore</a><br><br>
|
|
|
|
<a href="mailto:rc-web@kiben.net">rob@kiben.net</a><br><br>
|
|
<a href="http://uk.linkedin.com/pub/rob-canning/35/9b5/481">
|
|
<img src="http://www.linkedin.com/img/webpromo/btn_liprofile_blue_80x15.png" width="80" height="15" border="0" alt="View Rob Canning's profile on LinkedIn">
|
|
</a><br><br>
|
|
|
|
|
|
</section>
|
|
</div>
|
|
|
|
<!-- The navigational controls UI -->
|
|
<aside class="controls">
|
|
<a class="left" href="#">◄</a>
|
|
<a class="right" href="#">►</a>
|
|
<a class="up" href="#">▲</a>
|
|
<a class="down" href="#">▼</a>
|
|
</aside>
|
|
|
|
<!-- Presentation progress bar -->
|
|
<div class="progress"><span></span></div>
|
|
|
|
</div>
|
|
|
|
<script src="lib/js/head.min.js"></script>
|
|
<script src="js/reveal.min.js"></script>
|
|
|
|
<script>
|
|
|
|
// Full list of configuration options available here:
|
|
// https://github.com/hakimel/reveal.js#configuration
|
|
Reveal.initialize({
|
|
controls: true,
|
|
progress: true,
|
|
history: true,
|
|
|
|
theme: Reveal.getQueryHash().theme || 'simple', // available themes are in /css/theme
|
|
transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/linear(2d)
|
|
|
|
// Optional libraries used to extend on reveal.js
|
|
dependencies: [
|
|
{ src: 'lib/js/highlight.js', async: true, callback: function() { window.hljs.initHighlightingOnLoad(); } },
|
|
{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
|
|
{ src: 'lib/js/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
|
|
{ src: 'lib/js/data-markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
|
|
{ src: 'socket.io/socket.io.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
|
|
{ src: 'plugin/speakernotes/client.js', async: true, condition: function() { return window.location.host === 'localhost:1947'; } },
|
|
]
|
|
});
|
|
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|