Coding Math: Episode 13 – Friction

Feb 11 2014

Send to Kindle

I figure I might as well post these here too. Just in case people aren’t aware of them. :)

Send to Kindle

No responses yet

Coding Math Application Series

Feb 10 2014

Send to Kindle

Last week I kicked off a new series on the Coding Math Channel. It’s the Application series.

I was thinking that it’s nice to present new concepts in each video, but there is a limited amount that I can do with them. I try to make the main episodes be 10-15 minutes long. I can explain a concept, do a few drawings, show some math, write some code, see it in action, and maybe iterate on that once or twice. And then, that’s it for that topic. Hopefully the brief example was good enough, because I’m moving on to something else now.

So my thought was to start another series where I actually build some simple app or game, or at least the barest outline of such. With some real world applications of the principles that are covered in the other videos. Each video will be in the five minute range, adding just one or two small features to the current app or game. Each feature may make use of one or more of the concepts from the other videos.

The first game is something I call Ballistics. It’s just a simple idea where you aim a gun and it shoots a cannonball that you try to hit a target. Like the old QBasic game, Gorillas.

gorilla2

In the first episode, we use a bit of trigonometry, including arctangent, to aim the gun using the mouse. In this week’s upcoming episode, we’ll actually get a cannonball firing, so that will use the particle class, with velocity and gravity, and lots more real world application of trigonometry. But each one is a bite sized piece of an application. We might hit the same concept over and over in different parts of the same app, or in different apps. But that’s the whole idea, to see many different ways you can use these concepts.

So now, we have the main episode each Monday, a Mini episode – shorter 5-minute simple concept – on Wednesday, and these Application episodes on Friday.

I want to thank all of you who have supported me on Patreon.com. It really makes doing these videos more justifiable in terms of the time I spend on them. And if you are a supporter, know that only the main Monday episodes are Patreon sponsored episodes. The Minis and Applications are on the house.

Send to Kindle

No responses yet

2013 in Review

Jan 01 2014

Send to Kindle

For the last few years I’ve done a year in review type of post near the end of the year. I guess I blew that already. But January 1st isn’t a bad time to do it.

2013

2013 brought a big change for me. After almost 6 years of working at Infrared5, I left there to work at Disney Interactive. It was a tough decision. I started at IR5 because the people there were my friends. And more friends arrived over the years. But the company had started as a Flash shop and with the slow decline of Flash, I felt it was facing an identity crisis. Long story short, I felt I was stagnating there the last year or two and needed to move on.

Moving from a small company to a massive one like Disney is tough. Oddly, I find myself back doing a lot of Flash work. But really touching all kinds of stuff – Objective-C, C++, C#, JavaScript, Unity, Java. For a month or so I became the go-to Jenkins guy, setting up build servers for a bunch of different teams. That was a lot of fun. It can get a bit frustrating being on a massive team where you only own a small portion of the code and other people are working on other parts. I honestly prefer smaller projects that I can start from scratch, do the architecture and then start fleshing it out, with another person or two helping to do parts. Thus far at Disney I’ve mostly been jumping around assisting in ongoing projects for a few weeks to months. A kind of strike force of one. But when I’m done with the current project I’m on, I have a project lined up for 2014 that I’m very excited to get onto. Nothing hugely glamorous, but something I’ll be able to start up myself and be a lead on.

Other than work, I’ve started a couple other projects. Of course there was Playing With Chaos. That took up a few months of my spare time, but was a ton of fun and hugely satisfying to be able to pull off the self-publishing of a book. One thing I’ve realized publishers are good for is publicizing your book and driving sales. So it hasn’t exactly been a runaway best seller, but honestly, I don’t think it was ever destined to be. It’s a niche title. A labor of love.

And I started the Coding Math video series. This has also been very satisfying and keeps me excited on a weekly basis, planning out new subjects, writing scripts, recording and editing. I’m almost at the point where my own voice in my own ears doesn’t sound like fingernails on a chalkboard to me. And learning lots about the process as well. I can see myself that the quality of the videos has come way up since the first one, but still has a long way to go.

Earlier in the year, I decided to build an arcade cabinet. This never fully materialized, but did spark a new interest in woodworking and an old interest in electronics. I dabbled in both a bit, but both got pushed aside when I started working flat out on Playing With Chaos. But both will come in handy for a new project I’ll be doing this year…

