Wednesday, September 28, 2011

Album Covers: Now less sucky!

Goggles Music Manager 0.12.x currently features an album list with optional cover display. The cover display can be turned on from the preferences and displays a list of albums with a small cover image of 64 by 64 pixels. Here's what it looks like:



For certain cases it may work OK, but in all honesty it does come with some serious drawbacks:
  1. The cover image is rather small. For some people it may be just the right size, but often times I have wished they were bigger. For example, on larger displays like my Home Theater PC, they are barely recognizable. Browsing through your collection by cover is more fun when they're bigger.
  2. With the covers shown, it takes up a lot of useless vertical space. As you can see in the picture, for each item the image takes up the most of the vertical space (3x) with the text centered in the middle. The 'space to information' ratio is rather big. With wide screen displays being more prevalent, we really want to avoid taking up so much vertical space. Increasing the size of the cover would make it only worse.
  3. Covers are loaded in a non-threaded approach which makes the UI sluggish while the covers are loaded at start up. Depending on the number of covers this could take a long while and may consume lots of memory.

Threaded Cover Loader

So obviously there was room for improvement and the first issue I fixed some time ago was loading the covers in a background thread. This was made possible when I implemented the necessary infrastructure to move the importing of music to a background thread.

Every time the database is updated, it will automatically start the cover loader. It fetches covers for each album from disk, re sizes them and stores them in the cover cache. Once it is finished it notifies the UI, which then can display them.

Matrix View

The next change was to replace the list view with a matrix view. The list is still available, but doesn't show any covers. Here's how it looks:


The matrix view takes full advantage of any available horizontal and vertical space. As you can see the artist and album title are underneath the cover. Depending on the font size this may not always show the full name or title, but a tool tip with the complete info is available as well.

One detail I wanted to mention is that the cover loader will automatically apply cropping to a cover if it is close to being square.

Performance & Memory

The matrix view in combination with the new threaded cover loader worked pretty well for small collections. But with large number of albums, creating pixmaps for each of the covers took an awfully long time. What made it worse that this was happening in the UI thread.

I was able to optimize the pixmap creation by combining multiple covers (64) into one pixmap. (for 500 covers that means you only need to create 8 pixmaps instead 500). This seemed to work well, but I hadn't thought about memory consumption yet.

Recently a user was complaining that gogglesmm was using memory in excess of 130MB. Yes, that was over 2000 covers (uncompressed) in memory. That definitely made me rethink my approach of maintaining the cover cache. After all, for drawing purposes we only need to have the pixmaps in memory that are visible on screen.

I changed the cover cache so that all covers will stay compressed in memory until they are ready to be drawn. At the moment that the cover needs to be displayed, it gets uncompressed and transferred to a pixmap. Pixmaps get reused so in most cases you only have about 12 to 16 pixmaps in memory.

Initially I was concerned that decompressing  and updating the pixmap from within the drawing routine would be too slow, but surprisingly I hardly noticed any slow down. Granted, this is on Intel Core2duo laptop (couple of years old) but I'm quite hopeful this will work on more ancient hardware as well.

Last but not least, if you're not interested in seeing the covers, you're no longer penalized by it. The cover cache and loader will only be loaded if the cover view has been activated.

Future

Right now the cover size is fixed to 128 by 128 pixels. I'm probably going add a setting to change size of the cover.