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.

1 comment:

  1. Cùng lúc đó, trên không trung xuất hiện hơi thở nóng bỏng đến trình độ kinh khủng.

    - Đây chính là Cực Viêm Chi Địa sao.

    Nhạc Thành lẩm bẩm nói, nhìn hiện tượng trên bầu trời, chân mày Nhạc Thành khẽ nhíu lại, Cực Viêm Chi Địa này so với Thúy Phong Cổ Nham có mấy phần tương tự.

    - Khúc khích.

    Một mảdongtam
    mu moi ra hom nay
    tim phong tro
    nhac san cuc manh
    tổng đài tư vấn luật
    văn phòng luật hà nội
    tổng đài tư vấn luật
    thành lập công ty trọn gói
    chém gió
    trung tâm ngoại ngữnh khí lưu trên bầu trời bắt đầu khởi động, sau đó trong hạp cốc xuất hiện lổ hổng cự đại, lổ hổng này xuất hiện có thể nhìn thấy rõ Sơn Mạch đỏ ngầu.

    - Cực Viêm Chi Địa đã mở ra, mọi người mau vào.

    Bên ngoài Thần Hoàng Tộc các cường giả đều lao vào.

    - Minh La, Long Dược, chúng ta cùng đi vào.

    Thanh Sơn Lão Tổ nhìn Minh La, Long Dược nói, sau đó tung người đánh về phía bầu trời đi, nhóm người Lam Ma cùng Lục Ma theo sát sau đó.