tiny…

Yeah, I know I promised last time no more tinkering with AMP and the next release would be called version 2.

But version 1.22 is out anyway, representing a tiny, tiny, puny little bug-fix!

Basically, I was doing the computation for ––levelup incorrectly: I was comparing a composer’s average play-length to the global average play-length, which turns out to be a mathematically stupid thing to do. Say every Beethoven composition lasts 40 minutes. You play him 60 times (i.e., about 2,400 minutes’-worth of total play). What’s his average play length… er, 40 minutes (because 2,400 minutes ÷ 60 plays=40). Say Wagner operas all last 240 minutes (i.e., 4 hours each). You listen to him twice. Wagner’s average length of play is 240 minutes, but his cumulative play time is 480 minutes. Then say you have played 50 Scarlatti keyboard sonatas that each last 3 minutes: 150 minutes of cumulative play, but only 3 minutes on average. The global average play-length is 2,400+240+150=3,030 ÷ 3 composers, or 1,010 minutes per composer.

Now, on the original computation, I was comparing Beethoven’s 40 minute average with 1,810 minutes and saying ‘he’s below the average, so play on!’ And Wagner’s average 240 minutes was below 1,010, so he’s playable, too. And so is Scarlatti. Levelup in those computations made no difference at all, then!

What I meant to be doing, however, is saying 2,400 minutes of Beethoven is a hell of a lot of Beethoven: lay off playing him again until Wagner and Scarlatti have had a chance to catch up. And you do that by comparing their cumulative play-time to the global average play-time. Do it that way, and you end up saying ‘2,400 is a lot more than 1,010: Beethoven is ruled out, but 480 and 150 are below 1,010, though, so both Wagner and Scarlatti remain playable’.

Now, say that I randomly ended up playing Wagner 4 more times. That’s 960 extra minutes of play for him, bringing his cumulative total to 6×240=1,440 minutes. That also changes the global average play, of course: (2,400+1,440+150)/3=1,330 minutes. So after that last extra Wagner play, he’s now got more accumulated minutes than the global average: he’s now not playable until Scarlatti catches up!

Let us then say you somehow manage to endure a further 120 Scarlatti plays. He’s now got 170 plays at 3 minutes each, so 510 minutes cumulative play. But what’s the global average now? Well, it’s (2400+1440+510)/3=1450 minutes. Which means Wagner, still with “only” 1,440 accumulated minutes is playable once more. But one extra Wagner play takes him above the global average again, ruling him out until Scarlatti catches up again (after a further 150 keyboard sonatas), and so on: those two do tag-team, with lots of Scarlatti plays (but each mercifully only 3 minutes long), interspersed with occasional 4-hour Wagner marathons. Eventually… Scarlatti and Wagner both achieve cumulative plays that make Beethoven playable once more. If you do the maths, you’d find Beethoven only becomes playable once more when Wagner has been played 10 times and Scarlatti a whopping 800 times -because only at those numbers do all three composers have 2,400 minutes of cumulative play… which also happens to be the global average play time at that point. And that’s what ––levelup was meant to be doing all along: not levelling up the number of plays between composers, but levelling up the amount of play-time each composer gets. Composers who write ballets and operas get played fewer times than those that only penned short sonatas.

And that’s exactly what the revised levelling-up code now does. As I said originally, you wouldn’t want to run in ‘level up’ mode all the time, but as a periodic corrective to playing big operas and ballets, it’s quite useful in promoting ‘the little guys’ beyond their usual station in life!

A similar sort-of blunder affected ––unplayedworks. That was meant to ensure only recordings which had not previously been played would be played next. The way I wrote the code, though, meant that a composer who had an unplayed recording would correctly get selected at random… and then anything which that composer had written might get selected for next play. So you buy a new recording of Beethoven’s 5th; the code would spot that Beethoven has an unplayed recording; but then it would select for play that well-worn Solti recording of Beethoven’s 9th! D’oh! The code has now accordingly been tweaked to ensure that (a) only composers with unplayed recordings are selected and (b) only the unplayed recordings by the selected composer are played. So, it’s still not perfectly predictable: let’s say you buy two new recordings of Beethoven’s 5th and 7th symphonies. Using the ––unplayedworks switch now, you will definitely end up hearing one of those two symphonies… but it remains random chance which one of them you’ll get to listen to first.

Basically, two tiny little tweaks to existing code that makes it do what I said it would do originally, but failed to make happen originally! Not worth a version 2 release, I think… and definitely my last fiddle!