Tales of software craftsmanship

Tales of software craftsmanship

A summer of transcoding for Amarok

It’s been GSoC season for over a month now and I haven’t blogged, so now I’m going to try to fix that. After last year’s Multilevel playlist sorting project, one of my proposals has been accepted again for GSoC 2010: I’m going to implement on-the-fly transcoding in Amarok.

Amarok is a music player and manager built around very general concepts of tracks and media sources. The collection tries to decouple the format from the data itself and presents the music as tracks (with metadata) rather than files. In other cases, music isn’t even stored in local files. These concepts, and others, allow one to truly rediscover music through seamless internet sources and media devices integration, and the user in fact doesn’t have to care where the actual data comes from. The many sources at one’s fingertips are accessible in a consistent way and playable from the playlist.

However, even in this day and age of stuff in the cloud, there are situations in which the user still has to worry about media formats, e.g. when acquiring new music, or copying existing music from one collection to another or from the collection to a portable music player. That’s where transcoding kicks in.

For example, one might have a quantity of Windows Media Audio files that should be transcoded to a more Free format in order to be usable in the future, or a quantity of Monkey’s Audio files, which, while lossless, are not well supported everywhere, especially in PMPs. And then of course, even if someone has a collection full of FLAC files, which is a reliable and Free codec, a conversion into a lossy format such as Ogg Vorbis or MP3 might be necessary for use with a PMP simply for reasons of storage capacity.

So my idea is this: whenever the user can copy files, give him or her the choice to either just copy, just transcode or transcode with custom options. That way, we cover both of the following use cases:

  • “I’m running late for a 4 hour train ride and I haven’t updated the music collection on my portable player, I need to quickly copy over my tunes while making sure they will compatible with the portable player”
  • “if I tweak the quality rating of the Vorbis encoder exactly the way I want it I’m going to save 1% of the space on my portable music player and still get the audio quality my sensitive ears deserve”.

The current situation is that the transcoding operation (in the strictest possible sense) works, so the next thing I have to do is integrate it nicely with Amarok’s existing collections framework. The current implementation uses FFmpeg, but I’ve placed FFmpeg-specific stuff in a wrapper class so something else could quite easily be used in the future if need arises.

The following screenshot represents the current state of the still quite unfinished transcoding GUI.

On a somewhat unrelated note, I’ve been to the  KDE Multimedia+Edu sprint in Randa, Switzerland.

It was a lot of fun and very productive too. I wish to thank the whole organizers team. Special thanks go to Mario Fux for his mad organizational skills, to the cooking team which I had the pleasure to share the kitchen with while preparing vegan stuff and to Knut Yrvin for arranging a much needed meeting with the Brisbane office of Nokia, Qt Development Frameworks regarding QtMultimedia and the future of Phonon. Finally, thanks Anne-Marie Mahfouf for a gift she gave me which allowed me to taste again something I like very much but haven’t been able to eat because of nickel allergy.

LikeBack in Amarok

Amarok 2.3.0 has just been released but the Amarok team is already working hard on the next release. Shortly after mainline opened for feature commits I pushed a feature that will hopefully result in the next Amarok release being based on user feedback even more than 2.3.0: LikeBack integration.

What is LikeBack?

Short answer: a client-server system for gathering context-related, anonymous and immediate user feedback.

Long answer: described in a blog post by Valerio Pilo, KMess developer.

Pics worth more than 1K words (hint: the icons in the top right corner):

As I’ve read, LikeBack was originally developed for BasKet Note Pads and ported to KDE4 by KMess developers.

In Amarok the LikeBack bar is enabled by default only for testing releases i.e. git builds and betas. When the user has a good or bad experience, or gets an idea for a feature, he can click on one of the icons in the top right and submit a message. With LikeBack we gather comments of the types “like” “dislike” and “feature idea”, single and short suggestions, not discussions or bug reports. Bugs are still handled through the usual dialog that takes the user to bugs.kde.org, a system much better suited for bug tracking than LikeBack: this also means that if we receive something like a bug report under the guise of a “dislike” through LikeBack, we will have to consider it invalid.

The feedback we have received so far (several dozen comments in half a week) is quite positive, no insults yet (yay!).

