Category Archives: Uncategorized

3 Weekends, 3 Projects

In this post, I would like to share 3 projects that I managed to work on 3 recently weekends. For a variety of reasons and excuses I haven’t spent as much time as I would love working on my side projects this year. You might even notice that I’ve been way less active on twitter and on my blog (last post was a year ago?!). Anyways let’s start.

#3 – Slow Fast Slow in JS

TLDR: A web app that adjusts the video speed however you want.


The first small project is an implementation of an IOS app that I love called Slow Fast Slow. Not only it is slick looking, it helps adjust the speed of videos in a intutive manner, not just for the entirity but in sections while interpolating playback rates. Typically to do so you might use a feature called Time Remapping in After Effects that creates hollywood style bullet time scenes, and if you tried that before you know it’s not so simple to use. That’s a reason why I love the app is that you can easily do that, and it became a challenge for me to reimplement it in JS in the browser.

One of the interesting parts of the implementation is figuring out how the curves work. (Thankfully I had some experience playing with curves and splines). An initial approach was to use catmull rom splines however on observation it was ruled out since moving a point never affects more than 2 segments in the original app. Using an approach of rendering bezier curve lines between 2 blocks in a diagram such as mind maps, (using mid points for the bezier control points), I had voila moment that the behaviour match that of the original app. It’s simple, yet it’s really neat that it can work.

Next was integrating the UI with the video in the browser. Thankfully the html video element handles the speedup / slowdown with playback rate. It works well despite some limitations – for example not being able to play in reverse and buffering.

This was an interesting project, and apart from some technical bits I appreciated the UI/UX quality of the Slow Fast app (and wish I find more apps like this). What’s next would be to think about videos could potential be exported as a real video (eg. using ffmpeg.js, server side, or using the new MediaRecorder).

For those interested, check out related source code here.

#2 – Terminal Rendering for Three.js

TLDR: A Three.js Renderer that runs in the terminal.


3 years ago, I wrote ASCII Effect Adapter for three.js. That was a fun project, it was such an idea so simple I wondered why no one else did that (maybe it was because it wasn’t useful, but at least I’m glad I get to do it). However I believe it wasn’t a totally new idea because if you were to look up some old demoscenes videos, you might just find some 3D rendering in ASCII.

This year I learnt about a really cool nodejs module call blessed. It is a pure js library that helps build terminal applications, abstracting lower level details like terminal encodings. I first learnt about it reading about the webpack dashboard and subsequently tried it at work to build some terminal based tools. And for those curious why the name blessed, it is with constrast the commonly known (n)curses library used for terminal apps.

Running threejs with node.js (& npm/browserify) turns out to be something looked at before. Many class (eg Vector*) in threejs are pretty generic and have little problems running in nodejs. Classes like Renderers that touches the DOM are the more tricky parts.

The straight forward approach would be to mock the dom (as done as by others) using jsdom (quite a cool library too). However, I decided to mock the minimal parts needed (to avoid emulating the entire dom emulation, and lessen dependenices and overheads).

The first polyfill I did was to emulate the 2d canvas and for that I used node-canvas (that uses cario internally) need. The nice thing was that blessed has an AsciiImage widget, and to convert the canvas to the terminal screen all needed was to add this line icon.setImage(canvas.toBuffer()). As I continued working on the lib, I did refactor that code to do manual conversion of pixel to ascii, that gave me more control but strangely slightly slower.

Other challenges include figuring out what canvas size to use. I used a combination of using the number of columns and rows that the terminal reports, and the actual pixel size (if the terminal supports the command), together with some ratios calculations.

The next interesting challenge was to get TrackballControls to work. The trick to emulate the window, converting terminal mouse and keyboard events to DOM like events, which I thought was pretty cool it was possible.

Another idea I had was to eliminate native bindings for threejs-term. One approach was use Arrays instead of Cario to mock SoftwareRenderer. That managed to work but performance wasn’t too great.

