GSoC draft application

vedant agarwala vedant.kota at gmail.com
Sun Apr 28 22:15:36 UTC 2013


In the meantime, I have updated my project proposal as shown below. Your
inputs are is still as valuable so please comment :)

Name: Vedant Agarwala

Email Address: vedant.kota at gmail.com

Freenode IRC Nick: vedant

IM Service and Username: xmpp-google: vedant.kota at gmail.com

Location (City, Country and/or Time Zone): Kolkata, India GMT+5.30

Proposal Title: Improving and modularizing tag guessing

Motivation for Proposal / Goal: Currently, Amarok “guesses” tags of music
files through the MusicBrainz web service using either existing tags or
MusicIP (PUID) audio fingerprints. This method, however, is somewhat
outdated. MusicBrainz is phasing out MusicIP in favour of AcousID and other
methods of guessing tags have emerged. The aim of this project is to create
an abstract base class for tag guessing that can be suitably inherited by
other classes that aim to guess tags.

Getting tags from MusicBrainz is hard coded into the Amarok source code.
Hence tag guessing is not modularized; this makes it hard to add new Tag
Getters (like, for example, Last.fm). Moreover, MusicBrainz code is not
very well documented. So, it'll be very time consuming for a programmer
trying to add features even just to MusicBrainz since they will have to
read and understand the code. As of now, every track’s tags can only be
changed one by one that also after waiting a few seconds for each. More
often than not, the tags returned by MusicBrainz is incorrect or tags of
different kinds are returned.

Say when a user is listening to a particular song he/she realizes that some
tags to the song are missing. He/she will try to correct this by himself
and will be very happy to see a “Get tags from MusicBrainz” button. Rather
than updating the tags himself he/she clicks on the button and selects the
correct tags. But this is where it all ends. The user is only saved from
the trouble of typing. He/she still has to choose the correct tags. Many
times the user will not find any tags at all or they will be guessed wrong
entirely.

Moreover, there is no way of updating/correcting tags of multiple files. If
a user adds some new songs to the local collection with poorly formatted
tags. It is not uncommon for tracks to contain a track name in the format
“trackname - albumname - artistname” with the other details blank. Many
tracks contain names of websites (like downloaded from)  at the end of one
or more tags of the file. A user will want these tags to be fixed but it
will be a real pain to do this one by one. If he/she clicks on the “guess
tags from file” he/she is greeted by another dialog that takes a long while
to understand. Its likely that he/she will just close this dialog. Even if
he/she gets tags from MusicBrainz (assuming the fetched tags are correct),
getting them from each file one by one will be too much of a task for him.

