Blog Hiatus
So I don't post very often here anymore. I've determined that this is because I've allowed the focus of this blog to become very narrow.
Good blogs have a subject or general theme. I've tried to keep my posts focused, but it has become far constrained resulting in infrequent posting.
Because of this I'm putting the blog on hiatus until August. No posts, nothing. When it comes back I expect to have redesigned the site, done a major overhaul of the blogging engine, and decided on a broader theme that I will actually write about.
Until then, if you just can't survive without my quips and thoughts, check me out on twitter. You can just follow my RSS feed there if you're not interested in joining.
Album Sound Check - The GUI
A while ago you'll recall that I wrote a little Python script that would average out the sound check gain adjustment created by iTunes for a given set of songs.
I've gone a step farther and created a simple GUI tool for doing the same.
Album Sound Check (download link) provides a basic interface to editing this field based on the values in a given set of files.
After running the program go ahead and open a directory containing songs from your iTunes library. They will be scanned in and the gain dB adjustment values stored. ASC will then determine an average from this.
You can choose to not have certain songs affect the resulting average by unchecking the "Use" column. You can choose to not have the computed average applied to a given file by unchecking the "Apply" column.
Once you're ready just click "Apply" and ...
Oggify Updates
I've gone ahead and made an update to Oggify, pushing it to version 2.0.3. If you have version 2.0.1 or 2.0.2 you should really upgrade. They're a little bit (totally) broken.
Album Based Soundcheck
iTunes supports a feature called Sound Check. Similar to ReplyGain in other players, the goal is make songs playback at a similar volume. This is particularly useful with mixes, songs from various albums do not have jarring transitions. Since this computed on a song-by-song basis, different songs on a single album get different values. In some cases this creates a jarring experience while listening*.
For example: Muse's Absolution has an introduction track that never gets terribly loud, but leads in directly to a normal song. Sound Check did the following:
- "Intro" adjusted +19.5 dB
- "Apocalypse Please" adjusted -8.5 dB
The ending of the first track is meant to be the same volume as the beginning of the second, but because of Sound Check, this doesn't happen.
I have written album_soundcheck.py which computes the average volume of m4a or mp3 files and replaces the iTunes information ...
Best of 2008
This is out of the norm of my blog posts, but it being the end of the year I thought I'd mention some things I've found to be really good this year. I recommend these things to anyone.
Music
"Life in Technicolor," by Coldplay, from Viva la Vida
The first track from their new album. No actual lyrics, but great music. I've listened to it more than any other track on the album. Go buy it on Amazon or iTunes and enjoy 2 minutes of great music.
Weezer, by Weezer
The Red Album was really good. I had the chance to see Weezer in concert this fall, and I'm still sold on how great a band they are. Rivers does a lot of interesting stuff on this album, but I especially enjoy "The Greatest Man Who Ever Lived."
Video Games
Penny Arcade Adventures, On the Rain-Slick ...
Building Cocoa GUIs in Python with PyObjC, Part Six
Handling Images
Cocoa provides an easy interface for dealing with images, NSImage. It can be a bit tricky in Python, but once you get it right the first time, it is fairly easy. For our application we have the images stored inside the audio tags and need to populate an NSImage object from binary data stored as a Python byte-string.
There are a number of methods for initializing an NSImage object from various sources. A few of note:
initWithContentsofFile:
initWithData:
initWithPasteboard:
All of these are worth reading about in the developer documentation. We will be using initWithData:
. This accepts a NSData object to make the NSImage. This is a multiple step process, so we'll create a method to make things easier:
def buildNSImage(bytes):
data = NSData.dataWithBytes_length_(bytes, len(bytes))
return NSImage.alloc().initWithData_(data)
bytes
is a Python byte-string containing the image. NSImage will automatically handle the formatting ...
Audio of My UTOSC Presentation
I gave a presentation this past fall at UTOSC about various programming tips I've learned while I worked on Oggify. The audio from this was recorded and is now available. Enjoy.
Building Cocoa GUIs in Python with PyObjC, Part Five
Adding Python Modules to the Bundle
If you try to use Python modules on the standard OS X Python path import
statements will work fine. However, if you have non-standard modules that might be in a different location, or ones that you want to ship with, you will notice you can't just import
them.
To bring them into the application bundle you'll have to go through a couple steps, but when it is all done the application will be able to use the modules, and you don't have to require the end user to install anything extra.
Add the files to the Xcode project.
- Select 'Project -> Add to Project' (option-command-a)
- Select the Python module (directory) that you want to add.
-
On the next screen select "Copy items into destination group's folder (if needed)
- Select the correct targets in 'Add to Targets'
- Select "Create Folder References for ...
Now on Twitter
Well, I've finally given in, and am now on Twitter. You can find me as _ spr _ (hm. that's _spr_. python-markdown has a bug).
Key-Value Coding in PyObjC
So when doing GUIs in with PyObjC you'll realize that the IBOutlet
for tying objects to variables have a few limitations. The one I hit was that a single outlet can only be connected to one object. So I read up on Key-value coding. So to do this you have to add two functions per variable:
def name(self):
return self.var
def setName(self, x):
self.var = x
You can imagine that this becomes tedious really fast. Luckily there is a solution. As an example:
from PyObjCTools.KeyValueCoding import kvc
class controller(NSWindowController, kvc):
title = ""
artist = ""
album = ""
So this ties __getattr__
and __setattr__
to valueForKey:
and setValue:forKey
. Making every class variable available for Key-value coding. Very handy.
Rambling on Git
So during my UTOSC presentation I add some spare time, and ended up doing a "Git in Five Minutes" demo. I've done a written version for everyone to enjoy. So yes, I've written a Git tutorial.
Oh, and this Git Magic tutorial is pretty good too.
UTOSC Slides and Related Files
I presented at UTOSC this year, presenting a series of tips and best practices that I've learned from Oggify. Entitled Things I've Learned From Oggify, the slides are available on the conference site. There are a few files I used in the presentation which I have put in a tar and uploaded. Enjoy!
Blog Update | Django 1.0
The blog code has been updated to be compliant with the recent release of Django 1.0. And a small patch from Jeff.
Oggify 2.0 Released
Oggify has now been officially released at version 2.0. Oggify now includes:
- Man page
- Plugin framework
- Python
So go and download it now, and enjoy your audio conversion!
My iPhone 3G Buying Experience
I've been reading various responses to the iPhone 3G activation issues. These range from "my phone is a brick," "the store won't sell any that aren't activated," to "the line barely moves." I had a different experience yesterday morning out here in California.
I went to the smaller local Apple store in the Stanford Shopping Center. The line started at 5 AM (mall rules) and my friend and I got there at 7 AM. We were around the 100th in line. Around 9 AM the Apple employees started to alert people that if they had a business discount on their phone they needed to call AT&T and get it removed. So I called and in 5 minutes I got the PLU number removed from my account. I got into the store at 9:45 AM, and quickly bought my 8 GB. The employee helping me told ...