Personally, things are good. I ran my third marathon on my birthday in October. It wasn’t my best, but not my worst either. Since that race, running has taken a back seat for me. Marathon training is a four-month process that takes a lot out of you. I’ve gone through it three times in the last two years.So the last month or two I’ve taken a break. I’ve also gained some weight. So I start this year temporarily in the worst shape I’ve been in in a couple of years! But still, it’s better shape than I was in the previous 10 years.

I got a dog! I never was much of a dog person. Could take them or leave them. Some people at my last job believed I hated dogs. Not true. There were something like 5-6 dogs in the office and it was a major distraction all too often. Anyway, my daughter Kris has been dying for a husky for years. I kept saying no. My wife was on the fence. She finally joined my daughter’s side and they ganged up on me. So now we have a husky named Yuki. They promised to do all the work, including taking her for long walks twice a day. Of course, at this point, I am the chief dog walker. But this has had its benefits. At any rate, Yuki has totally changed our lives and is a really awesome addition to the family and home.

A husky needs a lot of walking. So I’m out with her 30-45 minutes or longer twice a day. This has lead to a couple of new hobbies. One is history. I’ve been into audiobooks for a while, listening during my long runs. But I started listening to history lectures from The Great Courses. You can get many of them on Audible.com and I can also get a lot from the library as well. (Side note: my use of the library has rocketed since I discovered that you can go on line and search for and order books, movies, and audiobooks from a huge network of libraries around greater Boston and suburbs. I can find almost anything if I’m willing to wait a week or three.) I’ve listened to a couple about the American Revolution, the Rise and Fall of the British Empire, The Fall and Rise of China, and the Rise and Fall of Soviet Communism in Russia. On deck are ones on Hitler’s empire, more about China, and the French revolution. And a few non-history subjects I wanted to learn about. It’s been a fantastic learning experience so far, and I’m able to bore my family to death with fascinating (to me) facts.

Also, while walking the dog at night, I started looking up in the sky. When I started, I could recognize the Big Dipper and Orion. And from the Big Dipper, I could sometimes locate the North Star. The rest was just random specs of light. But they were up there every night so I started looking closer. Tried a few different star chart apps, and settled on Stellarium. I just use the desktop app, spot a few things to look for before I go out, try to find them while I’m walking the dog, spot some other patterns while I’m out there and try to figure out what those were when I come back in. I have an app on my phone too, but it’s tough to use when you’re walking a dog and listening to history lectures. :) I got up to the point where I could find and name more than a dozen constellations and more than a dozen stars as well as other features, including Jupiter and Venus. This past week I started thinking of getting a telescope to take things to the next level. Much of what I read said to start with binoculars. So I got a half decent pair and took them out last night with my daughter. Holy cow! The moons of Jupiter, the Andromeda galaxy, the Orion nebula! I’m now honing up on telescope basics and reviews. I need one.

2014

So what’s in store this year?

1. I’d like to get out a printed version of Playing With Chaos. This requires formatting a decent PDF version, which I may sell directly in addition to the Amazon sales.

2. I have another self-publishing book idea that I started working on. This will be smaller and probably even more niche, but it has to be done. More on that if and when it moves forward.

3. Of course, I’ll be continuing on with the Coding Math series. Currently this is my top priority.

4. As hinted to above, I have another project in mind that will make use of both my electronics and woodworking skills (minor though they both may be). I’ve gotten started on this, but have some parts on order, will need to order more, and then will have various fabrication issues to work out. Taking this one slowly, but will report when there’s something to share.

5. More learning, learning, learning. Stars, planets, history, technology, etc.

To sum it up, I quote from the best New Year’s resolution tweet I’ve ever seen:

My new year’s resolutions:

1. Read
2. Write
3. Execute

#chmod777

https://twitter.com/bobspace/status/417799321921126400

Send to Kindle

No responses yet

Announcing Coding Math Video Series

Dec 12 2013

Send to Kindle