Implementation Details:

   -

   Creating a generic framework for tag getters: I will replace the
   existing musicbrainz directory by a taggetter directory. It will contain
   Controller and Provider classes (similar to StatSyncing) under the
   namespace TagGetter. The settings UI and related classes will also be
   present in this directory. I will change the musicbrainzTagger() in the
   TagDialog class to tagGetterController(). Once this is called, the
   TagGetter::Controller (a singleton class) will be invoked and process of
   tag guessing will begin. The Controller will have a list (a QList of
   ProviderPointers) of available Providers and it will create objects of each
   of them. Each of those objects will implementing the abstract base class
   Provider. As required, the Controller will be calling the methods (and
   connecting signals to slots) of the Provider on the main thread and via
   polymorphism appropriate methods of each Provider will be called.

   Each TagGetter::Provider will have its own directory under the TagGetter
   directory. They will contain classes and one that will implement the
   Provider class. Data will be shared among the classes (in the TagGetter
   namespace) probably via QExplicitlySharedDataPointer. Each provider will be
   running in parallel. As the different Providers do their work, results and
   progress of the work will available to the Controller via the signals
   connected to the slots of the Controller. Establishing a connection to the
   web service server, converting the music into data sendable over the
   internet, fetching results and the error handling will all be part of each
   Provider’s work. Separate threads won’t be required because the network
   operations will be handled by Qt (QNetworkRequest and QNetworkReply) and
   they are the most time consuming. If something else takes time to run (like
   decoding the audio and creating the fingerprint) then the provider will
   have to manage this on another thread (probably by using the
   ThreadWeaver::Job). As part of the contract of each provider, each of its
   methods must return quickly. This is important because the Controller
   will guarantee calling these methods on the main thread.

   The Controller will provide the Providers with track details (through
   the track pointer)such as track data (name, album, artist, length, file
   location etc.). The framework will contain a TagGetterMeta class. Objects
   of this class will store a TrackPtr to identify the the track in the
   Collection and metadata (name, artist, album, etc.) returned by the
   providers. Providers will return a QList of objects of this class. The
   metadata that has been updated will be non-zero. Providers should not store
   this data but they should keep the data that authenticates the provider
   (probably an API key that is received on authentication) as long as the
   objects of themselves exist since many lists of tracks can sent to be the
   Provider in succession, either by the user or programmatically (refer to
   last point of “implementation details”). A AbstractSettings class will also
   be present so that users can customize the settings of each Provider and
   each Provider can store a small amount of data in the data using the
   KGlobal::config(). This will also be beneficial for the programmer(s) who
   add more Providers. It will also keep a consistent look and feel of all the
   TagGetterProviders.
   -

   Rewriting MusicBrainz tag getter: I will rewrite MusicBrainz code
   according to the above framework. All the existing classes will shifted to
   the new musicbrainz subdirectory inside the taggetter directory. The
   MusicBrainzFinder will become MusicBrainzProvider, implementing the
   abstract Provider class. Other code will also be re-written but its work
   will mainly remain the same, except for one major difference. Currently,
   libofa is used to create the MusicIP (PUID) that is sent to MusicBrainz.
   MusicBrainz is phasing out PUIDs in favour of AcustIDs.

   Hence, the MusicBrainzProvide will use
Chromaprint<http://acoustid.org/chromaprint>to compute AcustIDs rather
than the MusicIP generated by libofa. Codecs
   will identified using ffmpeg. Phonon will be used for decoding while
   Chromaprint will be used to generate the AcoustID. Chromaprint uses the
   standard C library[*]<https://bitbucket.org/acoustid/chromaprint/src/master/src/chromaprint.h>so
using this won’t be a problem. I will make Chromaprint a part of the
   optional tag guessing package (replacing libofa) and update the cmakelists,
   making Chromaprint as a requirement for MusicBrainz tag guessing. Hence,
   the MusicBrainzProvider will be available only if Chromaprint has been
   installed. A HAS_CHROMAPRINT macro will keep track of this. The provider
   will be “available” only if the macro is defined. Just as now, the
“The::networkAccessManager()”
   will handle the connection to the MusicBrainz server. The audio
   fingerprint generated by Chromaprint will be sent to MusicBrainz via a
   QNetoworkRequest and a slot will be connected to listen for its reply.
   -

   Creating Last.fm tag getter: Create the Last.fm tag getter. First, I
   will add the tag based service and then, if schedule permits, I can add the
   fingerprint based service. Hence, two LastFm Providers will be created.
   Implementation will be very easy thanks to
liblastfm<https://github.com/lastfm/liblastfm>-
   A Qt C++ library for the Last.fm webservices. Both the Providers will share
   the authentication data and reply so that network requests aren’t
   needlessly duplicated. They will be in the same directory but will have two
   available providers. The network replies by Last.fm is in XML format.
   Hence, the QtXML module will parse the replies accordingly. Now the
   similarities end. The network requests and replies will have to handled
   differently by the different providers, since one will be tag based and the
   other fingerprint based.

   For the LastfmTagProvider the track/artist name has to sent to the
   Last.fm webservice API. The webservice will then return the other track
   metadata. After being correctly parsed it will signal the required slot so
   that the Controller receives the tracks whose metadata has been fetched.
   For the LastFmFingerprintProvider we will first have to generate a
   “fingerprint” of the track using the Last Fm
