libcdio-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Libcdio-devel] Miscellaneous questions, primarily on design


From: Samuel May
Subject: Re: [Libcdio-devel] Miscellaneous questions, primarily on design
Date: Sat, 21 Mar 2020 13:41:09 -0700

On Sat Mar 21, 2020 at 6:17 AM, Rocky Bernstein wrote:
> On Fri, Mar 20, 2020 at 5:01 PM Samuel May <address@hidden> wrote:
> > I'm working on Haskell bindings to libcdio
>
> I think this would be awesome! Here's a fun fact recarding haskell: 
> the person whose code started this all and wrote a VCD authoring tool 
> vcdimager, hvr <https://github.com/hvr> also now works a lot in 
> Haskell.  I think his natural inclination and rigor that went into 
> vcdimager and may have accidentally bled into libcdio steered him 
> towards selecting Haskell as his primary programming language later.

Nice!  Fun that I'm bringing it right back to the beginning again in 
some little way.


On Sat Mar 21, 2020 at 10:21 AM, Thomas Schmitt wrote:
> > * Is there any deliberate reasoning behind 2.1.0 not adding a 
> > cdtext_get_language_index(..) with cdtext_select_language_index(..)?
>
> Do you mean cdtext_set_language_index() rather than 
> cdtext_select_language_index() ?

*select*_language(..) and *set*_language_index(..) always trip me up; 
there's a reason I tweaked the names a bit when I wrote their bindings.
(Don't worry, I've also included a lookup table in the docs.)

> I guess it is expected that you list languages by 
> cdtext_list_languages_v2(), pick one by cdtext_set_language_index() 
> and an index which you know, and, if needed, memorize the index for 
> later use.

Yeah, that's what I gathered, and what I'm doing in the higher-level 
interface of my bindings.  I think I made note of that gap when I was 
working on the transition layer, where a theoretical user might have 
selected something other than block 0 with the low-level functions 
before passing things over to the interface which manages the indices 
behind the scenes.


Rocky Bernstein wrote:
> > Having the means to jump exactly where you want doesn't mean that 
> > you can get back to where you started with just 
> > cdtext_get_language(..) -- what if we just happen to have been on 
> > the /second/ CDTEXT_LANGUAGE_ENGLISH block by some perverse CDTEXT 
> > author, or more realistically which of several 
> > CDTEXT_LANGUAGE_UNUSED?
>
> If you want to define a different API ok and we could discuss it here.

Thinking about it further above, and now that I'm more removed from the 
immediate puzzling out of logic, I don't actually think doing so would 
be anything but bloat.  As Thomas said, the typical user should always 
know where they are, even if I as the middleman don't have it as easily.


Thomas Schmitt wrote:
> > * What about changing the language of a block?  I know libcdio isn't 
> > primarily a disc-authoring library, though with cdtext_set(..) and 
> > cdio_get_cdtext_raw(..) it can definitely be used constructively
>
> Indeed ? Does it burn audio CDs ?

I was maybe a bit over-generous in that description -- I mainly meant 
that if someone wanted to use libcdio as an over-qualified CDTEXT binary
editor, they for the most part could.  (Though see my next response to 
Rocky below.)

And you did have that successful experimental burn back in 2009, after 
all (not stalking you, just came across that email while digging for 
something else in the archives, and I didn't realize it was you until I 
pulled it back up now).  Though you can definitely make an argument that 
libcdio wasn't burning the disc, just providing low-level drive access.

> Changing the language would normally imply the need for translating 
> the texts to that new language.  If this translation and burning a new 
> CD is the goal, then i propose to use libburn and maybe its CLI 
> frontend cdrskin. Option cdtext_to_v07t=...  dumps the CD-TEXT packs 
> in human editable form. input_sheet_v07t=... may then be used to 
> submit the changed CD-TEXT to a CD burn run.  If you are interested in 
> the API, see
>   https://dev.lovelyhq.com/libburnia/libburn/raw/master/libburn/libburn.h
> and search for "CD-TEXT".

