Lose / Lose in the Music Industry

David Byrne had some interesting perspective on the history of royalty payments for recorded music, concluding with a question

Could the same thing happen today? Could musicians or other creative folks strike in order to get a fairer deal from the digital and media companies that are making loads of money from the content created by them?

I suppose that the obstacle would be the lack of unionization, but ultimately, musicians can choose to not license their catalog to Pandora or Spotify (the immediate suspects when Byrne says “digital and media companies”). Up until recently, Pink Floyd was unavailable online, and I believe that AC/DC still isn’t. The thing is that for up and coming acts, exposure is key. For new acts, the money is rarely in recording, it’s always in touring, and, if we’re really honest, clothing sales. It’s been a way of life to treat recordings as a loss leader for the tour.

I wondered earlier on Twitter about the ads on Pandora and Spotify. I can’t recall ever hearing an ad for an upcoming show in Denver, yet those 2 sites both know my location and my tastes. Listening to Pandora for an hour, I should hear about at least one upcoming show. On top of that, acts could easily just advertise merchandise. Like “The Head and the Heart? Come check out our new merchandise! (link through to band’s site, affiliate commission paid to Pandora/Spotify/whomever)” .

Looking at the financials from Pandora, it seems like they’re barely functioning as a business (-$.30 EPS according to Yahoo! Finance), betting on growth to fill in the holes. Yet clearly, digital music is the future, and is really present too. Rather than striking, someone needs to see where the interest of fans, artists, and distributors lie and connect them.

Review: AP Driven

I downloaded AP Driven yesterday. I’m a big fan of workout tracker apps, or rather, I’m a fan of the idea of workout tracker apps. In my experience, execution is lacking. The only tracker I’ve really liked is the Stronglifts tracker. It’s simple, straightforward, and does one thing really well: it guides you through the Stronglifts program. Most apps try to be too flexible, and I have no patience for putting together workouts by selecting from a list of hundreds of potential exercises. On top of that, the app needs to be easy to control. In the gym you’re sweaty, you’re trying to focus on your exercises, and I like to have my phone in an armband where it’s out of the way behind a plastic shield. The UI should be streamlined to allow you to do the minimum data entry, and should be designed so that the touch screen works under sub-optimal conditions.

AP Driven is written around Adrian Peterson’s training program. The program seems solid enough: a speed component and a strength component. One day into it, along with previewing day 2’s contents, I really like it so far. With a well defined program, it should be easy for the app to lead you through it.

AP Driven is definitely a well-polished app. It has a fancy splash screen, a nice little intro tutorial, and drops you into an interface that’s pretty easy to figure out what’s going on. But the real test is in the gym. Here’s what I found.

  • I’d really, really like a list of the exercises and the equipment I need at the start, for example on day 1 speed, you need the rope ladder, and on strength you need dumbells or kettlebells, a power rack, and a barbell with weights. It’s a bit of a pain to figure this stuff out as you go.
  • The first thing I found was that there was an overall lack of specifics. The speed portion contains a number of sprints. How long should I sprint? 10 yards? 40 yards? It’s never specified.
  • There was no mention of a recommended rest period between sets. Again, this is something Stronglifts does very well: you enter your reps and it starts a timer for the rest period so you have an audible cue when to start the next set.
  • In the strength portion, I didn’t see any recommendations on starting weight or increasing weight. You do have to make 10 reps on most exercises so I guessed at where a challenging weight would be and noted the weight in the notes. What I like about Stronglifts and Starting Strength is the unabmiguous weight prescription. I’m not sure what AP’s goal is here.
  • The videos are a great idea, and for the most part well done. 2 things I disliked: first, the editing was a bit to spastic, that MTV style of editing where you can’t mainain the camera angle for more than 5 seconds. Some of the cuts were useful, like showing AP’s footwork on the ladder exercises, but others just distracting. There was excessive use of slow motion, I thought.
  • There’s no useful sound on the videos, just sound effects. On top of that, playing a video kills your music track. I’d rather have the videos stay silent and just show me the exercise, unless there’s an actual voice track with useful info.
  • Another point on the music: I don’t like that it’s limited to the library on the phone. What I’d really like is for it to integrate with Pandora or Spotify, but I realize that’s a bit much to ask. Lacking that, AP Driven should work much harder to cooperate with a music player in the background. I’d like to just set Pandora and switch to AP Driven, but since AP Driven is constantly taking over the sound and leaving Pandora paused, I have to keep switching back.
  • Which brings up a final point: on some of the switches, AP Driven wants to re-initialize and start over with the noisy splash screen, which kills Pandora, and then I have to go back, restart Pandora, and switch back to AP Driven.
  • One final point: some of the touch points on the screen seem to be very tiny and can’t be controlled through the cover on my armband. It’s a real inconvenience to have to be taking my phone out of the armband to mess with the program.

