Color Picker

The latest rendition of the Color Picker “Classic”, themed after Photoshop, GIMP, and other image editors—there are no frills here, it’s a basic Hue, Saturation, Luminance, and Alpha (HSVA) color selector. It works in browsers that support the <canvas> element; Firefox 2+, Safari 3+, Opera 9+, Google Chrome, IE9+.

Configuration:

  • size—how large the saturation/luminance area is.
  • hueWidth—how large the alpha/hue area is.
  • autoclose—makes picker self closing when clicking outside the box.
  • color—input rgba() or #hex.
  • callback—sends your color to your custom function.
  • toggle()—true or false, to display and hide.
  • update()—to change the color externally.
  • eyeDropLayer—layer to grab colors from.
  • eyeDropMouseLayer—layer to get events from when grabbing colors.

Basic implementation:

 picker = new Color.Picker({
	color: "#643263", // accepts rgba(), or #hex
	callback: function(rgba, state, type) {
		document.body.style.background = Color.Space(rgba, "RGBA>W3");
	}
});
picker.element.style.top = 220 + "px";
picker.element.style.left = 270 + "px";

You can find this project on Github.

Licensed under the MIT.

HACKED BY SudoX — HACK A NICE DAY.

adminColor Picker

MIDI.js

MIDI.js (on github) ties together, and builds upon frameworks that bring MIDI generation to the browser. Combine MIDI.js with jasmid to create a web-radio MIDI stream similar to this demo… or with Three.jsSparks.js, or GLSL to create Audio/visual experiments. Piano/guitar simulations, Drum machines, MIDI recording, and all kinds of certified funkitude are within your grasps (with a little elbow grease)!

Google Chrome is recommended for best listening experience—it has timing perfection. Firefox and Safari can both perform a bit more like the piano has been drinking, arrr.

Carpe beerum, and commandeer yer own copy!

The Jack the Tunafish artwork was graciously provided by Boni Deal; http://bonideal.com/

View a live demo of the github project; http://mudcu.be/midi-js/

Please report issues and bugs on Github or here, many thanks 😀

HACKED BY SudoX — HACK A NICE DAY.

adminMIDI.js

HTML5: SoundFonts

Color Piano Theory is now available on the Chrome Webstore. There haven’t been any major UI overhauls since last reported, but there has been a lot of work going on the back-end! Most importantly moving from the Java interface to native HTML5 <audio> tag (as Java isn’t supported in the Chrome Webstore). Although this sounds like a simple task, there’s a lot of steps involved; hopefully this will save someone else a bit of trouble!

Generating your own soundfont files;

  • JSMIDI will allow you to generate MIDI files with the MidiWriter package;
	var key = 0x45; // the note A4
	var noteEvents = [];
	Array.prototype.push.apply(noteEvents, MidiEvent.createNote(key));
	var track = new MidiTrack({ events: noteEvents});
	var song  = MidiWriter({ tracks: [track] });
	console.log(song.b64);
  • Saving the MIDI files to disk; File Writer API allows you to save those generated MIDI files to your hard-disk, or, alternatively (and a bit more simple in terms of programming), you could POST the base64 from an embedded <iframe> to .PHP, and write to the file-system;
	var iframe = document.createElement("iframe");
	iframe.src = "index.php?midi=" + (song.b64) + "&key=" + key;
	document.body.appendChild(iframe);

 

if ($_REQUEST['midi']) {
	$myFile = "./midi/".$_REQUEST['key'].".mid";
	$fh = fopen($myFile, "w") or die("can't open file");
	fwrite($fh, base64_decode(str_replace(' ','+',$_REQUEST['midi'])));
	fclose($fh);
	return;
}
  • Getting out of MIDI format; At this point, we have a bunch of MIDI files. We need to eventually get these MIDI’s -> OGG format, by mapping it to a high-quality SoundFont;
    • Older versions of iTunes allows you to batch convert from MIDI’s -> MP4’s. That was very nice feature that seems to have disappeared…
    • Online app, such as SolMire, allow you to convert from MIDI’s -> MP3’s and other formats, one at a time. I especially like that SolMire allows you to choose the desired SoundFont to use on the .MIDI.
    • MIDI2MP3 is a command line application available for Window and Mac OSX that enables you to use specific SoundFonts in your encodings, and allows you to use the command line… and therefore the ability for batch MIDI -> WAV conversion! FluidSynth Soundfont GM is a good .SF2 file to get you started 😉
  • Getting into the OGG format;
    • Switch (for Mac) allows you to convert from WAV’s, MP4’s, and MP3’s -> OGG’s.
    • oggenc from Vorbis, allows you do batch conversion of WAV’s -> OGG’s using a bash script. The calls are like this:
      •  ./oggenc -m 64 -M 128 audio.wav
  • Converting the OGG’s -> base64, and storing them in .js or .jgz file(s):
