[MusicGeekNotes] Creating Music With Graphics, Lights and Smokes.

Create some music by clicking or dragging @ http://jabtunes.com/labs/jtenorion.html

** Warning: Can be CPU intensive. Safari / Chrome for best results. If you do not have a fast CPU, use less effects in the checkbox options.

Check out a video playing with this.

[Music Notes]
After a while, you may find that you’re creating some chinese-like, malay-like or javanese like music.

This is a clone of the fairly expensive electronic but a fairly cheap music instrument call the Tenori-On made by Yamaha.

Anyway, this version is closer’s to Andre’s implementation call ToneMatrix, a flash implementation using notes of a pentatonic scale, which allows you to pleasant sounding music evening if you click on it randomly. Just youtube it, and you can find how many others have created music with the Tonematrix.

[Geeknotes]
First of all my implementation differs with using a HTML 5 Canvas to render the graphics instead of flash.

I use the the Sion Library for the audio, creating a JS to AS bridge to generate sounds. Howeveer, with the still-in-progress Mozilla Audio Data API, one can easily modify this program to run fully in javascript soon.

My initial visual effects was less than satisfactory compared to Andre’s implementation and I got stuck at creating the “ripple effects”. I first tried the ripple algorithm used in my previous experiment, but such animation would be almost usuable and very likely to hang the browser.

After a period of rest, while reading on perlin noise in canvas, I started having some inspirations for this project again.

Its then struck me that I could implement this with a simple particle system with gradients.
I was also inspired by the use of gradients, alpha and composites stumped upon this while looking up collaborative programming.

So right now, although its not all perfect, but its a big improvement from the past.

Go ahead, have fun, create some music, hack the code, or provide some suggestions.

p.s. I found the layout look like an iPad after I used curve borders, not that I wanted to replicate the iP* devices.

Other WIP screenshots here.

(a cross post on my facebook note)

[geeknotes] Now, Have you met.. Instant QR Codes?

(Imported from my facebook note dated Monday, 28 June 2010 at 01:37)

This is a follow up to my previous geek note “Say Hi to Instant Barcodes”. The quick story here: nothing too fanciful, just a simple html 5 mashup for instant qrcodes using javascript, jquery, and Kazuhiko Arase qrcode jscode. See http://jabtunes.com/labs/qrcode.html

QRCode

The advantage for using QRCode over my previous barcode generator is that this 2d barcode packs more information in it, specifically for this mashup implementation, 119 binary characters with 30% recovery rate (using up to QR Code version 10, can be much more if we can implement till version 40). Think of it as maybe, twitter on a picture!


A picture can tell a hundred words, and this tiny qrcode does store a hundred characters.


Yes, the barcode scanner on android works with 2d barcodes.


And I think this is also a good way to send urls, telephone numbers and other contact to each other. With a lack of a standard vcard or bluetooth protocol, I think qrcodes should work much better!

Feedbacks would be great! and yes, you can download some codes and send me messages in QR Codes! Goodnight! :)

p.s. Tested on all modern browsers (& ie9 beta) except mobile browsers (pls let me know if it works!).

[geeknotes] Say Hi to Instant Barcodes

(This is repost of my facebook note dated 25 June 2010. Apparently there’s more notes to be imported, but maybe I’ll leave that for another time)

It seems to be ages since I last touched javascript but here’s a latest addition to my html 5 canvas experiments, a really simple (1d) barcode generator.

Type some words or numbers, and a barcode appears immediately (using the simple code 39 implementation without checksum- drawbacks, the not suitable for long data due to low density). Admire the barcodes, save it, otherwise artistically modify it (or have fun writing coded messages to each other).

To skip the talk and get to the action, see http://jabtunes.com/labs/bars.html

Barcode scanner on the android is a nifty cool feature.

Scanning my name. You could use it for telephone numbers too.

Yes it works.

Lastly here’s a barcode if you’d like some practice.

Goodnight :)