LikeBack is available in Amarok’s git mainline (and in git/nightly builds if your distro provides them) as of a few days ago (*not* in the 2.3.0 release), so feel free to give it a spin and let us know what you think, either through LikeBack or the usual channels.

Amarok 2.3.0 “Clear Light”

The Amarok team is always at work, aiming with every release to deliver the best music player on earth and beyond. For some it may be just great fun, for others it may be a sacred calling, but for all of us a release cycle is a journey with its ups and downs, that comes to an end with a release. Each release is a time when we unleash our brainchild into the wild, and take a moment to just feel proud about what we have achieved.

This is such a moment.

Today I’m happy to announce the immediate availability of Amarok 2.3.0 “Clear Light”, which brings countless improvements and fixes over Amarok 2.2.2, and lots of new features. This release is the result of extensive user feedback, and it contains many patches submitted by members of the greater Amarok and KDE community. Check out the release announcement and please digg it.

Evading the Microsoft tax

EeePC 1008HA with Archlinux and KDE SC 4.4

A few months ago I submitted my work for the Social Desktop Contest, organized by Frank of openDesktop.org. As you may remember, my submission was the social about dialog for KDE apps, currently only in Amarok, but I hope to move it to KDElibs when my university thesis work, my work work and other IRL stuff gives me a break.

Turns out, lots of people seemed to really like it (thank you for voting!), and it won the first prize, which was a Dell Mini 10v netbook with Ubuntu – a really great and appropriate gift for a Free Software contest.

Unfortunately Dell has a really weird way of doing business, long story short, regardless of the free movement of goods inside the EU, because of Dell’s arbitrary business choices it was virtually impossible to ship the netbook from Dell directly to me in Italy. Anyway, Frank and I found an alternative solution with me placing the order on Amazon.co.uk, and a few days ago I received an EeePC 1008HA (they didn’t have the Dell Mini 10v). The netbook market has changed a lot since its beginnings and nowadays it’s very hard to find a netbook without Windows, this one was no exception as it had the Microsoft tax on its price and that ghastly Windows license sticker on its underside. I hoped to get back the cost of the license, mostly for ethical reasons, and I hoped that Amazon.co.uk would do the right thing as described here, but a few weeks ago I picked up some random report on Slashdot about Amazon now refusing to cooperate in honoring Microsoft’s EULA, which made me worry a bit.

EeePC 1008HA with Archlinux and KDE SC 4.4

After I got the package, I just sent a polite message through the official Amazon.co.uk support channels, and at first, I got a canned response from a support guy offering me a full refund for the netbook. When I replied kindly requesting that they actually read my message, the support person replied with an e-mail full of apologies and offered me a ~30€ refund for the Windows license, without asking any further information or proof of any kind. I wouldn’t bet that the 30€ bill made it all the way to Microsoft through Asus, but I hope that if enough people bother Amazon with this, they might eventually poke Asus. So, including shipping and after the Windows refund, this netbook cost about the same as the Dell Mini 10v with Ubuntu would have, and it’s an awesome little gadget.

I’m running Archlinux on it, installed with the Chakra live distribution (the latest Archlinux live USB stick image isn’t recent enough for a confortable installation on this hardware), but I removed the stable (and awesome) KDEmod packages to replace them with packages from a KDE SC 4.4 snapshot repo. Hardware support under GNU/Linux is great, aside from the wired ethernet adapter which required some tweaking but it works now. Battery life is incredible. I had no trouble getting used to the keyboard, which is quite good, but the touchpad buttons are hard and they make middle-clicking difficult. The Atom N280 based system feels reasonably fast.

I want to take this chance to thank Frank Karlitschek for his hosting of the OCS contest and his help and cooperation.

Thumbs down Dell for actively refusing to do business like any decent internet store in the EU, and thumbs up Amazon.co.uk for cooperating with me in exercising the rights that the Windows EULA grants me.

Social Desktop integration in KAboutDialog

extendedabout7

A few years ago when I still wasn’t an Amarok developer, the development team appeared to me like a bunch of uber-l33t geeks with mad sk1lls locked up in some ivory tower, performing their arcane incantations. Obviously it’s not the developers’ fault, the issue was that no matter how hard you try to reach out to the wider community, there is always a not so blurred line between users and developers, and this social distinction raised the barrier to entry for me probably even more than my lack of coding skills did.