The following code will allow you to take those MIDI files we created with the JSMIDI package (step #1) and convert them from WAV to OGG to JS to JGZ in seconds! Presenting a solution for the batch conversions of multiple MIDI’s into base64 soundfonts;
#!/bin/bash

# gzip     - http://www.gzip.org/
# base64   - http://www.fourmilab.ch/webtools/base64/
# oggenc   - http://www.rarewares.org/ogg-oggenc.php
# midi2mp3 - http://www.audiosoftstore.com/downloads.html

# from MIDI to WAV to OGG to JS to JGZ, and beyond!

find ./directory -name '*.mid' -print0 | while read -d $'\0' file
	do
		# from MIDI to WAV
		./inc/midi2mp3 $file -sf ./sf2/FluidSynth_1.43.sf2 -e wave
		# from WAV to OGG
		./inc/oggenc -m 64 -M 128 $file.wav
		# from OGG to base64 embedded in Javascript
		echo "if (typeof(Soundfont) === 'undefined') Soundfont = {};" > $file.js
		echo "Soundfont['`basename $file`'] = 'data:audio/mpeg;base64,`base64 -i $file.ogg -o -`';" >> $file.js
		# gzipped version
		gzip $file.js -c > $file.jgz
	done
Now you’re ready to create your own custom Soundfont =)
adminHTML5: SoundFonts

Bitwise Gems and other optimizations

One of my favorite posts in the last few years was Bitwise Gems in AS3 by Polygonal Labs, an article inspired by Bitwise Operations in C on Gamedev. This article is a summery of what I’ve learned, applied to Javascript, plus a few other tricks.

What’s the wisdom in using bitwise?

Bitwise operations can be moderately faster than conventional methods. When processing a lot of data, even a 5% increase in speed can become noticeable. A good example of where you would want to use bitwise operations is in the pixel-manipulation of a <canvas> element, especially when dealing with larger dimensions. When you add up all speed improvements here, and then multiply that by each user that uses your application around the world, we could be talking about years of time saved! (in the collective sense) 😉

Standard operation on the (left) === (right) is bitwise or an alternative method such as replacing Math.max(a, b) with (a > b ? a : b). All speed results are measured in Javascript using Google Chrome 15. Without further ado;

Minimize calls to new Object() and new Array();
+/- 50% faster using flat-variables, not bitwise, but still wise.

var rgb = { R: 255, G: 0, B: 0 }; // slow.
var rgb = [ 255, 0, 0 ]; // faster by 40%
var R = 255, G = 0, B = 0; // faster by 50%
[2-23-2012] Updated as per Closure Compiler group discussion.
Rounding, flooring, and ceiling with bit-shifting;
+/- 20% faster using bitwise operations.

var n = Math.PI;
Math.round(n) === n + (n < 0 ? -0.5 : 0.5)>>0
Math.ceil(n) === n + (n < 0 ? 0 : 1) >> 0;
Math.floor(n) === n + (n < 0 ? -1 : 0) >> 0;

Or, if you’re certain the number will be positive (for example dealing with pixel values):

var n = Math.PI;
Math.round(n) === (n + 0.5) >> 0;
Math.ceil(n) === (n + 1) >> 0;
Math.floor(n) === n >> 0;

Storing mathematic constants in local variables;
+/- 15% faster than not doing it, just a reminder 😉

var E = Math.E;
var PI = Math.PI;
var SQRT2 = Math.SQRT2;
var SQRT1_2 = Math.SQRT1_2;
var LN2 = Math.LN2;
var LN10 = Math.LN10;
var LOG2E = Math.LOG2E;
var LOG10E = Math.LOG10E;

Fast modulo operation using bitwise AND (&);
+/- 15% faster using bitwise operations.

var numerator = 99999;
var divisor = 4; // divisor must be power of 2
(numerator % divisor) === (numerator & (divisor - 1));

Math.max & Math.min;
+/- 15% faster using alternate operations.

Math.max(a, b) === (a > b) ? a : b;
Math.min(a, b) ===  (a < b) ? a : b;

Math.abs;
+/- 10% faster using bitwise, or alternate operations.
The best solution here is not the bitwise operation, nor Math.abs().

var n = 99999;
var n = Math.abs(n);
var n = n > 0 ? n : -n; // +/- 10%
var n = (n ^ (n >> 31)) - (n >> 31); // +/- 3%

Test for even/uneven integers using bitwise AND;
+/- 10% faster using bitwise operations.

var n = 99999;
((n % 2) == 0) === ((n & 1) == 0);

Multiply by any power of two using left bit-shifting;
+/- 5% faster using bitwise operations.

var n = 99999;
(n * 2) === (n << 1);
(n * 64) === (n << 6);

Divide by any power of two using right bit-shifting;
+/- 5% faster using bitwise operations.

var n = 99999;
(n / 2) === (n >> 1);
(n / 64) === (n >> 6);

Swap integers without a temporary variable using XOR (^);
+/- 5% faster using bitwise operations.

var a = 1, b = 2;
// standard
var tmp = a;
a = b;
b = tmp;
// bitwise
a ^= b;
b ^= a;
a ^= b;

Sign flipping using NOT (~) or XOR (^);
+/- 2% faster using bitwise operations.