That might just have to be my next set of bindings.  I do eventually 
want to allow CD burning through the music library suite, and libburnia 
increasingly seems like a good library to use.  There's a number of 
other intermediate steps before I'd get much use out of integrating burn 
capabilities, though, and enough of those are dependant on metadata that 
I'll probably wind up writing my own CDTEXT handlers.  I will, however, 
definitely take a look at those functions for anything I'll need to keep 
in mind for saving my metadata to make the integration easier.  Thanks!


Rocky Bernstein wrote:
> > but without cdtext_set_current_language(..) or similar, there's 
> > always a little bit which would need to be tweaked afterward, or 
> > empty blocks which need to be generated and piped into 
> > cdtext_data_init(..) manually before starting to write anything new.
>
> You are correct i - it wasn't my intention to try to compete with 
> existing authoring code and libraries. However there is a fair bit of 
> overlap which is unavoidable.

Ah, right.  Do one thing but do it well.  I'm going to blame this on 
getting distracted by the presence of cdtext_set(..) -- there's no way 
to set the genre code either.  I'm guessing that cdtext_set(..) is in 
there primarily because it's needed for cdtext_data_init(..), and there 
wasn't much reason /not/ to add it to the interface?  Thanks for pulling 
me back to the proper scope!

> If what you are doing easily fits within the current model it can be 
> extended. However if it doesn't consider libburn or whatever else is 
> out there.

Slightly off the immediate topic: my plans ultimately have libcdio (and 
libburn) as only a very small corner of the final project -- basically, 
a music library manager built for disc-as-a-single-file access and 
duplicate-track weeding, which doesn't attempt to take over your system.  
It's just that the beginning of the pipeline -- ripping -- seemed like 
it would make a good place to start (especially given that I need to 
reconstruct my music files at the moment anyway), and I got sidetracked 
into giving the bindings more polish than necessary.


Thomas Schmitt wrote:
> > * Likewise should cdtext_set(..) really leave 
> > cdtext_get_first_track(..) and cdtext_get_last_track(..) with the 
> > original bounds?  I'm sure some weirdness might crop up if those 
> > don't match with the start/end tracks from the disc as a whole, but 
> > on the other hand I didn't expect the current behaviour and I'm sure 
> > I'm not the only one -- at the very least, it should be documented.
>
> I would expect that the track numbers from cdtext_get_*_track() are to 
> be used with cdtext_get().
> Am i wrong ?

I can't speak for the design decisions, but that's what my initial 
question is based on: what if someone sets a field on a new track for 
some reason, before iterating:

  cdtext_set(cdtext, CDTEXT_FIELD_TITLE, "some data", 64, NULL);
  for (track_t i=cdtext_get_first_track(cdtext); 
i<cdtext_get_last_track(cdtext); ++i) {
    ...
  }

Something like that wouldn't give them back all the tracks they might 
expect.  This is definitely less of an issue now that Rocky's reminded 
me that libcdio was never meant for editing info in-place, but I can 
still see people getting tripped up by it -- hence documenting it.

The "weirdness" was mostly referring to lazy users using a single track 
bound for both CDTEXT and disc tracks.  That probably falls under the 
category of "incorrect usage doesn't need to be protected", but it is 
still something I consider; I got a bit of a reputation in theory 
discussions of a system security methods course by not disregarding even 
the work required to brute force keys.


Rocky Bernstein wrote:
> > * On a less general note, is there any API or #define means to 
> > disable or redirect the warning messages printed to stdout?  I still 
> > need to figure out how to pass them to the user, but Haskell has a 
> > thing about avoiding unexpected side effects, and text suddenly 
> > appearing in the terminal certainly counts.
>
> There is this global variable cdio_loglevel_default 
> <https://www.gnu.org/software/libcdio/doxygen/logging_8h.html#a4a2cfa6fc840a2071972a79f81de7757>
> that indicate the level of pain needed before reporting a problem.,
>
> Also you can customize the logging routines with cdio_set_handler() 
> <https://www.gnu.org/software/libcdio/doxygen/logging_8h.html#ac3eed1c912be3ca91a6323e110fe6a2a>.