I’m trying to change this, by bringing the Social Desktop to one of the most prominent places where users learn about the development team of a program: the About dialog. By tying some openDesktop.org profile data into a modified KAboutBox, it’s much easier to convey the message that the project is developed by real people, with a new potential channel of user-developer interaction right inside the app. For users, the advantage is that developers are now easier to reach, and I also hope that this might increase the quality of the communication by making some potential trolls realize that they are not talking to nameless nicks on IRC. For contributors, this might also be a nice recognition of their accomplishments: many of us do this unpaid, for fun and for love, and it’s nice if at the end of the day one can at least get a pretty dialog with a picture and a few rows of credit.

But what does “integrating Social Desktop features” really mean? Well, it can mean everything and nothing, in this case it means a new dialog called ExtendedAboutDialog for lack of a better name. Contributors have additional extended entries with data downloaded from openDesktop.org that can be viewed if the user has internet access and an openDesktop.org account. The About dialog becomes a small social desktop client.

The implementation is currently based on Amarok, but I’m keeping it as generic as possible. It uses the OpenCollaboration Services API, through the Attica library. Attica is a library, not yet independent, as I understand originally developed for the OCS dataengine and currently in kdeplasma-addons. Though the dataengine with Attica is already in 4.3, the Attica library may land into KDE 4.4. Until then, I have crudely copied over libAttica into Amarok’s source tree.

This dialog is already integrated in Amarok’s master branch on Gitorious, and my work on this about dialog can be tracked on my Gitorious page http://gitorious.org/~teo.

What follows is a screenshot of the dialog on startup. We can’t try to download data right away because the user has to sign into openDesktop first. So we just show the old style credits, with a button on top.

extendedabout3

When the user clicks on “Connect to openDesktop…”, a login dialog appears and the data is fetched from openDesktop.org. Meanwhile, authors who don’t wish to use openDesktop.org are already added to the list.

extendedabout4

Finally, when the data has been downloaded, the list is completely populated.

extendedabout6

This works for contributors without author status too, with the profiles being shown in a thinner format to save space.

Social Desktop integration in KAboutDialog

This dialog is still a moving target, and I’m posting quite regular updates and screenshots on its openDesktop.org entry.

GSoC final report: Amarok’s playlist, hacked into submission

When I started working on my proposal for what would eventually become my Google Summer of Code 2009 project, I was a much less skilled coder with no experience on something as large as this project turned out to be. I’m not bragging about becoming so insanely wiser now, but I have certainly gained tons of valuable experience, learned a lot about software development, and had a great time doing it!

So what exactly have I accomplished this summer?

Those who have been following my updates might remember the first part.

Well, the initial idea was to implement multilevel sorting in Amarok’s playlist, with a nice GUI, and throw in configurable grouping if there’s time. However right from the start it was clear that much more invasive changes were needed. As I already mentioned, Amarok’s playlist uses Qt’s Model/View design pattern. When I began working on my project the playlist had a source model (a class which feeds the rows), a filter proxy model (which filters out some rows that don’t need to be shown when a filter is active), a grouping proxy model (which decides which tracks should be grouped together because they belong to the same album) and finally, the view. Ideally, each model should talk only to the model right below it (if any), and the view should only talk to the “topmost” model to avoid any screw-ups in row presence and order. Failure to enforce this results in spaghetti code, which is exactly what was going on in the playlist code at the time.

So most of my first GSoC month I spent despaghettifying these Model/View classes, so that the Playlist::Model feeds data only to the FilterProxy, which feeds data only to the GroupingProxy, which feeds data only to the view. During this despaghettification, I also added a new proxy model: SortProxy, which is the class that actually implements the multilevel sorting backend. A month or so later I also added another proxy, SearchProxy, by decoupling searching from filtering. So the final result, as I already mentioned, is Playlist::Model->Filter->Sort->Search->Grouping->View: 5 models and one view. Doing all this without Qt’s Model/View classes would have been *a lot* harder and much more chaotic. So by the end of the second month the playlist code was refactored and made much clearer, the right auxiliary classes had been associated with the right model or proxy (mostly the topmost one, GroupingProxy) and a simple testing GUI was in place for multilevel sorting.

