Sound effects – clicking noises!

February 10th, 2013

Today I spent a couple hours struggling with an annoying “clicking” noise that was showing up in my Asteroids Runner game when an asteroid got destroyed. It was somewhat sporadic and difficult to debug; early on in a game the noise was very common, and then it got less common as the session went on. How could this be?

The first thing I tried was implementing proper pre-loading of sound files, figuring that maybe there was a loading issue happening the first few times the sound played. ImpactJS handles this pretty well, letting you either load sounds at runtime (probably a bad idea), or using a sound manager to preload them:

ig.soundManager.load('media/explosion.mp3', true);
ig.soundManager.load('media/laser.mp3', true);
...
var deathSound = ig.soundManager.get('media/explosion.mp3');
deathSound.play();

This seemed to smooth out the first few sound effects which was a nice gain, but it didn’t actually solve the clicking problem at all!

Next I ventured into Audacity to try to learn more about what might be causing the noise. A little experimentation with various sound effects made it clear that abruptly stopping a sound (any sudden change in volume) can lead to that clicking effect, so I went off in search of any code path that could cause sounds to get stopped early.

I made the Sound objects multi-channel so that the browser is able to play them on top of each other, theoretically preventing a case where a sound is stopped early because a new one needs to start. This seemed to improve the overall sound quality but the click was still there. I was able to tell this working by logging which channel was being used in the Javascript console:

console.log("Returned channel #" + i);

So after circling the long way around the problem trying to find the bug in my code that was causing this, I dug back into Audacity and after playing various chunks of my explosion sound over and over, I came to an embarrassing realization: the clicking sound was actually in the sound file itself. It was an artifact of the original freeware sound I had downloaded. My code, instead of causing the bug, was actually just covering up the issue in many cases!

Example of a sharp volume change that could lead to a clicking noise when played at full speed

So after another web search for publicly usable sound effects and some rewiring and damping of the new explosion sound, Asteroids Runner is click free. It now has better initial performance and smoother overall sounds to boot!

 

Asteroids Runner – first look

February 2nd, 2013

After a few weeks of work, I’m finally ready to put up an early prototype of a little game I’ve been working on. It’s a vertical scroller that you control with the arrow keys and spacebar (definitely doesn’t work on a mobile device at this point). Everything is pretty rough at this point, but the basic idea is there. You can play it here: http://letxbe.com/AsteroidsRunner/

This is an exercise in using purely Javascript and HTML5 to make a game that’s portable to most platforms. Theoretically I can package it up so that it runs as an application anywhere. The only requirement is a fairly modern browser underneath (Internet Explorer 9 or later, equivalent for Chrome/Firefox/Safari).

It’s been interesting to learn a new Javascript framework and figure out how to program into it – the low-level graphics and input code is pretty much taken care of, so I get to spend all my time drawing graphics and writing the code for the behavior of each object. That’s turning out to be quite complex, particularly getting the input and movement of the player ship just right. There’s a lot of subtlety to getting it to accelerate/decelerate exactly right depending on the keyboard input.

Big stairs, little person

January 28th, 2013

Today I got to experience the joy of watching my baby girl climb stairs after dinner. This is one of my favorite things to do these days. I’m sure it will turn out to be just a phase for her and she’ll soon move on to other challenges, but right now she’s fascinated with learning the mechanics of the climb.

The thing that surprises me most is how much thought she puts into each movement. I had always generally assumed that babies just sort of ambled about randomly and only discovered how to crawl, walk, and climb by accident, but now I’m not so sure. In a scary environment where she understands that every move matters (don’t worry, I’m right there ready to catch her the whole time), she’s much more deliberate and thoughtful. When she gets herself stuck in a precarious position, she then has to think about what limb to move next and where to lean to get untangled. Those few seconds where she freezes and I can see her slightly shift her weight around test each handhold and foothold are a precious window into how much control and understanding she has of the way her body works and moves.

The immediate analogy that springs to mind in the Internet age is the online game QWOP. If you haven’t played it, go try it for a few minutes. I guarantee that it will make your day more interesting. To me it’s a powerful reminder of how impressive the human subconscious mind is and how much effort and calculation go into the everyday actions we don’t usually think about at all. To the conscious mind, an act like walking down the street is simple: one foot in front of the other. But this only works because the subconscious mind has learned through painstaking repetition how to move a dozen different muscles in a pattern that abstracts away the conscious mental concept “one foot forward”. Even before we’re old enough to begin to understand how we learn, we’ve already put thousands of hours into mastering an abundance of low-level skills that are just as deep and intricate as the trades, arts, and hobbies we usually spend our adult days thinking about.

