Tuesday, 30 July 2013

AudioCD. Week 6.

During last week I worked with MemoryMeta framework, metadata fetching and transcoding. Nothing very interesting in [MemoryMeta framework/metadata fetching], I just cleaned up the code.

Transcoding with Paranoia.

I've looked around libcdio and discovered that there is a library which allows to read data from CD in a platform independent way. So, I've started working with it during last week and I think it is good alternative for kio-audiocd. Current workflow looks like this (it definitely not a final version, but just prototype for testing): copying of track or bunch of tracks is prepared by standard Amarok transcoding framework, AudioCDCollectionLocation reimplements onlt getKIOCopyableUrls: for each track it starts new job where track is ripped to temporary wav file, when every copy-job is finished information about new tracks temporary locations goes again to standard transcoding framework.

The reason why I repeated word "standard"  quite few times is that if transcoding is done with help of kio-audiocd then AudioCDCollection uses its own implementation of transcoding process. For now there is significant bug in this prototype: resulting wav file isn't correct. Using imagination you can hear the desired melody, but it is obviously not enough ;) 

Monday, 22 July 2013

AudioCD. Week 5.

Plan for 5th week was "Integration of MemoryMeta framework for a track representation."  Under this plan I've refactored existing AudioCdMeta classes: AudioCd{Track, Album, Artist, Composer, Genre, Year}. Work isn't finished yet, but further improvements are planned for this week.

I've also started work on a CDDB metadata fetching. I have this CD in my collection, so it was chosen as a test subject. On the picture you can see the result:

I was faced with several problems. First one is that now AudioCd collection supports both CD-Text and CDDB, so everything is simple if CD has CD-Text but CDDB info isn't available or vice versa. But when both metadata sources are presented we should decide which to use. Maybe it is good idea to create a user-defined setting in the AudioCd collection for this case.
Source of a second problem is that a discid isn't unique. Let me show it on an  example. Site of FreeDb project isn't very convenient probably they haven't heard about GET,  therefore I can't give you a link to a search results for discid 880bfd09, but here is a picture with results returned from a database:

As you can see there are several entries in the database for the same discid and the main problem is that one of them describes entirely different CD. For now I just take first match from the results returned by libcddb, but this problem has to be addressed in a different way at some point.

P.S. I fully switched to libcdio branch, so new staff will show up only there.

Tuesday, 16 July 2013

AudioCd. Week 4.

During this week I had a fight with cd ejection. I haven't won it yet but I hope I will in upcoming few days.

I also continued my work on replacing kio-audiocd with libcdio. Current version of code supports asynchronous track enumeration with fetching metadata from Cd-Text. Let me show few pictures. I took audio CD with CD-Text. On the firts picture you can see how AudioCd collection for thi disc looked in Amarok+kio-audiocd:

On the left hand side you can see how collection created from the same CD looked last week (Amarok+libcdio), and on the right hand side -- how it looks now:

You can see that track number 5 has no proper name, but this is not bug, this information is missed in CD-Text.

I become a fan of libcdio, it is very powerful and easy to use library,  I have only one complaint concerning libcdio: api documentation isn't very rich.
If someone who is reading this are willing to help, then please take code from git://anongit.kde.org/clones/amarok/tgornak/melandory-gsoc.git branch name is libcdio, install it, take some of your CDs, listen for them and tell me about problems you have experienced.

P.S. I cheated a little bit in pictures, because  there is no CD-Text support in kio-audiocd, so there was no support of CD-Text in Amarok.

Wednesday, 10 July 2013

AudioCD. Bug hunting: new details.

Do you remember second week report, where I've described my problem with CD ejection, Solid and Amarok? Recently I've received comment with very clever idea. Here it is. Amarok is not the only KDE application which uses Solid, Dolphin is another example. So we can examine behaviour of solid-tester, Amarok and Dolphin in different combinations. Another observation from me was that Dolphin and Amarok both are relatively complex software, so I decided to include KsCd to testing list, because it also uses Solid and it is much simpler.

Then I started testing and found a very interesting behaviour:

