Hello everyone, Below is the outline for my "Improving and Modularizing tag guessing" Season of KDE project:
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, an object of TagGetter::Controller will be created 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. 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 the TrackPtr and hence with track data (name, album, artist, length, file location etc.). I will write a TagGetterMeta class. Member variables of this class will include a trackPtr (to store the track pointer of the track whose metadata is being fetched) and metadata variables (name, artist, album, etc.). After data has been fetched, Providers will fill the metadata to the TagGetterMetra objects according to the trackPtr and return this object via a signal to TagGetter::Controller. 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 quick succession. Each Provider can store a small amount of data in the data using the KGlobal::config(). A provider should add itself to the "plugins" section in Amarok Settings so that it can be enabled/disabled by the user. If badly required also provide some additional user changeable settings, since its best to keep working of plugins as abstracted from the user as possible. Adapt MusicBrainz tag getter to implement the abstract Provider class: 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 MusicIpProvider, implementing the abstract Provider class. Other code will also be re-written. Currently, libofa is used to create the MusicIP (PUID) that is sent to MusicBrainz. MusicBrainz is phasing out PUIDs in favour of AcustIDs. Hence, another Provider will be made (in the same directory). A AcoustIdProvider will use Chromaprint to compute AcustIDs rather than the MusicIP generated by libofa. Chromaprint will be used to generate the AcoustID. Chromaprint uses the standard C library[*] so code can easily be used withing existing classes. I will make libchromaprint a part of the optional tag guessing package (alongwith libofa) and update the cmakelists, making Chromaprint as a requirement for MusicBrainz tag guessing. Hence, the AcoustIdProvider will be available only if Chromaprint has been installed. Chromaprint will be part of the optional package. A HAS_CHROMAPRINT macro will keep track of this. The provider will be “available” only if the macro is defined. 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- A Qt C++ library for the Last.fm webservices. It is already used in Amarok. 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 and parsing will be handled by liblastfm itself. 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 be sent to the Last.fm webservice API. The webservice will then return the other track metadata. For the LastFmFingerprintProvider we will first have to generate a “fingerprint” of the track using the Last Fm Fingerprinter. This audio fingerprint will then be sent to the Last fm web service via a call to the 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. Tentative Timeline: September- week 1: Add the features (like using AcoustID) to this MusicBrainz tag getter week 2: Make the directories and write the abstract classes (with documentation). week 3: Re-write the MusicBrainz tag getter according to the framework with better documentation week 4: Polish, make cmakelists for, write make tests and compile the written abstract classes. October- week 1: Compile and run the new MusicBrainz. Fix issues and repeat week 2: (Holiday week) week 3: Complete the MusicBrainz tag getter. week 4: Write the Last.fm tag getter (as many features as time permits) November- week 1: Compile and run the new Last.fm. Fix issues and repeat week 2: Finish writing and test the Last.fm tag getter week 3: (College examinations) week 4: (College examinations) December- week 1: 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 week 3: Fix Bugs, streamline and optimize the code. week 4: Do some code cleaning and fix bugs so that my project can be pushed into the master branch. _______________________________________________ Amarok-devel mailing list Amarok-devel@kde.org https://mail.kde.org/mailman/listinfo/amarok-devel