Those who know me personally, or have followed my work on this site for the last twelve and a half years (has it really been that long???) know that I go in and out of all kinds of programming subjects. From the early Flash experiment days I was always into math and physics and interactivity. I’ve created some fairly popular games (Falling Balls, Gravity Pods). I’ve enjoyed creating algorithmic art at www.artfromcode.com, of which several pieces have been published or used in various contexts. And I’ve had a couple of gallery shows with my art. I’ve coded various other mobile apps. I’ve created a couple of very popular UI component sets – BitComponents, which were purchased by a company called BeamJive and published under their own name, and later the open source MinimalComps, which enjoyed huge success and popularity. I’ve worked on various build and process management tools, such as STProjectMaker, which has been pretty popular itself. I’ve revived my love of electronics from my youth and have posted a few things on that, which people have found useful. And of course I’ve written a dozen or so books on coding and spoken at dozens of conferences around the world. This is all above and beyond any coding I’ve done in my day job. Not a bad hobby!

So I jump around a lot, but as time goes on, I’ve been struggling to figure out that one thing that really drives me. When all is said and done, I think it comes down to teaching and educating others. That’s the one thing that I keep coming back to. I love to learn something and distill it down to its basics and then teach others in a way that is way more clear and easy to understand than all the stuff I had to wade through to learn it in the first place. Even when I create some piece of art or a game, and don’t publish the source code for that, I still have an urge to explain to others how to achieve the same effect, or mechanic, or whatever.

That’s one of the things I initially loved about conference speaking. But more and more, conferences are highlighting the more inspirational speakers. “Look at all this cool stuff I did. Work hard and someday maybe you can be like me.” Even the more technical speakers are generally just promoting some methodology they subscribe to or framework they created. There’s generally little room for teaching or education other than the few full or half-day workshop spots that some conferences do.

Writing books is awesome, but is a long, drawn out, several-month process before anyone but yourself sees anything that you write. This is true whether you’re working with a publisher or just doing self-publishing. And then people need to go buy the book to get anything out of it. I’ll probably do some more self-published books, but they will be shorter form I think.

Blogging is awesome. Or was awesome. I guess I just got burnt out on blogging. Does it show? :)

Earlier this year I was dabbling in woodworking. Set up a basement workshop and started watching videos by this guy Steve Ramsey on his Youtube channel, Woodworking for Mere Mortals. I don’t do so much on the woodworking front now, but I still watch every video he puts out, because he is so freaking awesome.

So I got thinking, maybe I could do something vaguely similar with coding. And thus was born…

The Coding Math Channel!!!

That’s http://www.youtube.com/user/codingmath

I cover a lot of the whys in the first video, but from what I’ve seen, a lot of coders struggle with math. They understand the language they are writing in, but when they are doing a layout or an animation or some kind of effect, they get bogged down in what formulas to use or what numbers to feed in, or what to apply those formulas to. This is something that, for some reason, has always clicked for me. And apparently, once it clicks for me, I’m able to explain in a way that helps it click for other people. I realize I’m tooting my own horn here, but this is what many people have said about my books and talks and blog posts. So I believe them.

Anyway, I figured I’d try to go over some useful math concepts, particularly as they relate to coding – the bits of math that coders need to know and will find useful. And not just cover the math as a disconnected, abstract thing, but use that math in code to demonstrate some kind of effect that you could really use in your own day-to-day programming. The video format is great for being able to draw rough sketches in real time while explaining some concept, and then switching over to demonstrate that concept while coding in real time, then showing the results in the browser – in real time. A flow that is not nearly as smooth in a book or blog post.

As of this writing, I’ve got four videos up there. I held off promoting this until I had at least a bit of useful content up there. I’m hoping to do minimally one video per week, probably publishing it on Monday mornings. I have a nice list of topics to cover, and if there’s any specific things you’d like to see covered, shout it out.

I know the production quality on these isn’t awesome. But I’m a noob here. Learning a bit more about the recording and editing process every time I do one, so bear with me. I think it will improve. :)

Also covered in the first episode is the rationale behind using HTML5/JavaScript as a base for these lessons. I’m not counting out the possibility of using other languages in some episodes though, as appropriate.

So, there you have it. Hope you find it useful.

Send to Kindle

2 responses so far

Running Google Chrome on a High DPI Windows Machine

Oct 18 2013

Send to Kindle

Chrome is my browser of choice. I’ve just moved from an original Surface tablet/laptop to a Lenovo Yoga 2 Pro. Chrome was a bit touchy on the Surface. Or I should say not so touchy. The relatively high DPI screen with the small size caused it to work pretty poorly with touch. I think MS did some updates of their own which seemed to help, but it was still a pain in the neck. I’d be jabbing at the screen like an angry woodpecker sometimes, trying to click on a link.

