New API calls burn_track_set_index(), burn_track_clear_indice()

This commit is contained in:
2012-01-03 19:43:26 +00:00
parent b8eb8b35d9
commit 83fa2ce51b
9 changed files with 177 additions and 34 deletions

View File

@ -1864,13 +1864,12 @@ int burn_disc_remove_session(struct burn_disc *d, struct burn_session *s);
CD-TEXT according to the content of the file.
For a description of CDRWIN file format see
http://digitalx.org/cue-sheet/syntax/
>>> fully supported commands: CATALOG CDTEXTFILE FLAGS ISRC PERFORMER REM
>>> fully supported commands: CATALOG CDTEXTFILE FLAGS INDEX ISRC PERFORMER REM
>>> SONGWRITER TITLE
>>> partly supported commands: FILE INDEX TRACK
>>> partly supported commands: FILE TRACK
>>> supported FILE types: BINARY MOTOROLA
>>> supported TRACK datatypes: AUDIO MODE1/2048
>>> ignored commands: POSTGAP PREGAP
>>> ignored INDEX numbers: 00, 02 to 99
>>> not allowed: mixing of ADUIO and MODE1/2048
>>> not allowed: unsupported FILE types
>>> not allowed: unsupported TRACK datatypes
@ -2373,6 +2372,39 @@ int burn_track_set_isrc_string(struct burn_track *t, char isrc[13], int flag);
void burn_track_clear_isrc(struct burn_track *t);
/* ts B20103 */
/** Define an index start address within a track. The index numbers inside a
track have to form sequence starting at 0 or 1 with no gaps up to the
highest number used. They affect only writing of CD SAO sessions.
The first index start address of a track must be 0.
Blocks between index 0 and index 1 are considered to be located before the
track start as of the table-of-content.
@param t The track to be manipulated
@param index_number A number between 0 and 99
@param relative_lba The start address relative to the start of the
burn_source of the track. It will get mapped to the
appropriate absolute block address.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return > 0 indicates success, <= 0 means failure
@since 1.2.0
*/
int burn_track_set_index(struct burn_track *t, int index_number,
unsigned int relative_lba, int flag);
/* ts B20103 */
/** Remove all index start addresses and reset to the default indexing of
CD SAO sessions. This means index 0 of track 1 reaches from LBA -150
to LBA -1. Index 1 of track 1 reaches from LBA 0 to track end. Index 1
of track 2 follows immediately. The same happens for all further tracks
after the end of their predecessor.
@param t The track to be manipulated
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return i > 0 indicates success, <= 0 means failure
@since 1.2.0
*/
int burn_track_clear_indice(struct burn_track *t, int flag);
/** Hide the first track in the "pre gap" of the disc
@param s session to change
@param onoff 1 to enable hiding, 0 to disable

View File

@ -139,6 +139,7 @@ burn_structure_print_disc;
burn_structure_print_session;
burn_structure_print_track;
burn_text_to_sev;
burn_track_clear_indice;
burn_track_clear_isrc;
burn_track_create;
burn_track_define_data;
@ -153,6 +154,7 @@ burn_track_set_byte_swap;
burn_track_set_cdxa_conv;
burn_track_set_cdtext;
burn_track_set_default_size;
burn_track_set_index;
burn_track_set_isrc;
burn_track_set_isrc_string;
burn_track_set_size;

View File

@ -592,6 +592,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020197 (FAILURE,HIGH) = Unsupported text input file feature
0x00020198 (FAILURE,HIGH) = CD-TEXT pack file readability problem
0x00020199 (SORRY,HIGH) = Text input file reading aborted
0x0002019a (SORRY,HIGH) = Bad track index number
libdax_audioxtr:

View File

@ -168,6 +168,8 @@ struct burn_track *burn_track_create(void)
return NULL;
t->refcnt = 1;
t->indices = 0;
for (i = 0; i < 100; i++)
t->index[i] = 0x7fffffff;
t->offset = 0;
t->offsetcount = 0;
t->tail = 0;
@ -441,6 +443,37 @@ void burn_track_clear_isrc(struct burn_track *t)
t->isrc.has_isrc = 0;
}
/* ts B20103 API */
int burn_track_set_index(struct burn_track *t, int index_number,
unsigned int relative_lba, int flag)
{
if (index_number < 0 || index_number > 99) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002019a,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Bad track index number", 0, 0);
return 0;
}
/* >>> if track size known : check index */;
t->index[index_number] = relative_lba;
if (index_number >= t->indices)
t->indices = index_number + 1;
return 1;
}
/* ts B20103 API */
int burn_track_clear_indice(struct burn_track *t, int flag)
{
int i;
for (i = 0; i < 100; i++)
t->index[i] = 0x7fffffff;
t->indices = 0;
return 1;
}
int burn_track_get_sectors(struct burn_track *t)
{
/* ts A70125 : was int */
@ -1024,7 +1057,7 @@ struct burn_cue_file_cursor {
int prev_block_size;
struct burn_track *track;
int track_no;
int track_has_index;
int track_current_index;
int track_has_source;
int block_size;
int block_size_locked;
@ -1055,7 +1088,7 @@ static int cue_crs_new(struct burn_cue_file_cursor **reply, int flag)
crs->prev_block_size = 0;
crs->track = NULL;
crs->track_no = 0;
crs->track_has_index = 0;
crs->track_current_index = -1;
crs->track_has_source = 0;
crs->block_size = 0;
crs->block_size_locked = 0;
@ -1173,6 +1206,13 @@ static int cue_attach_track(struct burn_session *session,
"In cue sheet file: TRACK without INDEX 01", 0, 0);
return 0;
}
if (crs->track_current_index < 1) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"No INDEX 01 defined for last TRACK in cue sheet file",
0, 0);
return 0;
}
if (crs->track_no > 1 && session->tracks == 0) {
/* >>> ??? implement ? */;
@ -1191,7 +1231,8 @@ static int cue_attach_track(struct burn_session *session,
crs->prev_file_ba = crs->current_file_ba;
crs->prev_block_size = crs->block_size;
crs->track = NULL;
crs->track_has_index = crs->track_has_source = 0;
crs->track_current_index = -1;
crs->track_has_source = 0;
crs->current_file_ba = -1;
if (!crs->block_size_locked)
crs->block_size = 0;
@ -1487,33 +1528,42 @@ no_time_point:;
goto ex;
file_ba = ((minute * 60) + second ) * 75 + frame;
if (file_ba <= crs->prev_file_ba) {
if (file_ba < crs->prev_file_ba) {
overlapping_ba:;
libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Overlapping INDEX addresses in cue sheet file",
"Backward INDEX address in cue sheet file",
0, 0);
ret = 0; goto ex;
}
if (crs->prev_track != NULL && !crs->track_has_index) {
if (crs->prev_track != NULL && crs->track_current_index < 0) {
size = (file_ba - crs->prev_file_ba) *
crs->prev_block_size;
if (size <= 0)
goto overlapping_ba;
burn_track_set_size(crs->prev_track, size);
}
crs->track_has_index = 1;
if (crs->track_current_index + 1 != index_no &&
!(crs->track_current_index < 0 && index_no <= 1)) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Backward INDEX number in cue sheet file",
0, 0);
ret = 0; goto ex;
}
crs->track_current_index = index_no;
if (index_no != 1) {
/* >>> what to do with index != 1 ? */;
/* >>> INDEX 00 defines start of a track pregap
Pregap and postgap still has to be properly
mapped onto track
*/;
if (crs->current_file_ba < 0)
crs->current_file_ba = file_ba;
/* Set index address relative to track source start */
ret = burn_track_set_index(crs->track, index_no,
file_ba - crs->current_file_ba, 0);
if (ret <= 0)
goto ex;
if (crs->track_has_source) {
ret = 1; goto ex;
}
@ -1557,7 +1607,6 @@ overlapping_ba:;
if (crs->offst_source != NULL)
burn_source_free(crs->offst_source);
crs->offst_source = src;
crs->current_file_ba = file_ba;
crs->track_has_source = 1;
} else if (strcmp(cmd, "ISRC") == 0) {
@ -1783,7 +1832,7 @@ cannot_open:;
/* Attach last track to session */
if (crs->track != NULL) {
/* Set track size up to end of file */
if (crs->current_file_ba < 0) {
if (crs->current_file_ba < 0 || crs->track_current_index < 1) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"No INDEX 01 defined for last TRACK in cue sheet file",
@ -1794,7 +1843,7 @@ cannot_open:;
crs->source_size) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020194,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"INDEX 01 time point exceeds size of FILE from cue sheet file",
"TRACK start time point exceeds size of FILE from cue sheet file",
0, 0);
ret = 0; goto ex;
}

View File

@ -37,8 +37,11 @@ struct burn_track
int refcnt;
struct burn_toc_entry *entry;
unsigned char indices;
/* lba address of the index */
unsigned int index[99];
/* lba address of the index. CD only. 0x7fffffff means undefined index.
To be programmed relative to track source start before burning,
but to hold absolute addresses after burning or reading.
*/
int index[100];
/** number of 0 bytes to write before data */
int offset;
/** how much offset has been used */

View File

@ -301,6 +301,7 @@ int burn_write_close_session(struct burn_write_opts *o)
This is useful only when changes about CD SAO get tested.
# define Libburn_write_with_function_print_cuE yes
*/
#define Libburn_write_with_function_print_cuE
#ifdef Libburn_write_with_function_print_cuE
@ -450,7 +451,7 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
int nwa)
{
int i, m, s, f, form, pform, runtime = -150, ret, track_length;
int leadin_form, leadin_start;
int leadin_form, leadin_start, pregap;
unsigned char ctladr, scms;
struct burn_drive *d;
struct burn_toc_entry *e;
@ -459,6 +460,13 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
int ntr = session->tracks;
int rem = 0;
#define Libburn_track_multi_indeX yes
#ifdef Libburn_track_multi_indeX
int j;
#endif
d = o->drive;
@ -571,12 +579,14 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
e[2].control = e[1].control;
e[2].adr = 1;
/* ts A70121 : The pause before the first track is not a Pre-gap.
/* ts A70121 : The pause before the first track is not really Pre-gap.
To count it as part 2 of a Pre-gap is a dirty hack. It also seems
to have caused confusion in dealing with part 1 of an eventual
real Pre-gap. mmc5r03c.pdf 6.33.3.2, 6.33.3.18 .
ts B20103 : It is not really Pre-gap with audio tracks.
*/
tar[0]->pregap2 = 1;
pregap = 150;
pform = form;
for (i = 0; i < ntr; i++) {
@ -593,20 +603,64 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
goto failed;
}
#ifdef Libburn_track_multi_indeX
for(j = 0; j < tar[i]->indices || j < 2; j++) {
if(tar[i]->index[j] == 0x7fffffff) {
if (j > 1)
break;
if (j == 0 && i > 0)
continue;
/* force existence of mandatory index */
tar[i]->index[j] = 0;
} else if (j == 0) {
tar[i]->index[j] = 0;
} else if (j == 1 && tar[i]->index[0] == 0x7fffffff) {
tar[i]->index[j] = 0;
}
if (j == 1) {
tar[i]->entry = &e[3 + i];
e[3 + i].point = i + 1;
burn_lba_to_msf(runtime, &m, &s, &f);
e[3 + i].pmin = m;
e[3 + i].psec = s;
e[3 + i].pframe = f;
e[3 + i].adr = 1;
e[3 + i].control = type_to_ctrl(tar[i]->mode);
}
/* >>> ??? else if j == 0 && mode change to -data :
Extended pregap */;
/* >>> ??? user defined pregap ? */;
/* >>> check index with track size */;
tar[i]->index[j] += runtime;
ret = add_cue(sheet, ctladr | 1, i + 1, j, form, scms,
tar[i]->index[j]);
if (ret <= 0)
goto failed;
runtime += pregap;
pregap = 0;
}
#else /* Libburn_track_multi_indeX */
if (i == 0) {
ret = add_cue(sheet, ctladr | 1, 1, 0, form, 0,
runtime);
if (ret <= 0)
goto failed;
runtime += 150;
}
} else if (pform != form) {
/* ts A70121 : This seems to be thw wrong test. Correct would
be to compare tar[]->mode or bit2 of ctladr.
*/
if (pform != form) {
ret = add_cue(sheet, ctladr | 1, i + 1, 0, form, scms,
runtime);
if (ret <= 0)
@ -653,6 +707,9 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
if (ret <= 0)
goto failed;
#endif /* ! Libburn_track_multi_indeX */
/* ts A70125 :
Still not understanding the sense behind linking tracks,
i decided to at least enforce the MMC specs' minimum