For the GUI, I chose to adapt a familiar paradigm to a new use case, so I used a breadcrumb path based widget. A sort scheme is a progression of levels, which represent sorting criteria, and those are applied to the playlist in real time. What’s even better, sorting is not an action but a state, which means that the original sort order can be recalled at any time. One of the sorting levels is also “Random”, so almost for free this interface also implements configurable multilevel shuffle!

Multilevel playlist sorting interface

In the last weeks, which were quite busy, I implemented configurable grouping, so the user is no longer forced just to group by album or not group at all. Finally, as a bonus, I took advantage of the existing Amarok URL infrastructure to implement playlist view bookmarks. These bookmarks define a URL for each playlist configuration, which aggregates a sorting scheme, a grouping category, a playlist layout and a filtering expression, and store it in the bookmark manager. The user can then instantly apply these bookmarked states and avoid having to rebuild a sorting scheme, a grouping category, select a layout and enter a filter string manually.

Playlist view bookmarks!

Playlist view bookmarks make it much easier to control this mighty playlist, which will be landing on a GNU/Linux distribution near you with Amarok 2.2 some time this fall!

I’d like to take this chance to thank my GSoC mentor Nikolaj Hald Nielsen and the whole Amarok team for their patience, dedication and help.

GSoC update – The playlist sorting breadcrumb

The last time I wrote about multilevel playlist sorting in Amarok a few weeks ago, the backend work was mostly completed but the (temporary) GUI was fugly, just a bunch of comboboxes.

Not any more.

For Amarok 2.2, among other things, we are working on improving the consistency of the user experience by adding horizontal symmetry, so both the browsers pane (default left) and the playlist (default right) will look and feel similar. Those two areas already had very similar filter bars, and since a few days ago they also both have breadcrumbs.

Until recently, breadcrumb bars have been used almost exclusively in file managers, but there’s no reason why they couldn’t be used to express any sort of sequence of objects in a hierarchy. In Amarok 2.2, we are introducing this common and well understood GUI metaphor and using it to express new and complex operations. More than a month ago, Amarok developer Nikolaj Hald Nielsen implemented the breadcrumb concept in the browsers pane, where it’s used to easily navigate through the ever increasing list of Amarok’s music sources. We like to say that with Amarok 2 the world is your playlist, and the browsers breadcrumb bar is an ingenious way to bring the world’s music to the user’s playlist through our Internet services framework.

A few days ago I pushed to Amarok’s git repository a first version of a new breadcrumb interface, this one is used in the playlist. Every item in the breadcrumb represents a sorting level, or category. It doesn’t implement any kind of navigation (like usual breadcrumb bars), but so far we have found that it works remarkably well for expressing sorting schemes, which are nothing more than selections of nested objects of some kind. To express “sort by artist, and if the tracks have the same artist then by album, and if the tracks belong to the same album then by track number”, the user just has to “navigate” to “Artist > Album > Track number” in the breadcrumb bar, and the playlist view changes accordingly in real time. But what’s even better, and unlike usual “spreadsheet” sorting interfaces, this sorting method is technically a state and not an action, which means that the original track order is preserved and can easily be restored by clearing the contents of the breadcrumb bar.

The new Amarok playlist sorting interface

A few features are still missing before I can call this GSoC project “done” and I’m currently working on them, mostly sort order inversion and sort scheme bookmarking.

GSoC update – lasagna code

It’s been more than a month since my last GSoC status update. I wanted to blog more often, but unfortunately I had nothing shiny to show, all the work I’ve done was under the hood, mostly on implementing multilevel sorting and refactoring the playlist code. The refactor is what took most of the time and it’s still not finished. Basically what I’ve been doing is converting one kind of italian pasta into another, spaghetti code into lasagna code.  So a couple of new classes have popped up to enforce a consistent interface for all the playlist proxies and to share code, and I’ve been trying to make every proxy talk only to the proxy directly below it.

In pseudo-UML, this is the situation I’m trying to achieve, the arrow means “is-a” and the arrowless line means “has-a” or generally “talks-to”:

amarok-playlistuml