Now the Yoga 2 Pro has an outrageously high DPI screen: 3200×1800. There’s a bit more physical real estate, but the current version (30) of Chrome was completely unusable on it form a touch screen viewpoint. Literally unusable. (Literally literally, not that new figuratively literally.) Taps on links either just wouldn’t work at all, or would be off by several hundred pixels and activate some link on another part of the page. I assume it’s got something to do with the scaling.

However, after digging around a bit, I found that there’s a setting you can start Chrome with that almost completely, if not completely, fixes this. You just add “–high-dpi-support=1″ to the command used to start Chrome. Night and day. Clicks register correctly with the first tap.

Update, makes it much simpler, and only have to do it in one spot.

1. Open Chrome, type “chrome://flags” into the url field.

2. Search for “HiDPI Support”.

3. Change to “Enabled”.

4. Restart Chrome.

5. Ignore the rest of this post! ;)

The rest of this post is still valid, but if you do the above, it’s unnecessary.

Now, all you need to know is where to put this flag to make sure that Chrome starts correctly. Basically, you need to find the shortcut that you’re using to start Chrome and add it to that. For this Windows 8 machine, I believe there are two ways I’m starting Chrome: a task bar shortcut and the start screen.

1. Task bar shortcut. If you have a shortcut to Chrome in your task bar, right click on it. You’ll see a quick list and near the bottom will be an item called “Google Chrome”. This is the actual shortcut that you need to change. Right click on that and choose properties, like in the picture below (you can click to expand these if needed):

chrome_properties

That will give you the shortcut properties dialog. In the Target field, you will see the actual path to chrome.exe in quotes. Just add the line –high-dpi-support=1 (note that it’s two hyphens before the word, high) after the quotes like in the next pic:

chrome_properties_2

Click OK to save and the next time you start Chrome with the task bar shortcut, you should be in high DPI mode. Yay.

2. The start page. If you have a Chrome tile on your Windows 8 start page, or you start Chrome by going to the start page and typing Chrome, you’ll need to do the same thing for another shortcut. I believe this one is also the shortcut that is used for apps that open Chrome when it is set at your default browser.Actually, any apps that open a link in a new browser will merely launch Chrome directly, without using a shortcut. However, if you already have a Chrome window open, apps will open links as a new tab in that Window, using the settings it was launched with. I guess the solution is to keep a Chrome window open? At least until this support goes mainstream. The shortcut should be located here:

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Google Chrome\

In that folder, you should see a Google Chrome shortcut. Right click on it, choose properties and do the same thing as last time.

If you have any other Chrome shortcuts or launchers, you’ll need to do the same thing there.

Hopefully, this will get addressed as some kind of automatic default in a future release of Chrome and this post will be obsolete. It’s also worth noting that Chrome Canary seems to work well on high DPI screens out of the box. So that’s promising for a future regular Chrome version. In the meantime, hope this helps you.

Send to Kindle

12 responses so far

JavaScript Audio Synthesis Part 3: Making Music

Oct 01 2013

Send to Kindle

First of all, I am not a musician by any stretch of the imagination. But that fact will become obvious all too soon. But if you’re going to make sound with code, you wind up either making sound effects or music. So let’s start with music. My goal here was to create a simple “tracker” application. You program in notes, it plays those notes back in progression to form a song. Of sorts.

I’m going to keep the song very simple. Mary Had a Little Lamb. It’s a song that you can play every note with one beat, so you don’t have to mess around with different length notes. Here’s a simple version of the song transcribed into notes and rests:

g f e f
g g g -
f f f -
g b b -
g f e f
g g g g
f f g f
e – - -

A quick search on the ‘net gives you the frequency values for the notes b, e, f and g, the only ones you’ll need for this song. Code that into an object:

scale = {
	g: 392,
	f: 349.23,
	e: 329.63,
	b: 493.88
}

And then you can just code the song as a string.

song = "gfefgg-fff-gbb-gfefggggffgfe---";

Now you can create an AudioContext and an oscillator and set an interval that runs at a certain speed. In the interval callback, get the next note, find its frequency and set the oscillator’s frequency to that value. Like this:

