My First Domain name

January 13th, 2010

The very first domain name I ever bought was tacoland.com. I accidentally let it expire and it was registered within days by a link farm company and then later sold to BuyDomains. man I hated them so much. Five years later I did some work for BuyDomains. I probably could have gotten it back cheaply, but I realized it was a stupid site anyway.

A few weeks after tacoland, I registered GrilledCheese.com, a site I still like but haven’t updated in like 9 years. Ah well.

iPhone Hardware Accessories Roundup

January 11th, 2010

It’s been about half a year since Apple announced that they would be allowing 3rd parties to develop integrated hardware/software applications for the iPhone. Here is a roundup of what has come out so far.

wwdc keynote 2009 screenshot

In my opinion, the most exciting announcement made at the 2009 WWDC was that the 3.0 version of the iPhone operating system would support integration with 3rd party hardware. Considering the number of stupid docks out there, I fully expected there to be hundreds of new accessories for the iPhone by the end of the year.

Here we are, a little over six months out, and I decided to dig around and see just what 3rd party hardware is out there with iPhone integration goodness.

Multimedia

L5 RemoteL5 IR Dongle
Turns your iPhone into a universal remote.
link to site
WowWee Pico ProjectorWowWee Cinemin Pico Projector
Small projectors are being touted by tons of hardware manufacturers. I have yet to see anyone buy one but maybe since this one works with the iPhone it will be the first.
link to site

Lifestyle

WakeMateWakeMate
This is an armband that monitors your sleep to wake you up at exactly the right moment in your cycle. Even more compelling to me than the waking up is that it monitors your sleep and makes nice charts of it on their web site.
link to site
PedalBrainPedalBrain
This is appealing because rather than try to invent new proprietary hardware this good looking bicycle mount reads data from standard Ant+ sensors on your bike to track everything you would want to know about your riding. The mount is carbon fiber which pretty much ensures it will cost a ton but also that I will buy one.
link to site
Ant+

Commerce

iCarte RfID ReaderiCarte RfID Reader
This one doesn’t get much press, but a cheap reliable RfID reader could be just what the RfID industry needs to get their technology into smaller businesses and retail shops.
link to site
SquareSquare
Square is getting a ton of press despite their newness in the industry and the fact that their dongle looks like absolute crap and plugs into your microphone jack. Of course, their software looks tip top and the company was started by Jack Dorsey of Twitter fame. I won’t be impressed until I see one work in person or they beat out the wikipedia entry for the word “square” in google rankings.
link to site
Verifone Payware MobileVerifone Payware Mobile
A much better looking accessory from a proven player in the payment processing biz, the press is largely ignoring these guys because they are all in love with Square. What will probably kill these guys is the fact that they are a very 1.0 company and generally a pain in the ass to buy services from.
link to site

Other

Nasa Chemical SensorNasa Chemical Sensor
As far as I know, this one isn’t available for sale but it is very cool to see that those way smart folks at NASA are out hacking up their own accessories. I recently watched a documentary about the Apollo Space program and wondered if you could now replace the 1975 NASA Central Command Center with a good iPhone app.
link to site

What I’d like to see

This is a good start, but I really hope and expect to see some crazy and varied 3rd party hardware add-ons this year.

  • A real barcode scanner, you know with a lazer and not trying to make the camera do something it doesn’t want to.
  • A voltmeter
  • An oscilloscope
  • Still no Dj accessories? Despite the billion iPod mixers, you guys can’t make an auto-tune mixer or something?
  • Um, lazertag guns
  • Expensive home automation systems, so people on MTV cribs can replace all the light switches in their house with iPhones.
  • Something that plugs into my power tools. Don’t know how, but surprise me. Chainsaw hero?

Simple Image Cropping with Flex

January 6th, 2010

Here is a simple, pure as3, image cropper I wrote for Flex. I’ll try do a post later in the week describing how to use it in Flash cs3 and cs4.

