New API calls burn_track_set_index(), burn_track_clear_indice()

This commit is contained in:
Thomas Schmitt 2012-01-03 19:43:26 +00:00
parent 9441dea7b8
commit 12390fa88e
9 changed files with 177 additions and 34 deletions

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "Jan 01, 2012" .TH CDRSKIN 1 "Jan 03, 2012"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -508,8 +508,8 @@ To enable CD-TEXT from the cue sheet file, cdrskin option -text has to be
present. present.
.br .br
cdrskin currently supports TRACK datatypes AUDIO and MODE1/2048 which may cdrskin currently supports TRACK datatypes AUDIO and MODE1/2048 which may
not be mixed. It ignores commands POSTGAP and PREGAP. Only INDEX 01 not be mixed. It ignores commands POSTGAP and PREGAP.
is interpreted yet. Data source may be of FILE type BINARY or MOTOROLA. Data source may be of FILE type BINARY or MOTOROLA.
.br .br
Non-CDRWIN commands ARRANGER, COMPOSER, MESSAGE are supported. Non-CDRWIN commands ARRANGER, COMPOSER, MESSAGE are supported.
.br .br

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2012.01.02.164110" #define Cdrskin_timestamP "2012.01.03.194322"

View File

@ -632,7 +632,7 @@ CDRWIN cue sheet files:
A CDRWIN cue sheet file defines the track data source (FILE), various text A CDRWIN cue sheet file defines the track data source (FILE), various text
attributes (CATALOG, TITLE, PERFORMER, SONGWRITER, ISRC), track block types attributes (CATALOG, TITLE, PERFORMER, SONGWRITER, ISRC), track block types
(TRACK) and track start addresses (INDEX 01). (TRACK), track start addresses (INDEX).
The rules for CDRWIN cue sheet files are described at The rules for CDRWIN cue sheet files are described at
http://digitalx.org/cue-sheet/syntax/ http://digitalx.org/cue-sheet/syntax/
There are three more text attributes mentioned in man cdrecord for defining There are three more text attributes mentioned in man cdrecord for defining
@ -647,7 +647,7 @@ CATALOG 1234567890123
FILE "cdtext.bin" BINARY FILE "cdtext.bin" BINARY
TITLE "Joyful Nights" TITLE "Joyful Nights"
TRACK 01 AUDIO TRACK 01 AUDIO
FLAGS DCP 4CH PRE FLAGS DCP
TITLE "Song of Joy" TITLE "Song of Joy"
PERFORMER "Felix and The Purrs" PERFORMER "Felix and The Purrs"
SONGWRITER "Friedrich Schiller" SONGWRITER "Friedrich Schiller"
@ -676,7 +676,6 @@ Commands POSTGAP, PREGAP are ignored.
Only FILE types BINARY, MOTOROLA are allowed. Only FILE types BINARY, MOTOROLA are allowed.
Only TRACK datatypes AUDIO, MODE1/2048 are allowed. They may not be mixed in Only TRACK datatypes AUDIO, MODE1/2048 are allowed. They may not be mixed in
the same session. the same session.
INDEX numbers 00, 02 to 99 are ignored.
On the other hand, ARRANGER, COMPOSER, MESSAGE are supported unconditionally. On the other hand, ARRANGER, COMPOSER, MESSAGE are supported unconditionally.

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. CD-TEXT according to the content of the file.
For a description of CDRWIN file format see For a description of CDRWIN file format see
http://digitalx.org/cue-sheet/syntax/ 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 >>> SONGWRITER TITLE
>>> partly supported commands: FILE INDEX TRACK >>> partly supported commands: FILE TRACK
>>> supported FILE types: BINARY MOTOROLA >>> supported FILE types: BINARY MOTOROLA
>>> supported TRACK datatypes: AUDIO MODE1/2048 >>> supported TRACK datatypes: AUDIO MODE1/2048
>>> ignored commands: POSTGAP PREGAP >>> ignored commands: POSTGAP PREGAP
>>> ignored INDEX numbers: 00, 02 to 99
>>> not allowed: mixing of ADUIO and MODE1/2048 >>> not allowed: mixing of ADUIO and MODE1/2048
>>> not allowed: unsupported FILE types >>> not allowed: unsupported FILE types
>>> not allowed: unsupported TRACK datatypes >>> 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); 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 /** Hide the first track in the "pre gap" of the disc
@param s session to change @param s session to change
@param onoff 1 to enable hiding, 0 to disable @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_session;
burn_structure_print_track; burn_structure_print_track;
burn_text_to_sev; burn_text_to_sev;
burn_track_clear_indice;
burn_track_clear_isrc; burn_track_clear_isrc;
burn_track_create; burn_track_create;
burn_track_define_data; burn_track_define_data;
@ -153,6 +154,7 @@ burn_track_set_byte_swap;
burn_track_set_cdxa_conv; burn_track_set_cdxa_conv;
burn_track_set_cdtext; burn_track_set_cdtext;
burn_track_set_default_size; burn_track_set_default_size;
burn_track_set_index;
burn_track_set_isrc; burn_track_set_isrc;
burn_track_set_isrc_string; burn_track_set_isrc_string;
burn_track_set_size; burn_track_set_size;

View File

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

View File

@ -168,6 +168,8 @@ struct burn_track *burn_track_create(void)
return NULL; return NULL;
t->refcnt = 1; t->refcnt = 1;
t->indices = 0; t->indices = 0;
for (i = 0; i < 100; i++)
t->index[i] = 0x7fffffff;
t->offset = 0; t->offset = 0;
t->offsetcount = 0; t->offsetcount = 0;
t->tail = 0; t->tail = 0;
@ -441,6 +443,37 @@ void burn_track_clear_isrc(struct burn_track *t)
t->isrc.has_isrc = 0; 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) int burn_track_get_sectors(struct burn_track *t)
{ {
/* ts A70125 : was int */ /* ts A70125 : was int */
@ -1024,7 +1057,7 @@ struct burn_cue_file_cursor {
int prev_block_size; int prev_block_size;
struct burn_track *track; struct burn_track *track;
int track_no; int track_no;
int track_has_index; int track_current_index;
int track_has_source; int track_has_source;
int block_size; int block_size;
int block_size_locked; 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->prev_block_size = 0;
crs->track = NULL; crs->track = NULL;
crs->track_no = 0; crs->track_no = 0;
crs->track_has_index = 0; crs->track_current_index = -1;
crs->track_has_source = 0; crs->track_has_source = 0;
crs->block_size = 0; crs->block_size = 0;
crs->block_size_locked = 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); "In cue sheet file: TRACK without INDEX 01", 0, 0);
return 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) { if (crs->track_no > 1 && session->tracks == 0) {
/* >>> ??? implement ? */; /* >>> ??? implement ? */;
@ -1191,7 +1231,8 @@ static int cue_attach_track(struct burn_session *session,
crs->prev_file_ba = crs->current_file_ba; crs->prev_file_ba = crs->current_file_ba;
crs->prev_block_size = crs->block_size; crs->prev_block_size = crs->block_size;
crs->track = NULL; 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; crs->current_file_ba = -1;
if (!crs->block_size_locked) if (!crs->block_size_locked)
crs->block_size = 0; crs->block_size = 0;
@ -1487,33 +1528,42 @@ no_time_point:;
goto ex; goto ex;
file_ba = ((minute * 60) + second ) * 75 + frame; file_ba = ((minute * 60) + second ) * 75 + frame;
if (file_ba <= crs->prev_file_ba) { if (file_ba < crs->prev_file_ba) {
overlapping_ba:; overlapping_ba:;
libdax_msgs_submit(libdax_messenger, -1, 0x00020192, libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Overlapping INDEX addresses in cue sheet file", "Backward INDEX address in cue sheet file",
0, 0); 0, 0);
ret = 0; goto ex; 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) * size = (file_ba - crs->prev_file_ba) *
crs->prev_block_size; crs->prev_block_size;
if (size <= 0) if (size <= 0)
goto overlapping_ba; goto overlapping_ba;
burn_track_set_size(crs->prev_track, size); 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) { if (crs->current_file_ba < 0)
crs->current_file_ba = file_ba;
/* >>> 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
*/;
/* 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; ret = 1; goto ex;
} }
@ -1557,7 +1607,6 @@ overlapping_ba:;
if (crs->offst_source != NULL) if (crs->offst_source != NULL)
burn_source_free(crs->offst_source); burn_source_free(crs->offst_source);
crs->offst_source = src; crs->offst_source = src;
crs->current_file_ba = file_ba;
crs->track_has_source = 1; crs->track_has_source = 1;
} else if (strcmp(cmd, "ISRC") == 0) { } else if (strcmp(cmd, "ISRC") == 0) {
@ -1783,7 +1832,7 @@ cannot_open:;
/* Attach last track to session */ /* Attach last track to session */
if (crs->track != NULL) { if (crs->track != NULL) {
/* Set track size up to end of file */ /* 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_submit(libdax_messenger, -1, 0x00020192,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"No INDEX 01 defined for last TRACK in cue sheet file", "No INDEX 01 defined for last TRACK in cue sheet file",
@ -1794,7 +1843,7 @@ cannot_open:;
crs->source_size) { crs->source_size) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020194, libdax_msgs_submit(libdax_messenger, -1, 0x00020194,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, 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); 0, 0);
ret = 0; goto ex; ret = 0; goto ex;
} }

View File

@ -37,8 +37,11 @@ struct burn_track
int refcnt; int refcnt;
struct burn_toc_entry *entry; struct burn_toc_entry *entry;
unsigned char indices; unsigned char indices;
/* lba address of the index */ /* lba address of the index. CD only. 0x7fffffff means undefined index.
unsigned int index[99]; 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 */ /** number of 0 bytes to write before data */
int offset; int offset;
/** how much offset has been used */ /** 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. 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 yes
*/ */
#define Libburn_write_with_function_print_cuE
#ifdef 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 nwa)
{ {
int i, m, s, f, form, pform, runtime = -150, ret, track_length; 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; unsigned char ctladr, scms;
struct burn_drive *d; struct burn_drive *d;
struct burn_toc_entry *e; 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 ntr = session->tracks;
int rem = 0; int rem = 0;
#define Libburn_track_multi_indeX yes
#ifdef Libburn_track_multi_indeX
int j;
#endif
d = o->drive; 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].control = e[1].control;
e[2].adr = 1; 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 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 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 . 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; tar[0]->pregap2 = 1;
pregap = 150;
pform = form; pform = form;
for (i = 0; i < ntr; i++) { for (i = 0; i < ntr; i++) {
@ -593,20 +603,64 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
goto failed; 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) { if (i == 0) {
ret = add_cue(sheet, ctladr | 1, 1, 0, form, 0, ret = add_cue(sheet, ctladr | 1, 1, 0, form, 0,
runtime); runtime);
if (ret <= 0) if (ret <= 0)
goto failed; goto failed;
runtime += 150; runtime += 150;
} } else if (pform != form) {
/* ts A70121 : This seems to be thw wrong test. Correct would /* ts A70121 : This seems to be thw wrong test. Correct would
be to compare tar[]->mode or bit2 of ctladr. be to compare tar[]->mode or bit2 of ctladr.
*/ */
if (pform != form) {
ret = add_cue(sheet, ctladr | 1, i + 1, 0, form, scms, ret = add_cue(sheet, ctladr | 1, i + 1, 0, form, scms,
runtime); runtime);
if (ret <= 0) if (ret <= 0)
@ -653,6 +707,9 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
if (ret <= 0) if (ret <= 0)
goto failed; goto failed;
#endif /* ! Libburn_track_multi_indeX */
/* ts A70125 : /* ts A70125 :
Still not understanding the sense behind linking tracks, Still not understanding the sense behind linking tracks,
i decided to at least enforce the MMC specs' minimum i decided to at least enforce the MMC specs' minimum