Beginning to create new API call burn_read_audio
This commit is contained in:
parent
100be5078c
commit
0728d855d5
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2012.11.24.181347"
|
||||
#define Cdrskin_timestamP "2012.11.29.111344"
|
||||
|
@ -4003,7 +4003,7 @@ BURN_END_DECLS
|
||||
*/
|
||||
#ifdef Libburn_develop_quality_scaN
|
||||
|
||||
/* B21108 ts */
|
||||
/* ts B21108 */
|
||||
/* Experiments mit quality scan command F3 on Optiarc drive */
|
||||
int burn_nec_optiarc_rep_err_rate(struct burn_drive *d,
|
||||
int start_lba, int rate_period, int flag);
|
||||
@ -4011,4 +4011,46 @@ int burn_nec_optiarc_rep_err_rate(struct burn_drive *d,
|
||||
#endif /* Libburn_develop_quality_scaN */
|
||||
|
||||
|
||||
/* Early experimental:
|
||||
*/
|
||||
#define Libburn_with_read_audiO
|
||||
|
||||
#ifdef Libburn_with_read_audiO
|
||||
|
||||
/* ts B21119 */
|
||||
/** Read CD audio sectors in random access mode.
|
||||
The drive must be grabbed successfully before calling this function.
|
||||
Only CD audio tracks with 2352 bytes per sector can be read this way.
|
||||
I.e. not data tracks, not CD-video-stream, ...
|
||||
@param d The drive from which to read.
|
||||
It must be a real MMC drive (i.e. not a stdio file)
|
||||
and it must have a CD loaded (i.e. not DVD or BD).
|
||||
@param sector_no The sector number (Logical Block Address)
|
||||
@param data A memory buffer capable of taking data_size bytes
|
||||
@param data_size The amount of data to be read. This must be aligned
|
||||
to full multiples of 2352.
|
||||
@param data_count The amount of data actually read (interesting on error)
|
||||
@param flag Bitfield for control purposes:
|
||||
bit0= - reserved -
|
||||
bit1= do not submit error message if read error
|
||||
bit2= on error do not try to read a second time
|
||||
with single block steps.
|
||||
bit3= Enable DAP : "flaw obscuring mechanisms like
|
||||
audio data mute and interpolate"
|
||||
bit4= return -3 on SCSI error
|
||||
5 64 00 ILLEGAL MODE FOR THIS TRACK
|
||||
and prevent this error from being reported as
|
||||
event message. Do not retry reading in this case.
|
||||
(Useful to try the last two blocks of a CD
|
||||
track which might be non-audio because of TAO.)
|
||||
@return 1=sucessful , <=0 an error occured
|
||||
with bit3: -2= permission denied error
|
||||
@since 1.2.6
|
||||
*/
|
||||
int burn_read_audio(struct burn_drive *d, int sector_no,
|
||||
char data[], off_t data_size, off_t *data_count, int flag);
|
||||
|
||||
#endif /* Libburn_with_read_audiO */
|
||||
|
||||
|
||||
#endif /*LIBBURN_H*/
|
||||
|
@ -100,6 +100,7 @@ burn_os_open_track_src;
|
||||
burn_precheck_write;
|
||||
burn_preset_device_open;
|
||||
burn_random_access_write;
|
||||
burn_read_audio;
|
||||
burn_read_data;
|
||||
burn_read_opts_free;
|
||||
burn_read_opts_new;
|
||||
|
@ -596,6 +596,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x0002019a (SORRY,HIGH) = Bad track index number
|
||||
0x0002019b (SORRY,HIGH) = CD track number exceeds range of 1 to 99
|
||||
0x0002019c (SORRY,HIGH) = Session has no defined tracks
|
||||
0x0002019d (SORRY,HIGH) = Audio read size not properly aligned
|
||||
|
||||
|
||||
libdax_audioxtr:
|
||||
|
@ -36,9 +36,9 @@ void mmc_erase(struct burn_drive *, int);
|
||||
void mmc_read_toc(struct burn_drive *);
|
||||
void mmc_read_disc_info(struct burn_drive *);
|
||||
void mmc_read_atip(struct burn_drive *);
|
||||
void mmc_read_sectors(struct burn_drive *,
|
||||
int,
|
||||
int, const struct burn_read_opts *, struct buffer *);
|
||||
int mmc_read_cd(struct burn_drive *d, int start, int len,
|
||||
int sec_type, int main_ch,
|
||||
const struct burn_read_opts *o, struct buffer *buf, int flag);
|
||||
void mmc_set_speed(struct burn_drive *, int, int);
|
||||
void mmc_read_lead_in(struct burn_drive *, struct buffer *);
|
||||
void mmc_perform_opc(struct burn_drive *);
|
||||
|
@ -93,6 +93,7 @@ struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
|
||||
opts->report_recovered_errors = 0;
|
||||
opts->transfer_damaged_blocks = 0;
|
||||
opts->hardware_error_retries = 3;
|
||||
opts->dap_bit = 0;
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
@ -129,6 +129,14 @@ struct burn_read_opts
|
||||
/** The number of retries the hardware should make to correct
|
||||
errors. */
|
||||
unsigned char hardware_error_retries;
|
||||
|
||||
/* ts B21119 */
|
||||
/* >>> Needs API access */
|
||||
/** Whether to set DAP bit which allows drive to apply
|
||||
"flaw obscuring mechanisms like audio data mute and interpolate"
|
||||
*/
|
||||
unsigned int dap_bit;
|
||||
|
||||
};
|
||||
|
||||
#endif /* BURN__OPTIONS_H */
|
||||
|
109
libburn/read.c
109
libburn/read.c
@ -159,6 +159,8 @@ drive, or only store a subset of the _opts structs in drives */
|
||||
drive_lba);
|
||||
|
||||
/* >>> ts A61009 : ensure page.sectors >= 0 before calling */
|
||||
/* >>> ts B21123 : Would now be d->read_cd() with
|
||||
with sectype = 0 , mainch = 0xf8 */
|
||||
d->r ead_sectors(d, drive_lba, page.sectors, o, &page);
|
||||
|
||||
printf("Read %d\n", page.sectors);
|
||||
@ -538,6 +540,113 @@ ex:;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libburn_with_read_audiO
|
||||
|
||||
/* ts B21119 : API function*/
|
||||
int burn_read_audio(struct burn_drive *d, int sector_no,
|
||||
char data[], off_t data_size, off_t *data_count, int flag)
|
||||
{
|
||||
int alignment = 2352, start, upto, chunksize = 1, err, cpy_size, i;
|
||||
int sose_mem = 0, ret;
|
||||
char msg[81], *wpt;
|
||||
struct buffer *buf = NULL, *buffer_mem = d->buffer;
|
||||
|
||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
||||
*data_count = 0;
|
||||
sose_mem = d->silent_on_scsi_error;
|
||||
|
||||
if (d->released) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index, 0x00020142,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Drive is not grabbed on random access read", 0, 0);
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
if (d->drive_role != 1) {
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020146,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Drive is a virtual placeholder (stdio-drive or null-drive)",
|
||||
0, 0);
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
if ((data_size % alignment) != 0) {
|
||||
sprintf(msg,
|
||||
"Audio read size not properly aligned (%d bytes)",
|
||||
alignment);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002019d,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
if (d->busy != BURN_DRIVE_IDLE) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index, 0x00020145,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Drive is busy on attempt to read audio", 0, 0);
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
|
||||
d->busy = BURN_DRIVE_READING_SYNC;
|
||||
d->buffer = buf;
|
||||
|
||||
start = sector_no;
|
||||
upto = start + data_size / alignment;
|
||||
wpt = data;
|
||||
for (; start < upto; start += chunksize) {
|
||||
chunksize = upto - start;
|
||||
if (chunksize > (BUFFER_SIZE / alignment))
|
||||
chunksize = (BUFFER_SIZE / alignment);
|
||||
cpy_size = chunksize * alignment;
|
||||
if (flag & 2)
|
||||
d->silent_on_scsi_error = 1;
|
||||
if (flag & 16) {
|
||||
d->had_particular_error &= ~1;
|
||||
if (!d->silent_on_scsi_error)
|
||||
d->silent_on_scsi_error = 2;
|
||||
}
|
||||
err = d->read_cd(d, start, chunksize, 1, 0x10, NULL, d->buffer,
|
||||
(flag & 8) >> 3);
|
||||
if (flag & (2 | 16))
|
||||
d->silent_on_scsi_error = sose_mem;
|
||||
if (err == BE_CANCELLED) {
|
||||
if ((flag & 16) && (d->had_particular_error & 1))
|
||||
{ret = -3; goto ex;}
|
||||
if(!(flag & 4))
|
||||
for (i = 0; i < chunksize - 1; i++) {
|
||||
if (flag & 2)
|
||||
d->silent_on_scsi_error = 1;
|
||||
err = d->read_cd(d, start + i, 1, 1, 0x10,
|
||||
NULL, d->buffer, (flag & 8) >> 3);
|
||||
if (flag & 2)
|
||||
d->silent_on_scsi_error = sose_mem;
|
||||
if (err == BE_CANCELLED)
|
||||
break;
|
||||
memcpy(wpt, d->buffer->data, alignment);
|
||||
wpt += alignment;
|
||||
*data_count += alignment;
|
||||
}
|
||||
|
||||
ret = 0; goto ex;
|
||||
}
|
||||
memcpy(wpt, d->buffer->data, cpy_size);
|
||||
wpt += cpy_size;
|
||||
*data_count += cpy_size;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
ex:
|
||||
BURN_FREE_MEM(buf);
|
||||
d->buffer = buffer_mem;
|
||||
d->busy = BURN_DRIVE_IDLE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif /* Libburn_with_read_audiO */
|
||||
|
||||
|
||||
#ifdef Libburn_develop_quality_scaN
|
||||
|
||||
/* B21108 ts */
|
||||
|
@ -477,7 +477,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||
out.read_toc = mmc_read_toc;
|
||||
out.write = mmc_write;
|
||||
out.erase = mmc_erase;
|
||||
out.read_sectors = mmc_read_sectors;
|
||||
out.read_cd = mmc_read_cd;
|
||||
out.perform_opc = mmc_perform_opc;
|
||||
out.set_speed = mmc_set_speed;
|
||||
out.send_parameters = spc_select_error_params;
|
||||
|
@ -1462,6 +1462,8 @@ static char *scsi_command_name(unsigned int c, int flag)
|
||||
return "READ DISC STRUCTURE";
|
||||
case 0xb6:
|
||||
return "SET STREAMING";
|
||||
case 0xb9:
|
||||
return "READ CD MSF";
|
||||
case 0xbb:
|
||||
return "SET CD SPEED";
|
||||
case 0xbe:
|
||||
@ -1587,7 +1589,7 @@ int scsi_show_command_reply(unsigned char *opcode, int data_dir,
|
||||
if (data_dir != FROM_DRIVE)
|
||||
return 2;
|
||||
if (opcode[0] == 0x28 || opcode[0] == 0x3C ||
|
||||
opcode[0] == 0xA8 || opcode[0] == 0xBE) {
|
||||
opcode[0] == 0xA8 || opcode[0] == 0xB9 || opcode[0] == 0xBE) {
|
||||
/* READ commands */
|
||||
/* >>> report amount of data */;
|
||||
|
||||
|
@ -147,7 +147,11 @@ void toc_find_modes(struct burn_drive *d)
|
||||
lba = burn_msf_to_lba(e->pmin, e->psec,
|
||||
e->pframe);
|
||||
mem->sectors = 1;
|
||||
|
||||
ts B21119 : Would now be d->read_cd() with
|
||||
with sectype = 0 , mainch = 0xf8
|
||||
d->read_sectors(d, lba, mem.sectors, &o, mem);
|
||||
|
||||
t->mode = sector_identify(mem->data);
|
||||
*/
|
||||
}
|
||||
|
@ -382,10 +382,10 @@ struct burn_drive
|
||||
int is_stopped;
|
||||
|
||||
void (*read_disc_info) (struct burn_drive *);
|
||||
void (*read_sectors) (struct burn_drive *,
|
||||
int start,
|
||||
int len,
|
||||
const struct burn_read_opts *, struct buffer *);
|
||||
int (*read_cd) (struct burn_drive *, int start, int len,
|
||||
int sec_type, int main_ch,
|
||||
const struct burn_read_opts *, struct buffer *,
|
||||
int flag);
|
||||
void (*perform_opc) (struct burn_drive *);
|
||||
void (*set_speed) (struct burn_drive *, int, int);
|
||||
void (*send_parameters) (struct burn_drive *,
|
||||
|
Loading…
Reference in New Issue
Block a user