Overall, the AP Driven program seems to be a great workout. The app itself needs a few improvements.

Anemic Domain Models

Somebody passed around Anemic Domain Model at work yesterday. I’m not quite sure what Fowler’s arguing here. At one point he’s advocating for a richer domain model, then at the end he advocates POJOs.

For one thing, it’s a bit dated. Fowler wrote this in 2003, when we all had less experience with distributed objects. We still don’t have a good way to put behavior on the wire, so unless your validations are expressed in XSD, they don’t transfer across the wire. So there’s some confusion with a domain model for information exchange vs a domain model for actually programming on a server.

I also see that people tend not to do any more than validation (including relational integrity checks) at the domain level, because that’s typically a bit too low for anything more than rudimentary calculations. Let’s take the PurchaseOrder straw man. You know the one, we’re doing a shopping cart system and we have a PurchaseOrder with LineItems, each one having a Price. It’s one thing to calculate the Sum of LineItems in a PurchaseOrder, but it’s another thing to try to put the tax calculations in there. My first instinct on something like sales tax is that it belongs at a higher level, because the calculations for sales taxes are typically anywhere from complex to insanely complex.

I wonder if Fowler’s thinking on this has changed at all. I don’t understand the point of a service layer that only coordinates. That’s what we’d call a Controller in MVC. There has to be a place for a layer of logic that’s too complex and goes across domain objects, yet isn’t concerned with the mechanics of marshalling a request & response, validating parameters, etc.

MVC Code Smells

I’m sure someone has addressed this more rigorously before me. I’m just throwing out thoughts after seeing Code Coalition’s coverage of MVC in the iOS course I’m taking from them. I know MVC and I’ve worked in MVC environments for years, but something in hearing someone else explain it:

  • Controllers communicate with Models and with Views. The big clue here is the name: the controller controls things. If you’re getting the sense that the Controller’s being pushed around or pushed aside, you’re on the wrong path.
  • Views and Models have limited communication with controllers, basically through a delegate system or defined interface. The pattern here is easy: your model and view should work with any controller that implements the defined interface.
  • Views don’t talk to Models.
  • Models don’t talk to Views.
  • Controllers don’t do calculations or “business logic”. I think that leaving this out of MVC causes some bad code to be written because you need some business logic, it’s not a model, it’s not a view, so you shrug and put it in the controller.

Mixing Data & Behavior

Brad Wilson popped off this tweet last week. I had to think about this one for a while.

The second point is really obvious. What’s the point of mocking an object that has no behavior? If you need to return fake data, you can easily do that through a basic data object, and I’d say that if you’ve got data you can’t fake, that’s indicative of a design problem.

It’s the initial point that doesn’t make sense. As I learned it, the whole point of OO is to bind behavior to data. Take a data structure like Stack<T> – while Stack should be entirely isolated from the T type’s data or behavior, it does have internal state that gets manipulated by its methods.

I’m going to go on a limb and say that Brad’s differentiating “state” from “data”. Using the Stack example, a stack might have a Count property and a Top accessor that reflect the current state of the object, but it’s not data per se, as the values are modified by methods and not directly.

My pocket psychology take is that we love anachronisms because they’re imperfect. Like humans are imperfect. We form relationships with people who are flawed all the time.

DHH: Worse is Human

Sometimes those relationships end up toxic or co-dependent. I remember Douglas C. Schmidt saying at a conference that “MS-DOS is a testament to the resilience of the human spirit”. More frequently, in the examples DHH gives, it’s the feeling of control. People like a manual transmission because of control. Programmers clung to Assembly, and then C, because of “control”. There may be some reason for that. In the mid 90’s, the Microsoft C compiler could generate some pretty bad code, back when machines had clocks measured in MHz. I’m sure when automatic transmissions came out, they didn’t shift very well under performance conditions. The same way with ABS braking. But these days, the technology is so good. I’ve had ABS save me from at least a fishtail, if not worse.

I think DHH is onto something though. One thing I noticed with kid’s books is the recurring nostalgia for obsolete technology: the Thomas the Train books, The Little Red Lighthouse and the Great Gray Bridge, many of the Lois Lenski books. So maybe people like your product because they have more control, whether they need it or not.

On Passwords

Tim Bray had a good piece on password managers the other day. I use KeePassX on my linux machine, which is becoming awkward because I don’t use it much anymore – Ubuntu 12.04 has made my networking so unstable as to be unusable. So the idea of having something like 1Password to back up to “the cloud”… um, Dropbox, is appealing. It’s also scary.

But what’s scarier is stories about things like combinator attacks. All it takes is one site with lousy security (I’m looking at you, Evernote), a leaked password file with weak security, and suddenly any site you’ve re-used a password on is a target. I make an effort to use good security, and my credit cards are all stored on sites using high-entropy passwords, using the maximum complexity allowed. But heavily used sites I use things that are easier to remember, and some of these passwords get re-used. After reading the Wired article, I’m starting to think that I need to take password security more seriously and start using a password manager and go for fully random, really hard to guess passwords, everywhere.