The last idea I should mention before I should stop talking about this project is using Braille for rendering. Turns out some brilliant people have figured out how to abuse unicode braille characters to give you 8 subdivisions in a terminal character. Turn out it is not difficult to implement it, and it gives an interesting effect in threejs-term, the only limitation being you can’t get different colours for each “sub-pixel”. I even got a little side-track to reimplement the XKCD braille comics in js.

In closing, I think had fun with threejs-term. Terminal seems to be such old and limited technology yet I’ve learnt different cool stuff doing this. Going forward, I think I would love to explore node-gl or headless-gl for threejs-term, as well as rendering more (CJK and emoticons) unicodes. As for the blessed library, I think there are so much more use cases for it, and I would love to see someone implement Vim or Tmux using it one day.

#1 – Mr.doob’s Code Style™

TLDR: MDCS is now available as an ESLint rule (and npm module). MrDoob approves Editor now supports ES6 and also powered by Eslint now.


It’s been almost more than a year since I’ve updated Mr Doob approves. Once a while, it might be used by a threejs contributor using it to format code in PRs, and sometimes for the fun, I like to toggle between code styles. On another weekend while trying to update the JSCS formatting rules, I realized that JSCS have sunseted and I took the opportunity to migrate the rules to EsLint.

Not a bad timing. The contributors of JSCS have now joined Eslint, and given the popularity of EsLint (I guess in addition to wider spread use of ES6), ESLint has became more matured too. The JSCS editor was fairly mature, so I think it was good for it to have some usage in real life before another migration.

It was also good that there were a couple of test cases for mdcs in JSCS, so after adding a couple more test case, the migration to ESLint became easier. What’s funny was that only after I hand migrated the rules, did I realize there was a migration guide from JSCS to EsLint though.

Apart from using EsLint to power “mrdoob approves”, the fact that Eslint is supported by many editors and project led me to question why not expose the eslint rule as an npm module instead? Therefore to now use the rule, one can simply run

npm install –save-dev eslint-config-mdcs

And add a line `{ “extends”: “mdcs” }` to .eslintrc.

After adding .eslintrc to the three.js project, I learnt a rule can also be added via package.json.

This is a good milestone with my experiences with code formatting, something that seems so trivial yet in many ways complex and subjective. We started with an itch, a vision, till executing that the vision.

Code formatting has also brought me down the route playing with, experimenting, learning about tools like sed, code painter, jscs, autoformatting patches, esprima till eslint. Despite the journey, it’s nice to see tools like npm and eslint in action. One recent related interesting article I was reading, was the journey behind Feross’s standard style.

Next steps: Getting more code styles to run in the editor (mainly figuring how to browserify the plugins) and more exploring more funky code styles (semi-colons style indentations).

Final thoughts: I’m not sure if I jabbering down this what might be quite lengthy post, but it’s always nice getting a blog post of out my system. It’s about time for me to write less and more often, and continue working on interesting stuff that matters.

Emscripten Experimentation Experience

At one point Emscripten was the hottest thing in the JS world and I decided to try it. I started writing about the experience in this post but the procrastinator in me didn’t finish it. Fortunately, the content went into these slides and gave a talk about it in Feb earlier this year. The slides should cover most of the content here but feel free to read on if you have the time.

I talked about a struggle with Emscripten, on how the going wasn’t easy especially for someone who wasn’t familiar with C. Still various times the idea of using emscripten was incepted (eg. this twitter thread). Among the stuff that I wanted to try porting was GLSL Optimizer. I gave it my first shot and wasn’t successful with that. GLSLOptimizer was also written because HLSL2GLSLfork (for unity3d) generated GLSL code that could be optimized.

Emscripten probably wasn’t the most complex piece of software (besides it have probably been used successfully with millions lines of code) but why did I failed again and again? In retrospective there were a few reasons