solid-tester + KsCd
Everything is going like clockwork: solid-tester receives all signals in time, kscd also perfectly reacts on CD insertion and ejection. Mindful reader may already have idea about where problem lies, but if you don't then just answer a question: what is main difference between KsCd and Amarok/Dolphin? Spoiler:  KsCd doesn't use kio audiocd, but Amarok/Dolphin does.
solid-tester + Dolphin
And this is where fun begins. After brief look it seems that behaviour of solid-tester+Dolphin is the same as behaviour of solid-tester+Amarok. But I managed to gain some extra info. Let me list processes which has dolphin in theirs names (I've trimmed output of ps in order to fit it to reasonable length):
3635 dolphin
3639 kdeinit4: kio_trash [kdeinit] trash klauncherMT2024.slave-socket dolphinth3635.slave-socket
3640 kdeinit4: kio_file [kdeinit] file klauncherMT2024.slave-socket dolphinKP3635.slave-socket
3641 kdeinit4: kio_file [kdeinit] file klauncherMT2024.slave-socket dolphinbZ3635.slave-socket
3646 kdeinit4: kio_audiocd [kdeinit] audiocd klauncherMT2024.slave-socket dolphinbh3635.slave-socket
Then If you kill dolphin nothing happens. But if we check ps output again then we can see that  kio_audiocd  slave (line 5) is still there. But when you kill it solid-tester receive ejection signal.

 After this experiment I was pretty sure that problem is in solid+kio-audiocd. In order to have more evidences I checked out my libcdio branch and tested it. It works: Amarok and solid-tester both receive insertion and ejection signals normally. Also to test it yourself you can run Dolphin and then insert and eject CD few times AdiocdCD icon from left menu will appear and disappear normally  until you'll decide to load content of AudioCD.

Saturday, 6 July 2013

AudioCD. Week 3.

Goal for third week was "Decision about track enumeration routine should be made."
During second week I composed a list with few applications which I planned to review: k3b, kscd, vlc. Close friend of word 'review' is 'criteria'. Formulating criteria helped me realized that goal for third week is incomplete because we need not only enumerate tracks but also fetch metadata: artist name, track title and so on. And it is better to have solution which works for both problem. For the metadata fetching two approaches can be used: read CD-Text which is stored on CD or get metadata from internet databases such as MusicBrainz or CDDB. My opinion is that we should definielly support CD-Text and one of the internet databases. Now Amarok supports CDDB, so I think we should stay with it. Another important thing is that solution should work not only in Linux, but also in Windows.

Last week I showed track enumeration routine which was based on libmusicbrainz3. This approach has following advantages: first, libmusicbrainz3 uses libdiscid for track enumeration and disc id calculation and this library is cross-platform, second, MusicBrainz database can be used for metadata fetching. But as I said above I really want to support CD-Text (my motivation is simple -- most of my CDs has CD-Text on them).

But I think I found better solution during last week: libcdio (vlc uses it). I'll quote description of libcdio:
The libcdio package contains a library for CD-ROM and CD image access. Applications wishing to be oblivious of the OS- and device-dependent properties of a CD-ROM or of the specific details of various CD-image formats may benefit from using this library.
Plus it supports CD-Text and also CDDB. I've started playing with it. Current code which uses libcdio is synchronous, supports track enumeration and fetching some information from CD-Text.  For more details, check libcdio branch in my clone.

Thursday, 4 July 2013

AudioCD. Week 2.

Plan for second week was: "New implementation of AudioCdCollection. After this step is completed, Amarok should support AudioCd in a same way as before." New implementation of  AudioCdCollection was done during first week, so second week began with a testing of new AudioCD collection implementation. At the beginning of a week I did not found any problem and decided to continue my work with what was planned on a third week: "Decision about track enumeration routine should be done." 

I've created preliminary list of software which operates with CD and should be checked: k3b, kscd, vlc. I've started my work with investigation how kscd enumerates tracks. Kscd uses libmusicbrainz3. So I've tested enumeration of CD with libmusicbrainz3 in Amarok. There is new branch in my personal clone called musicbrainz, where you can find this code. If you don't need information about AudioCD from musicbrainz then libdicsid can be used for enumeration. For now main problem with libmusicbrainz3 is that CD-Text doesn't available out of the box.

At the end of last week I've discovered bug in AudioCD collection. It is known issue (see bug 319036) that AudioCD collection doesn't disappear from Collection View when CD is ejected from outside Amarok and I did not pay much attention to it during testing. But I discovered that AudioCD collections also not always appears in Amarok if CD was not inserted before the start of Amarok. So it turned out that problem is in receiving signals from Solid.

Let me start explanation with describing AudioCD detection workflow. First we check among devices which were inserted before start of the Amarok is there AudioCd:
QList<Solid::Device> devices = Solid::Device::listFromType( Solid::DeviceInterface::OpticalDisc );
foreach( const Solid::Device &device, devices )
    if( isAudioCD( device.udi() ) )
        // create collection

If so we create collection for it. Then we connect solid device detection and solid device ejection events to some slots:
connect( Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)), 
         SLOT(slotAddSolidDevice(const QString&)) );
connect( Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)), 
         SLOT(slotRemoveSolidDevice(const QString&)) );
As I wrote above there is problem with receiving signals from Solid. So my first thought was that I use functionality provided by Solid in a wrong way, so I've created a small snippet in order to test it. And it works perfectly it detects AudioCD on startup, reacts on CD insertion and ejection. So problem is somewhere in Amarok. Then I was faced with very strange behaviour. Imagine that there is running instance of Amarok with AudioCd collection in collections and there is running instance of solid-tester, I eject CD using button on CD-Rom and there is no any effect neither in Amarok nor in solid-test, but when I close Amarok, solid-tester reports about ejection.

I would love to tell you that I discovered what is wrong, but no. So wait for good news :)

UPD 09.07.2013 I wrote that  "K3b uses libmusicbraimz3" It is wrong, I meant kscd.