Of course, this is screaming for a federated solution, but I wonder, would that be any better? I mean, if I use Facebook login everywhere can I trust Facebook’s security and protocol, and more importantly can I trust that Facebook is only going to act as a login provider? They don’t necessarily need to know that I’m logging into Groupon or whatever. That’s the rub with any of the federation solutions, they all come with strings… no, ropes, attached.


I’ve had a blog since 2002, though in recent years, my posting has tailed off. Around the new year, my hosting provider was sold to a new operator and the site has experienced significant downtime. I finally decided to switch hosting providers and in the process, I’ve switched from Textpattern, which I never really liked, and finally flat out hated, to WordPress, which so far seems to be not bad.

I don’t know if I’ll import the old posts. Some of the really old stuff I still have backed up in static files and it would be easy enough to upload, but the Textpattern stuff may be gone. I’m not sure that’s a tragedy. I’m starting to feel like when it comes to data, maybe it takes the occasional forest fire to clear out the cruft and let the trees grow.

Installing curb on a mac

I’ve had more than my share of problems getting curb installed on my mac. First was the ominous warnings running brew install curl

==> Caveats
This formula is keg-only: so it was not symlinked into /usr/local.

Mac OS X already provides this software and installing another version in
parallel can cause all kinds of trouble.

The libcurl provided by Leopard is too old for CouchDB to use.

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you’ll need to add to your
build variables:

LDFLAGS: -L/usr/local/opt/curl/lib
CPPFLAGS: -I/usr/local/opt/curl/include

==> Summary

/usr/local/Cellar/curl/7.29.0: 75 files, 1.9M, built in 2.2 minutes

The warnings about the LDFLAGS/CPPFLAGS turned out to be a red herring, though brew install curb blew up on compile

HA001050:curb gweakliem$ sudo ARCHFLAGS=”-arch x86_64″ gem install curb
Building native extensions. This could take a while…
ERROR: Error installing curb:
ERROR: Failed to build gem native extension.

/Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/bin/ruby extconf.rb
checking for curl-config… yes
checking for curlinfo_redirect_time… *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

Provided configuration options:
/Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/mkmf.rb:368:in `try_do’: The complier failed to generate an executable file. (RuntimeError)
You have to install development tools first.
from /Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/mkmf.rb:446:in `try_compile’
from extconf.rb:52:in `block in have_constant’
from /Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/mkmf.rb:693:in `block in checking_for’
from /Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/mkmf.rb:280:in `block (2 levels) in postpone’
from /Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/mkmf.rb:254:in `open’
from /Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/mkmf.rb:280:in `block in postpone’
from /Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/mkmf.rb:254:in `open’
from /Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/mkmf.rb:276:in `postpone’
from /Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/mkmf.rb:692:in `checking_for’
from extconf.rb:44:in `have_constant’
from extconf.rb:62:in `<main>’
Gem files will remain installed in /Users/gweakliem/.rvm/gems/ruby-1.9.2-p320/gems/curb-0.8.4 for inspection.
Results logged to /Users/gweakliem/.rvm/gems/ruby-1.9.2-p320/gems/curb-0.8.4/ext/

I wasted a good bit of time doing variations on this:

rake install EXTCONF_OPTS=’–with-curl-dir=/usr/local/opt/curl/lib –prefix=/usr/local/Cellar/curl/7.29.0/’

Which turned out to be the wrong solution. Part of my problem may have been a lack of the Development Tools, which you install through XCode, but the real issue came from tracking down mkmf.log, in my case in ~/.rvm/gems/ruby-1.9.2-p320/gems/curb-0.7.18/ext/mkmf.log

“/usr/bin/gcc-4.2 -o conftest -I/Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/include/ruby-1.9.1/x86_64-darwin10.8.0 -I/Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/include/ruby-1.9.1/ruby/backward -I/Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/include/ruby-1.9.1 -I. -I/usr/local/opt/curl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -I/Users/gweakliem/.rvm/usr/include -fno-common -pipe -I/usr/local/include -g conftest.c -L. -L/Users/gweakliem/.rvm/rubies/ruby-1.9.2-p320/lib -L/usr/local/opt/curl/lib -L. -L/Users/gweakliem/.rvm/usr/lib -lruby.1.9.1-static -lpthread -ldl -lobjc -L/usr/local/lib -lcurl -lidn -lssl -lcrypto -lldap -lssl -lcrypto -lz”
ld: library not found for -lidn
collect2: ld returned 1 exit status
checked program was:
/* begin */
1: #include “ruby.h”
3: int main() {return 0;}
/* end */

I puzzled over -lidn for a while, which turned out to be libidn. After that discovery, the solution was easy:

sudo brew install libidn
sudo gem install curb