Wednesday, 3 September 2014

GSoC Completed

Many times in the last three months I wondered whether I would be able to post something with such a title. But I am finally so glad to do so. Relived also.

In my remaining work I had to fetch lyrics automatically from Web APIs. I couldn't find documentation for this online. The best I could do was use Lrc-ShowX's code. I wondered how hard could that be

The thing I considered to be the easiest, turned out to be the most hellish. It was just suppose to be porting python code to Java script, which I did, keyword for keyword; learning both the languages in the process. But I wasn't getting the expected results. Now debugging. Sigh! It took me a week of intensive debugging only to realize that JavaScript is incapable of the large bitwise operations that I was doing. Python, on the other hand, has no limit on the size of its integer. Its not worth one week of intensive coding and debugging only to learn that JavaScript's largest integer is not large enough.

But actually, I learnt more than that. I leant persistence, that some problems are smaller than they seem and probably many more things than I can consciously remember.

Once the problem was identified, I quickly found a workaround. I made a C++ function that performed the calculation and returned the result. It is actually very hacky since in Amarok we have scripts (in JavaScript) that manage lyrics- decoupled from the rest of the Qt/C++ code. The function I made is useful only to the ttplayer lyrics script. Though I wasn't proud of this bit of code, it had to be done and I had to move on. I had crossed a hurdle but the marathon still had to be completed.

From there on it was mostly uneventful. I just used the existing Amarok script (that fetched plain text lyrics), except for the fetching part. I sent the results back through the same Amarok scripting API. My code was already there to handle the rest. It was working before the mid term. But even then it was very satisfying to see everything working in harmony.

Also, I just added a draft to update Amarok 's wiki page so that it reflected the feature I have added.

I had completed my GSoC project not only officially but also by my standards. It was a real proud moment. Some days later, after I submitted my code for review, there was another:


Friday, 25 July 2014

Another report

As I make progress on my project, I learn just as all gain is not monetary not all progress is code.

From the time of my last report (Sorry Myriam since it was more than a week ago), I have not written any "pushable" code i.e. only some code has been changed that serve as markers (like a TODO) for future work or some really minor bugs fixed that I stumbled upon as I use my flavor of Amarok.

Anyway, I was going through the collectionscanner code, trying to understand how it works: it as another process that the main Amarok process communicates with. It is designed to go through files and directories and mark files that are useful to Amarok. Like .mp3 , .ogg , etc. I am thinking to add .lrc to this list. For this I will have to create a class whose instance would represent an lrc file.

After this I will need to add these lyrics to the Amarok database. I still haven't been able to decide should I make this change in the generic core/collections/Collection.cpp class or the core-impl/collections/SqlCollection.cpp class. When this is over, I will just have to save the lyrics as lyrics tag and the LyricsApplet will pick it up.

Wednesday, 9 July 2014

post mid-term report

As I had written in my earlier post my job is two-fold. Now, for the second half of my GSoC project, I have to work on downloading the LRC file.

When I was writing my proposal it appeared that highlighting would be the tougher part compared to fetching .lrc files from webserivces. But if history has taught me anything, it is that proposals rarely ever end up like implementation. I had planned to pirate the LrcShow-X's code. It fetches .lrc files from a number of sites. But after spending a week on trying to understand it code, I am uncertain whether I would be able to reliably pirate even one such provider reliabally. If you know of such a webservice (that provides .lrc files) please comment.

Another way of implementing it would be making Amrok's scripting interface work directly with the .py files of LrcShow-X. It would mean that I will have to enable Amarok's scripting interface to work with python scripts (unless Amarok does not do so already). LRC-ShowX's source has different classes for different webservice engines, each of wich has a superclass "engine.py". Hence, all have a common interface. I would just have to use this.


I have not written any code as yet. Matters are a bit tense. I hope just as the highliting part turned out to be easier than I imagined, this part turns out to be easier as well.

Wednesday, 18 June 2014

Sponsors required for KDE code sprint in Randa

Hello,

KDE is organizing a "coding sprint" in Randa, Switzerland. KDE Developer Sprints are focused gatherings of KDE developers to work on a specific part of KDE. Sprints are an opportunity to plan, design, and hack (think 20% socialization and 80% perspiration). Though sprints are supported by KDE e.V. financially and organizationally, we are having more enthusiastic people than funds allotted to us by KDE e.V. We need your support in helping us to fill this gap.

Me and some other students like me are willing to goto Randa but cannot if we are not sponsored. Any contribution you could make would go a long way in helping the organizers meet their target. Also, you could the spread the word on social networks or any other media to help us.


Website for Randa sprint: https://sprints.kde.org/sprint/212

Tuesday, 17 June 2014

First Report

As the title (Lyrics Support improvements) of my Google Summer of code project suggests, I am improving the way lyrics are fetched and displayed in Amarok. Personally, I like to follow the lyrics of the song that is playing; so I added this is idea to the Idea Page for GSoC 2014. And now here I am, working on it. I goal of my project is to highlight the particular line from the entire lyrics text that is being played.
The way following each “currently playing line” works is by parsing a LRC file- at the beginning of each line of lyrics is a timestamp tag ( [mm:ss.xx] <lyrics line> ). This represents that the time interval between this timestamp and the next, this particular “lyrics line” is being “played'. My job is to make Amarok parse this LRC and for the current playing time of the song, highlight the line in the lyrics text.
So my job is twofold-
  • Download the LRC file
  • Parse this LRC and highlight the line accordingly.
