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
|
#ifdef Libburn_develop_quality_scaN
|
||||||
|
|
||||||
/* B21108 ts */
|
/* ts B21108 */
|
||||||
/* Experiments mit quality scan command F3 on Optiarc drive */
|
/* Experiments mit quality scan command F3 on Optiarc drive */
|
||||||
int burn_nec_optiarc_rep_err_rate(struct burn_drive *d,
|
int burn_nec_optiarc_rep_err_rate(struct burn_drive *d,
|
||||||
int start_lba, int rate_period, int flag);
|
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 */
|
#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*/
|
#endif /*LIBBURN_H*/
|
||||||
|
@ -100,6 +100,7 @@ burn_os_open_track_src;
|
|||||||
burn_precheck_write;
|
burn_precheck_write;
|
||||||
burn_preset_device_open;
|
burn_preset_device_open;
|
||||||
burn_random_access_write;
|
burn_random_access_write;
|
||||||
|
burn_read_audio;
|
||||||
burn_read_data;
|
burn_read_data;
|
||||||
burn_read_opts_free;
|
burn_read_opts_free;
|
||||||
burn_read_opts_new;
|
burn_read_opts_new;
|
||||||
|
@ -596,6 +596,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
0x0002019a (SORRY,HIGH) = Bad track index number
|
0x0002019a (SORRY,HIGH) = Bad track index number
|
||||||
0x0002019b (SORRY,HIGH) = CD track number exceeds range of 1 to 99
|
0x0002019b (SORRY,HIGH) = CD track number exceeds range of 1 to 99
|
||||||
0x0002019c (SORRY,HIGH) = Session has no defined tracks
|
0x0002019c (SORRY,HIGH) = Session has no defined tracks
|
||||||
|
0x0002019d (SORRY,HIGH) = Audio read size not properly aligned
|
||||||
|
|
||||||
|
|
||||||
libdax_audioxtr:
|
libdax_audioxtr:
|
||||||
|
@ -36,9 +36,9 @@ void mmc_erase(struct burn_drive *, int);
|
|||||||
void mmc_read_toc(struct burn_drive *);
|
void mmc_read_toc(struct burn_drive *);
|
||||||
void mmc_read_disc_info(struct burn_drive *);
|
void mmc_read_disc_info(struct burn_drive *);
|
||||||
void mmc_read_atip(struct burn_drive *);
|
void mmc_read_atip(struct burn_drive *);
|
||||||
void mmc_read_sectors(struct burn_drive *,
|
int mmc_read_cd(struct burn_drive *d, int start, int len,
|
||||||
int,
|
int sec_type, int main_ch,
|
||||||
int, const struct burn_read_opts *, struct buffer *);
|
const struct burn_read_opts *o, struct buffer *buf, int flag);
|
||||||
void mmc_set_speed(struct burn_drive *, int, int);
|
void mmc_set_speed(struct burn_drive *, int, int);
|
||||||
void mmc_read_lead_in(struct burn_drive *, struct buffer *);
|
void mmc_read_lead_in(struct burn_drive *, struct buffer *);
|
||||||
void mmc_perform_opc(struct burn_drive *);
|
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->report_recovered_errors = 0;
|
||||||
opts->transfer_damaged_blocks = 0;
|
opts->transfer_damaged_blocks = 0;
|
||||||
opts->hardware_error_retries = 3;
|
opts->hardware_error_retries = 3;
|
||||||
|
opts->dap_bit = 0;
|
||||||
|
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,14 @@ struct burn_read_opts
|
|||||||
/** The number of retries the hardware should make to correct
|
/** The number of retries the hardware should make to correct
|
||||||
errors. */
|
errors. */
|
||||||
unsigned char hardware_error_retries;
|
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 */
|
#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);
|
drive_lba);
|
||||||
|
|
||||||
/* >>> ts A61009 : ensure page.sectors >= 0 before calling */
|
/* >>> 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);
|
d->r ead_sectors(d, drive_lba, page.sectors, o, &page);
|
||||||
|
|
||||||
printf("Read %d\n", page.sectors);
|
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
|
#ifdef Libburn_develop_quality_scaN
|
||||||
|
|
||||||
/* B21108 ts */
|
/* 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.read_toc = mmc_read_toc;
|
||||||
out.write = mmc_write;
|
out.write = mmc_write;
|
||||||
out.erase = mmc_erase;
|
out.erase = mmc_erase;
|
||||||
out.read_sectors = mmc_read_sectors;
|
out.read_cd = mmc_read_cd;
|
||||||
out.perform_opc = mmc_perform_opc;
|
out.perform_opc = mmc_perform_opc;
|
||||||
out.set_speed = mmc_set_speed;
|
out.set_speed = mmc_set_speed;
|
||||||
out.send_parameters = spc_select_error_params;
|
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";
|
return "READ DISC STRUCTURE";
|
||||||
case 0xb6:
|
case 0xb6:
|
||||||
return "SET STREAMING";
|
return "SET STREAMING";
|
||||||
|
case 0xb9:
|
||||||
|
return "READ CD MSF";
|
||||||
case 0xbb:
|
case 0xbb:
|
||||||
return "SET CD SPEED";
|
return "SET CD SPEED";
|
||||||
case 0xbe:
|
case 0xbe:
|
||||||
@ -1587,7 +1589,7 @@ int scsi_show_command_reply(unsigned char *opcode, int data_dir,
|
|||||||
if (data_dir != FROM_DRIVE)
|
if (data_dir != FROM_DRIVE)
|
||||||
return 2;
|
return 2;
|
||||||
if (opcode[0] == 0x28 || opcode[0] == 0x3C ||
|
if (opcode[0] == 0x28 || opcode[0] == 0x3C ||
|
||||||
opcode[0] == 0xA8 || opcode[0] == 0xBE) {
|
opcode[0] == 0xA8 || opcode[0] == 0xB9 || opcode[0] == 0xBE) {
|
||||||
/* READ commands */
|
/* READ commands */
|
||||||
/* >>> report amount of data */;
|
/* >>> 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,
|
lba = burn_msf_to_lba(e->pmin, e->psec,
|
||||||
e->pframe);
|
e->pframe);
|
||||||
mem->sectors = 1;
|
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);
|
d->read_sectors(d, lba, mem.sectors, &o, mem);
|
||||||
|
|
||||||
t->mode = sector_identify(mem->data);
|
t->mode = sector_identify(mem->data);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
@ -382,10 +382,10 @@ struct burn_drive
|
|||||||
int is_stopped;
|
int is_stopped;
|
||||||
|
|
||||||
void (*read_disc_info) (struct burn_drive *);
|
void (*read_disc_info) (struct burn_drive *);
|
||||||
void (*read_sectors) (struct burn_drive *,
|
int (*read_cd) (struct burn_drive *, int start, int len,
|
||||||
int start,
|
int sec_type, int main_ch,
|
||||||
int len,
|
const struct burn_read_opts *, struct buffer *,
|
||||||
const struct burn_read_opts *, struct buffer *);
|
int flag);
|
||||||
void (*perform_opc) (struct burn_drive *);
|
void (*perform_opc) (struct burn_drive *);
|
||||||
void (*set_speed) (struct burn_drive *, int, int);
|
void (*set_speed) (struct burn_drive *, int, int);
|
||||||
void (*send_parameters) (struct burn_drive *,
|
void (*send_parameters) (struct burn_drive *,
|
||||||
|
Loading…
Reference in New Issue
Block a user