It’s hard work being a baby. My daughter’s work ethic is rather stunning considering the relative scale of her movement and the amount of motor development she has to do. Imagine spending your entire day using and stretching muscles that are completely exhausted from being used and stretched the day before; it’s no surprise at all that babies can sleep like the dead every night for twelve hours and still nap twice a day. There’s a big difference between sitting and walking around with well-developed adult muscles and the baby-equivalent of training for a triathlon for six hours a day. Compared to what she goes through and how hard she pushes herself, even an exhausting day for me running around the office is easy stuff. If I worked as hard as she did, I’d get cranky around bedtime, too.

Responsive web design

January 24th, 2013

Today I decided it was time to join the revolution and do some redesign of my site so that it renders reasonably well on a mobile device or a small screen. My old design had some issues when the horizontal resolution of the viewport got below 960px or so, which is not a good limitation to have when we seem to be fast approaching the point where more users browse the web on a device than on a PC.

I used the techniques described in Shay Howe’s guide here: http://learn.shayhowe.com/advanced-html-css/responsive-web-design to add some custom CSS for the case where the viewport is less than 975px wide, and some even more extreme handling for viewports less than 650px:

/***********************
*** MOBILE TRANSFORM ***
***********************/
@media all and (max-width: 975px) {
	#sidebar {
		width: 100%;
		position: relative;
		top: 0px;
		right: 0px;
	}

	html {
		word-wrap: break-word;
	}

	img, .mceTemp, .wp-caption {
		max-width: 100%;
	}

	#page {
		margin-left: auto;
		margin-right: auto;
		width: 95%;
	}

	.narrowcolumn {
		width: 90%;
	}
}

/* on very narrow devices, collapse the margins completely*/
@media all and (max-width: 650px) {
	body {
		margin-left: 0px;
	}
	#page {
		margin-left: 0px;
		margin-right: 0px;
		width: 100%;
	}
	.narrowcolumn {
		width: 99%;
	}
	.post {
		margin-left: 0px;
		margin-right: 0px;
		padding-right: 0px;
	}
}

What this does is basically:

  1. Move the sidebar to the bottom of the page
  2. Cap the width of images at 100% of their parents’ width
  3. Set the post content to fill 100% of the page width, instead of just being centered

I struggled for a while with device pixel density and trying to get fancy with different sets of styles for “retina” devices, but it turned out to be a dead end. I think I was mistaking issues with viewport width for pixel density issues, and manually setting the viewport width=”device-width” was the best fix I found (fortunately I have control over the markup in PHP).

SVG drag-and-drop: more features, organized, and up on GitHub

November 10th, 2012

Today I did some organizing and refactoring on my SVG drag-and-drop framework. It now supports picking up any of multiple children, and is sorted nicely into class files that it ‘imports’ right before use. As far as I can tell my solution differs a little bit from others around the web in that it represents the children and parents as Javascript objects, encapsulating the movement logic inside. I believe it would be more reusable since there’s very little code in the top-level Javascript that actually knows about the SVG document.

Here’s the script that’s specific to this example:

//Import the classes we need
importClass("scripts/svg_lib.js");
importClass("scripts/svg_movable_parent.js");
importClass("scripts/svg_movable_child.js");
//Instantiate and link all the objects
window.onload = function () {
 //define the object that can be dragged
 var myTriangle = document.getElementById("myTriangle");
 //secondary element that can be dragged
 var myTriangle2 = document.getElementById("myTriangle2");
 //specify the region in which dragging should work well
 var myParent = document.getElementById("svgHost");

 var movableParent = new com.SVG.MovableParent;
 var movableTriangle = new com.SVG.MovableChild;
 var movableTriangle2 = new com.SVG.MovableChild;

 movableParent.Initalize(myParent);
 movableTriangle.Initialize(myTriangle, movableParent);
 movableTriangle2.Initialize(myTriangle2, movableParent);

 movableParent.AddChild(movableTriangle);
 movableParent.AddChild(movableTriangle2);
};

Everything else is hidden away inside the svg framework classes. All of the code is up on GitHub, and you can play with the demo itself here.

Fridge-Mounted Shopping List

October 5th, 2012

Last weekend I added a new angle to a project I’ve been working on for a while: easy shopping list functionality for the family. Previously I had created the AJAX web app that we use on our smartphones, and we had been entering new items on the phones as well.

To take this to the next level, I decided to repurpose my old Nook Color (it’s pretty much unusable for much of anything now) and make it a dedicated shopping-list-entry device.

Neodymium magnets superglued to the back of the nook. The soft, rubbery surface made the superglue bond amazingly well - there's no way I could pull these magnets off.

