<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bits&#039;n&#039;Bites</title>
	<atom:link href="http://www.bitsnbites.eu/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.bitsnbites.eu</link>
	<description></description>
	<lastBuildDate>Mon, 30 Apr 2012 11:43:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>The SoundBox synth</title>
		<link>http://www.bitsnbites.eu/?p=155</link>
		<comments>http://www.bitsnbites.eu/?p=155#comments</comments>
		<pubDate>Mon, 30 Apr 2012 11:43:05 +0000</pubDate>
		<dc:creator>m</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.bitsnbites.eu/?p=155</guid>
		<description><![CDATA[After releasing the 4k demo SWAY, I&#8217;ve received much positive feedback regarding the synth that was used to produce the music. The synth is based on a new work-in-progress project that I have not released yet. However, my colleges convinced &#8230; <a href="http://www.bitsnbites.eu/?p=155">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After releasing the 4k demo <a href="http://pouet.net/prod.php?which=59203" target="_blank">SWAY</a>, I&#8217;ve received much positive feedback regarding the synth that was used to produce the music. The synth is based on a new work-in-progress project that I have not released yet. However, my colleges convinced me to participate in the <a href="https://developer.mozilla.org/en-US/demos/devderby" target="_blank">Mozilla Dev Derby</a> (April 2012 is all about audio), so I submitted a slightly stripped down version yesterday (I had to remove the PHP/server parts). So, now you can try it out at least (it&#8217;s GPL, so all source is available): I call it <a href="https://developer.mozilla.org/en-US/demos/detail/soundbox-lite" target="_blank">SoundBox Lite</a>.</p>
<p>The background to the tool is obviously <a href="http://sonantlive.bitsnbites.eu/" target="_blank">Sonant Live</a>, but with some useful changes:</p>
<ul>
<li>The soft synth core was rewritten, generally giving better sound quality (better filter logic, supporting sharp transients etc) and faster sound generation.</li>
<li>There are now four note tracks per pattern, so you can do proper chords.</li>
<li>An &#8220;effects track&#8221; was added per pattern, which gives you the opportunity to change any instrument / fx parameter dynamically (quite useful!).</li>
<li>A new distortion effect was added, giving that powerful dirty sound.</li>
<li>Also, some functions that I personally did not use that much, or that were just redundant, were removed (for a more compact player routine).</li>
</ul>
<p>I will continue working on a more public release. In the meantime, enjoy the demo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitsnbites.eu/?feed=rss2&#038;p=155</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Targeting the mobile platform</title>
		<link>http://www.bitsnbites.eu/?p=146</link>
		<comments>http://www.bitsnbites.eu/?p=146#comments</comments>
		<pubDate>Mon, 27 Feb 2012 21:30:34 +0000</pubDate>
		<dc:creator>m</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[WebGL]]></category>

		<guid isPermaLink="false">http://www.bitsnbites.eu/?p=146</guid>
		<description><![CDATA[The latest and greatest version of Opera Mobile (version 12) has just been released, which includes support for lots of HTML 5 goodies, including WebGL. While it usually works great, I noticed that many sites, HTML apps and demos have &#8230; <a href="http://www.bitsnbites.eu/?p=146">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The latest and greatest version of Opera Mobile (version 12) has <a href="http://my.opera.com/ODIN/blog/2012/02/25/opera-mobile-12-and-introducing-opera-mini-next">just been released</a>, which includes support for lots of HTML 5 goodies, including WebGL. While it usually works great, I noticed that many sites, HTML apps and demos have not really been designed for the mobile platform.  In this post I will try to cover two important factors to keep in mind if you want your HTML5 / WebGL app to work well on a mobile device:</p>
<ol>
<li>Adapt the viewport size/scale to the mobile screen.</li>
<li>Support touch input.</li>
</ol>
<p><em>(I was originally planning to write up some notes on WebGL performance and precision considerations too, but I&#8217;ll save that for a later post).</em><br />
<span id="more-146"></span></p>
<h2>Viewport size</h2>
<p>Mobile browsers are quite different from traditional desktop browsers when it comes to how the page size is handled. Instead of using a page width equal to the browser window width, mobile browser typically use a virtual page size that is much larger than the mobile screen, and let the user zoom in and out to be able to both get an overview of the page and easily focus on the interesting parts.</p>
<p>When you make a game or demo, you typically want to fit your canvas/page to the screen of the mobile device and disable zooming. This serves two important purposes:</p>
<ol>
<li>User interaction is much easier if you don&#8217;t have to pan around to see the entire screen and find buttons etc.</li>
<li>Performance! You don&#8217;t want to render more pixels than you need, especially on a mobile device with limited GPU &amp; CPU performance.</li>
</ol>
<p>The solution is to use the <strong>viewport meta tag</strong>, like this (for instance):</p>
<pre>&lt;meta name="viewport" content="width=device-width,
 maximum-scale=1, minimum-scale=1, target-densitydpi=device-dpi"&gt;</pre>
<p>Doesn&#8217;t look too cryptic, does it? Perhaps worth explaining though is the <strong>target-densitydpi=device-dpi</strong> argument. It basically tells the browser to bypass any zoom settings and use a 1:1 mapping of your pixels onto the screen (most browsers use a zoom factor &gt; 100% on devices with high pixel densities).</p>
<p>You can find a very good description of how it works here: <a href="http://dev.opera.com/articles/view/an-introduction-to-meta-viewport-and-viewport/" target="_blank">An introduction to meta viewport and @viewport</a>. The viewport meta-tag is supported by all mobile browsers that I have tried (Opera Mobile, Android browser and Firefox for Android).</p>
<p>Here is an example page with and without the meta viewport tag:</p>
<ul>
<li><a href="http://www.bitsnbites.eu/misc/meta-viewport-1.html">No meta viewport</a></li>
<li><a href="http://www.bitsnbites.eu/misc/meta-viewport-2.html">With meta viewport</a></li>
</ul>
<p>You should be able to spot the difference quite easily on a mobile device. E.g. try to zoom both versions of the page.</p>
<h2>Touch input</h2>
<p>Typically when you design an interactive web app, you add support for mouse and/or keyboard input. Unfortunately, that is not of much use on a mobile device. What you want is to use touch input events instead.</p>
<p>Essentially, you use <strong>addEventListener</strong> to catch <strong>touchstart</strong>, <strong>touchmove</strong> and <strong>touchend</strong> events. In the JavaScript event handler you get an array of touch positions (yes &#8211; full multi touch support), each containing the properties <strong>clientX</strong> and <strong>clientY</strong>. For instance:</p>
<pre>function touchHandler (e) {
  e.preventDefault();
  for (var i = 0; i &lt; e.touches.length; i++) {
    var pos = e.touches[i];
    // Do something cool with pos.clientX, pos.clientY ...
  }
}

function init() {
  var c = document.getElementById("canvas");
  c.addEventListener('touchstart', touchHandler, false);
  c.addEventListener('touchmove', touchHandler, false);
  c.addEventListener('touchend', touchHandler, false);
}</pre>
<p>With this information, you can easily map touch events to your in-game UI elements or click on or aim at objects in a 3D world, for instance.</p>
<p>Here is a simple example: <a href="http://www.bitsnbites.eu/misc/touch-events.html">touch events</a>. Touch on the screen, and the HTML 5 logo should move to that position.</p>
<p>The recently released Opera <a href="http://shinydemos.com">shiny demos</a> also has a nice example of touch input: <a href="http://shinydemos.com/touch-tracker/">Touch tracker</a>.</p>
<p>Now, let&#8217;s make some great mobile apps!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitsnbites.eu/?feed=rss2&#038;p=146</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Frank 4k WebGL demo &#8211; Lessons learned</title>
		<link>http://www.bitsnbites.eu/?p=112</link>
		<comments>http://www.bitsnbites.eu/?p=112#comments</comments>
		<pubDate>Thu, 17 Nov 2011 07:09:57 +0000</pubDate>
		<dc:creator>m</dc:creator>
				<category><![CDATA[Compression]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WebGL]]></category>

		<guid isPermaLink="false">http://www.bitsnbites.eu/?p=112</guid>
		<description><![CDATA[So, I&#8217;ve just released my first proper 4k WebGL demo: Frank 4k! It&#8217;s a neat multi-part demo with 3D graphics and a low-fi synth tune, all written entirely in JavaScript (as far as I know, it&#8217;s the first of its &#8230; <a href="http://www.bitsnbites.eu/?p=112">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://frank.bitsnbites.eu"><img class="alignright size-full wp-image-115" title="Frank 4k" src="http://www.bitsnbites.eu/wp-content/uploads/2011/11/frank-01.jpg" alt="Frank 4k" width="200" height="129" /></a> So, I&#8217;ve just released my first proper 4k WebGL demo: Frank 4k! It&#8217;s a neat multi-part demo with 3D graphics and a low-fi synth tune, all written entirely in JavaScript (as far as I know, it&#8217;s the first of its kind).</p>
<p>Try it <a title="Frank 4k" href="http://frank.bitsnbites.eu" target="_blank">here (compressed)</a> or <a title="Frank 4k (safe mode - uncompressed)" href="http://frank.bitsnbites.eu/safe.html" target="_blank">here (&#8220;safe mode&#8221;, no compression, with error checks etc)</a>.</p>
<p>I have to admit that the design is kind of simple. One of the reasons is that I mostly focused on fitting it all into less than <strong>4096 bytes</strong>.</p>
<p>If you want to know more about how I did it, read on&#8230; I hope that this post will inspire more people to try out the slightly odd art of 4k JavaScript demo programming.</p>
<h3><span id="more-112"></span>Strategy &amp; Goals</h3>
<p>The goals were, quite simply: make a multi-part WebGL demo with synthesized music, and make it fit into less than 4096 bytes. The strategy was equally simple:</p>
<ul>
<li>Use <a href="http://sonantlive.bitsnbites.eu/" target="_blank">Sonant Live</a> to create the music.</li>
<li>Use <a href="http://www.iquilezles.org/apps/shadertoy/" target="_blank">Shader Toy</a> to design my GLSL shaders.</li>
<li>Create a simple framework in JS to play the music and run the WebGL stuff.</li>
<li>Finally compress it all with <a href="http://closure-compiler.appspot.com/home" target="_blank">Google Closure Compiler</a> &amp; <a href="http://crunchme.bitsnbites.eu/" target="_blank">CrunchMe</a>.</li>
</ul>
<p><img class="size-full wp-image-118 alignright" title="frank-02" src="http://www.bitsnbites.eu/wp-content/uploads/2011/11/frank-02.jpg" alt="" width="200" height="129" />To be able to use several shaders, and still keep the size down, I decided to make good use of the DEFLATE encoder (used by CrunchMe) by making the shaders as similar as possible (meaning a lot of repeated strings that get magically compressed away). Another solution could have been to make some sort of shader builder system (similar to how it&#8217;s done in <a href="http://www.pouet.net/prod.php?which=53605" target="_blank">Muon Baryon</a>), but the former approach seemed simpler.</p>
<p>As for what to display, I decided to go for some simple fragment shader based ray tracing. Showing several different parts became a simple case of switching between different shader programs along a time line, like this:</p>
<pre>parts = [
    [30, 6], // Tunnel
    [45, 2], // Mirrored slow
    [60, 1], // Wild
    [75, 0], // Basic
    [90, 5], // Even wilder
    [105, 4], // Mirrored fast
    [120, 7], // Tunnel
    [135, 3], // Sepia mirrored
    [9000, 0]
];

var prg = p[0]; // NOTE: This is the first part
for (var i = 0; t &gt; parts[i][0]; i++) prg = p[parts[i][1]];
gl.useProgram(prg);</pre>
<p>I toyed around with different combinations of shaders until my compression pipeline gave me a result of somewhere between 6K and 8K. That&#8217;s when I started optimizing&#8230;</p>
<h3>Optimizing Code &#8211; Part 1</h3>
<p>The first step taken was to minimize the sound synth. I essentially did three things:</p>
<ol>
<li>Remove parts of the music data that wasn&#8217;t actually used (such as unused patterns).</li>
<li>Remove parts of the sound generation code that wasn&#8217;t used, based on the instrument settings (e.g. notch filters weren&#8217;t used at all in my tune).</li>
<li>Since I was using WebGL, the demo already required typed arrays, so I changed the slightly bulky CanvasPixelArray code to use Int32Array instead.</li>
</ol>
<p>This gave some significant savings. Rationale: If you start out with a generic solution (e.g. the Sonant music synth in this case), strip it down as far as possible based on your specific needs.</p>
<h3>Compression</h3>
<p><img class="alignright size-full wp-image-122" title="frank-03" src="http://www.bitsnbites.eu/wp-content/uploads/2011/11/frank-03.jpg" alt="" width="200" height="129" />The CrunchMe compression tool was great, but I was sure that it could do even better. After looking around for different alternatives to the zlib DEFLATE implementation, I finally arrived at Ken&#8217;s <a href="http://advsys.net/ken/utils.htm" target="_blank">PNGOUT</a> tool. Now, it&#8217;s not open source, but making my CrunchMe tool call the command line tool to do an extra compression pass was simple enough (hey! all tricks allowed!).</p>
<p>This gave me another 100-200 bytes. Rationale: Use the best compression tools available, event if it means that your build system gets a bit &#8220;funny&#8221;.</p>
<h3>Decompression</h3>
<p>Apart from doing compression, the CrunchMe tool adds some decompression code to the final code. Here, I mainly did two things that helped remove quite a few bytes:</p>
<ol>
<li>Generate code more dynamically. In particular, I replaced generic expressions like <em>a.length</em> and <em>x.width*x.height</em> with constant expressions.</li>
<li>Pollute the global name space (no closures, no vars).</li>
</ol>
<p>Rationale: Write and generate specialized code, and don&#8217;t care if you pollute the global name space.</p>
<h3>Optimizing Code &#8211; Part 2</h3>
<p>At this point, I think I was about 800 bytes from my goal, and started doing all sorts of optimizations. Here are a few tips:</p>
<ul>
<li>Your code does not have to do exactly what you first designed it to do, as long as it still looks and sounds OK. Simplify expressions. Do approximations. Drop precision in constants.</li>
<li><img class="alignright size-full wp-image-127" title="frank-04" src="http://www.bitsnbites.eu/wp-content/uploads/2011/11/frank-04.jpg" alt="" width="200" height="129" />In the same sense, your GLSL code does not have to be correct &#8211; you will always get a result! Very subtle changes can create quite interesting effects. For instance, the over-bright second tunnel part is the result of changing a + to a &#8211; in a distance calculation equation.</li>
<li>The Closure Compiler will rename your variables &amp; functions to shorter names. However, it will not shorten names of public APIs (e.g. document.getElementById), so stay away from those and/or find shorter variants that do the same.</li>
<li>The Closure Compiler will not touch the GLSL code (obviously). Mangle the code yourself (or use a GLSL minification tool). Use short names, and find short GLSL representations (e.g. length(a-b) is slightly shorter than distance(a,b)).</li>
<li>Utilize the DEFLATE algorithm as much as possible by using similar constructs across your code (e.g. prefer using only cos() instead of mixing sin() and cos()).</li>
<li>Forget code structure &amp; OO programming. Merge all classes and name spaces! This removes code and usually helps the Closure Compiler to do a better job.</li>
<li>When you&#8217;re close to your goal, do silly things like re-arranging your code and changing non-critical constants to help the compression algorithm find that sweet spot. For instance, changing a constant 9999 to 9090 helped me get below the 4096 limit for the first time.</li>
<li>And as usual (in the 4k arena): <strong>size matters more than speed</strong>!</li>
</ul>
<h3>Result</h3>
<p>So, the result is an HTML file (32 bytes) and a <a title="Compressed JavaScript file" href="http://frank.bitsnbites.eu/f.js" target="_blank">JavaScript file</a> (4060 bytes) for a total of <strong>4092 bytes</strong>. You can see the un-compressed original source code here: <a href="http://frank.bitsnbites.eu/frank-unpacked.js" target="_blank">frank-unpacked.js</a>.</p>
<h3>System Requirements</h3>
<p><img class="alignright size-full wp-image-128" title="frank-05" src="http://www.bitsnbites.eu/wp-content/uploads/2011/11/frank-05.jpg" alt="" width="200" height="129" />Theoretically, this demo should run in any browser that supports WebGL, provided that there is adequate hardware support. It has been tested in Chrome, Firefox and Opera 12 alpha under Linux and Windows on NVIDIA, ATI and Intel graphics cards.</p>
<p>If you run into problems with the 4k version, try the &#8220;safe&#8221; version (at least it should give you some error message if it fails).</p>
<p><em>Note to Windows users with Firefox or <em>Chrome</em></em>: You may experience a bug in ANGLE (something like &#8220;Shader@0x0644E000(49,145): error X3000&#8243;) if you don&#8217;t force your browser to use the OpenGL back end rather than the DirectX back end (<em>Firefox</em>: about:config &gt; webgl.prefer-native-gl = true, <em>Chrome</em>: chrome.exe &#8211;use-gl=desktop).</p>
<p><em>Note to Firefox users</em>: The demo may appear to have a poor video refresh rate, due to <a title="Mozilla Bug 587465" href="https://bugzilla.mozilla.org/show_bug.cgi?id=587465" target="_blank">a bug</a> in the HTML Audio currentTime implementation. Try Chrome or Opera for a more fluent experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitsnbites.eu/?feed=rss2&#038;p=112</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Muon Baryon in 6k JavaScript</title>
		<link>http://www.bitsnbites.eu/?p=98</link>
		<comments>http://www.bitsnbites.eu/?p=98#comments</comments>
		<pubDate>Mon, 08 Aug 2011 16:58:54 +0000</pubDate>
		<dc:creator>m</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WebGL]]></category>

		<guid isPermaLink="false">http://www.bitsnbites.eu/?p=98</guid>
		<description><![CDATA[I present to you my latest hack: Muon Baryon for JavaScript/WebGL. (Note: requires an HTML5/WebGL browser, a decent graphics card, and the pre-calculation time before the demo actually starts is quite long). The Original So, what is Muon Baryon? It&#8217;s &#8230; <a href="http://www.bitsnbites.eu/?p=98">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I present to you my latest hack: <a title="Muon Baryon online demo" href="http://muonbaryon.bitsnbites.eu/" target="_blank">Muon Baryon for JavaScript/WebGL</a>. (Note: requires an HTML5/WebGL browser, a decent graphics card, and the pre-calculation time before the demo actually starts is quite long).</p>
<h2>The Original</h2>
<p>So, what is Muon Baryon? It&#8217;s a Windows 4k demo originally created by Youth Uprising, Ümlaüt Design and Outracks. More precisely, it&#8217;s the winner of the <a href="http://archive.assembly.org/2009/4k-intro" target="_blank">Assembly 2009 4k contest</a> (so it&#8217;s a bit old &#8211; but still one of my absolute favorites). You can find out more <a title="Muon Baryon at pouet.net" href="http://www.pouet.net/prod.php?which=53605" target="_blank">here</a>.</p>
<h2>The HTML5 Port</h2>
<p>Now, Muon Baryon was low hanging fruit for an HTML5 port, since:</p>
<ol>
<li>Most of it is written in <a href="http://en.wikipedia.org/wiki/GLSL" target="_blank">GLSL</a>, which is available through <a href="http://en.wikipedia.org/wiki/WebGL" target="_blank">WebGL</a>.</li>
<li>The most complicated non-GLSL part was the music synth, and it has<a title="Doing a sound synth in JavaScript" href="http://www.bitsnbites.eu/?p=1" target="_blank"> already been ported to JavaScript</a>.</li>
</ol>
<p>So, to begin with I started out converting the remaining C code to JavaScript, which mostly consisted of replacing things like glUseProgram() with gl.useProgram(), etc (a no-brainer). I also had to replace the handy desktop OpenGL call <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml" target="_blank">glRect</a> with slightly more bloated vertex buffer code.  When trying it out for the first time, nothing worked (black screen)&#8230; of course. I suspected the GLSL code and inserted the following lines after compiling the shaders:</p>
<pre>if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
    alert(gl.getShaderInfoLog(shader));</pre>
<p>I quickly realized that the original GLSL code was written for the older desktop GLSL 1.x (using ftransform etc), while WebGL uses GLSL ES, which has dropped a few functions.  Here are a few things I had to do to convert the GLSL code to GLSL ES:</p>
<ol>
<li>Replace <em>ftransform</em> with a &#8220;custom&#8221; position attribute (quite simple, since the demo didn&#8217;t use any transformations).</li>
<li>Include the line <em>precision highp float;</em> in the fragment shaders.</li>
<li>Replace the <em>while</em>-loop with a fixed length <em>for</em>-loop, i.e:</li>
</ol>
<pre>while(g&lt;1.){ ... }</pre>
<p>becomes:</p>
<pre>for(int j=0; j&lt;999; j++){if(g&gt;=1.)break; ... }</pre>
<p>Not sure about how good this solution is, but at least Firefox and Chrome do not complain.  Another thing I did was to make the shader resolution independent (the original was hard-coded to a certain screen resolution). Other than that, it was quite straight forward work.</p>
<h2>The Result</h2>
<p>The size of the original Windows demo was 3977 bytes. I did not expect to be able to squeeze the JavaScript port down to 4k, but I hoped to get it below 8k at least. And the final result, after using <a href="http://code.google.com/intl/sv/closure/compiler/" target="_blank">Google Closure Compiler</a> and <a href="http://crunchme.bitsnbites.eu/" target="_blank">CrunchMe</a> to compress the code, is: <strong>5846 bytes</strong>!!</p>
<p>The un-packed code can be found here: <a href="http://muonbaryon.bitsnbites.eu/demo-unpacked.js" target="_blank">demo-unpacked.js</a></p>
<p>&#8230;and the (unreadable) packed code can be found here: <a href="http://muonbaryon.bitsnbites.eu/demo.js" target="_blank">demo.js</a></p>
<h2>Getting it to run</h2>
<p>Ok, I have tried this in Firefox 5 and Chromium 13+ under Ubuntu with an NVIDIA 9600 card (fairly old by now), and it works just fine.</p>
<p>Windows users may find that it will not work by default (seems to be an issue in the ANGLE GLSL-&gt;HLSL conversion). To make it work, enable the OpenGL back-end.</p>
<p>In Firefox, go to about:config, filter out &#8220;webgl&#8221; and change <strong>webgl.prefer-native-gl</strong> to <strong>true</strong>.</p>
<p>With Chrome, you have to start the program with an extra argument, like this: <strong>chrome.exe &#8211;use-gl=desktop</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitsnbites.eu/?feed=rss2&#038;p=98</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Let&#8217;s make some music &#8211; online!</title>
		<link>http://www.bitsnbites.eu/?p=68</link>
		<comments>http://www.bitsnbites.eu/?p=68#comments</comments>
		<pubDate>Tue, 21 Jun 2011 16:29:22 +0000</pubDate>
		<dc:creator>m</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.bitsnbites.eu/?p=68</guid>
		<description><![CDATA[Music trackers for PCs have been around for decades, and I&#8217;ve personally used quite a few of them, starting with SoundTracker on the Amiga, and then various version and ProTracker, OctaMED, MadTracker and ReNoise, to name the ones I&#8217;ve used &#8230; <a href="http://www.bitsnbites.eu/?p=68">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Tracker_(music_software)" target="_blank">Music trackers</a> for PCs have been around for decades, and I&#8217;ve personally used quite a few of them, starting with <a href="http://en.wikipedia.org/wiki/Ultimate_Soundtracker" target="_blank">SoundTracker</a> on the Amiga, and then various version and <a href="http://en.wikipedia.org/wiki/Protracker" target="_blank">ProTracker</a>, <a href="http://en.wikipedia.org/wiki/OctaMED" target="_blank">OctaMED</a>, <a href="http://www.madtracker.org/" target="_blank">MadTracker</a> and <a href="http://www.renoise.com/" target="_blank">ReNoise</a>, to name the ones I&#8217;ve used the most.</p>
<p>Some time ago, I came across <a href="http://www.pouet.net/prod.php?which=53615" target="_blank">Sonant</a>, which is a very specialized tracker. Its main purpose is to create songs that can be used in tiny demos, where the size of the song data plus the player software must not exceed a couple of kilobytes (for comparison, an MP3 file is usually several megabytes).</p>
<p>For various reasons, I decided to make a JavaScript port of Sonant, and the result is:</p>
<p><a title="Sonant Live" href="http://sonantlive.bitsnbites.eu" target="_blank"><img class="aligncenter size-full wp-image-81" title="Sonant Live" src="http://www.bitsnbites.eu/wp-content/uploads/2011/06/sonant-live-logo.png" alt="Sonant Live" width="257" height="49" /></a></p>
<p>Feel free to try it out!</p>
<p><span id="more-68"></span></p>
<h2>The &#8220;Why?&#8221;</h2>
<p>Why make a synth tracker in JavaScript? The top reasons were probably:</p>
<ul>
<li>I already had the <a title="Doing a sound synth in JavaScript" href="http://www.bitsnbites.eu/?p=1">synth</a> implemented &#8211; so the editor was the next natural step.</li>
<li>I wanted a Linux port of the Sonant tool (which was originally a native Windows app). What better way to do it than in JavaScript?</li>
<li>Push the limits of current browser technology (i.e, can it be done?).</li>
</ul>
<p>Note: There have already been some attempts at doing online trackers, for instance the <a href="http://www.skale.org/" target="_blank">Flash port of Skale Tracker</a> (nice, but Flash) and apparently an <a href="http://vimeo.com/11411533" target="_blank">HTML 5 synth</a> (has anyone ever seen this live?).</p>
<h2>The disclaimer</h2>
<p>Just to be clear:</p>
<ul>
<li>Sonant Live is still beta (functions are missing, the user interface is not optimal, and there are bugs).</li>
<li>It is a minimal synth that&#8217;s designed for production of music for minimal demos (i.e. do not expect to find a fully fledged omnipotent music studio).</li>
</ul>
<h2>The wish list</h2>
<p>One of the goals of making this tool was to explore what can be done with current browser technologies. Throughout the work, I&#8217;ve come up with a few wishes for the future directions of browsers:</p>
<ul>
<li><strong>Low latency audio API</strong> &#8211; The current HTML audio element was not really designed for real-time interactive audio. In fact, it acts more like a subset of the video element, which in turn seems to primarily be a replacement for Flash video players (such as the one used on YouTube). With a proper audio API, such as <a href="http://www.khronos.org/opensles/" target="_blank">OpenSL ES</a> (WebSL, anyone?), interactive music and game apps would be much more compelling. For instance, the JavaScript synth in Sonant Live is fully capable of producing audio in real-time, so with a &#8220;real&#8221; audio API it would be possible to get instantaneous playback.</li>
<li><strong>Better optimizing JIT compilers</strong> &#8211; As pointed out by Erik Möller in a <a title="JavaScript performance 2" href="http://my.opera.com/emoller/blog/2011/05/13/javascript-performance-2" target="_blank">blog post</a>, you can get a great deal of performance gain by just eliminating property accesses and common sub expressions. In fact, I roughly got a 2x performance win (on <em>all</em> browsers) just by pre-loading common object properties and expressions in local variables. These are well known compiler optimizations that should not have to be performed by the programmer. Now, I realize that the situation is a bit more complicated for a dynamically typed language with setters/getters, but my point is that without those compiler optimizations, bad programming practices are actually encouraged.</li>
<li><strong>Typed arrays</strong> &#8211; Life would just be so much simpler if high performance typed arrays were common place. For now, I had to resort to using the <a href="https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas" target="_blank">CanvasPixelArray</a> trick, which gives me 8-bit arrays (while I&#8217;d like to use 16-bit arrays).</li>
<li><strong>More flexible web workers</strong> &#8211; The message passing paradigm may be great and fail safe and all, but it really does not cut it for passing huge amounts of data between workers (in my case, I&#8217;d like to create the multi-megabyte audio data in  a worker, and pass it to the UI thread). Shared objects would be much more efficient (read only or mutex locked, etc).</li>
<li><strong>Better URL handling</strong> &#8211; I suspect that in most browsers, the internal URL handling is optimized for URL:s that are at most a few hundred characters long. For short URL:s, keeping a few duplicates around and traversing the string is cheap, but then a 50MB URL comes along&#8230; For instance, when I tried to export a WAV file from Sonant Live, Firefox 4 peaked at 1.6GB , Opera peaked at 2.8GB, and Chrome peaked at 1.1GB and puked (Chrome processes seem to have an upper memory limit of 1GB).</li>
</ul>
<h2>The future</h2>
<p>The future is not to see&#8230; However, some things are obvious candidates for the future of Sonant Live.</p>
<p>First, the GUI is far from complete. For instance, there are some missing functions (copy/paste, undo, etc), and it would be nice to make the editor usable on mobile devices too (e.g. tablets). It would also be nice to make the tool more interactive (e.g. sound playback while pressing keys on the &#8220;piano&#8221; for easier instrument tuning).</p>
<p>Another area of improvement is the synth. As it is now, the synth is 100% compatible with the original Sonant tool, which I consider a feature rather than a bug. However, it is quite limited, and there are several simple improvements that can make the synth more powerful (even if minimalism is to be preserved). Some ideas that I have are:</p>
<ul>
<li><strong>Richer oscillators</strong> &#8211; e.g. up to 8 oscillators with different detune settings, which can give quite rich sounds (e.g. check out the <a title="Superwave P8 demo" href="http://www.youtube.com/watch?v=dyp32IA2KfM" target="_blank">Superwave P8</a> VSTi synth, which uses such tricks).</li>
<li><strong>Better polyphony</strong> &#8211; supporting several note columns per channel would make it easier to do things like chords.</li>
<li><strong>Effect commands</strong> &#8211; e.g. control instrument and effect parameters dynamically from the pattern.</li>
<li><strong>Distortion</strong> &#8211; cheap operation, <a title="Synth distortion example" href="http://www.youtube.com/watch?v=9qUfEwXKvl8" target="_blank">fat sound</a>.</li>
<li><strong>Drums</strong> &#8211; Hmmm&#8230; Something should be done to spice up drum sound generation.</li>
</ul>
<p>These changes would not make the song data noticeably larger (at least not if you compress/deflate it, which is the typical use case), nor would it make the player routine much more complicated.</p>
<p>Another area of improvement would be server-side storage of songs (they are usually less than 1KB compressed, so no problem with disk quotas), so that you can easily access all your songs from anywhere, and publish them for others to enjoy, etc.<br />
<a name="challenge"></a><br />
<h2>The challenge</h2>
<p>Feeling inspired? Since Sonant Live is quite minimalistic, it is a bit of a challenge to create good sounding music with it.</p>
<p>So, if you make your own cool song or groovy instrument, I&#8217;d like to hear it! Until I get some sort of song submission form up, you can post an URL to your song file in a comment to this post (I can grab it and delete the comment). If it&#8217;s good, I&#8217;ll include it in the song list on the front page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitsnbites.eu/?feed=rss2&#038;p=68</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Sonant Live &#8211; sneak peek</title>
		<link>http://www.bitsnbites.eu/?p=61</link>
		<comments>http://www.bitsnbites.eu/?p=61#comments</comments>
		<pubDate>Sun, 05 Jun 2011 21:50:43 +0000</pubDate>
		<dc:creator>m</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.bitsnbites.eu/?p=61</guid>
		<description><![CDATA[Have been working on a web tool that I think is a bit different from the rest: It&#8217;s a music tracker that runs entirely in your browser! It&#8217;s currently a beta-release, but with some patience and training you can get &#8230; <a href="http://www.bitsnbites.eu/?p=61">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Have been working on a web tool that I think is a bit different from the rest: It&#8217;s a <a href="http://en.wikipedia.org/wiki/Tracker_(music_software)" target="_blank">music tracker</a> that runs entirely in your browser!</p>
<p>It&#8217;s currently a <strong>beta</strong>-release, but with some patience and training you can get it to do wonderful things. So try it out now: <a href="http://sonantlive.bitsnbites.eu/">http://sonantlive.bitsnbites.eu/</a></p>
<p><del>The most annoying limitation right now is the lack of a progress bar (you get kind of a progress indicator in Opera &#8211; but not in other browsers). Haven&#8217;t solved how to do the music generation in a web worker yet (for instance, I use a 2D canvas context in the synth, which I think isn&#8217;t possible in a Web Worker).</del></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitsnbites.eu/?feed=rss2&#038;p=61</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Benchmarking different browsers with the synth</title>
		<link>http://www.bitsnbites.eu/?p=55</link>
		<comments>http://www.bitsnbites.eu/?p=55#comments</comments>
		<pubDate>Thu, 26 May 2011 16:11:56 +0000</pubDate>
		<dc:creator>m</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.bitsnbites.eu/?p=55</guid>
		<description><![CDATA[In an earlier post I mentioned that Opera performs very well with my JavaScript port of the software synth Sonant. Out of curiosity, I did some benchmarking of other browsers as well (this time on a quad core Xeon running &#8230; <a href="http://www.bitsnbites.eu/?p=55">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In an <a title="Impressive JavaScript performance!" href="http://www.bitsnbites.eu/?p=51">earlier post</a> I mentioned that Opera performs very well with <a title="Doing a sound synth in JavaScript" href="http://www.bitsnbites.eu/?p=1">my JavaScript port</a> of the software synth <a title="Sonant 4k synth system" href="http://www.pouet.net/prod.php?which=53615" target="_blank">Sonant</a>.</p>
<p>Out of curiosity, I did some benchmarking of other browsers as well (this time on a quad core Xeon running Ubuntu 11.04 64-bit). Again, I tested the tune from the <a title="Muon Baryon 4k demo" href="http://www.pouet.net/prod.php?which=53605" target="_blank">Muon Baryon</a> demo (you can get the song file <a title="ambidumbi.snt - 4KB" href="ftp://ftp.untergrund.net/users/thygrion/ambidumbi.snt" target="_blank">here</a> if you wish to try it yourself in the <a title="Sonant to JavaScript converter/player" href="http://synth.bitsnbites.eu/convert.html" target="_blank">online player/converter</a>).</p>
<p>For reference, I ran the original demo (assembler optimized) in <a title="Wine Windows environment for Linux" href="http://www.winehq.org/" target="_blank">Wine</a> (I believe it should perform as in native Windows, but it uses 32-bit machine code instead of the 64-bit machine code in the browser JIT:s).</p>
<h3>Results</h3>
<p>So, here are the results (lower is better):</p>
<table>
<tbody>
<tr>
<th>Opera 11.11</th>
<td><strong>35 s</strong></td>
</tr>
<tr>
<th>Chromium 13.0.774.0</th>
<td>44 s</td>
</tr>
<tr>
<th>Firefox 4.0.1</th>
<td>70 s</td>
</tr>
<tr>
<th>Original demo (native x86, running in Wine)</th>
<td><em>42 s</em></td>
</tr>
</tbody>
</table>
<h3>Conclusions</h3>
<p>Well, Opera is ahead of the competition here (it&#8217;s twice as fast as Firefox 4!), but Chromium isn&#8217;t far behind.</p>
<p>Also worth noting is that Opera is even faster than the native original synth. While this may sound amazing (yes, I think it is!), please remember that the comparison is not really fair. For instance, the original was optimized for size, not for speed (the JIT compilers in the browsers probably optimize more for speed), and as I mentioned, the original runs in 32-bit mode, while the browsers run in 64-bit mode.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitsnbites.eu/?feed=rss2&#038;p=55</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Impressive JavaScript performance!</title>
		<link>http://www.bitsnbites.eu/?p=51</link>
		<comments>http://www.bitsnbites.eu/?p=51#comments</comments>
		<pubDate>Tue, 10 May 2011 21:58:51 +0000</pubDate>
		<dc:creator>m</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.bitsnbites.eu/?p=51</guid>
		<description><![CDATA[I just compared the song generation time in the JavaScript port of Sonant to the hand optimized x86 assembler version of the same synth, as used in the original Muon Baryon 4k demo. I found the SNT tune here, and &#8230; <a href="http://www.bitsnbites.eu/?p=51">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I just compared the song generation time in the JavaScript port of Sonant to the hand optimized x86 assembler version of the same synth, as used in the original <a href="http://pouet.net/prod.php?which=53605" target="_blank">Muon Baryon 4k demo</a>.</p>
<p>I found the SNT tune <a title="ambidumbi.snt (Muon Baryon tune)" href="ftp://ftp.untergrund.net/users/thygrion/ambidumbi.snt">here</a>, and ran it in Opera in my new <a title="Sonant to JavaScript convert &amp; player" href="http://synth.bitsnbites.eu/convert.html" target="_blank">online Sonant player</a> (check &#8220;Play Now!&#8221; if you wish to play the song in your browser), and guess what:</p>
<p>Native asm synth: <strong>43s</strong><br />
JavaScript synth: <strong>47s</strong></p>
<p>That means that the JavaScript synth is less than 10% slower than the hand optimized native assembly language synth!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitsnbites.eu/?feed=rss2&#038;p=51</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript synth source released</title>
		<link>http://www.bitsnbites.eu/?p=44</link>
		<comments>http://www.bitsnbites.eu/?p=44#comments</comments>
		<pubDate>Sat, 07 May 2011 17:12:43 +0000</pubDate>
		<dc:creator>m</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.bitsnbites.eu/?p=44</guid>
		<description><![CDATA[For those who want to try out the JavaScript sound synth yourselves, I&#8217;ve released the source code. It&#8217;s available in a GIT repository over at Gitorious: https://gitorious.org/js-sonant/js-sonant. The code has been released under the zlib/libpng license, so use it as you &#8230; <a href="http://www.bitsnbites.eu/?p=44">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For those who want to try out the <a title="Doing a sound synth in JavaScript" href="http://www.bitsnbites.eu/?p=1">JavaScript sound synth</a> yourselves, I&#8217;ve released the source code. It&#8217;s available in a GIT repository over at Gitorious: <a title="js-sonant Git repository" href="https://gitorious.org/js-sonant/js-sonant" target="_blank">https://gitorious.org/js-sonant/js-sonant</a>.</p>
<p>The code has been released under the <a href="http://www.opensource.org/licenses/zlib-license.php" target="_blank">zlib/libpng license</a>, so use it as you wish. Many thanks to Jake Taylor (Ferris / Youth Uprising) for making the original Sonant synth available.</p>
<p>To make your own music, use the simple <a title="Sonant by Youth Uprising" href="http://www.pouet.net/prod.php?which=53615" target="_blank">Sonant editor tool</a> (it&#8217;s a Windows tool, but it works well in Linux/<a href="http://www.winehq.org/" target="_blank">Wine</a> too).</p>
<p><del>I still haven&#8217;t made any tool for converting the song data to JavaScript</del>. There&#8217;s also an <a title="Sonant - JavaScript conversion tool" href="http://synth.bitsnbites.eu/convert.html" target="_blank">online tool</a> available for converting binary Sonant song files (.snt) to JavaScript song files that can be played by js-sonant.</p>
<p>Happy hacking!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitsnbites.eu/?feed=rss2&#038;p=44</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Compression of JavaScript programs</title>
		<link>http://www.bitsnbites.eu/?p=20</link>
		<comments>http://www.bitsnbites.eu/?p=20#comments</comments>
		<pubDate>Sun, 24 Apr 2011 17:04:14 +0000</pubDate>
		<dc:creator>m</dc:creator>
				<category><![CDATA[Compression]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.bitsnbites.eu/?p=20</guid>
		<description><![CDATA[In an earlier post I promised that I would come back to the topic of compressing JavaScript programs efficiently, so here we go&#8230; In this post, I&#8217;ll go through some techniques for creating self extracting, compressed JavaScript programs. Since this &#8230; <a href="http://www.bitsnbites.eu/?p=20">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In an <a title="Doing a sound synth in JavaScript" href="http://www.bitsnbites.eu/?p=1">earlier post</a> I promised that I would come back to the topic of compressing JavaScript programs efficiently, so here we go&#8230;</p>
<p>In this post, I&#8217;ll go through some techniques for creating self extracting, compressed JavaScript programs.</p>
<p><span id="more-20"></span></p>
<p>Since this is quite a lengthy post, here&#8217;s an outline as an overview and for quick navigation:</p>
<ul>
<li><a href="#why_compress">Why compress JavaScript?</a></li>
<li><a href="#closure_compiler">The Google Closure Compiler</a></li>
<li><a href="#selecting_method">Selecting a compression method</a>
<ul>
<li><a href="#existing_libraries">Existing libraries</a></li>
<li><a href="#using_liblzg">Using liblzg</a></li>
</ul>
</li>
<li><a href="#handling_binary">Handling binary data</a>
<ul>
<li><a href="#base64">Base64</a></li>
<li><a href="#latin1">Latin 1</a></li>
<li><a href="#utf16">UTF-16</a></li>
<li><a href="#utf16_downside">The downside to UTF-16 encoding</a></li>
<li><a href="#liblzg_conclusions">Conclusions for the liblzg approach</a></li>
</ul>
</li>
<li><a href="#better_png">Doing even better &#8211; PNG</a>
<ul>
<li><a href="#png_idea">The PNG idea</a></li>
<li><a href="#png_logic">The decompression logic</a></li>
<li><a href="#png_conclusions">Conclusions for the PNG approach</a></li>
</ul>
</li>
<li><a href="#crunchme">Wrapping it up &#8211; CrunchMe</a></li>
</ul>
<p><a name="why_compress"></a></p>
<h3>Why compress JavaScript?</h3>
<p>There may be several legitimate reasons for compressing your JavaScript files. The most obvious is probably to reduce network bandwidth, which can be achieved with <a href="http://en.wikipedia.org/wiki/HTTP_compression" target="_blank">HTTP compression</a> (i.e. by using gzip compression between the server and the client at the protocol level).</p>
<p>There are, however, some less common cases where you can not, or are not allowed to, rely on HTTP compression. The use case that originally triggered my interest is the somewhat artificial JavaScript file size limitation of certain <a href="http://en.wikipedia.org/wiki/Demo_(computer_programming)" target="_blank">demo</a> contests. For instance, the <a href="http://gl64k.com/" target="_blank">WebGL 64k contest</a> has the following rules:</p>
<blockquote>
<ul>
<li>Submission file size MUST be ≤ 64k (65,536 bytes)</li>
<li>No external requests, everything must be inlined in the JavaScript</li>
</ul>
</blockquote>
<p>Pay close attention to the second point: all assets, such as images and music, must be inlined in the JavaScript source code, and according to the first point, the source code must not exceed 65536 bytes. Those are quite challenging limits!</p>
<p>In order to make an interesting program, you will certainly want make good use of those bytes, and that calls for <em>compression</em>.</p>
<p><a name="closure_compiler"></a></p>
<h3>The Google Closure Compiler</h3>
<p>First things first: There is a great tool from Google called the <a href="http://closure-compiler.appspot.com/home" target="_blank">Google Closure Compiler</a>. The closure compiler will basically trim down your JavaScript code to a minimum by:</p>
<ul>
<li>Removing all comments and unnecessary white-spaces.</li>
<li>Renaming variables and properties to shorter names.</li>
<li>Refactoring expressions and constructs into a more compact form.</li>
</ul>
<p>Needless to say, any attempts at compressing JavaScript source code should always start by using the closure compiler.</p>
<p>With that said, this article will focus mainly on taking compression even further by applying binary compression methods to the already compact code produced by the closure compiler.<br />
<a name="selecting_method"></a></p>
<h3>Selecting a compression method</h3>
<p>One of the main problems that we face when we want to compress a JavaScript program is that it must be able to decompress itself, which means that the decompression code must not take too much space, or the gain from compressing the original program would be lost!</p>
<p>Another problem is that the binary compressed data stream must be stored in the JavaScript source somehow (more on that later).<br />
<a name="existing_libraries"></a></p>
<h4>Existing libraries</h4>
<p>Since the decompression routine must be small, existing (efficient but large) decompression libraries such as <a href="http://jsxgraph.uni-bayreuth.de/wp/2009/09/29/jsxcompressor-zlib-compressed-javascript-code/">JXGraph</a> and <a href="https://github.com/dankogai/js-deflate">js-deflate</a> are disqualified (the decompression routine from the latter, which seems quite minimal, weighs in at <strong>4924 bytes</strong> when run through the Google Closure Compiler, which is a bit on the heavy side).<br />
<a name="using_liblzg"></a></p>
<h4>Using liblzg</h4>
<p>My first solution to the problem was to use the <a href="http://liblzg.bitsnbites.eu/">liblzg compression library</a>, which was specifically designed to enable a light weight decompression routine. As it turns out, the decompression routine fits into about <strong>450 bytes</strong> of JavaScript code (with a potential of becoming even smaller with some tweaking), which is clearly acceptable for our needs.<br />
<a name="handling_binary"></a></p>
<h3>Handling binary data</h3>
<p>This brings us to another problem: how to store binary data in a JavaScript source file.<br />
<a name="base64"></a></p>
<h4>Base64</h4>
<p>The tried and true method for storing binary data in text files is of course <a href="http://en.wikipedia.org/wiki/Base64" target="_blank">base64</a>. However, since that scheme is only able to store six data bits per text character, we get a data growth of <strong>33%</strong> (assuming an 8-bit character encoding)! That data growth will severely damage the compression ratio, so we ought to find a better method.<br />
<a name="latin1"></a></p>
<h4>Latin 1</h4>
<p>The first method that I tried was to use plain <a href="http://en.wikipedia.org/wiki/Latin_1">Latin 1</a> encoding &#8211; i.e. just put the compressed byte data into a JavaScript string in a Latin 1 encoded JavaScript source file. Obviously, that will not work without some tweaks, since there are several byte values that are forbidden in such a string (0-31, 39, 92, and 127-159, to be more precise).</p>
<p>By substituting invalid byte codes with two valid characters, and some &#8220;clever&#8221; shifting of codes to minimize the occurrences of invalid codes (based on the statistical content of liblzg compressed data), the data growth factor could be reduced to about <strong>5-10%</strong>.</p>
<p>Surely, we can do better than that?<br />
<a name="utf16"></a></p>
<h4>UTF-16</h4>
<p>Yes we can! Please note that while in Latin 1 encoding there are 26% invalid code points (in the 0-255 range), <a href="http://en.wikipedia.org/wiki/Utf-16" target="_blank">UTF-16</a> only has about 3% invalid code points (in the entire 0-65535 range, only 2151 code points must be avoided).</p>
<p>So, let us use UTF-16 coding for our packed JavaScript program! A 2-byte <a href="http://en.wikipedia.org/wiki/Byte-order_mark" target="_blank">BOM</a> in the beginning of the file will ensure that the browser understands that we use UTF-16 (it&#8217;s actually even safer than Latin 1 encoding, which can be misinterpreted as UTF-8 by some clients or text-editors).</p>
<p>Now we can just pack two bytes from the compressed data stream into a single UTF-16 character, and again have a fall back for invalid code points (use two valid UTF-16 characters to encode two bytes that would otherwise make up an invalid code), giving at most a data growth of <strong>less than 4%</strong> (in the case of liblzg compressed data, the figure is usually less than 1%).<br />
<a name="utf16_downside"></a></p>
<h4>The downside to UTF-16 encoding</h4>
<p>There is one severe downside to using UTF-16 encoding: the decompression routine must be encoded in UTF-16 too, which means that it will take twice the space (i.e. over <strong>900 bytes</strong>)! For small files, that may even make the final file <em>larger</em> than with Latin 1 encoding.</p>
<p>But fear not, the solution is near: we can pack the decompression routine!</p>
<p>How? Well, let&#8217;s use the same trick as for the binary data: pack two characters into one UTF-16 character. The decompression routine has a nice property: it&#8217;s pure ASCII (only using codes in the range 32-126). This means that combining two consecutive bytes into a single Unicode character will <em>always</em> result in a valid code point (all codes in the range 2020-7e7e are valid UTF-16 codes).</p>
<p>Since packing the decompression routine in a UTF-16 string will never produce invalid codes, we get 0% space loss, <em>and</em> the routine for unpacking the packed string is very simple. Yes, we need an additional unpacking routine, and it has to be in plain (unpacked) UTF-16 form, but it does not add much to the code since it&#8217;s very basic. It looks something like this (before mangling it to a more compact form):</p>
<pre>var i, c, p = '<em>...packed-string...</em>', s = '';
for (i = 0; i &lt; p.length; i++)
{
  c = p[i];
  s += String.fromCharCode(c &gt;&gt; 8, c &amp; 255);
}
eval(s);</pre>
<p><a name="liblzg_conclusions"></a></p>
<h4>Conclusions for the liblzg approach</h4>
<p>So, at this point, we&#8217;ve taken the liblzg compression pretty much as far as we can for making a self extracting JavaScript program. In summary:</p>
<ul>
<li>A self-extracting JavaScript module (about 600 bytes).</li>
<li>Fairly well-packed binary data (only about 3% larger than the original binary size).</li>
<li>Pure ECMAScript implementation (very high cross-browser compatibility).</li>
<li>Decent compression ratio (though not quite as good as <a href="http://en.wikipedia.org/wiki/DEFLATE" target="_blank">DEFLATE</a>, <a href="http://en.wikipedia.org/wiki/Bzip2" target="_blank">Bzip2</a>, <a href="http://en.wikipedia.org/wiki/Lempel–Ziv–Markov_chain_algorithm" target="_blank">LZMA</a>, etc).</li>
</ul>
<p>While we have achieved great results, we can do even better!<br />
<a name="better_png"></a></p>
<h3>Doing even better &#8211; PNG</h3>
<p>Wouldn&#8217;t it be great if we could access some browser API that can decompress DEFLATE encoded data from JavaScript? Most browsers use <a href="http://en.wikipedia.org/wiki/Zlib" target="_blank">zlib</a> internally for many different things, but still there is no direct support for zlib from JavaScript&#8230;</p>
<p>However, if we are willing to sacrifice compatibility with legacy browsers (e.g. IE 6, 7 and 8), there is a cool trick that we can use (that relies heavily on the &lt;canvas&gt; element): store our JavaScript program in a <a href="http://en.wikipedia.org/wiki/Portable_Network_Graphics" target="_blank">PNG</a> image file (let each character in the source code be one pixel in the image, ranging from 0-255 in gray scale intensity).</p>
<p>So what good would that do &#8211; and how can we use it?<br />
<a name="png_idea"></a></p>
<h4>The PNG idea</h4>
<p>OK, so a little background on the PNG image file format:</p>
<ul>
<li>PNG uses the DEFLATE algorithm for compression (which is the same that is used in ZIP and gzip, for instance).</li>
<li>The file format is lossless (no pixel values are distorted).</li>
<li>All modern browsers can decode PNG images when loaded to an Image object.</li>
<li>We can draw the PNG image to a canvas element and read back pixels using the getImageData() method!</li>
</ul>
<p>In other words, with the aid of the canvas element, we can decompress a PNG image and extract its contents into a JavaScript String object, that we can then execute (e.g. with eval).</p>
<p>Again, we can use the UTF-16 &#8220;trick&#8221; for storing the raw PNG image data in a JavaScript string without experiencing too much data growth.<br />
<a name="png_logic"></a></p>
<h4>The decompression logic</h4>
<p>As with the liblzg solution, we need some decompression code. Only this time it&#8217;s not the actual decompression algorithm, but a small program that does roughly the following:</p>
<ol>
<li>Decode the UTF-16 string to a binary &#8220;string&#8221; (containing the raw PNG data).</li>
<li>Encode the binary string as Base64, using the <a href="https://developer.mozilla.org/en/DOM/window.btoa" target="_blank">btoa()</a> method.</li>
<li>Generate a <a href="http://en.wikipedia.org/wiki/Data_URI_scheme" target="_blank">data URI</a> by prepending a small header: &#8220;data:image/png;base64,&#8221;</li>
<li>Load the data URI into an Image object.</li>
<li>In the onload handler of the image:
<ol>
<li>Draw the image to a canvas element.</li>
<li>Read back the pixel values and put them into a new string.</li>
<li>Execute the content of the string.</li>
</ol>
</li>
</ol>
<p>The size of this decompression program is roughly the same as the liblzg decoder, but on the other hand the DEFLATE compression method gives us better compression ratios than liblzg (the main reason is that while liblzg only uses <a href="http://en.wikipedia.org/wiki/LZ77_and_LZ78" target="_blank">LZ77</a> compression, DEFLATE uses a combination of LZ77 and <a href="http://en.wikipedia.org/wiki/Huffman_coding" target="_blank">Huffman</a> compression).<br />
<a name="png_conclusions"></a></p>
<h4>Conclusions for the PNG approach</h4>
<p>At this point, and with the given goal (making a fairly small JavaScript source file even smaller), the PNG method described above seems to be as far as you can get with current browser technology when it comes to compression ratio (when including the decompression routine as part of the compressed deliverable).</p>
<p>The key benefits with this method are:</p>
<ul>
<li>Reuse the DEFLATE decompression routine in browser:
<ul>
<li>Commonly available (every browser that supports PNG).</li>
<li>Quite good compression ratios (JavaScript code compresses well).</li>
</ul>
</li>
<li>Encode the raw PNG data in a valid UTF-16 string:
<ul>
<li>Very low overhead for encoding binary data in a string (only 3-4%, compared to 33% for Base64).</li>
<li>Very little chance for the data to be misinterpreted by the browser.</li>
</ul>
</li>
</ul>
<p><a name="crunchme"></a></p>
<h3>Wrapping it up &#8211; CrunchMe</h3>
<p>I hope that you found the compression methods described here useful and/or interesting.</p>
<p>If you want to compress your own JavaScript programs, there is an open source command line tool available called <a href="http://crunchme.bitsnbites.eu/" target="_blank">CrunchMe</a>.</p>
<p><em>Note: At the time of writing this, the tool is still under development (beta), but it should be stable enough for normal use (<del>you will have to compile it yourself, though</del>).</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitsnbites.eu/?feed=rss2&#038;p=20</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
	</channel>
</rss>