p.s. tested in Chrome, Firefox, Opera (barcodes without text for IE). Javascript lovers, the html file is self contained (except for jquery). Use/hack as you like

Really Simple High Defination Youtube Video Downloader

This is a really delayed repost of my “geeknote” Really Easy High Defination Youtube Video Downloader. I’m not sure how happy is Google/Youtube with this, or how soon they would change their site so that this wouldn’t work, so no warranties and please use this wisely at your own risk.
~~~~~~~~~~~~~~~~~~~~~~

It started as a bookmarklet I created to download Vimeo HTML5 MP4 videos easily, but soon others were interested in a youtube version. So read on and I’ll try to explain this simply and briefly.

How can I use it?
Go to a youtube video, eg http://www.youtube.com/watch?v=xEF66GRecQg Click on the download bookmark, and the download links will appear under the title. Pick the version you like, and you can watch it in your browser or download them. Usually I use 270p version if I wish to transfer it to my mobile phone for watching. If 720p or 1080p are available, they gives really nice high quality videos.

How can I install this?
Create a bookmark in firefox, chrome, safari or opera. For the link, paste the following block of code into the bookmark’s url.

javascript:(function(){var%20scripts=document.getElementsByTagName('script');for(i=0;i


How can I uninstall this?
Just delete the bookmark if you have added it. Some users have mentioned you can just run the code pasting the entire block into the url.

What’s so special about this compared to so many other downloaders?
This downloader is minimally intrusive and tries to be as unobstructive as possible. It runs only when you click on the bookmarklet. Although it’s unobstructive, its give you the options on the quality, resolution and format you can download. Its really fast and easy to use.

Compared to other software, plugins, addon etc, the installation requires no downloads or browser restarts. Uninstalling is as simple as deleting a bookmarklet. Not to mention that many other scripts are not working well due to some recent changes made by Youtube/Google.

Any updates planned?
Only if I have the time, I would parse the parameters to detect the available formats supported in the current video. This can eliminate the links the current versions adds to the site, but this feature is unnecessary if the user observe what formats the video provides in the little box at the bottom right of the screen.

Reasons why to download videos rather than streamed live?
1. You wish to enjoy more of the video and less of silly comments and the links call ads Google place into the video player.
2. If you are using on a smaller device like a netbook and find that the flash player lags quite a little
3. You think the experience of youtube’s HTML5 player is really horrible
4. You just bought a new 1 Petrabyte hard disk, and wish to borrow some of Google’s bandwidth to utilize more of your unlimited mobile internet and relatively empty disk space.

This is a great tool! Do you accept donations?
I have not tried accepting donations before, but I’ll leave how you can thank me to your creativity. :)

Update!
This script have been modified by my friend Ernest who did an all-nighter for automatically detecting video quality (eg. the HD links will not appear if they are not available).

javascript:(function(){var%20s=document.body.innerHTML.toString();var%20source=s.match(/("video_id":%20"\S+".+"t":%20"\S+")|("t":%20"\S+".+"video_id":%20"\S+")/i);var%20source2=s.match(/("fmt_list":%20\S+")/);var%20residu=String(source2).match(/\d+\.?\d*/g);if(source!==null){var%20u=(String(source).replace(/(?:(?:"video_id":%20"(\S+)".+"t":%20"(\S+)")|(?:"t":%20"(\S+)".+"video_id":%20"(\S+)"))/i,'http:\/\/www.youtube.com\/get_video?video_id=$1+$4&t=$2+$3'));function%20add(t,u){var%20a=document.createElement("a");var%20t=document.createTextNode(t);a.appendChild(t);a.setAttribute('href',u);var%20b=document.getElementById("watch-headline-user-info");if(b==null)b=document.getElementsByTagName("body").item(0);b.appendChild(a)}add('Download%20[LQ%20FLV]%20',u);add('[270p%20MP4]%20',u+'&fmt=18');if(residu.indexOf("34")>=0)add('[360p%20FLV]%20',u+'&fmt=34');if(residu.indexOf("35")>=0)add('[480p%20FLV]%20',u+'&fmt=35');if(residu.indexOf("22")>=0)add('[720p%20HD%20MP4]%20',u+'&fmt=22');if(residu.indexOf("37")>=0)add('[1080p%20HD%20MP4]%20',u+'&fmt=37')}})()


Rain, Water, Ripples with HTML Canvas, Javascript, JQuery

One of the exciting reasons to work with canvas is that you are not only able to create 2d graphics easily with javascript, one can easily do do pixel manipulation on images.

Think about it, in case you don’t think its cool right now, is that you only need notepad, a recent web browser and a few lines of code to do cool stuff work with 2d graphics without compilation. Take an example, you can create a greyscale image from a color photo into without photoshop or other software as see in pixastic.

In this post, I will outline how easy it is to code with javascript and canvas to simulate water ripples, along with some issues encountered. After I discovered this old water algorithm (during the DOS era I suspect) on creating waves, I thought why not try this with HTML Canvas, and so I did.

Ripples with Javascript

STEP 1. Creating a canvas element.
This can created easily with javascript, or just add some html code into the body

<canvas id="jripples"></canvas>

STEP 2. Load an image with JS when document is loaded for which we can use the jquery $(document).ready

$(document).ready(function(){
init(); // Run stuff when document is ready.
});

Here’s the code to load an image


var img = new Image();
img.src = "hello.jpg" // path and filename of image
img.onload = function() {} // run the next portion of code when the image loads

STEP 3. Draw the image onto the canvas


canvas = document.getElementById('jripples');
$('#jripples').width(img.width); // We set the canvas width and height with jquery
$('#jripples').height(img.height);
canvas.style.height = canvas.height = img.height ; // Set the canvas size to the image
canvas.style.width = canvas.width =img.width;

ctx = canvas.getContext("2d"); // Get the 2d drawing context
ctx.clearRect(0,0,canvas.width,canvas.height); // Clear the canvas
ctx.drawImage(img, 0,0,canvas.width,canvas.height); // Draw the image

Just a caveat though, to get or manipulate pixels from an image, the image needs to be loaded from the domain or would result in a browser security violation.

STEP 4. Build the data structures behind the wave
orginalData = ctx.getImageData(0,0,canvas.width,canvas.height).data; // The array of pixels for the image
myImageData = ctx.getImageData(0,0,canvas.width,canvas.height); // Modifications of pixels
buffer1 = []; // Create new array for the image buffer
buffer2 = [];
// orginal data length is 4 times the pixel dimensions since they store RGBA (red,green, blue, alpha)
for (var i=0; i buffer1[i] = 0;
buffer2[i] = 0;
}

STEP 5. Creating ripples (the wave algorithm) function

function processWater(source, dest) {
for (var i=imagewidth; i< source.length-imagewidth; i++)
{
// check for bounds
var xi = i % imagewidth;
if ((xi==0) || (xi==imagewidth-1)) continue;

dest[i] = (
((source[i-1]+
source[i+1]+
source[i-imagewidth]+
source[i+imagewidth]) >>1) ) -dest[i];

dest[i] -= (dest[i] >> 5); // Damping - Quick divde by 32 (5 bits)

}
}

while the original article explains how this works, this article explains it in another simpler manner

Two height maps are used to store the current and previous states of the water.
Each frame you will toggle between state maps.
For each array element in the current state array:-
Look at the neighbouring pixels from the previous state, i.e. above, below, left and right. Take the sum and divide by 2. Because we are dividing by 2 a right-shift will work beautifully.
Now subtract the value in the current state map.
If we left it like that the ripples would never subside so we need to diminish the strength of the ripple every pass. The most realistic way of doing this is to reduce the resulting height by a fraction of itself. Once again we can use right-shift to optimise this.

Note that I ensured the loops avoid any edge bound pixel to prevent wrap arounds.

STEP 6. Render the new image with waves.
function texture(buffer) {
var xoffset, yoffset;
for (var i=imagewidth; i {
// check for bounds
var xi = i % imagewidth;
if ((xi==0) || (xi==imagewidth-1)) continue;

xoffset = buffer[i-1] - buffer[i+1];
yoffset = buffer[i-imagewidth] - buffer [i+imagewidth];

var offset = i+xoffset+yoffset*imagewidth;

if (offset>0 && offset

for (var x=0;x<3;x++) { //4 for alpha
myImageData.data[i*4+x] = orginalData[offset*4+x];
}

}

}
// Draw
ctx.putImageData(myImageData, 0, 0);

}

This estimates the pixel offset due to refraction of water (read more on Transparent Surface Ray-Tracing) based on height of the wave and copies the pixels from the orginal array into the new imagearray object. This imagedata is returned to the 2d object using putImageData to be drawn.

STEP 7. Call the rippling function in a timer
rippling = setInterval(ripple, 50); // This calls the ripple function every 20 times a second

STEP 8
We can calling another timer to add rain
raining = setInterval(function() { // random rain
var randomX = Math.round(Math.random() * canvas.width);
var randomY = Math.round(Math.random() * canvas.height);
buffer1[randomY*imagewidth+randomX] += Math.round( Math.random()*-500);
},300);

STEP 9. Add more raindrops/ripples reactivity to mouse clicks. We use jquery to add mouse listeners quickly.
$(canvas).mousedown(function(e) {
var x = e.pageX - $(this).offset().left;
var y = e.pageY - $(this).offset().top ;

buffer1[y*imagewidth+x] = -400;
clicked.dragged= true;

}).

STEP 10. Provides FPS(Frames per second)
setInterval(function() {
$('#jdebug').html(fpsCount + " fps");
fpsCount= 0; // recent
},1000);

This isn’t the most accurate way to calculate FPS, since the callback may not be accurate in itself. Rather, one should try getting the actual time subtracted from the last elapsed time to calculate the fps.

Enjoy. Here’s the link to javascript ripples demo
Remember that you may need to upload your html and images to a webserver to test (or change your browser security settings).

Other Considerations.
This run on all modern browsers (Firefox, Safari, Chrome, Opera) except IE due to the lack of support with Canvas. While the Excanvas provides some compatibility, it does not provides get/putImageData calls. Until IE9 releases, flashcanvas pro may solve this compatibility issue.

From my observations, the bottleneck seems to be when the browser render the image after the putImageData javascript. Right now firefox seems to be able to render 2x faster than chrome, and the self proclaimed fastest browser on earth, Opera, seems to renders about 3 times faster than chrome (to 100fps on small images).

While this wave algorithm may be efficient when there are many waves, this method may not be as efficient when there are few waves on large images/canvases. Even a image of 640 pixels can hang the browser (be warned).

One simple way to speed up the waves is scale down the image. If putImageData is the bottleneck, then we can hope that the browser would optimize these soon. (with Direct2D just implemented for firefox nighties, maybe soon will be soon!) Other interesting alternatives would be to implement WEBGL or O3D which uses the C++ stack or GPU to speed up the rendering, although these are not widely supported right now. The better idea, I imagine, is to implement another algorithm which renders the ripples from its wave source, which would probably run faster on large images with few waves.

Finally, creating ripples seems to be a classic challenge and if you were to do a simple search, would be able to find implementations for DOS graphics, OpenGL or other 3d Programming, Java graphics, and for the most recent implementations, Processing applet and Flash/AS3. One can even find this effect on desktops with dreamrender or beryl/compiz fuzion. Still this seems to be the first implementation with javascript/canvas other than one other on the net have seem to created a “ripple effect” with canvas, which is not really similar.

School work along other commitments is keeping me really busy, besides this is not even part of any computer graphics classes I required to take. So while there are perhaps more enhancements and optimizations that can be done, I’ll be leaving that up to you readers :)