Usability in Hardware

November 9th, 2011

I have a TC Electronic BMC-2 monitor controller, that I use and like, for controlling volume on nearfield monitors and headphones in my studio.

But it has a usability problem. We talk about usability in software all the time, but here’s an example of a hardware usability problem. Here’s the back panel:

BMC-2 Back Panel

Whose brilliant idea was it to put the headphone jack under the power jack? When I use it, I’m always in front of the unit, reaching over the top to control it. Which one of these jacks is likely to get plugged and unplugged more often?

Maybe the BMC-2mkII will reverse the positions of these. I doubt it will be a free downloadable update though.

Opinions ,

From the Audio Unit Programming Guide

November 4th, 2011

Audio Plug-In manufacturers would do well to read and re-read this paragraph.

Adding Copy Protection

If you choose to add copy protection to your audio unit, it’s especially important to consider the audio unit’s opening sequence. The time for copy protection is during audio unit initialization—not instantiation. Therefore, you put copy protection code into an override of the Initialize method from the SDK’s AUBase superclass. You do not put copy protection code into an audio unit’s constructor.

Here is a scenario where this matters. Suppose a user doesn’t have the required hardware dongle for your (copy protected) audio unit. Perhaps he left it at home when he brought his laptop to a performance. If your audio unit invokes its copy protection on instantiation, this could prevent a host application from opening. If your audio unit invokes its copy protection on initialization, as recommended, the performer could at least use the host application.

Opinions , ,

Nerdy Mac Tip

September 19th, 2011

Here’s a nerdy tip for Mac users. Open Automator, and create a new Service workflow. Set it to receive no input, then drag a “Run Shell Script” item into the workflow. Replace the default “cat” in the text area with this:

echo -n `uuidgen | tr A-Z a-z` | pbcopy

Save the service as “Copy New UUID to Pasteboard”. Now whenever you run the service, it generates a fresh UUID that is on your pasteboard, which you can then copy into whatever context you need it.

If you never need a UUID, then, umm, maybe just don’t worry about this tip.

Tips

What part of this is hard to understand?

September 12th, 2011

Amendment 4.

The right of the people to be secure in their persons, houses, papers, and effects, against unreasonable searches and seizures, shall not be violated, and no Warrants shall issue, but upon probable cause, supported by Oath or affirmation, and particularly describing the place to be searched, and the persons or things to be seized.

Amendment 5.

No person shall be held to answer for a capital, or otherwise infamous crime, unless on a presentment or indictment of a Grand Jury, except in cases arising in the land or naval forces, or in the Militia, when in actual service in time of War or public danger; nor shall any person be subject for the same offence to be twice put in jeopardy of life or limb; nor shall be compelled in any criminal case to be a witness against himself, nor be deprived of life, liberty, or property, without due process of law; nor shall private property be taken for public use, without just compensation.

Amendment 6.

In all criminal prosecutions, the accused shall enjoy the right to a speedy and public trial, by an impartial jury of the State and district wherein the crime shall have been committed, which district shall have been previously ascertained by law, and to be informed of the nature and cause of the accusation; to be confronted with the witnesses against him; to have compulsory process for obtaining witnesses in his favor, and to have the Assistance of Counsel for his defence.

I guess some people just don’t get it.

This is not the country in which I grew up and was taught that we were a free country, with principles, that stood for something.

Uncategorized

On the Timing of the Jobs Address

September 8th, 2011

President Obama will address a Joint Session of Congress tonight (Thursday, Sept. 8th) regarding his job stimulus plan. He had originally requested to do so last night (Wednesday, Sept. 7th), but House Speaker John Boehner asked him to change the plan, and he agreed to it.

Mr. President: Please allow me to show you what the correct response should have been.

Read more…

Opinions

Those evil smartphones…

March 16th, 2011

You can’t make this shit up: Richard Stallman thinks that smartphones are “Stalin’s Dream”. But:

“There’s a version of Android called Replicant that can run on the HTC Dream phone without proprietary software, except in the U.S. In the U.S., as of a few weeks ago there was still a problem in some dialing library, although it worked in Europe. By now, maybe it works. Maybe it doesn’t. I don’t know.”

And later:

Over the course of 38 minutes, our connection was lost five times, including just after Stallman’s comments about electronic eavesdropping and free software for phones. We tried to connect again several hours later but were unable to complete the interview via phone.