I'll take a look at those, thanks!  cdio_set_handler(..) especially 
seems promising -- I'd rather not just banish every message to the ether 
if I don't have to.


Thomas Schmitt wrote:
> > * More troublingly, has anyone ever run into issues with CdIo_t 
> > sessions locking up your drives?  If I call some functions (I don't 
> > /think/ it happens across the board, but I haven't gone looking for 
> > a pattern yet) the physical button on the front of my drive stops 
> > working until I call cdio_eject_media(..) or *_drive(..) from the 
> > software side.
>
> In the end it is SCSI command START/STOP UNIT which locks the tray and 
> releases it. It might depend on driver and/or operating system whether 
> and at what occasion the lock command is sent to the drive. 

Rocky Bernstein wrote:
> > I know it's an issue with my Haskell, and likely with 
> > cdio_destroy(..) not getting called by the garbage collector for 
> > some reason, but I figured if anyone had come across before it in 
> > earlier development, you could save me time digging to verify that.
>
> The closest thing I can think of has to do with working on OS/X. If 
> you want to write to the drive you need to get exclusive access to the 
> drive which locks out any other access. And then when you do get 
> access, you should make sure that when the process using the drive 
> finishes it reliquishes exclusive access. cdio_open_am() 
> <https://www.gnu.org/software/libcdio/doxygen/device_8h.html#adb5f3f481d81cbf91231715c1ea9aad8>
> is the top-level function. I see the string "psz_access_mode" 
> parameter isn't described, I guess because this is driver specific 
> which really means it is OS specific. This should be documented better 
> in the future.
>
> Looking at the code though I see that SCSI access has been commented 
> out because it is in need of fixing up. However if you look at the 
> GNU/Linux code in lib/driver/gnu_linux.c around line 80 
> <http://git.savannah.gnu.org/cgit/libcdio.git/tree/lib/driver/gnu_linux.c#n80>
> you'll see the different levels of access modes. In particular there 
> is read/write (_AM_MMC_RDWR) and read/write exclusive 
> (_AM_MMC_RDWR_EXCL) and later you'll see the access-mode string that 
> correspond to this are "MMC_RDWR" and "MMC_RDWR_EXCL".
>
> To dig in and get more information about the instruction sequence set 
> the log level mentioned above to debug.
>
> Finnally, if this turns out to requre a bunch of SCSI MMC commands 
> that logically acts as a single high-level function, we can add that 
> function in. In particular mmc_eject_media() 
> <https://www.gnu.org/software/libcdio/doxygen/mmc__hl__cmds_8h.html#af8ea9a156462b898c0854a95697b35cb>
> works this way.

All right, sounds like I might need to go source diving for SCSI 
commands or access modes instead.  I'll go through the thread that's 
spun off in that direction when I can focus on it a bit better.


Rocky Bernstein wrote:
> > * Finally, is there a vetting process or anything else I should be 
> > aware of for language bindings?
>
> None that I can think of. Having done a few of these, I'll say up 
> front that many of the binding I've done don't cover the full set of 
> capabilites, just those that I wanted or needed and could easily 
> figure out how to do.  Being lazy has paid off, many or most of the 
> bindings are rarely used and I've only had to make small adjustments.  
> Or better the few that have tried these have offered patches for the 
> thing that they needed.

That sounds great!  Unfortunately my perfectionism won't let me do that!  
It all boils down to "If I do this, I want to do it well" and no 
judgement on you, but if I deliberately leave part of it undone, I don't 
feel that I myself did a good job of it.  It's like that 
considering-all-edge-cases thing I mentioned above: what if the one 
other person who might use the bindings wants to use the part I left 
aside?  I recognize that (if well-chosen) it's a very small chance, but 
I can't stop myself from seeing that chance.


Sam



reply via email to

[Prev in Thread] Current Thread [Next in Thread]