libcdio-help
[Top][All Lists]
Advanced

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

Re: [Libcdio-help] Custom read_audio function


From: Rocky Bernstein
Subject: Re: [Libcdio-help] Custom read_audio function
Date: Mon, 21 Nov 2011 23:26:57 -0500



On Mon, Nov 21, 2011 at 9:09 AM, Bastiaan Timmer <address@hidden> wrote:
Hi!

After reading an old message on this mailing list (http://lists.gnu.org/archive/html/libcdio-devel/2008-02/msg00001.html)
I wrote a custom read_audio function for ripping audio cd's. The read function basically looks like this:

long readRaw2448(cdrom_drive_t *drive, void *pbuf, lsn_t firstsector, long sectors)
{
 // ... do some allocations ...

 driver_return_code_t ret;
 if ((ret = mmc_read_cd(drive->p_cdio, s_buffer, firstsector, CDIO_MMC_READ_TYPE_ANY, false, false,
                        0, true, false, false, 1, s_buffersize, sectors)) != DRIVER_OP_SUCCESS)
 {
   std::cout << "RETURN CODE: " << ret << std::endl;
   return ret; // will be negative if we get here
 }

 // ... handle the data (handle subframe, copy audio into pbuf) ...

 return sectors;

}

Then, I simply set cdrom_drive_t.read_audio to this function, and read a cd with a loop nearly identical to the one
used in the paranoia.c example:

for (i_cursor = i_first_lsn; i_cursor <= i_last_lsn; i_cursor ++)
{
 int16_t *p_readbuf = paranoia_read(p, callback);
 if (!p_readbuf)
 {
   std::cout << "Failed to read frame" << std::endl;
   return false;
 else
 {
   std::cout << "Got frame" << std::endl;
   // ... handle returned frame ...
 }
}

Now this all worked splendidly, but yesterday I wrote another custom read function to be used in some other
circumstances. This time, I made a slight mistake in the mmc command, causing mmc_read_cd() to fail and return
DRIVER_OP_BAD_PARAMETER. Now I had never seen the read function fail before, but simply assumed that if the
read_audio function would not return a number of sectors, but a negative value (an error), paranoia_read() would
return NULL so that the cd reading loop would break (the 'if (!p_readbuf)' part). Instead, I just get the
following messages repeated:

[MESSAGE] (CdioInternal) : ioctl CDROM_SEND_PACKET failed: Invalid argument
RETURN CODE: -5
[WARNING] (CdioCddaInterface::callback()) : paranoia_read() reports `read error' at sector 0

The first of these is a message from a log_handler (set with cdio_log_set_handler()). The second is the cout seen
in the readRaw2448() function shown above. The last is a message from my callback (given as parameter to
paranoia_read()). The messages get repeated in series of 4, where the sector number changes from 0 to 25 to 50 to 75
and then back to 0. Calling paranoia_read_limited() instead of paranoia_read() in the loop does not seem to help,
paranoia_read() will just not return. At what point could/should I break from the loop if read_audio returns an error
code? Am I returning the correct values from the read function (driver_return_code_t on error, sectors on success)?
Any other remarks?

thanks,
Bas Timmer

 
This is a tough one. I'll do my best to describe things as I see it. But probably a discussion should go on as to how to approach.

paranoia_read() is from Monty/Xiph's paranoia;  thus it follows that API, which as you have noted is not to return NULL on error.  I don't see why it couldn't  do so, but that would be changing the paranoia API. So it would be best to get it changed both in paranoia as well as libcdio's use of it.

The way paranoia expects a program to handle errors is via that callback. You note that you did get an error through the callback. The part that is tricky here is that with all this indirection, I'm not sure how the callback can actually get the error parameter. But we could make sure there is some way.

As for the multiple level of error messages, well that is all under your control. The low-level libcdio error messages can be turned off by setting the log level.  And then there is the std::cout you added. And finally there is the error message in the callback. Choose however many or which you want to see.

As for the question of at what point you should bread from the read loop on an error depends on you. Probably if you get a BAD_PARAMETER_OP, that's probably not going to change so you could bail immediately. Other errors may require more discrimination. The whole idea of cd-paranoia though is to tolerate errors on the hope that some of them are transient. But with that flexibility comes the responsibility of the program to make the determination.


reply via email to

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