Note: I do not speak for my employer, who happens to make some pretty nice smartphones.

Uncategorized

Designated Initializers in Objective-C

September 21st, 2010

So, if you are a Mac/Objective-C developer, you are probably familiar with the Designated Initializer. The Designated Initializer (“DI”) is, in an Objective-C class, the one initializer in a class that is supposed to do the heavy lifting in initializing an object for use. Other initializers of the class should generally invoke the DI.

Similarly, subclasses of a given class should, in their DI, invoke the superclass DI (and the other initializers of the subclass should invoke the subclass DI). This way, any way the object gets initialized, the DI of both the superclass and the subclass are sure to be invoked.

The documentation does a decent job of explaining this, but I think it’s easy to miss an important detail, and that is that in a subclass, you must take care not only to invoke the superclass’ DI, but you also have to override it. (If your DI is different from the superclass’ DI, this is not necessarily obvious.)

For example, take these two classes:

@interface DJMySuperclass : NSObject
{
    DJMyInfo* importantData_;
    BOOL someImportantSwitch_;
}

// The designated initializer for DJMySuperclass:
- (id) initWithImportantData:(DJMyInfo*)importantData;

@end

@interface DJMySubclass : DJMySuperclass
{
    DJMoreInfo* moreImportantData_;
}

// The designated initializer for DJMySubclass:
- (id) initWithImportantData:(DJMyInfo*)importantData
           moreImportantData:(DJMoreInfo*)moreImportantData;

@end

Fairly straightforward so far, right? Now, take this implementation:

@implementation DJMySuperclass

- (id) init
{
    return [self initWithImportantData:nil];
}

- (id) initWithImportantData:(DJMyInfo*)importantData
{
    if (self = [super init]) {
        if (importantData) {
            importantData_ = [importantData retain];
        } else {
            importantData_ = [[DJMyImportantData alloc] init];
        }
        someImportantSwitch_ = YES;
    }
    return self;
}

- (void) dealloc
{
    [importantData_ release];
    [super dealloc];
}

@end

So far so good; completely obvious. Now let’s take this subclass implementation:

@implementation DJMySubclass

- (id) init
{
    return [self initWithImportantData:nil moreImportantData:nil];
}

- (id) initWithImportantData:(DJMyInfo*)importantData
           moreImportantData:(DJMoreInfo*)moreImportantData
{
    if (self = [super initWithImportantData:importantData]) {
        someImportantSwitch_ = NO;
        if (moreImportantData) {
            moreImportantData_ = [moreImportantData retain];
        } else {
            moreImportantData_ = [[DJMoreInfo alloc] init];
        }
    }
    return self;
}

- (void) dealloc
{
    [moreImportantData_ release];
    [super dealloc];
}

@end

Again, totally straightforward, right? So where is the bug?

Imagine this extension (or, maybe instead of a category extension, imagine a similar future addition to the superclass and subclass, a year down the road and done by a different developer).

@interface DJMySuperclass(JBJoeBlowsAdditions)

- (id) JB_returnsACopy;

@end

@implementation DJMySuperclass(JBJoeBlowAdditions)

- (id) JB_returnsACopy
{
    return [[[[self class] alloc] initWithImportantData:importantData_] autorelease];
}

@end

@implementation DJMySubclass(JBJoeBlowAdditions)

- (id) JB_returnsACopy
{
    DJMySubclass* other = [super JB_returnsACopy];
    [other->moreImportantData_ release];
    other->moreImportantData_ = [moreImportantData_ retain];
    return other;
}

@end

Where’s the bug?

The bug is that if you have a DJMySubclass object called foo, and you call DJMySubclass* bar = [foo JB_returnsACopy];, you’ll discover that bar->someImportantSwitch_ contains YES, when you thought you had a class invariant for DJMySubclass where someImportantSwitch_ was always forced to NO.

Why?

Because JB_returnsACopy in the superclass uses the initWithImportantData: initializer, and you didn’t cover it in DJMySubclass, so your designated initializer in the subclass never got invoked.

The fix is simple: cover the superclass’ DI in your subclass, and invoke your DI.

@implementation DJMySubclass

- (id) initWithImportantData:(DJMyInfo*)importantData
{
    return [self initWithImportantData:importantData
                     moreImportantData:nil];
}

@end

The documentation for Designated Initializers says:

It’s important to know the designated initializer when defining a subclass. For example, suppose we define class C, a subclass of B, and implement an initWithName:fromFile: method. In addition to this method, we have to make sure that the inherited init and initWithName: methods also work for instances of C. This can be done just by covering B’s initWithName: with a version that invokes initWithName:fromFile:.

General Principle: The designated initializer in a class must, through a message to super, invoke the designated initializer in a superclass.

This general principle, while true, is not sufficient. You really need to make sure to cover the superclass’ DI in your subclass, as described in that first paragraph, and shown in the accompanying diagram 3-3.

Tips ,

HDMI: Progress?

September 8th, 2010

If you were not a member of the A/V club in school, you can skip this post now.

So. Until yesterday, I had the following A/V setup. Our receiver was a Sony STR-DG910. It does video switching, and has 3xHDMI 1.2 inputs, plus some component and composite inputs.

Our monitor was a Westinghouse LVM-37w1 (RIP). We had the receiver connected to it by exactly one cable; an HDMI-DVI cable. (The Westinghouse has no HDMI inputs; only DVI+HDCP.) The only other cable connected to the LVM-37w1 was power. We liked it that way; it meant we didn’t have a lot of spaghetti on the wall (the monitor was wall-mounted).

The spaghetti was behind the A/V rack (really a coffee table), which had a PS3, a Wii, a TiVo HD XL, an Apple TV, the receiver, and a Pioneer DVD changer.

We had the PS3 and the TiVo connected to the receiver via HDMI. The AppleTV wouldn’t output HDMI to the receiver, for reasons unknown to me, so we had it connected via component. Ditto for the Pioneer. The Wii only supports composite or component. The receiver upconverts SD (or component HD) signals to HDMI.

Last night a storm ate the TV (monitor). (And yes, it was plugged into a hot-shit A/V power distribution center, which is apparently worth approximately the same as the contents of our guinea pig cage.) Today I bought a Vizio E470VA to replace it. It has 4xHDMI 1.3 inputs. I intended to connect it the same way as the previous one was: just hook an HDMI cable up from the receiver to the TV.

When I do this, it will not display a picture. It works fine if I connect the various devices (TiVo, PS3, etc.) directly to it. But it will not display a picture sent from the receiver.

So it looks like I’m going to have to connect each device directly to the TV, and switch the video there (instead of in the receiver), and either handle audio separately or connect still another cable from the TV back to the receiver to get the right audio signal to come up.

Instead of two cables (power and HDMI) running up my wall to the TV, I will now have at least 7: Power, TiVo, PS3, AppleTV, DVD, Wii, and audio. This is progress indeed.

Is there an explanation for this that won’t make me want to take a baseball bat to the collective heads of the HDMI standards forum?

Uncategorized

Becky and the Shark

August 14th, 2010

I don’t know that I need to add anything to this:

Becky and a shark

Becky found a shark on the beach.

Uncategorized

E-Books vs. Paper: Environmental Concerns

July 13th, 2010

I recently mentioned on Twitter that it was somewhat ironic that Rachel Carson’s Silent Spring, which I’d like to read, was only available in “dead tree” editions (and thus not convenient for me).

I quickly got back two nearly identical responses telling me to go to a library. Obviously this doesn’t kill another tree, but what it does do is indirectly perpetuate demand for paper books over electronic publishing, and as I said, I want to vote with my wallet for electronic editions, which I prefer not only because of their convenience (I always have an iBooks- and Kindle-capable device on me, unless I expect to get wet), but also because I perceive them to be a more environmentally conscious choice.

Another response I got, though, calls that perception into question, linking to an article that maintains that electronic media are just as polluting as paper publishing, because of the environmental damage done by coal mining and other ingredients (such as toxic computer parts) of electronic publishing.

My reaction to this, though, is that these environmental impacts, though real now, reflect the infancy of the information-based age. While it may be true now that buying one Kindle or ePub book and reading it (and considering the amortized impact of it’s production) incurs environmental costs that may be on par with the incremental and amortized costs of a paper book (a point which I do not concede), I believe that the environmental costs of electronic publishing are falling faster than the costs of paper publishing are, and that my gut tells me this trend is likely to continue.

So, fortunately for me, this is a case where my convenience and my conscience are aligned.

What do you think? Tell me via Twitter or Facebook, or by a post on your own blog that links back here.

Musings ,

Get Adobe Flash playerPlugin by wpburn.com wordpress themes