window.onload = function() {

	var audio = new window.webkitAudioContext(),
		osc = audio.createOscillator(),
		position = 0,
		scale = {
			g: 392,
			f: 349.23,
			e: 329.63,
			b: 493.88
		},
		song = "gfefgg-fff-gbb-gfefggggffgfe---";

		osc.connect(audio.destination);
		osc.start(0);

	setInterval(play, 1000 / 4);

	function play() {
		var note = song.charAt(position),
			freq = scale[note];
		position += 1;
		if(position >= song.length) {
			position = 0;
		}
		if(freq) {
			osc.frequency.value = freq;
		}
	}
};

Now this actually works and you should be able to recognize the melody somewhat. But it leaves a lot to be desired. The biggest thing is that there is no separation between notes. You have a single oscillator running and you’re just changing its frequency. This ends up creating a sort of slide between notes rather than distinct notes. And when there’s a rest, well, there is no rest. It just keeps playing the last note.

There are various ways to try to handle this. One would be to call stop() on the oscillator, then change its frequency, then call start() again. But, when you read the documentation, it turns out that start and stop are one time operations on an oscillator. Once you call stop, it’s done. That particular oscillator cannot be restarted. So what to do?

The suggested answer is actually to create a new oscillator for each note. Initially, this sounds like a horrible idea. Create and destroy a new object for every single note in the song??? Well, it turns out that it’s not so bad. There are some frameworks that create a sort of object pool of notes in the background and reuse them. But the downside to that is that every note you create and start continues playing even if you can’t hear it. It’s your choice, and I suppose you could do all sorts of profiling to see which is more performant. But for Mary Had a Little Lamb, I think you’ll be safe to create a new oscillator each time.

To do this, make a new function called createOscillator. This will create an oscillator, specify its frequency and start it. After a given time, it will stop and disconnect that oscillator. You can then get rid of the main osc variable in the code and call the createOscillator function when you want to play a note.

window.onload = function() {

	var audio = new window.webkitAudioContext(),
		position = 0,
		scale = {
			g: 392,
			f: 349.23,
			e: 329.63,
			b: 493.88
		},
		song = "gfefgg-fff-gbb-gfefggggffgfe---";

	setInterval(play, 1000 / 4);

	function createOscillator(freq) {
		var osc = audio.createOscillator();

		osc.frequency.value = freq;
		osc.type = "square";
		osc.connect(audio.destination);
		osc.start(0);
		
		setTimeout(function() {
			osc.stop(0);
			osc.disconnect(audio.destination);
		}, 1000 / 4)
	}


	function play() {
		var note = song.charAt(position),
			freq = scale[note];
		position += 1;
		if(position >= song.length) {
			position = 0;
		}
		if(freq) {
	 		createOscillator(freq);
		}
	}
};

This sounds better already. Each note is distinct, and when there is a rest, no note plays. But you can do even better.