[kml_flashembed publishmethod=”static” fversion=”9.0.0″ useexpressinstall=”true” replaceId=”flex_image_crop” movie=”http://www.wirelust.com/apps/flex_image_crop/bin-debug/main.swf” width=”640″ height=”458″ targetclass=”flashmovie”]

screenshot for people without flash

[/kml_flashembed]

Features:

  • Very Simple
  • Allows you to set min and max values for height and width
  • Holding shift key keeps aspect ratio

You currently have to do the cropping on your own, either in flash or server side. I will followup later with examples of how to do that.

To embed this into you application, all you have to do is:

import com.wirelust.imagecrop.ImageCrop;
import com.wirelust.imagecrop.CropBox;
 
private var imageCrop:ImageCrop = new ImageCrop();
private function onCreationComplete():void {
	imageCrop.loadImage("demo1.jpg");
	
	// imageBox is an mx:HBox in my mxml
	imageBox.addChild(imageCrop);
	
	var crop:CropBox = imageCrop.cropBox;
	
	// Set up the initial crop
	crop.cropX = 178;
	crop.cropY = 187;
	crop.cropWidth = 249;
	crop.cropHeight = 219;
}

You can then listen for CropBox.EVENT_CHANGED to get the dimensions of the box as it changes:

private function onCreationComplete():void {
	// snipped ...
	
	crop.addEventListener(CropBox.EVENT_CHANGED, onCropChanged);
}
private function onCropChanged(event:Event):void {
	if (imageCrop.cropBox != null) {
		xValue.text = imageCrop.cropBox.cropX.toString();
		yValue.text = imageCrop.cropBox.cropY.toString();
		widthValue.text = imageCrop.cropBox.cropWidth.toString();
		heightValue.text = imageCrop.cropBox.cropHeight.toString();
	}
}

Files

 Download source code

Monty Widenius is trying to regain control of MySQL and why this is bad for OSS

January 2nd, 2010

One of the most widely discussed topics to go around the tech industry last year was the Oracle acquisition of Sun and what this meant for the MySQL database. This topic held up the merger with the US DOJ and currently has it stalled in the EU commission.

One of the primary forces behind these hold ups is a series of FUD articles written by Monty Widenius, the most recent just a few days ago. Monty has a huge following so whenever he writes up one of these articles it gets huge circulation and riles up the Slashdot and LAMP crowds.

I think that the open source community should be very skeptical about anything written by Monty on this topic, and should start looking at the big picture of what this merger means for themselves and the various players involved.

I don’t know why I haven’t been seeing many serious rebuttals to Michael’s posts. I can only guess that is because everyone working at Sun and Oracle are prohibited from speaking up on the matter.

Here is what I think everyone should consider:

1. Sun is the largest contributor to Open Source in the world

2. Java, which sun is responsible for, one of the largest ecosystem of open source software in the world.

IBM, RedHat, the Apache Foundation, Oracle, Google, and hundreds of other companies have based themselves on Java. Java is by far the most used platform out there today. Out of this wide adoption has sprung a massive open source ecosystem that can only be rivaled by Linux. I don’t have any studies but I wouldn’t be surprised if there was much more open source Java code out there than C.

The Java community in my experience, by and large, is very reluctant to touch anything that is not open source. In the past 10 years the community has moved from expensive application servers and IDEs to free alternatives. Projects like JBoss, Glassfish, Tomcat, Eclipse, and Netbeans are the dominant players in the space and have been driving the mindset that to be a player in this market you have to be free.

3. Sun is in trouble and risks going out of business if no-one buys it. Talks with IBM broke down, and there aren’t many other companies that can make a purchase.

Not much else to say here. Oracle has been having some rough years. Hardware sales are down and they’ve been spending too much on R&D. Sun needs someone to buy them and buy them quickly. They have been actively been doing layoffs that affect all of their open source efforts (including MySQL) while this drags out. Further delays, or the blocking of this merger will only further harm the OSS Community.

4. Oracle already owns Berkely DB and InnoDB, which current versions of MySQL rely on.

This same sort of noise and FUD was made years ago when Oracle bought these two products. Oracle has continued to maintain these and has been a more stable steward of the projects than when they were independent.

5. It doesn’t make business sense for Oracle to try to kill MySQL.

First off – MySQL does not compete with Oracle Database. Anyone who thinks it does does not understand what Oracle Database is. People that use Oracle tend to buy the whole oracle package (DB, App Server, IDE, Middleware, etc..). There are free alternatives to everything in this stack, including many products owned by Oracle but companies that want Oracle are companies that want the piece of mind that support for the stack brings.

There are no CTOs out there hemming and hawing about wether to use MySQL or Oracle. It would be like sitting around and trying to decide if you were going to buy a Ford Focus or an M1 Abrams Tank. I’m not using this analogy to point out that Oracle has many more features (it does) or that it is better than MySQL, only that it is different. You would never buy the tank to commute to work or for most of your driving needs. The same is true with MySQL, it is perfect for most projects and Oracle tends to be a little too heavyweight.

Furthermore, for companies that do insist on purchasing the Oracle stack but want to use MySQL would now be able to buy the support stack with MySQL in it. Oracle can now sell the complete support package and their customers can feel good about getting everything from one vendor. Companies that buy Oracle are most likely the companies that would be paying for MySQL support as well. If a customer comes to oracle, what do they care which database the customer wants to use when they own both.

The last thing Oracle would want to do is alienate a large developer community. Changing anything about MySQL would hugely upset not just the LAMP and Java communities but just about everyone on the planet. This is just bad business.

6. All Oracle will own is a trademark and some engineers.

The source code for MySQL is already free. Anyone can fork it off and start another project and attempt to gain community support around their new project. The only thing they can’t do is call it MySQL. Monty has already started one such fork called MariaDB.

Open source projects are about the community rallying around ideas, not around companies. Monty argues that a forked product could never compete with MySQL without the name recognition. This isn’t true. If the community feels that Oracle is doing a bad job as a maintainer, but someone else is releasing new features on some other project, people will switch very quickly. We see this all the time in the Linux world with the community switching from one fork to another of a large project.

Monty says that forks can never happen because they would need funding and resources. What this argument ignores is that large companies with a lot invested in MySQL could step up if the project is faltering. If Oracle were to stop releasing updates, do you think Google is going to sit around and do nothing? The community would jump ship to GoogSQL or whatever if it came to that and was seen as a better product.

6. Monty Widenius has the most to gain from Oracle divesting in MySQL.

Like everything else in the world, when there is an argument, you need to step back and ask yourself who has the most to gain. Widenius sold MySQL for a hefty personal gain and is now trying to wrestle back control by spreading fear throughout the MySQL community.

Monty has been making noise since September 2008 (before the announced Oracle-Sun merger) and complaining about the direction of the project. He didn’t feel Sun was doing a good job and started immediately calling for forks and and a change of direction. The community heard Widenius out but didn’t build up a ton of support for his ideas, because by and large, most people are satisfied with the job Sun is doing.

Right before the Sun ownership, MySQL was in the process of rolling out a non-free enterprise edition and telling people that they would have to pay for new features. The company I was working for at the time had MySQL sales reps and consultants flat out tell us that we would need to purchase a support agreement if we wanted to use the Falcon Engine or clustering past v5.5. Sun put a stop to this.

In Summary

I am not under any illusions that an Oracle-Sun merger would be all sunshine and roses. I think that Sun has developed a culture and business model around everything being open and free and Oracle has not. Oracle will need to make some big changes about how it does business in order for the merger to work.

I would prefer if Sun could remain an independent company but we have to face facts, Sun is in trouble and there aren’t many other companies that can bail them out. If Sun is allowed to continue it’s downward spiral then we are facing a great loss to the open source community.

I am not worried about the Oracle stewardship of any of Sun’s open source products precisely because of the community support. Oracle can’t afford to make huge changes and alienate hundreds of thousands of developers who have some say in how much money their companies give to Oracle. Doing something like killing or even changing GlassFish, VirtualBox, ZFS, or any other OSS project could lead to less sales in it’s existing stack of software.

[snippit] – generating a faux waveform in AS3

December 8th, 2009

Working on a Flash project. I had to use the microphone to record some audio and generate a simple waveform so the user has some feedback that they are being heard. While not a true waveform, you can use the microphone activity level to generate something that works pretty well.

[kml_flashembed publishmethod=”static” fversion=”9.0.0″ movie=”http://www.wirelust.com/examples/waveform/bin-debug/waveform.swf” width=”500″ height=”250″ targetclass=”flashmovie”]

Get Adobe Flash player

[/kml_flashembed]

Here is the code to generate the above sample:

import com.wirelust.waveform.Waveform;
import flash.media.Microphone;
 
private var wave:Waveform = new Waveform();
private var mic:Microphone;
 
private function init():void {
	wave.height = 50;
	wave.width = 450;
	wave.y = this.height/2 - wave.height/2;
	wave.x = this.width/2 - wave.width/2;
	this.addChild(wave);
	
	mic = Microphone.getMicrophone();
	mic.setUseEchoSuppression(false);
	
	// loopback is required so we can get the activity level and create the waveform. - so stupid
	mic.setLoopBack(true);
	
	// turn off the volume for the loopback
	var mySoundTransform:SoundTransform = new SoundTransform();
	mySoundTransform.volume = 0;
	mic.soundTransform = mySoundTransform;
	
	this.addEventListener(Event.ENTER_FRAME, onFrameEnter);
}
 
private function onFrameEnter(event:Event):void {
	if (mic != null && !mic.muted) {
		wave.add(mic.activityLevel);
		wave.invalidateDisplayList();
	}
}

And for the Waform class:

import flash.display.*;
import flash.events.*;
import flash.geom.Matrix;
 
import mx.core.*;
import mx.graphics.IFill;
import mx.graphics.IStroke;
import mx.graphics.SolidColor;
import mx.graphics.Stroke;
 
public class Waveform extends UIComponent {
	private var levels:Array = new Array();
	public var color:uint = 0x000000;
	public var borderColor:uint = 0xCCCCCC;
	public var borderWidth:uint = 1;
	public var autoScale:Boolean = true;
	
	public function Waveform() {
	}
	
	public function add(level:Number):void {
		// trim the levels so we don't keep eating up memory
		while(levels.length > this.width) {
			levels.shift();
		}
		levels.push(level);
	}
	
	override protected function updateDisplayList(param1:Number, param2:Number) : void {
		var scaleFactor:Number = 1;
		// autoscale will find the highest volume and scale all lines in the display accordingly.
		if (autoScale) {
			var highestLevel:Number = 0;
			for (var i:uint=0; i<levels.length; i++) {
				if (levels[i] > highestLevel) {
					highestLevel = levels[i];
				}
			}
			scaleFactor = height/2/highestLevel;
		}
 
		super.updateDisplayList(param1, param2);
		graphics.clear();
		graphics.lineStyle(1, color, 1, true, LineScaleMode.NORMAL);
		var lineX:uint = 0;
		for (var j:uint=0; j<levels.length; j++) {
			graphics.moveTo(lineX, this.height/2 - (levels[j] * scaleFactor));
			graphics.lineTo(lineX, this.height/2 + (levels[j] * scaleFactor));
			lineX++;
		}
		
		if (borderWidth > 0) {
			graphics.lineStyle(borderWidth, borderColor, 1, true, LineScaleMode.NORMAL);
			graphics.drawRect(0, 0, this.width, this.height);
		}
	}
}
}

Files

 Download source code

MBTA Bus Tracker Widget for OSX

November 24th, 2009
mbta bus tracker icon This is a widget for showing you real-time data about bus arrival times for a chosen stop. Using Next-bus satellite data you can have a very accurate prediction of when your bus is coming.

Currently, the following 5 bus routes are supported

  • 39
  • 111
  • 114
  • 116
  • 117

screenshot of MBTA Bus Tracker Widget

download icon Download Version 1.0

0x80070005 error when trying to create Scheduled Task in Windows 2003

October 12th, 2009

When I was trying to set up a scheduled take in windows 2003, I kept getting this error: 80070005 access is denied

A lot of googling and I found the following things to try if you are having a similar issue:

Local Security policy Settings

1. Open your local security policy control panel:
Start -> Control Panel -> Administrative Tools -> Local Security Policy
2. go to the folder:
Security\Local Policies\Security Options
3. check the following permissions:
Interactive logon: Require Domain Controller authentication to unlock – set to Disabled
Network Access: Let everyone permissions apply to anonymous users – set to Enabled
Interactive Login: Message text for users attempting to log in – clear this setting

That last one creates a popup message that appears when users log into the computer. I found that this causes problems with some but not all of scheduled tasks.

File Permissiosn

Check the file and folder permissions of whatever script you are tying to execute. Make sure that the user you are trying to run the scheduled task as has Read and Execute permissions for the script.

If your script is a .bat file, make sure the user has Read and Execute permissions for cmd.exe

If your script is a .vbs. file, make sure that the user has Read and Execute permissions for cscript.exe

Too many permissions, try an unprivileged user

With older copies of windows it was fairly common practice to run all scheduled tasks as Administrator or some other type of super user. Security policies tend to be tighter now and are often set to restrict users with too much power as logging on in batch mode.

Create a new user who is a member of only the default Users group. Grant this user permissions on the folders you need to run your scheduled tasks. Keeping this user out of the Administrators group will make your server more secure and might clear up the Access Denied error.

Stereoscopic camera

October 9th, 2009

Last month Gillian asked me to help her with an event that she had promised to shoot in 3D. I think I’ve gotten Gillian to adapt some of my “how hard could it be” attitude over the years.

After a ton of Googling, and realizing that that fancy Fuji3d camera wouldn’t be out in time. I decided to tether two Canon SD750’s using the plans described on this fine blog.

After getting all the parts I needed and set up, I chickened out when it came to soldiering wires directly to the internals of the camera. I am a little rusty with my soldiering and I had a 1 week deadline. If I ruined either of the cameras I wouldn’t be able to get another in time for the event.

Luckily, there is a whole community dedicated to exactly what I wanted to do and they had some simple solutions that didn’t require any permanent alterations to the cameras. A little bit of light soldiering and cutting and we were in business. The camera came out great and worked perfect for the event.

DSC00004.JPG

For the mount I used aluminum that I cut with a jigsaw and file, then riveted together. For the electronics all I needed was a few usb cables, an audio cable and jack, a momentary push button, and a 4 AA battery pack. All in all, it cost about $75 in parts – including the rivet gun. I already had 1 camera so the second one I got for $100 on ebay.

IMG_0672
IMG_0680
DSC09971
DSC00036_ps

Merging the photos taken was trivial with StereoPhoto Maker. An awesome piece of free software that I wish was open source so it could be ported to OSX, or better yet a CLI version.

Here is one of the images Gillian took that night. Any pair of red-blue glasses should work with it. You can see the whole gallery here. I have a few more shots from around the city on my Flickr stream.

AS3 port of JZLib

June 8th, 2009

Last month I was working on a project that used FZip to decompress some zip files in flash.

One tricky thing about FZip is that when running in Flash Player it requires your zip files to have an adler32 checksum for each file in order to work. This is normally fixed with a work around python script provided with FZip.

The python script is easy and all, but why not figure out how to do it in pure AS3 with more standard zip files?

The checksum is needed because AS3’s ByteArray only supports ZLib when running in Flash Player. In AIR it supports deflate which is what zip files use by default. I would be really curious to hear from Adobe why they chose not to support deflate since you need deflate for Zlib to work anyway.

I decided to implement inflate in as3 but I didn’t want to do it with new code so I looked for FOSS projects to port. JZlib was a good choice because Java is similar to AS3 and it didn’t rely on any external system calls.

This port supports everything in JZlib so you can use it for any inflate or deflate operations you might need.

To use with FZip

I used this library in FZip so it no longer requires that zip files be converted before use. It is tested to be working with the OSX cli zip command. It doesn’t work with OSX finder zip compression because of another issue.

In FZipFile.as:

protected function parseContent(data:IDataInput):void {
	if(_compressionMethod === COMPRESSION_DEFLATED && !_encrypted) {
		if(HAS_INFLATE) {
			// Adobe Air supports inflate decompression.
			// If we got here, this is an Air application
			// and we can decompress without using the Adler32 hack
			// so we just write out the raw deflate compressed file
			data.readBytes(_content, 0, _sizeCompressed);
		} else if(_hasAdler32) {
			// Add zlib header
			// CMF (compression method and info)
			_content.writeByte(0x78);
			// FLG (compression level, preset dict, checkbits)
			var flg:uint = (~_deflateSpeedOption << 6) & 0xc0;
			flg += 31 - (((0x78 << 8) | flg) % 31);
			_content.writeByte(flg);
			// Add raw deflate-compressed file
			data.readBytes(_content, 2, _sizeCompressed);
			// Add adler32 checksum
			_content.position = _content.length;
			_content.writeUnsignedInt(_adler32);
		} else {
			data.readBytes(_content, 0, _sizeCompressed);
 
			//throw new Error("Adler32 checksum not found.");
		}
		isCompressed = true;
	} else if(_compressionMethod == COMPRESSION_NONE) {
		data.readBytes(_content, 0, _sizeCompressed);
		isCompressed = false;
	} else {
		throw new Error("Compression method " + _compressionMethod + " is not supported.");
	}
	_content.position = 0;
}
 
protected function uncompress():void {
	if(isCompressed && _content.length > 0) {
		_content.position = 0;
		if(HAS_INFLATE) {
			_content.uncompress.apply(_content, ["deflate"]);
		} else if(_hasAdler32) {
			_content.uncompress();
		} else {
			var uncompr:ByteArray = new ByteArray();
			var d_stream:ZStream=new ZStream();
			d_stream.next_in = _content;
			d_stream.next_in_index = 0;
			d_stream.next_out = uncompr;
			d_stream.next_out_index = 0;
			
			var err:int = d_stream.inflateInitWithNoWrap(true);
			while(d_stream.total_in <= _content.length && i<=_content.length*4) {
				d_stream.avail_in=d_stream.avail_out=10;
			
				err=d_stream.inflate(JZlib.Z_NO_FLUSH);
				if(err == JZlib.Z_STREAM_END) {
					System.println("decompress success:" + this.filename);
					break;
				} else if (err == JZlib.Z_STREAM_ERROR) {
					System.println("stream error:" + this.filename + " " + d_stream.msg);
					break;
				} else if (err == JZlib.Z_DATA_ERROR) {
					System.println("data error:" + this.filename + " " + d_stream.msg);
					break;
				//} else {
				//	System.println("status:" + this.filename + " " + err);
				}				
			}
			err=d_stream.inflateEnd();
 
			_content = uncompr;			
		}
		_content.position = 0;
		isCompressed = false;
	}
}

*** UPDATE 2/9/2010: Thanks to Kathrin Furtlehner for sending me a test case for a bug where it wasn’t extracting the full file when dealing with longer strings. I updated the patched FZip archive to reflect the fix.

Fonts on the web – Part 1

May 31st, 2009

I’ve been reading and hearing a lot of rumbling lately from designers lately desperately looking for a better way to add fonts to their web design.

I feel that there is a lot of confusion in the design and web developer community as to what the issues are with font embedding or linking and when there isn’t confusion I often find myself on the opposite side of the debate and end up at a impasse with whoever I am talking with. In the past month I have found myself in this position more than once in person.

Last week I was posting a response on MildFuzz (link) and I realized that just debating the technical merits of the problem and proposed solutions isn’t going to get me anywhere. I set out to write a blog post to express my positions and beliefs and explain the technical problems to people but as I was writing I realized that there is just too much to dump into a single blog post.

My goal here is to write a long multi-part post that frames the technical issues, talks about proposed solutions, touches on the debates going on in the community, and offers my thoughts on a solution to the problem. This first post will just be an introduction.

first. About me:
I have been working as a professional web and application developer for 11 years now. Before that I did some type design and released several commercial and free fonts over at GrilledCheese.com. While the site may appear very very stale, I have been working for months now updating all of my typefaces and preparing them for a re-release. (Cleaning up glyphs that are over 10 years old and converting to OpenType is quite a chore, not to mention the 10 or so unfinished works I never released). I am most likely going to release most of my typefaces as Creative Commons licensed works or some hybrid commercial entity that I will talk about in a later article. Since I am now a professional programmer and not a designer I tend to look at things from more of a technical perspective and that will probably come through in this writing.

here is an outline of the posts I am working on

  • A brief history of type and fonts
  • The type industry compared to other creative works
  • Type on the web – methods and controversy
  • My proposed solution