Fingerprinter<https://github.com/lastfm/Fingerprinter>.
   This audio fingerprint will then be sent to the Last fm web service via a
   call to the track.getFingerprintMetadata<http://www.last.fm/api/show/track.getFingerprintMetadata>.
   Then the web service will return the track metadata along with a
   “confidence rating” to specify how accurately the track has been
   identified. All this data will be parsed by the QtXML module and sent to
   the Controller in a manner similar to above.
   -

   A better GUI: A better GUI is required. Though I will need to discuss
   with the Amarok developers what the new GUI should like so that it
   follows the general look and feel of Amarok, I am proving my interpretation
   as follows: I will replace the existing "Get tags from MusicBrainz"
   button by "Get tags from the following services: ". It will be followed by
   a drop-down list with check-boxes for each item containing names of the
   services.

   [image: http://troll.ws/image/458a61bc#.UX0fS0GH7gx]

   In “Amarok Settings” there will be a tag guessing section and every
   TagGetterProvider can create a tab to change settings of the individual
   provider. As getting tags from the individual services will run in
   parallel, results will be displayed as soon as they are fetched via the
   TagGetter::Controller. This list will persist in memory so that if the user
   closes the dialog and then reopens it, tags won’t have to be fetched again
   (until Amarok restart). The user can choose the best tags from the
   generated list. If tags from multiple sources are the same they should be
   clubbed and appear higher up the list compared to the others. Tags from
   different sources have to cross-checking for this similarity. Each set of
   tags that have been fetched will be accompanied by a “confidence rating”-
   between 0 and 1, and provided by the respective Provider. For similar tags
   the ratings will be added (or maybe similar way of increasing the rating
   that can be found out by testing). The list will be continually sorted
   according to the rating of each tag. The list will be a bullet list with
   colors depicting the “confidence rating”- 0 to 1 = red to green (as it is
   now). All user visible strings (buttons and tool-tips) will be written
   using i18n(). i18nc() will be used wherever requiered- like, for a label
   stating "number of track(s)".
   -

   A GUI for getting tags of multiple songs simultaneously: Its a  feature
   by which tags for multiple tracks (if not the entire local collection) can
   be changed. Getting tags requires many user clicks as of now, especially
   for multiple tracks. To solve this, a "Tag Getter Wizard" will select the
   best tags for every track. Best ones are written to files without user
   approval but in a reversible way. Tags will be saved to database and can be
   reversed/changed anytime (even after amarok restart) in both ways- 1) for
   individual tracks 2) through a list showing the changed tags.

   A user can start the wizard select the playlists and/or tacks whose tags
   need to be guesses, then make it run in the background or make it run in
   the foreground showing the details of each track whose tags are being
   changed (and missing ones added). Or, he/she can set it to run on the
   entire local collection and/or as new tracks are added to the local
   collection. I will make decoupled and modularized code so that support
   for this wizard can easily be extended to other collections. After the
   wizard has completed its operation a list will show the user the updated
   tags each a button that will reverse the the changes. Not all fetched
   tags will be updated. Though I can achieve the right balance only by user
   testing, as of now I set the default as "tags with confidence rating >1
   will be updated". This can easily be changed by the user in the settings
   page. Again, I will write every code according to the KDE
   internationalization guildlines. The exact look of this wizard will be
   decided after discussion with the Amarok team but a rough idea of features
   is depicted below:[image: http://troll.ws/image/438a77c9#.UX0fXEGH7gx]

*[The first and final pages of the Wizard]*
*

Tentative Timeline:

Bonding Period ( May end to mid June): Decide on finer points. Like,
details of the generic framework of tag getters, discuss how the end-user
GUI will look like, the look of and how to use the “wizard” to guess tags
for many songs, etc. Talk to my mentor and refine the implementation based
on his/her suggestions.

June-

<--- GSoC commences--->

week 3: Make the directories and write the abstract classes (with
documentation).

week 4: Polish, make cmakelists for, write make tests and compile the
written abstract classes.

July-

week 1: Re-write the MusicBrainz tag getter according to the framework with
better documentation

week 2: Add the features (like using AcoustID) to this MusicBrainz tag
getter

week 3: Compile and run the new MusicBrainz (displaying results in the old
UI itself)

week 4: Write the new GUI code. Run MusicBrainz tag getter in this fashion

<--- Mid term --->

August-

week 1: Write the Last.fm tag getter (as many features as possible)

week 2: Finish writing and test the Last.fm tag getter

week 3: Test the Last.fm and MusicBrainz tag getter together in the new GUI

week 4: Make the tag getter wizard

September-

week 1: Test the new wizard. Write make tests to make sure that new tag
getters follow the set framework

week 2: Improve documentation. Fix bugs that have been discovered over the
weeks

<--- suggested “pens down” --->

week 3: Fix Bugs, streamline and optimize the code.

<--- firm “pens down” --->

week 4: Do some code cleaning and fix bugs so that my project can be pushed
into the master branch.

October-

week 1: Improve documentation. Fix bugs.

Other Obligations: I have no other obligations. I can easily spent about 50
hours a week: around 8 hrs a day in slots of 2 to 3 hrs, one each in the
afternoon (10am-1pm), evening (4pm-6pm) and at night (10pm-1am), with some
hours less on weekends. Summer vacations will be going on till mid July.
Even after college starts, I will be following the same schedule for GSoC
coding. It is easily possible because very few classes are held in the
beginning of the semester and even if they do clash with my coding
time-period, the college teachers excuse GSoC students' absence from class.
Since I will have no other coursework obligations, I can continue to code
50 hours a week (with a similar schedule) even up till September.

About Me: I am currently in my second undergraduate year in National
Institute of Technology, Durgapur, India, studying Computer Science and
Engineering. I have experience coding experience with C/C++, Java
(including Android and making GUI using Java swing) and web services. I
have submitted 3 patches (Junior Jobs, one each for
Rekonq[1]<https://git.reviewboard.kde.org/r/107662/>and Amarok
[2] <https://git.reviewboard.kde.org/r/109283/> as well as a improved
formatting patch for Amarok[3] <https://git.reviewboard.kde.org/r/109295/>)
and 2 more are under review (both Junior Jobs for
Amarok[4]<https://git.reviewboard.kde.org/r/110101/>
[5] <https://git.reviewboard.kde.org/r/110082/>).

I love coding for open source. I’m sure working with a mentor who is
virtually present won’t be a problem. I have interacted (mainly with Matej
a.k.a. Strohel on IRC) over IRC, the amarok mailing list, reviewboard and
also the KDE bug tracking system. During the work period code can easily be
shared via GitHub. If it is possible, meeting a mentor face to face will
obviously be much more helpful. I have worked with my college seniors in
this fashion who have introduced me to Linux and Open-Source. Countless
times I have been to their rooms for advice and to solve my problems.

After GSoC I plan to become an active developer for Amarok and also for
other projects of KDE.

*


On Mon, Apr 29, 2013 at 2:43 AM, vedant agarwala <vedant.kota at gmail.com>wrote:

> Matej, it seems you are doing all the work around here and applying for
> GSoC too
> Kudos.
>
>
> On Mon, Apr 29, 2013 at 1:42 AM, Matěj Laitl <matej at laitl.cz> wrote:
>
>> On 28. 4. 2013 Lydia Pintscher wrote:
>> > Vedant Agarwala <vedant.kota at gmail.com> wrote:
>> > > Yes Myriam you are right. Sorry for the impatience. I missed the fact
>> that
>> > > you people must be very busy and in a different time-zone.
>> > > Thank-you for correcting first timers like me.
>> >
>> > Has Vedant gotten feedback by now?
>>
>> Not yet, but on my TODO list, but real life gets in the way, hopefully
>> tomorrow.
>>
>> Edward, Markey, Ralf, Sam, Bart, Teo: c'mon step in, I cannot do all the
>> work
>> myself.
>>
>>         Matěj
>> _______________________________________________
>> Amarok-devel mailing list
>> Amarok-devel at kde.org
>> https://mail.kde.org/mailman/listinfo/amarok-devel
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/amarok-devel/attachments/20130429/3b8d1300/attachment-0001.html>


More information about the Amarok-devel mailing list