The notes are just flat tones at this point. You can improve this by giving them a quick and dirty sound envelope. In real life, a sound doesn’t usually just start at full volume and cut out to silence when its time is up. The volume usually ramps up a bit first (the attack) and fades out quickly or slowly (the decay). Actually, sound envelopes can be much more complex than this (http://en.wikipedia.org/wiki/ADSR_envelope#ADSR_envelope) but a simple attack and decay to 0 will do fine for now and give the notes a much better sound.

As a sound envelope controls the volume of a sound, you’ll need to create a gain node. Do this inside the createOscillator function:

	function createOscillator(freq) {
		var attack = 10,
			decay = 250,
			gain = audio.createGain(),
			osc = audio.createOscillator();
...

The attack and decay values there are in milliseconds. This means that the sound will ramp up from 0 to full volume in 0.01 seconds and then back down to 0 in .25 seconds.

Next, the gain node will need to go between the oscillator’s output and the destination in order to control the volume of that oscillator.

		gain.connect(audio.destination);
		gain.gain.setValueAtTime(0, audio.currentTime);
		gain.gain.linearRampToValueAtTime(1, audio.currentTime + attack / 1000);
		gain.gain.linearRampToValueAtTime(0, audio.currentTime + decay / 1000);
...

First you set the gain to 0, which in essence sets the volume to 0. You do this with the setValueAtTime method, passing in the current time from the AudioContext object. In other words, set the volume to 0, NOW.

Then you use linearRampToValueAtTime to set the attack and decay. This says go from whatever value you are currently at and interpolate to this new value so that you arrive there at the specified time. Note that the values you pass in here are in seconds, so you’ll need to divide by 1000 when using millisecond values.

Finally, you connect the oscillator to the gain, set the frequency and start it. And of course, when you clean up, you’ll need to disconnect everything as well.

		osc.frequency.value = freq;
		osc.type = "square";
		osc.connect(gain);
		osc.start(0);
		
		setTimeout(function() {
			osc.stop(0);
			osc.disconnect(gain);
			gain.disconnect(audio.destination);
		}, decay)
}

The final code is below:

window.onload = function() {

	var audio = new window.webkitAudioContext(),
		position = 0,
		scale = {
			g: 392,
			f: 349.23,
			e: 329.63,
			b: 493.88
		},
		song = "gfefgg-fff-gbb-gfefggggffgfe---";

	setInterval(play, 1000 / 4);

	function createOscillator(freq) {
		var attack = 10,
			decay = 250,
			gain = audio.createGain(),
			osc = audio.createOscillator();

		gain.connect(audio.destination);
		gain.gain.setValueAtTime(0, audio.currentTime);
		gain.gain.linearRampToValueAtTime(1, audio.currentTime + attack / 1000);
		gain.gain.linearRampToValueAtTime(0, audio.currentTime + decay / 1000);

		osc.frequency.value = freq;
		osc.type = "square";
		osc.connect(gain);
		osc.start(0);
		
		setTimeout(function() {
			osc.stop(0);
			osc.disconnect(gain);
			gain.disconnect(audio.destination);
		}, decay)
	}

	function play() {
		var note = song.charAt(position),
			freq = scale[note];
		position += 1;
		if(position >= song.length) {
			position = 0;
		}
		if(freq) {
	 		createOscillator(freq);
		}
	}
};

Now the notes have a more bell-like sound. It’s not awesome, but it’s a whole lot better. Mess around with trying to create different envelopes to see how that changes the sound. Code in your own song strings too. Don’t forget to add any additional note frequencies that you might use. You might even want to do something with allowing more than one-beat notes, though that starts to get a bit more complex.

Anyway, this is pretty rough and dirty code. A whole lot that could be improved upon here, but it’s good for demonstration purposes and hopefully gives you a better understanding of the underlying fundamentals than a more complex structure would. Have fun with it.

Send to Kindle

3 responses so far

JavaScript Audio Synthesis Part 2: Interactive Sound

Sep 28 2013

Send to Kindle

In yesterday’s post I covered the bare bones basics of creating audio with the Web Audio API. In this post, I’ll demonstrate one way to start creating some interactivity.

One of the simplest and most dynamic ways to capture interactivity on a computer is by simply reading the mouse position. The strategy for this next experiment is to use the mouse’s y-position to control the frequency of a single oscillator. The code for this is super simple:

window.onload = function() {

	var context = new window.webkitAudioContext(),
		osc = context.createOscillator(),
		h = window.innerHeight;

	osc.connect(context.destination);
	osc.start(0);

	document.addEventListener("mousemove", function(e) {
		osc.frequency.value = e.clientY / h * 1000 + 300;
	});
};
 

Create an AudioContext and an oscillator, get the window dimensions, connect and start the oscillator and listen for mousemove events.

In the mousemove handler, e.clientY / h will be a number from 0 to 1. Multiply this by 1000 and add 300 and you’ll have a frequency from 300 to 1300. This gets assigned to the oscillator’s frequency value. Move your mouse around the screen and get different pitches. Simple.

Remember, the above has only been tested in the latest version of Chrome at the time of this writing. Other configurations may work; some may require some changes.

Now what about they x-axis? Yesterday you had two oscillators going. Let’s try to hook the mouse’s x-position to that second oscillator.

window.onload = function() {

	var context = new window.webkitAudioContext(),
		osc = context.createOscillator(),
		osc2 = context.createOscillator(),
		gain = context.createGain(),
		w = window.innerWidth,
		h = window.innerHeight;

	osc.frequency = 400;

	osc.connect(context.destination);
	osc.start(0);

	gain.gain.value = 100;
	gain.connect(osc.frequency);

	osc2.frequency.value = 5;
	osc2.connect(gain);
	osc2.start(0);

	document.addEventListener("mousemove", function(e) {
		osc.frequency.value = e.clientY / h * 1000 + 200;
		osc2.frequency.value = e.clientX / w * 30 + 5;
	});
};
 

This is much the same as the final code from yesterday, but now you’re using the mouse x- and y-positions to control the frequencies of both oscillators. Move your mouse all over the screen now and you’ll get all kinds of science-fictiony sounds. I picture a 1950′s flying saucer taking off, or maybe an alien ray gun. Mess with the frequency ranges of both oscillators and try changing the oscillator types for both – mix and match square, sawtooth and triangle waves for all kinds of interesting results.

Send to Kindle

No responses yet

Audio Synthesis in JavaScript

Sep 27 2013

Send to Kindle

This is something I’ve wanted to play with for a long time. So the other day I buckled down and started searching around.

Yes, you can create sound in JavaScript. In some browsers. Supposedly, it works in Chrome 14, Firefox 23, Opera 15 and Safari 6. Not IE. But, I’ve only tested this in Chrome. So for now, consider this something experimental and fun to lay with, not for your super awesome works-in-every-browser game.

I found several sites that had build up complex libraries based on the Web Audio API. These weren’t the greatest things to learn the basics from, but I eventually was able to pare some of the code down to the bare minimum needed to create some sounds in the browser. There’s also the MDN documentation here: https://developer.mozilla.org/en-US/docs/Web_Audio_API, which is a great reference, but not a step-by-step tutorial for creating sounds. There are a few tutorials linked to from there as well, but none really covered what I was interested in.

So, to get down to it, let’s create some noise.

First you need to create an AudioContext object. This is similar in concept to HTML5′s 2D graphics context for canvas. The context is the overarching object that you’ll use to create all the pieces that will create the sound you’re going to make. For Webkit-based browsers, you get an AudioContext like so:


var context = 
    new window.webkitAudioContext();

The AudioContext has a few properties, the most important one being “destination”. The destination is basically the output of the context, where the sound goes. You can think of it as your speakers.

audiocontext

The next thing you need to know about the Web Audio API is that it is a node based system. You use the AudioContext to create various nodes that are used to create and shape sounds. Nodes have inputs and outputs that you can use to hook various nodes together into different configurations.

The most direct way to create a sound is to create an oscillator node. An oscillator node has zero inputs and one output. You can hook that output to the destination of your context. You’ll also need to specify a frequency for the oscillator. 440 hz will create the musical note, A. Here’s the code:

var context = new window.webkitAudioContext();

var osc = context.createOscillator();
osc.frequency.value = 440;
osc.connect(context.destination);
osc.start(0);
 

And here’s how this looks from a node view:

oscillator

Yeah, it says “frequency: 500″. My goof. Not changing it. Live with it.

You have an oscillator node with a frequency of 440 connected to the destination of the AudioContext. Call start(0) and you should get an annoying sound coming out of your speaker.

The oscillator node has a couple of other properties. One is “type”. This is the type of wave it uses to generate the sound. It defaults to “sine”. But, you can try “square”, “sawtooth” or “triangle” and see how they sound by doing this:

osc.type = "sawtooth";

There’s also a “custom” type, but that involves creating and setting a custom wave table. If you’re into it, go for it.

Anyway, wasn’t that easy? Let’s expand on it and create another oscillator that messes with the first one.

To do this, you’ll create two new nodes, an oscillator node and a gain node. A gain node is usually used to change the volume of a sound, but you’ll be using it here to alter the frequency of the original oscillator node. You’ll also create another, slower oscillator node. This new oscillator node’s output will be connected to the gain node. A gain node has a single input and a single output. As the new oscillator goes up and down at a frequency of 1 hz (once per second), it will affect the output of the gain node. A gain node also has a value property. If you set that to 100, then the gain node’s output will cycle from +100 to -100 as the new oscillator slowly cycles.

Now you need to hook this +/- 100 gain node output to the original oscillator. But remember that oscillator nodes don’t have any inputs, so you can’t connect it directly to the oscillator node. Instead, you connect it directly to the frequency property of the node. Now that gain output will change the original frequency of 440 hz + or – 100 hz as it cycles. A picture is worth several hundred words.

oscillator2

One oscillator is connected to the gain node, which is directly connected to the other oscillator’s frequency. That oscillator is connected to the destination. Here’s the code:

var context = new window.webkitAudioContext();

var osc = context.createOscillator();
osc.frequency.value = 440;
osc.connect(context.destination);
osc.start(0);

var gain = context.createGain();
gain.gain.value = 100;
gain.connect(osc.frequency);

var osc2 = context.createOscillator();
osc2.frequency.value = 1;
osc2.connect(gain);
osc2.start(0);

Run that and you should hear a siren like sound.

You can also change the type of the second oscillator. Try making that a square wave:

osc2.type = "square";

square

Now, instead of cycling smoothly from +100 to -100, the gain’s output will be exactly +100 for half the cycle than jump to exactly -100 for the second half. The result is more like a siren you’d hear in Europe or the UK. It also drives my dog crazy.

Anyway, that’s the bare minimum. Check out the API at the link mentioned previously. There’s a lot more you can do with it from here.

Send to Kindle

No responses yet

Playing With Chaos is Published!

Sep 20 2013

Send to Kindle

At long last, the book is available for sale. It took a few days to get through all the copy edits and then a few last minute tweaks, then I hit the big old publish button. A few hours later, it was live … except in the US, Japan, India and Canada. I’m not sure if there is just some lag in the system for certain countries. I contacted support, they said they’d look into it and I never heard back, but the book soon went live on the US and Canadian stores. As of this writing it’s still listed as unavailable for purchase in India and Japan. It may resolve itself, but I’ll keep pushing on it anyway.

As mentioned previously, the whole process was a great experience and feels like a big accomplishment to have pulled it off from inception to being in the store, all under my own steam.

Anyway, go get it if this is the kind of thing you’re interested in. I hope you enjoy it. If so, it would be really nice to start seeing some good reviews stacking up there. :)

