I confess, I’m an Apple user. My first computer when I was a wee lad was a Wozniak edition Apple IIGS, and then a Mac Plus. I went over to PCs for a while but returned to the Mac years ago and love every minute of it. I love the attention to detail that Apple puts into their products and the emphasis on good design. I’m not an Apple snob or anything, but I do think it is a shame that Apple hasn’t made better penetration into large enterprises, and I admit that I do wince a little every time I go into a client site and see row after row of Windows PCs… but I digress.
Why I love Apple…
In the last update of iTunes for Mac, Apple did something that truly knocked my socks off: Apple finally figured out how to handle classical music.
Let me explain. If you are cataloging pop music, you will want to store the performer and the song title. The album info may or may not be relevant but the key fields are the performer and song title. In classical music, these fields are significantly less important in that the title of a piece might be “Symphony #5” or something like that. What you really care about is the combination of composer AND the title. (IE: Tchaikovsky’s violin concerto is a different work than Mendelssohn’s violin concerto) But wait… there’s more.
Major works are often divided up into sections or movements and on recordings, these sections usually will have their own tracks. The actual title of the movements are usually pretty non-descriptive such as “Allegro Moderato”, “Freilich” or something like that.
Anyway, you can see, record companies encode all this information, but do so in a way that makes each track title really long and unwieldy. This is where Apple really upped their game.
In the latest version of iTunes, Apple introduced the concept of storing the ‘work name’ instead of just the song title. You could use this for pop music, but really it seems geared towards classical music and it was a major improvement in cataloging classical music. You can see in the image below that when things are cataloged using Apple’s new system, it makes organizing classical music a breeze.
So what’s wrong with that?
Why I also hate Apple…
Apple finally figured out how to catalog classical music. Awesome. What they didn’t do, was put some parser into iTunes to extract all these fields from the CD metadata and populate the appropriate fields correctly. So if I want all my music to look like the results on the left (and I do) I have to go through and adjust the titles manually. I see that Apple attempted to automate this process, but they didn’t get it right.
In the example below, the full track title is Beethoven: Symphony #7 In A, Op. 92 – 1. Poco Sostenuto, Vivace. When you switch iTunes into the “classical music mode” you’ll note that the composer is listed as the work name (wrong), the movement number is blank and the name of the movement contains the catalog or opus number, then the movement number and finally the movement title–all wrong. Here’s how the fields should be populated:
My disappointment in Apple comes from the fact that the iTunes team clearly put a lot of thought and effort into how to accurately catalog and store classical music and laid the foundation to do it better than any other music program I’ve seen. Despite this, they failed at a key point, which was automatically ingesting the data into this format and as a result, I would bet that many iTunes users who listen to classical music don’t even know this feature exists.
How to fix this:
In looking at this, I noticed that record labels do seem to be fairly consistent in how they encode the metadata for classical albums and as such, I wrote the following code snippet to extract all the relevant fields from the data.
import re import pandas as pd pattern = r'(.+?):\s(.+?)\s-\s(.*)?' testData = """ Dvořák: Symphony #6 In D, Op. 60 - 2. Adagio Shostakovich: Symphony #5 In D Minor, Op. 47 - Moderato, Allegro Non Troppo, Etc. Shostakovich: Symphony #7 In C, Op. 60, "Leningrad" - Allegretto Shostakovich: The Bolt Suite #5 - 3. The Dance Of The Drayman Shostakovich: The Bolt Suite #5 - 1. Overture Shostakovich: Symphony #5 In D Minor, Op. 47 - Largo Ravel: L'Enfant Et Les Sortilèges - Oh! Ma Belle Tasse Chinoise! Schubert: Symphony #9 In C, D 944, "Great" - 1. Andante, Allegro Ma Non Troppo Prokofiev: Symphony #1 In D, Op. 25, "Classical" - 4. Finale: Vivace Shostakovich: Lady Macbeth Of Mtsensk - Act 1/Sc. 1: Proshcháy, Katerina Bach: Toccata, Adagio & Fugue In C, BWV 564 - 3. Fugue Copland: Rodeo - 1. Buckaroo Holiday Handel: Suite In D For Trumpet & Orchestra - 1. Overture Rimsky-Korsakov: Capriccio Espagnol, Op. 34 - 2. Variazioni """ data = testData.split("\n") movementPattern = r'(\d+)\.?(.+)' tracks = [] for line in data: record = {} patternMatch = re.match( pattern, line ) if patternMatch: record['composer'] = patternMatch.group(1) record['workTitle'] = patternMatch.group(2) record['section'] = patternMatch.group(3) movementObj = re.match( movementPattern, patternMatch.group(3)) if movementObj: record['movementNumber'] = movementObj.group(1) record['section'] = movementObj.group(2) tracks.append( record ) df = pd.DataFrame(tracks)
The code above works reasonably well at extracting the correct fields from the metadata as you can see in the table below.
composer | movementNumber | section | workTitle | |
---|---|---|---|---|
0 | Dvořák | 2 | Adagio | Symphony #6 In D, Op. 60 |
1 | Shostakovich | NaN | Moderato, Allegro Non Troppo, Etc. | Symphony #5 In D Minor, Op. 47 |
2 | Shostakovich | NaN | Allegretto | Symphony #7 In C, Op. 60, “Leningrad” |
3 | Shostakovich | 3 | The Dance Of The Drayman | The Bolt Suite #5 |
4 | Shostakovich | 1 | Overture | The Bolt Suite #5 |
5 | Shostakovich | NaN | Largo | Symphony #5 In D Minor, Op. 47 |
6 | Ravel | NaN | Oh! Ma Belle Tasse Chinoise! | L’Enfant Et Les Sortilèges |
7 | Schubert | 1 | Andante, Allegro Ma Non Troppo | Symphony #9 In C, D 944, “Great” |
8 | Prokofiev | 4 | Finale: Vivace | Symphony #1 In D, Op. 25, “Classical” |
9 | Shostakovich | NaN | Act 1/Sc. 1: Proshcháy, Katerina | Lady Macbeth Of Mtsensk |
10 | Bach | 3 | Fugue | Toccata, Adagio & Fugue In C, BWV 564 |
11 | Copland | 1 | Buckaroo Holiday | Rodeo |
12 | Handel | 1 | Overture | Suite In D For Trumpet & Orchestra |
13 | Rimsky-Korsakov | 2 | Variazioni | Capriccio Espagnol, Op. 34 |
The challenge:
So Apple, I’ve thrown down the gauntlet. I’ve put up code for how to fix this. I realize iTunes isn’t implemented in Python, but I don’t think it would be too hard to map this to c++ or whatever language it was written in. If I can do this in 20 min, I’m pretty sure that you can do this as well. All of the classical music listeners who use iTunes will be grateful! Make it so!
[…] an Apple guy through and through. (You can read more about my love/hate relationship here.) My first computer ever was a Woz edition Apple ][ GS and although I […]