I could have used a pre-built fridge mount, but it didn’t seem worth the cost and I wanted to include at least a little bit of DIY. Fortunately, these little 0.3″ magnets worked well. I was a little surprised that I needed so many given the amazing apparent strength of these little guys. I guess sideways force (from gravity) is not their strong suit. With six of them glued on, it stays up even with the door opening and closing and use of the device.

Fortunately CyanogenMod has a custom override setting that can prevent the Android device from ever locking the screen if it’s plugged in to a power source, so no special tweaking was needed for that part.

Here’s the device in action:

Built-in shopping list. Run out of something? Just type it in after you close the fridge door. Automatically synced to our smartphones through the web app.

And here’s the list:

Close-up of shopping list

So far it’s worked well in the week since it’s been up and we’ve given it a couple test runs. I just need to come up with a more permanent cable management solution for the power cord – maybe some kind of magnetic clip to make it nice and straight.

SVG Drag and Drop

September 22nd, 2012

This week as part of some prototyping for work, I put together a quick demo of an SVG path element that can be dragged by clicking and holding.

I also did a little experimenting with some object-oriented Javascript and was very happy with how it turned out. The “Movable” object could be used to drag any SVG element as long as you know what its DOM parent is.

I put it on “CSSDeck” (although locally I’m just running on my machine with Coda), which is a pretty cool little site that lets you host up a demo with minimal effort. Here’s the link: http://cssdeck.com/labs/paradigm72-svg-drag/0

Coda Trial

July 19th, 2012

I had a little time this week to take another pass at OS X and thought I would give Coda another try given all the rave reviews I’ve read of it.

I had previously downloaded the 7-day trial a couple months ago and figured it would be expired, but I fired it up any way just to check and got a nice surprise:

It turns out the trial is “7 days of actual use”, so I wasn’t punished for being too busy to get back to it until now. I’m fairly impressed that Panic took this extra step to program a mechanism for tracking days of actual use, a feature which would only benefit demo users. Very nice sign of polish.

 

After a fair amount of tinkering and a few frustrations (there really should be guidance about what “Remote Root” means, since it’s really more like “Remove relative path”), I got everything connected the right way. The result on a 27″ screen once you figure out how to actually add 2 vertical splits is impressive:

HTML, CSS, Live Preview, Webkit inspector, and sidebar visible at the same time in Coda

This beats any setup I was previously able to piece together using text editor windows, Chrome, SourceTree, and CyberDuck. It gets very, very close to showing everything I need to do all my editing and testing on a single screen. There’s still some tab switching, but enough of the context is maintained that it preserves flow far better than rearranging windows.

Still a few days left to go on my trial – with a $75 price tag I definitely need to be as sure as possible that there aren’t any nasty surprises or incompatibilities. But so far I’m very impressed and leaning towards “buy”. Coda’s website is here: http://www.panic.com/coda/

Theme update

July 14th, 2012

Today felt like a good day to play around with CSS and fix some of the weird styling problems with this site, so I gave it an overhaul. The big wins were fixing the vertical alignment of the sidebar, finding a nice tiled linen image for the background, and switching to the very slick “Helvetica Neue” font.

If you’re viewing this on an RSS reader, go to the main site to see the new layout: http://www.letxbe.com/

You can get at the stylesheet directly at: http://www.letxbe.com/wordpress/wp_letxbe_style.css. I’ll try to get it up on Github soon and maybe even publish it as an installable WordPress theme now that I’m pretty happy with it.

Check for write permission!

May 22nd, 2012

A few days ago I was making updates to my shopping list web app, reorganizing the pieces into a directory structure more logical than just “everything dumped in the top-level directory”.

After a quick round of updating all the file linking to point into the right subdirectories (including a few minutes of head-scratching to remember that I needed to prepend “..\” to hop between them), I had it partially working.

I went back and forth between the pre- and post-cleaned up revisions in git, and it seemed that no matter what I did, the cleanup broke all of my PHP scripts except the one that retrieved the list contents. All of the scripts that tried to modify the list (adding to it, removing from it, or modifying an entry) failed and didn’t do anything.

I double-checked that file paths were correct. I did copy-pasting between the working and non-working scripts to try to rule out possible causes. I even did as much line-by-line debugging as I could in Chrome, which wasn’t all that much since the failure was in the server-side PHP and not the client code.

Ultimately I had it narrowed down to a state where as far as I could tell, there was no logical difference between the retrieve script and the rest of the scripts; but still only the others failed.

Finally I realized my error:

Default permissions when I create a new folder under /Users/ in OS X

The new “/lists”  subdirectory that I had created could not be written to by the server process, because by default, new directories I create don’t have that permission flag set. So it ended up being not a code issue at all, just a directory configuration problem. Something to watch for!