[lang]

Present Perfect

Personal
Projects
Packages
Patches
Presents
Linux

Picture Gallery
Present Perfect

morituri pre-release

Filed under: DAD,GStreamer,Hacking,Python — Thomas @ 12:15 am

2009-9-12
12:15 am

After a visit from the unicode police I’m gearing up for a first morituri release.

If you’re on F-11, you can just install my repository and then install the latest snapshot with
yum -y install morituri

After that, pop in a relatively well-known CD, then type:

rip offset find

Hopefully, it will be able to tell you the read offset of your CD drive.

Then do

rip cd rip --offset (the number from above)

and it should proceed to look up the CD on MusicBrainz, rip and verify the tracks to flac, and then do an AccurateRip verification.

Let me know if that works out for you. And if you’re not on Fedora 11, you can always check out the source code directly, it’s not much harder to get running.

15 Comments »

  1. So, to recap (I didn’t read all the techtalk): this is the way to go for “perfect” CD-rips, right?
    Or aren’t we there yet (looking at https://thomas.apestaart.org/morituri/trac/browser/trunk/TODO )

    Is there a way to handle (musicbrainz) preferences? In picard (the musicbrainz official client), you can configure how to name/tag/categorize in directories all your songs. how do you handle this here?

    Also, one thing about Musicbrainz that bothers me a while are the continuous updates of their database. I.e. after tagging, there’s a high chance that the data you already used gets improved with typo’s/normalisation etc. I still haven’t found a good way to ‘update’ all my songs based on updates @ MB. Right now I would have to rescan my collection, filter/fix incorrect detections etc, which wouldn’t be worth the hassle.

    Comment by Dieter_be — 2009-9-12 @ 9:32 am

  2. I’ve tried it bu it fails with some unicode problem ?

    See:
    rip offset find
    Trying read offset 0 …
    Traceback (most recent call last):
    File “/usr/bin/rip”, line 28, in
    sys.exit(main.main(sys.argv[1:]))
    File “/usr/lib/python2.6/site-packages/morituri/rip/main.py”, line 12, in main
    ret = c.parse(argv)
    File “/usr/lib/python2.6/site-packages/morituri/extern/command/command.py”, line 295, in parse
    return self.subCommands[command].parse(args[1:])
    File “/usr/lib/python2.6/site-packages/morituri/extern/command/command.py”, line 295, in parse
    return self.subCommands[command].parse(args[1:])
    File “/usr/lib/python2.6/site-packages/morituri/extern/command/command.py”, line 271, in parse
    ret = self.do(args)
    File “/usr/lib/python2.6/site-packages/morituri/rip/offset.py”, line 123, in do
    archecksum = self._arcs(runner, table, 1, offset)
    File “/usr/lib/python2.6/site-packages/morituri/rip/offset.py”, line 169, in _arcs
    trackCount=len(table.tracks))
    File “/usr/lib/python2.6/site-packages/morituri/common/checksum.py”, line 229, in __init__
    ChecksumTask.__init__(self, path, frameStart, frameLength)
    File “/usr/lib/python2.6/site-packages/morituri/common/checksum.py”, line 53, in __init__
    assert type(path) is unicode, “%r is not unicode” % path
    AssertionError: ‘/tmp/tmpJF7qZn.track01.offset0.morituri.wav’ is not unicode

    Comment by seb42 — 2009-9-12 @ 2:09 pm

  3. @seb42: oops, wrong prerelease. Fix in subversion and uploaded to repo, please update and try again!

    Comment by Thomas — 2009-9-12 @ 7:04 pm

  4. What about FreeDB support? My CDs tend to never be available in Musicbrainz.

    Comment by Tobias — 2009-9-12 @ 7:21 pm

  5. Doesn’t seem to work for me:

    # rpm -qa morituri
    morituri-0.0.0.1-0.20090912.194418.fc11.noarch

    $ rip offset find
    Traceback (most recent call last):
    File “/usr/bin/rip”, line 28, in
    sys.exit(main.main(sys.argv[1:]))
    File “/usr/lib/python2.6/site-packages/morituri/rip/main.py”, line 12, in main
    ret = c.parse(argv)
    File “/usr/lib/python2.6/site-packages/morituri/extern/command/command.py”, line 295, in parse
    return self.subCommands[command].parse(args[1:])
    File “/usr/lib/python2.6/site-packages/morituri/extern/command/command.py”, line 295, in parse
    return self.subCommands[command].parse(args[1:])
    File “/usr/lib/python2.6/site-packages/morituri/extern/command/command.py”, line 271, in parse
    ret = self.do(args)
    File “/usr/lib/python2.6/site-packages/morituri/rip/offset.py”, line 83, in do
    runner.run(t)
    File “/usr/lib/python2.6/site-packages/morituri/common/task.py”, line 349, in run
    log.getExceptionMessage(task.exception))
    File “/usr/lib/python2.6/site-packages/morituri/extern/log/log.py”, line 633, in getExceptionMessage
    (filename, line, func, text) = stack[frame]
    IndexError: list index out of range

    I’ve tried with a Lite-On iHDS118 and an Optiarc AD-7201S. In /var/log/messages

    __ratelimit: 12 callbacks suppressed
    Buffer I/O error on device sr0, logical block 0
    Buffer I/O error on device sr0, logical block 1
    Buffer I/O error on device sr0, logical block 2
    Buffer I/O error on device sr0, logical block 3
    Buffer I/O error on device sr0, logical block 4
    Buffer I/O error on device sr0, logical block 5
    Buffer I/O error on device sr0, logical block 6
    Buffer I/O error on device sr0, logical block 7
    sr 2:0:0:0: [sr0] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE,SUGGEST_OK
    sr 2:0:0:0: [sr0] Sense Key : Illegal Request [current]
    ILI
    sr 2:0:0:0: [sr0] Add. Sense: Illegal mode for this track
    end_request: I/O error, dev sr0, sector 0
    Buffer I/O error on device sr0, logical block 0
    Buffer I/O error on device sr0, logical block 1
    sr 2:0:0:0: [sr0] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE,SUGGEST_OK
    sr 2:0:0:0: [sr0] Sense Key : Illegal Request [current]
    ILI
    sr 2:0:0:0: [sr0] Add. Sense: Illegal mode for this track
    end_request: I/O error, dev sr0, sector 0
    sr 2:0:0:0: [sr0] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE,SUGGEST_OK
    sr 2:0:0:0: [sr0] Sense Key : Illegal Request [current]
    ILI
    sr 2:0:0:0: [sr0] Add. Sense: Illegal mode for this track
    end_request: I/O error, dev sr0, sector 0

    Comment by Alex B — 2009-9-12 @ 8:41 pm

  6. Hmm. Seems like rip is getting my devices the wrong way round. If an audio CD is loaded in /dev/scd0, it tries to rip from /dev/scd1 and vice-versa.

    With an audio CD loaded in both:

    $ rip offset find
    Trying read offset 0 …
    Traceback (most recent call last):
    File “/usr/lib/python2.6/site-packages/morituri/common/task.py”, line 366, in c
    callable(*args, **kwargs)
    File “/usr/lib/python2.6/site-packages/morituri/program/cdparanoia.py”, line 253, in _read
    self._done()
    File “/usr/lib/python2.6/site-packages/morituri/program/cdparanoia.py”, line 315, in _done
    self.quality = self._parser.getTrackQuality()
    File “/usr/lib/python2.6/site-packages/morituri/program/cdparanoia.py”, line 167, in getTrackQuality
    return min(frames * 2.0 / reads, 1.0)
    ZeroDivisionError: float division

    $ ls -Al /dev/sr* /dev/*cd* /dev/*dvd*
    lrwxrwxrwx 1 root root 3 2009-09-13 11:42 /dev/cdrom -> sr0
    lrwxrwxrwx 1 root root 3 2009-09-13 11:42 /dev/cdrom1 -> sr1
    lrwxrwxrwx 1 root root 3 2009-09-13 11:42 /dev/cdrw -> sr1
    lrwxrwxrwx 1 root root 3 2009-09-13 11:42 /dev/dvd -> sr0
    lrwxrwxrwx 1 root root 3 2009-09-13 11:42 /dev/dvd1 -> sr1
    lrwxrwxrwx 1 root root 3 2009-09-13 11:42 /dev/dvdrw -> sr1
    lrwxrwxrwx 1 root root 3 2009-09-13 11:42 /dev/scd0 -> sr0
    lrwxrwxrwx 1 root root 3 2009-09-13 11:42 /dev/scd1 -> sr1
    brw-rw—-+ 1 root optical 11, 0 2009-09-13 11:42 /dev/sr0
    brw-rw—-+ 1 root optical 11, 1 2009-09-13 11:42 /dev/sr1

    $ groups
    xxx dos audio builders optical pulse-rt Domain Admins Domain Users

    $ cdrdao disk-info –device /dev/scd0
    Cdrdao version 1.2.3rc2p1 – (C) Andreas Mueller
    /dev/scd0: ATAPI iHDS118 4 Rev: FL03
    Using driver: Generic SCSI-3/MMC – Version 2.0 (options 0x0000)

    That data below may not reflect the real status of the inserted medium
    if a simulation run was performed before. Reload the medium in this case.

    CD-RW : no
    Total Capacity : n/a
    CD-R medium : n/a
    Recording Speed : n/a
    CD-R empty : no
    Toc Type : CD-DA or CD-ROM
    Sessions : 1
    Last Track : 12
    Appendable : no

    $ cdrdao disk-info –device /dev/scd1
    Cdrdao version 1.2.3rc2p1 – (C) Andreas Mueller
    /dev/scd1: Optiarc DVD RW AD-7201S Rev: 1.09
    Using driver: Generic SCSI-3/MMC – Version 2.0 (options 0x0000)

    That data below may not reflect the real status of the inserted medium
    if a simulation run was performed before. Reload the medium in this case.

    CD-RW : no
    Total Capacity : n/a
    CD-R medium : n/a
    Recording Speed : n/a
    CD-R empty : no
    Toc Type : CD-DA or CD-ROM
    Sessions : 1
    Last Track : 10
    Appendable : no

    Comment by Alex B — 2009-9-13 @ 10:53 am

  7. Seems to be pycdio’s fault:

    >>> pycdio.get_devices_with_cap(pycdio.FS_MATCH_ALL, any)[1:]
    [‘/dev/scd1’, ‘/dev/sr0’, ‘/dev/sr1’]

    What’s wrong with /dev/scd0, pycdio?!?

    Comment by Alex B — 2009-9-13 @ 11:04 am

  8. Beg pardon, I think it’s the [1:] in cdio.py’s get_devices_with_cap that’s dropping /dev/cdrom (aka /dev/scd0).

    I guess the SWIG code is now working properly here, at least.

    Comment by Alex B — 2009-9-13 @ 9:36 pm

  9. Confirmed; removing the [1:] makes ‘rip offset find’ apparently work on my iHDS118. Trying:

    $ rip offset find -d /dev/scd1

    (i.e. the AD-7201S)

    results in:

    Trying read offset 0 …
    Traceback (most recent call last):
    File “/usr/lib/python2.6/site-packages/morituri/common/task.py”, line 366, in c
    callable(*args, **kwargs)
    File “/usr/lib/python2.6/site-packages/morituri/program/cdparanoia.py”, line 253, in _read
    self._done()
    File “/usr/lib/python2.6/site-packages/morituri/program/cdparanoia.py”, line 315, in _done
    self.quality = self._parser.getTrackQuality()
    File “/usr/lib/python2.6/site-packages/morituri/program/cdparanoia.py”, line 167, in getTrackQuality
    return min(frames * 2.0 / reads, 1.0)
    ZeroDivisionError: float division

    Comment by Alex B — 2009-9-13 @ 9:48 pm

  10. Looks like the device doesn’t get passed on to cdparanoia.py’s ReadTrackTask()

    Comment by Alex B — 2009-9-13 @ 10:05 pm

  11. @dieter_be: yes, the idea is that you can use morituri for perfect rips, much like EAC, but with less configuration hassle. Whether I’m there yet depends on what my testers think. I nailed down the last bug I had in cdrdao that gave offset errors, so with that patched cdrdao and morituri it should now work.

    For the naming, there are two options to handle directory and track naming according to a template. Please try it out and give me some feedback.

    As for musicbrainz getting updated, there’s nothing you can do about that in a ripper. Another project I am working on bit by bit is a web-based management app for tracks, with various features, but one of them integrating with MusicBrainz’s data and hopefully that one will be continuously updating the metadata for tracks. I don’t think that would make sense to do straight in the files though.

    Comment by Thomas — 2009-9-19 @ 2:14 pm

  12. Do a release quickly so we can do other stuff!

    Comment by Kristien — 2009-9-19 @ 2:23 pm

  13. I will, don’t worry!

    Comment by Thomas — 2009-9-19 @ 2:23 pm

  14. re: point 3, i was thinking about storing the “track id” (or whatever it’s called in musicbrainz) in the id3 comment field or something. and/or keep the id of the album in a text file in the directory that represents the album. then it would be pretty easy to mass-update metadata.

    and web-based? what’s wrong with a shell?

    Comment by Dieter_be — 2009-9-19 @ 5:29 pm

  15. Storing the musicbrainz id’s might work; I opened https://thomas.apestaart.org/morituri/trac/ticket/4 to track that.

    I’m not sure it would be easy to mass-update – the MusicBrainz web api’s allow one query per second, on my 25000 song collection that would take a while.

    There’s nothing wrong with a shell. Anyone who thinks they can write a good management and playback app for music with a shell is welcome to do so :)

    Comment by Thomas — 2009-9-19 @ 6:22 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

picture