I’m almost there, but right now, even if the tracks are displayed sorted, they are played in the original order which makes no sense, so the next step is to make the code that handles progress through the playlist (navigators) talk to the topmost proxy (GroupingProxy). Also, a new proxy might pop up soon to cleanly handle searching, which is a pretty different concept vs. filtering that just happens to share the same GUI.

Anyway, as a refreshing break from the Playlist::*Proxy heavy lifting, I hacked together a new testing interface for multilevel playlist sorting:

amarok-newsortinggui

Disclaimer: I’m aware that it’s ugly as hell, and that it doesn’t allow to sort by inverse alphabetic order, it’s just a temporary GUI for everyone to play with and test the sorting functionality. I’m still a few weeks away from starting work on the real thing, which I plan to implement as a breadcrumb-like widget.

GSoC status update – of proxies and maps

Hello again. In my introductory post I declared that I would post regular status updates about my Summer of Code work on Amarok’s playlist – and of course I’m already slacking off.

I started researching and coding towards the end of april so I have almost a month of work to report now. Unfortunately there are no pretty pictures this time because all the work has been under the hood so far.

As Amarok’s playlist uses a model-view paradigm, I have added a new proxy model between the filter proxy and the grouping proxy, so at the moment Amarok’s playlist view displays data that passes through a stack of four models (1 source model + 3 proxy models). GUI work will begin a bit later, at the moment the interface is just a combo box and a button that says “Sort!” which I use for testing. So what does it actually do right now? The good news is that multilevel sorting of the playlist kind of works: the user just has to hardcode a multilevel sorting scheme or select one of the available schemes from the combo box, click “Sort!” and the magic happens. Basically, the sorting scheme gets translated into a QList that maps all the source indexes to an ordered n-tuple, this QList is then used as a lookup table. The bad news is that sometimes the magic spell goes terribly wrong, as I still have to handle the consistency of the  map when the playlist is already sorted and the user adds, moves or removes some tracks. All the time I put into studying algorithms at the university has finally paid off big time, and I’m being very careful about the efficiency of the code – in the present state the sort proxy stuff might crash Amarok from time to time, but at least when it works it’s quite fast 😀

All this and hopefully much more should land in trunk some time after Amarok 2.1.1 gets released.

Hacking Amarok’s playlist into submission

Hello!

My name is Teo Mrnjavac and some of you might know me from my previous work on Amarok as a Summer of KDE student last year. Back then I implemented an interface for defining layouts by drag’n’dropping, which has been used for extracting tags, organizing the collection,  defining playlist item layouts and also in Kopete for configuring contact list items as I’ve heard.

This year my Google Summer of Code proposal has been accepted and with the help of my mentor Nikolaj Hald Nielsen I’m embarking on a mission to make Amarok’s playlist the awesomest playlist ever.

The full title of the project as submitted is “Finish the playlist: multilevel playlist sorting with configuration interface”, which means that I’ll mostly be working on implementing multilevel sorting, plus some other related fixes.

The current implementation of the playlist view in Amarok has become much more configurable recently, allowing the user to customize the format of each item by dragging around tokens that represent the fields of the track’s metadata. However, there’s still no way to sort these items according to the content of the fields, forcing the user to move around the items manually to achieve the desired effect. This can be tedious and impractical even on small playlists.
A playlist is a list, and a user expects a list to be sortable. In this case, simple single level sorting just wouldn’t suffice: Amarok’s playlist is much more than a bunch of lines of text.
To reach feature-completeness with the Amarok 1.4 playlist, and to conquer an important milestone on Amarok’s road to eternal awesomeness, a nifty interface is needed to sort the tracks.
So during this GSoC season I plan to deliver multilevel sorting for the playlist, an interface to configure it and configurable grouping.

If all this was TL;DR (it would probably be for me), here’s a nice mockup of a possible multilevel sorting interface that shows off my mad Kolourpaint skills. Notice the thin multilevel sorting bar under the playlist search bar. It’s simple as that, the user would click the “+” to add the next sorting level through a menu.

At the end of my GSoC work the playlist would be considered feature complete.

Last year I was a very lazy blogger and now I would like to change that so I guess you can expect regular progress reports. I have been informed that failure to comply with the blogging requirements about my work this year will result in me feeling the Amarok community manager’s Long Pointy Stick Of Doooooooooooooooooooom (TM).

Cheers!

Pages:123