Send to Kindle

5 responses so far

Playing With Chaos, August Update

Aug 22 2013

Send to Kindle

The book is done! Well, not done, done, as in out-the-door done. But I finished all the chapters and all the code and all the images. I’ve worked over every chapter 2-3 times myself and now the book is over to a team of tech reviewers and a professional copy editor. This will give the book the final polish in both the technical sense, making sure the explanations are correct and the code works, and also in a spelling/grammar/style sense, making me look more literate than I am. I’m already getting some great feedback from the reviewers, and while my ego always takes a huge hit at this stage of the game, it’s all going to mean a higher quality book that hits your hands. I’m hoping to wrap up this stage of things in the next couple of weeks and have the book ready on Kindle by mid-September.

I just wanted to make a quick comment on the activity of self-publishing. It’s been an amazing experience! I’ve written or co-written something like 12 books before this, which has been extremely helpful during the process of writing my own book. I have a pretty good idea how to structure things, what voice to use, the importance of consistency, how the various workflows go, etc. But doing the whole thing by myself … the analogy that comes to mind, though it may not make sense to you, is that it’s like the first time you go on a big trip by yourself. Not Disneyland with your parents, or those school or maybe even business trips, but the first time you decide you want to go somewhere, you choose where you’ll go, book the flight, book the hotel, rent the car, pay for everything, put it on the calendar, pack your own bags, make it out the door on time without forgetting anything vital, arrive at your destination, have fun, and make it back home alive. It’s all you, and there’s a sense of pride that you handled it all yourself. OK, to be honest, I still feel that way when I book a trip myself, but anyway…

That’s what this experience was like. I decided to write the book, came up with the subject, didn’t have to get approval from anyone at any stage of the process. Came up with an outline, started writing, came up with my own workflows, got my own reviewers and editor. When working for a publisher, as edits come in, I always felt like, “OK, whatever. They want it that way, we’ll do it that way.” Particularly in the late stage copy edits. I’d get a marked up manuscript with a bunch of corrections and some questions for clarification. I’d answer the questions and for the most part just blindly sign off on the rest of it. This time around, it’s so intimately my own creation that there’s a very different feeling that goes along with it. Any change I make that’s based on someone else’s advice is something I closely scrutinize. That’s not to say that I’m rejecting stuff outright, but I’m still 100% mentally involved in the process at this point and 100% focused, which is not always the case in the late stages of a publisher-controlled book.

Anyway, I guess it’s neither here nor there, but personally, it’s such a huge difference for me that I wanted to say something about it. At this point, I couldn’t imagine going back to a traditional publisher. Not that my experiences with them were bad – in particular, I always had a great time with the folks at Friends of ED – but being in charge of the process myself is so much better.

Send to Kindle

5 responses so far

« Newer posts Older posts »