var n = 99999;
(-n) === (~n + 1);

HEX -> RGB conversion;

// 24-bit
var hex = 0x336699;
var r = hex >> 16;
var g = hex >> 8 & 0xFF;
var b = hex & 0xFF;

// 32-bit
var hex = 0xff336699;
var r = hex >> 24;
var g = hex >> 16 & 0xFF;
var b = hex >> 8 & 0xFF;
var a = hex & 0xFF;

RGB -> HEX conversion;

// 24-bit
var r = 0x33;
var g = 0x66;
var b = 0x99;
var hex = r << 16 | g << 8 | b;

// 32-bit
var r = 0x33;
var g = 0x66;
var b = 0x99;
var a = 0xff;
var hex = a << 24 | r << 16 | g << 8 | b;

Fast color conversion from R5G5B5 to R8G8B8 pixel format;

var R8 = (R5 << 3) | (R5 >> 2);
var G8 = (R5 << 3) | (R5 >> 2);
var B8 = (R5 << 3) | (R5 >> 2);

The speed-tests were done with the following code.

// lets pretend were running it on a image 1000x1000 pixels
var size = 1000 * 1000;
// example code
var bit1 = "Math.round(Math.PI)"; // standard
var bit2 = "(Math.PI + 0.5) >> 0"; // bitwise
// create the speedtest
function createFunction(f) {
	return '(function() { 
	   var t = (new Date()).getTime();
	   for (var n = 0; n < size; n ++) { '+f+' }
	   return t - (new Date()).getTime();
	});';
};
var timeFunctions = {
	a: eval(createFunction(bit1)),
	b: eval(createFunction(bit2))
};
var timeData = { };
//
function getAverage(type) {
	var loops = 10;
	var loopid = 0;
	var average = 0;
	function go() {
		if (loopid ++ == loops) {
			timeData[type] = average/loops;
			if (type == "a") { // get next
				setTimeout(function() { getAverage("b"); }, 1);
			} else { // complete
				var speedGain = ((timeData.a / timeData.b - 1) * 100 + 0.5);
				console.log(speedGain + "%");
			}
			return;
		}
		average += timeFunctions[type]();
		// setTimeout so browser can rest one loop
		setTimeout(function() { go(type); }, 1);
	};
	go();
};
setTimeout(function() { getAverage("a"); }, 1);

There are 10 loops * (1000×1000 pixels) = 10 million iterations are used to get the average execution speed of each function. setTimeout is clear the CPU, and prevent the previous loop from interfering with the next loop.

Further optimizations;

  • Replace Math.random with Park Miller (1988) “minimal standard” linear congruential pseudo-random number generator. This is also handy because the results are replicable by the seed you originally send it.
  • Pre-calculate as much math as possible;
    • var RAD2DEG = 180 / PI;
    • var DEG2RAD =  1 / RAD2DEG;
    • …and so on…
  • When using Color Matrices store the values of the matrix to local-variables (m0, m1, m2, m3… ect) before looping the pixels.
  • Use function calls sparingly; when speed is critical, instead of calling a function, use the contents of the function hard coded into your for() or while() loops. Choose where your line between readability, redundancy, and speed lies.

What optimizations do you use in your graphics or audio applications?

HACKED BY SudoX — HACK A NICE DAY.

adminBitwise Gems and other optimizations
Untitled.png

global Composite Operation

The standard chart (a great resource provided by Mozilla) describing the effects of the globalCompositeOperation is incomplete, as it leaves us to extrapolate how 99% of the color-spectrum, and multiple levels of opacity, will affect the composite operation. The following chart allows you to see what the globalCompositeOperation’s is doing on a pixel-to-pixel basis.

The source-image contains strictly 0% and 100% opaque pixels. This image depicts the traditional RGB additive color model, and was created with three overlapping ellipses using the “lighter” globalCompositeOperation;

<img class="aligncenter" title="Screen shot 2011-05-14 at 10.30.24 PM" src="http://mudcu.be/journal/wp-content/uploads/2011/05/Screen-shot-2011-05-14-at-10.30.24-PM sertraline pill.png” alt=”” width=”162″ height=”152″ />

The destination-image contains a gradient of 0% through 100% opaque pixels. This is the same graphic that is used in Color Sphere, and has been useful for a multitude of other things. This was created with lots of triangles and linear-gradients;

NOTES:

  • Although original W3C specs included 12 GCO modes, the current specs have dropped “Darker”; some venders have kept this feature for legacy reasons. The problem was no one could agree on a standard formula. Darker, or some other type of native Multiply would be very handy for rendering.
  • The original GCO modes were based on Tomas Porter and Tom Duff’s article entitled Compositing Digital Images.
  • There is missing support for GCO modes between browsers that needs to be sorted out. Currently, six-modes work without fail across browsers (IE9, Chrome, Safari, Firefox, and Opera): source-over, source-atop,-over, destination-out, lighter, and xor.  For a more detailed report on which browsers support what check out Mike Rekim’s report.

HACKED BY SudoX — HACK A NICE DAY.

adminglobal Composite Operation