So far I have worked on the second part. Parsing the LRC was pretty straightforward, I used the QRegExp class match the timestamps and extract the minutes, seconds and hundredths of a second. This timestamps are keys in a QMap. The values of this QMap are indexes of the line in the lyrics. It took some learning of regular expressions as went along coding and some trial and error.
Now comes the hard part: highlighting the line. When I was writing my project proposal, I had no idea on how to do this. I searched the internet for some software (line minilyrics for Windows) or a music player that displays scrolling lyrics. Ironically, I found LrcShow-X. It fetches and displays scrolling floating lyrics in a separate window. Works with many LINUX music players including Amarok! It was on KDE-apps and hence was open sourced. I looked it source code which was in PyQt. I thought I would go though its code and make an even better lyrics display as an applet (like the Analyzer, and old lyrics applet) in Amarok. I wanted to create a rectangular lens that would incsease the size of the line in the middle. This would be the currently playing line in the lyrics text. I didn't write any code but I researched a lot. I decided how to the code, including mentioning the names of classes and functions in the Qt library. This is how the first version of my project proposal looked. Bad idea! As Mamarok (Myriam Schweingruber) pointed out, it was like reinventing the wheel and I should go something more simple that gets the job done rather than trying to accomplish so much at once. She suggested me to OggKate. It can create an ogg video stream playable in a HTML5 browser using a LRC file and ogg audio file. Following her advice I researched and rewrote my proposal to use OggKate. I kept adding and editing my proposal till the last minute of student application deadline.
During the coding period, I started by adding liboggkate to Amarok but after a few lines of code later, I found out that OggKate was for ogg files only. No .mp3, .wav, etc. It would be a total waste to do so much of work and lyrics would be displayed for a few file formats. So, I got back to research mode. This worried me as I should have been coding at this time. Anyway, I got back to LrcShow-X and trying to understand its source code. This is when I understood the importance of a well maintained source code and why maintainers have to be so pedantic. Anyway, I went on. Took me a few days, as I was new to python itself. I tried to use its code in its entirety, by trying to embed python code into Qt/C++ code. This wasn't easy and I realized that PyQt is for using Qt in python. It would be very redundant for me to embed python code in Qt code that inturn used Qt code. I felt that all the py code would be using Qt classes that would be identical (and faster) in C++, at least for GUI code. Some more days of research later, I turned out to be right. All that LrcShow-X was doing was “selecting” the current playing line. Yes, “selecting”; just as one selects text by dragging the cursor over text. So simple, so brilliant. I could use this in the existing Amarok lyrics applet; no need to write another applet (as I had planned and mentioned in my proposal).
I was halfway to my mid-term submission and with no useful code written I needed to act fast. I wrote the LRC parser and changed code in the LyricsApplet class. In order to test it, I (and you) just have to paste LRC formatted lyrics into the lyrics tag of the particular song. It can be done either by editing the lyrics in the lyrics applet or by right-clicking on a song-> “edit track details”->”lyrics”. I I did this for a few songs and saw the results with my fingers crossed. After some debugging, the lyrics was highlighted as I expected but the experience wasn't very astounding, there no animation as the lines changed and highlighting went from one line to another: again, as I expected. I added two buttons to control offset and some code to save the offset back to the LRC formatted lyrics. The write to file operation is performed only when the track is changed. This was important as setting the offset correctly requires many clicks (and often in quick succession) and would lead to many write operations. Some more bug fixing and I am ready for my midterm submission. However, some features, like editing lyrics while the song is playing and pausing of highlighting if the user is actually trying to select some text on the Lyrics applet still need to be added.
Rather than fixing these issues I would move on to the other part of my twofold job- fetching the LRC style lyrics from the internet. Again I am tempted to use the code of LrcShow-X because it works so well. I hope I would have better luck this time as lyrics fetching in Amarok is implemented via scripts. I hope this works just as well for python scripts as it does for javasripts. LrcShow-X has a lot of potential web services from which it can fetch the content but individually porting them to be used for Amarok would be a Herculean task. It would be better for me to add support for python scripts, make a python script to interface between the Amarok scripting framework and the source code of LrcShow-X. As much as I love abstraction, I would probably need to have a settings window to control this behavior as a lot web services would mean a lot of chances for some unexpected behavior after a release. I am not sure how exactly this will play out; if the first half of my GSoC project is any indication, it would be nothing like what I have written. But I am sure of one thing, it will be a great learning experience for me.

My ultimate goal is to add the features that I have promised. I hope I achieve it. Not only would it improve the Amarok experience, it would pave the way to developments in Amarok; like karaoke. I love karaoke (even though I am very bad at it). Though it is out of the scope of this project to implement a karaoke feature, implementing LRC support is halfway to karaoke.