1) these projects weren’t trivial
2) my Emscripten environment was probably messed up
3) I wasn’t familiar with C or C++ world (even though I’ve programmed in c and objc)
4) I wasn’t familiar with the build systems automake/make/cmake/premake, its ecosystems and workflows

These factors made it like learning to jump before crawling. So I’d put these on my backburner. Once in a while I try getting my hands dirty again, till I hit another brick-wall. Repeat.

One day I was reading some GLSL code online and I mistaken it as HLSL. Thinking about how to convert it to GLSL, I end up attempting emscripten-ization again. HLSL2GLSL project came to mind but this time found out a new hlsl-to-glsl project, which turns out to be a newer and simpler shader project.

This project uses premake, so I learn about it. I had progress building stuff, and despite some errors, I could fix. I realized that there were also forks of that project (eg. being used by the witness), and I tried those code too. I also figure that premake doesn’t have to be used. I could run a simple compilation command.

/usr/lib/emsdk_portable/emscripten/1.29.0/emcc src/*.cpp -o hello.html -s EXPORTED_FUNCTIONS=”[‘_parseHLSL’]” –bind -O3

There were other pitfalls and lessons learn’t along the way. Especially with how the JS and emscripten are bridged. There were different approaches: CCall could be used, or using marcos, eval and bindings but one have to be careful the datatypes gets converted correctly through the bridge too.

So yeah, I got emscripten working for the HLSL converter demo and source code

That gave me some experience and confidence boost, and I went on to make glsl-optimizer work. Glsl-optimizer has more code and slightly more complexted, but I follow the previous approach of rolling my own build scripts and and had it work too. See Demo and Code.

There’s one thing I haven’t manage to solve, that is getting data corruption issues using link-time optimizations, so it’d cool if anyone managed to fix that, that would bring down the generated JS even further.

And there’s has been recent update with these projects – Jaume (aka thespite) has attempted integrating GLSL optimizer in his really cool Chrome WebGL Shader Editor extension.

One of the ideas still lingering in my mind would be porting a good sounding midi / wavetable synthesizer like fluidsynth to JS. Stay tuned!

Traveling with Animal Friends Around the World

Its a new year! Oh what blatant lie but still, its my first post for 2013!

You know, the feeling I’m feeling is that that feeling when there’s so much to do, even more that you wish to do, but so little that you really do.

Since resuming blogging has this great inertial, I decided to share some of travel adventures around the world (LA, Japan, Taiwan) with my animal friends (guess who they are!), before writing on more technical stuff.

I guess it all started on a trip to about 4 years ago. Then I was working in the San Francisco bay are then, and with a cheap pair of air tickets, I flew down to Los Angeles for a quick get away alone, until I met Piglet.

LA’s metro

Downtown LA

Walt Disney Concert Hall

Aquarium of the Pacific

Piglet and Jellyfish

Then it was the period of H1N1 Swine influenza, and so the saying that “pigs fly” became true.

Next stop, Japan with Doraemon, the Japanese Robotic cat from the future.

Doraemon on the plane

Doraemon in Tokyo’s JR train

Doraemon and the crowded Kaminarimon in Asakusa

Doraemon in Akihabara Electric Town

Doraemon watches sunrise at Atami

Doraemon and the Shinkansen

Doraemon and a big Rubik’s cube in Osaka

Doraemon in Kaleidoscope in Osaka’s Science Museum

Doraemon goes Kyoto cycling

Doraemon at the Ryōan-ji, a Zen temple famous for its dry garden. Here Doraemon is enlightened that you need to mediate about nothing to be enlightened about nothing.

At the beautiful Hirosawa lake

Doraemon in Arashiyama bamboo forest

The skies tear as Doraemon waves goodbye to Japan

Now for the next destination, Taiwan.

Angry bird at the Sun Moon lake.

At the beautiful mountain side of Cingjing.

At the sheep farm

At Taroko Gorge (thanks to my friend yeda for the correction from “Taroko” :)

Throwing Angry bird in a cable car up Maokong, Taipei.

Angry bird hikes up Jinguashi.

Angry Bird meets his enemies, at the local pig farm.

Angry bird launches into space, returning to my home in Singapore.

Where to, who shall I go with next? Thanks for reading, and hope you enjoyed this little adventure.


p.s. a technical bit – this is the first time I experimented writing this post with zenpen. Its a pretty cool tool (Since I usually post my photos on facebook, I just drag them in). I then used $(‘section’).innerHTML to extract the html code, clean some attributes before pasting into my blog.


Its been an awesome 2 days at JsCampAsia – great talks, great people, fun events.

Group picture from above!

It was about 2 years ago when I first watch Ryan Dahl’s node.js presentation at jsconf online. I subsequently found other quality jsconf talks so when I first learnt that JsCampAsia was going to be held in Singapore, I decided it was an event I should attend.

When Thomas Gorissen the JSCamp organizer asked if would like to conduct a workshop on three.js, I was really excited and agreed. So I learnt Ricardo/@mrdoob had mentioned me earlier at JSConf.EU, and it was a pity he couldn’t come as he was attending dotJs in Paris.

Mozilla’s Michal Budzynski asking Google’s Eric Bidelman a question. JSCamp’s Thomas on the right

Its my first time giving a talk at such scale, so its really nice to have some attendees came to me telling me that they have found have enjoyed the workshop or have found three.js interesting. (I’m sure no one was nasty enough to tell me if I was bad, so I’ll probably do some self criticism when I grab a copy of my video)

With one of the JSCamps’s helpers

Apart from the excitement of speaking, it just pleasurable to listen to the talks to the speakers coming from around the world – some really interesting, some informative, some engaging, enjoyable – and some I’ve missed out, I’ll be will catching them once the videos get released.

Of the best loved talks about replacing html & css with js by Jed Schmidt

So the last thing awesome about JSCamp is about meeting people, although some really briefly. To the audiences who said hi, thanks or even asking questions, I’m thankful and appreciate that. In turn, I probably have asked other speakers some difficult or silly questions.

On returning home (at the northern end of this small island), my body decided it deserved a day of hibernation.

Overall, JSCampAsia was a great conference, and to be a small part of it is my honor and pleasure. Hope to see you all again!

Some links
Official Blog –
Collection of Links –

Handout for 1st session –
Slides for 1st session –
Sample code –
Slides for 2nd session –

Some photos

Speakers lunch

A picture of the conference hall

Jan from Amsterdam who spoke on dependency injection in “The Architect Way” on our way back.

With my colleagues from zopim who attended this conference too

Only bad thing about seating in the front is the “giraffe neck”.

Panel discussion – pretty sure @divya isn’t looking at her mobile phone this time.

This is me on my 2nd session showing a visualization of a photo with three.js

Everyone getting ready for the group photo!

Everyone with my Jelly Bean’s panorama shot.

Shim Sangmin from Korea, creator of Collie . He has great slides on High Performance Mobile Web Game Development in HTML5. He bought lots of Kaya jam home too :)

[geeknotes] JSON DB

When I first learn’t about the json format, I thought: “what a great idea!”.

All the great things about it- simplicity, leanness, exactly what xml wasn’t but ought to be.

Soon I reasoned that the json format can be persisted in storage in its own form. One can build a simple, portable database using json records with minimal code.

“Why hasn’t anyone else built it?” I thought.

(sketch from couchdb’s site)

Well, now we have CouchDB, a document based storage project by apache and Cloudant, for your couchdb cloud needs.

[geeknotes] Repairing a Broken MJPEG AVI

file created: 2009-05-24 14:09
file size: 514 MB (538,972,160 bytes)

Fixing Broken AVI Header

Its kinda sad. We drove over 4 states (5 if we count montana) for over a day (another half to get to old faithful), setup my equipment, and when the recording of the eruption was almost over, I tripped over my own cables which caused this laptop to crash to the floor while recording the video to crash , with the battery pack disengaged.

Maybe its one of those times my heart dropped together with my items, but since the rugged laptop still manage to boot, and some hope lied within me that I would be able to recover the video one day. While I thought streaming broken video files were no big deal, it wasn’t so easy. My usual tools- media player classic, virtualdub, videolan etc were unable to play this file at all. It wasn’t until yesterday I attempted to rescue this file again.

1st I tried this open source “DivFix++ is #1 AVI Video Repair & Preview Utility” called DivFix++. While it managed to detect FourCC frames, the resulting video file was still unplayable. Okay let’s take a step back. Then because the Canon 40D I was using have officially has no video features, I used the open source EOS Video Record which allowed some form of video recording if the camera was tethered to a pc.

EOS Movie Record saves the resulting video in a MJPG format, so I tried figuring if JPGs could be extracted from the motion video file. I tried looking for MJPG2JPEG converters but none existing other than 2 examples of source codes here and here. I also started to examine and studying the file structures of AVIs, RIFF, JPEG etc, and with the help of a hex editor (the freeware HxD works great ), started digging around the file.

So when I’m peeking around the file at HEX Offset 04F0000 or human friendly number 75431936, the viewer showed full of zeros. Not a good news, because it meant there was not data beyond that point (buffer were not flush). From my estimation, based on file sizes, what was an approximately 2minute video is probably a sub 20s video. Which makes me feel like rewriting the subject as: “repairing a broken heart”, but read on…

I noticed DivFix++ almost generated a 75MB file which i meant it must have found the same errors I suspected and strip them off. So using the software did not entirely gone to waste. On examining the headers of the file, I found it empty which is a pretty good reason that nothing could play this file. I then remembered that EOS Movie Record writes the video headers only after recording. So following the avi riff structure, I copied in header values like frame rate, resolution etc, and eureka, the video became playable.

So, its not too sad and not all’s lost. The badly abused laptop (actually my mom’s and the 1st laptop I used much) still survived, I managed to recover 16s, and learn a couple of things about video file formats. And my photography apprentice of that day Ben Chua did took some photos with my spare camera.
Old Faithful, Yellowstone

p.s. You might be able to see the short segment of the recovered video below.

An Email For Singnet

Dear Singnet,

I’m a loyal Singnet customer for more than 5 years. My ID is ****** and my IC no. is ******. I would firstly like to thank you for providing me and my family with our internet connectivity these years.

I’m writing in to describe my less than happy experiences in getting my broadband internet plan renewed. I’ve been to but have not made the decision on what to select even though I’ve been thinking about the 5Mbps plan.

I spared some time one afternoon to call the singnet helpdesk, after navigating the usual automated telephone system, and waiting to connect my line to an operator, I asked for the details of my current plan, including how much I’m paying monthly. The operator said he would check it out and ask me to hold on the line, which I did. After listening to some music and voice promotions, the line was dropped. Upset, I made no further attempt to call in that day.

I tried to settle my recontract matter again when I was in Woodlands at the recent Singnet roadshow. After a long queue, I was asked by a promoter to do the recontract at home. Not willing to hold up others waiting, I inquired if he knew of other promotions that are offered. He said that there would be a roadshow somewhere in March, I replied that my contract would be ending before then and took my leave.

Now, here’s what I do not understand and hope you would give me some answers. Why are new customers getting better offers and existing customers like me have to resist the temptations to switch providers. Take the case of the roadshow which offered movie tickets (and free registration) to new users in addition to the same offers we get in the recontract plans (I don’t even need the extra value added services). If I wanted the free goodies of a new sign up, I could have terminate my contracts and get another of my family member to sign up a new contract.

What do you suggest I do? Should I terminate at the end of my existing plan or revert to normal charges while I wait for new promotions? Or perhaps there are other offers that I can consider to renew my plan? Its interesting to note that I’ve paid less than $10 (with my loyalty rewards deduction) when I signed up Singnet years ago when I was a student. Today, I’ve have yet to complete studies, but I paying few folds more than previously. Its true that the speed I get now is different from what I get from before, in comparison however, hardware prices drop for an increase in value.

I’m not trying to say that Singnet is like the Microsoft with its unethical FUD practices, providing crippled services then increasing the prices for some improvements, but I have some concerns above that can be addressed.

I looking forward to hear from you, please contact me by phone ****** or mobile ******.


Update 1:
The singnet has closed the email that I could write in previously. Therefore, I’ve been made to use their online form and that’s why I posted this here (I seldom want to do complains). Their automated email is below.

Dear Valued Customer,

Thank you for your email.

We apologise for any inconvenience caused by the closure of this
mailbox. To streamline and improve our processes, we have set up an
online form for our customers to share with us their comments and views
or to find out more about our services.

We would appreciate it if you could complete the form at and we
will reply to you within 3 working days.

For SingNet promotion enquiries, you may contact our Customer Service
Officers at 1610 from 8.00 am to 6.00 pm on Mondays to Saturdays
excluding Sundays and Public Holidays.

For technical support, you may call the following hotlines:
Dial-up 1800-7334133 9 am to 6 pm Mondays to Saturdays, closed Sun/PH
Broadband 1800-8486933 8 am to 12 midnight daily
JetPack 1900-9152829* 8 am to 12 midnight daily
Magix 1800-8486933 8 am to 12 midnight daily

* Calls are charged at 30cents per minute.

Thank you

Yours Sincerely,

SingNet Email Support
(this is a system automated reply)

SingNet Homepage :
Customer Care :
Internet Security :
Update 2 (1 March)

So Singnet got their Recontract Team to contact me. Not much was offered to me, I was even surprised that they started billing normal rates even before my promotional contract ended. However, I was asked to consider the new Mio plan which have more savings as the mobile, home phone and internet lines are combined – very likely in a move to compete with Starhub plans. Also the lady that spoke to me said I could wait for the next roadshow to consider my plan and get back to her. Maybe that’s the most they could do, maybe they aren’t too bordered.

Update 3 (2 March)

I went into a SingTel / Singnet shop at Bedok to enquire about MIO plan. The dealer was a nice guy who took time to explain and check up if I could convert my existing plans. The benefits are cheaper rate with a combined bill, unlimited local calls using their digital voice, all connected to their wireles “mio box”. The catch I’m guessing is that I guess there are limitations to the mio box. Their contractors would come down to install, if you need an extra telephone jack/extension then extra payment have to be made. Others factors include whether their box work with my router?

Also if there’s a blackout, I guess digital voice will fail, I suppose they expect you to use your handphone then (Then again, you won’t get the unlimited wifi/voip with mio in that situation). Well, I still have to consider. Some other webpages shows negative and positive remarks.

A Singaporean’s (Bad) Experience with Singtel’s MIO

Official Singtel Generation MIO Thread at HardwareZone

Converting Batch of NWCs to MIDis to MP3 to CD

1. Preparing NWC files.
2. Save as Midis
3. Convert Midi to Wave/Mp3
4. Burn the Files

Step 1: Preparing NWC files.
Find available nwc files on the net, otherwise creating, composing, importing, transposing or editing songs in NWC is relatively easy.

Step 2: Save to midi
If you have noteworthy composer, you can save the song as a midi file. Otherwise, or if you prefer batch processing, you could try my converter.

Step 3: To convert midi to wav/mp3 you need a software synthesizer.

SynthFont is a great windows freeware which uses SoundFonts to render the wav/mp3s. TiMidity is the popular open source software synthesizer on multiple plateforms.

Side note: Other cool free MP3 tools are Audacity, Messer & RazerLame

Step 4: Burning to CDs
Most general purpose Cd writing software and many free utilities would support creating audio CDs with mp3s or wave.