New option input_sheet_v07t=

This commit is contained in:
Thomas Schmitt 2011-12-14 13:26:06 +00:00
parent 14846c73fb
commit 45ea58a536
5 changed files with 773 additions and 11 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 "Dec 12, 2011" .TH CDRSKIN 1 "Dec 14, 2011"
.\" 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:
@ -786,8 +786,7 @@ are 0, then the correct values get silently inserted. If there are non-zero
CRC bytes, then a mismatch causes the abort of the burn run. CRC bytes, then a mismatch causes the abort of the burn run.
This check can be disabled by option -force. This check can be disabled by option -force.
.br .br
The CRC algorithm is known as CRC-16-CCITT with divisor 0x11021. Note that this option overrides option input_sheet_v07t= .
The resulting bits have to be inverted.
.TP .TP
.BI \-toc .BI \-toc
Print the table of content (TOC) which describes the tracks recorded on disc. Print the table of content (TOC) which describes the tracks recorded on disc.
@ -1044,6 +1043,57 @@ With multi-session DVD, blank=fast will act like dvd+rw-format -blank=full .
.br .br
growisofs -dvd-compat is roughly equivalent to cdrskin without option -multi. growisofs -dvd-compat is roughly equivalent to cdrskin without option -multi.
.TP .TP
.BI input_sheet_v07t= path
Read CD-TEXT definitions from a Sony Input Sheet version 0.7T. Up to eight
such sheets can be read by multiple input_sheet_v07t= options.
Each will define a CD-TEXT language block.
.br
The information in such a sheet is given by text lines of the following form:
purpose specifier [whitespace] = [whitespace] content text
[whitespace] is zero or more ASCII 32 (space) or ASCII 9 (tab) characters.
The purpose specifier tells the meaning of the content text.
Empty content text does not cause a CD-TEXT attribute to be attached.
.br
The following purpose specifiers apply to the session as a whole:
Purpose specifier | Content example
-------------------------------------------------------------
Text Code = 8859
Language Code = English
Album Title = Joyful Nights
Artist Name = United Cat Orchestra
Songwriter = Various Songwriters
Composer = Various Composers
Arranger = Tom Cat
Album Message = For all our fans
Catalog Number = 1234567890
Genre Code = Classical
Genre Information = Feline classic music
Closed Information = This is not to be shown by CD players
UPC / EAN = 1234567890123
Text Data Copy Protection = OFF
First Track Number = 1
Last Track Number = 3
.br
The following purpose specifiers apply to particular tracks:
Purpose specifier | Content example
-------------------------------------------------------------
Track 01 Title = Song of Joy
Track 01 Artist = Felix and The Purrs
Track 01 Songwriter = Friedrich Schiller
Track 01 Composer = Ludwig van Beethoven
Track 01 Arranger = Tom Cat
Track 01 Message = Fritz and Louie once were punks
ISRC 01 = XYCRR1101234
.br
Track numbers are decimal despite the leading 0. There should be as many track
definitions as there are track source files given.
.br
See libburn's doc/cdtext.txt for a detailed definition of 0.7T and the
possible values for Text Code, Language Code, Genre Code, Text Data Copy
Protection.
.br
This option will get into effect only if no option textfile= is given.
.TP
.BI \--list_formats .BI \--list_formats
List the available format descriptors as reported by the drive for the List the available format descriptors as reported by the drive for the
loaded media. Each descriptor line begins with "Format idx" and the loaded media. Each descriptor line begins with "Format idx" and the

View File

@ -421,8 +421,6 @@ double Sfile_microtime(int flag)
} }
#ifndef Cdrskin_extra_leaN
/** Read a line from fp and strip LF or CRLF */ /** Read a line from fp and strip LF or CRLF */
char *Sfile_fgets(char *line, int maxl, FILE *fp) char *Sfile_fgets(char *line, int maxl, FILE *fp)
{ {
@ -437,6 +435,8 @@ char *ret;
return(ret); return(ret);
} }
#ifndef Cdrskin_extra_leaN
/** Destroy a synthetic argument array */ /** Destroy a synthetic argument array */
int Sfile_destroy_argv(int *argc, char ***argv, int flag) int Sfile_destroy_argv(int *argc, char ***argv, int flag)
@ -2762,6 +2762,7 @@ set_dev:;
" --grow_overwriteable_iso emulate multi-session on media like DVD+RW\n"); " --grow_overwriteable_iso emulate multi-session on media like DVD+RW\n");
printf( printf(
" --ignore_signals try to ignore any signals rather than to abort\n"); " --ignore_signals try to ignore any signals rather than to abort\n");
printf(" input_sheet_v07t=<path> read a Sony CD-TEXT definition file\n");
printf(" --list_formats list format descriptors for loaded media.\n"); printf(" --list_formats list format descriptors for loaded media.\n");
printf(" --list_ignored_options list all ignored cdrecord options.\n"); printf(" --list_ignored_options list all ignored cdrecord options.\n");
printf(" --long_toc print overview of media content\n"); printf(" --long_toc print overview of media content\n");
@ -3316,6 +3317,11 @@ struct CdrskiN {
unsigned char *text_packs; unsigned char *text_packs;
int num_text_packs; int num_text_packs;
int sheet_v07t_blocks;
char sheet_v07t_paths[8][Cdrskin_adrleN];
int cdtext_test;
/** The list of tracks with their data sources and parameters */ /** The list of tracks with their data sources and parameters */
struct CdrtracK *tracklist[Cdrskin_track_maX]; struct CdrtracK *tracklist[Cdrskin_track_maX];
int track_counter; int track_counter;
@ -3469,6 +3475,10 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
o->swap_audio_bytes= 1; /* cdrecord default is big-endian (msb_first) */ o->swap_audio_bytes= 1; /* cdrecord default is big-endian (msb_first) */
o->text_packs= NULL; o->text_packs= NULL;
o->num_text_packs= 0; o->num_text_packs= 0;
o->sheet_v07t_blocks= 0;
for(i= 0; i < 8; i++)
memset(o->sheet_v07t_paths, 0, Cdrskin_adrleN);
o->cdtext_test= 0;
o->track_type_by_default= 1; o->track_type_by_default= 1;
for(i=0;i<Cdrskin_track_maX;i++) for(i=0;i<Cdrskin_track_maX;i++)
o->tracklist[i]= NULL; o->tracklist[i]= NULL;
@ -4597,6 +4607,7 @@ int Cdrskin_obtain_nwa(struct CdrskiN *skin, int *nwa, int flag)
/* @param flag bit0-3= source of text packs: /* @param flag bit0-3= source of text packs:
0= CD Lead-in 0= CD Lead-in
0= session and tracks
*/ */
int Cdrskin_print_text_packs(struct CdrskiN *skin, unsigned char *text_packs, int Cdrskin_print_text_packs(struct CdrskiN *skin, unsigned char *text_packs,
int num_packs, int flag) int num_packs, int flag)
@ -4608,6 +4619,8 @@ int Cdrskin_print_text_packs(struct CdrskiN *skin, unsigned char *text_packs,
from= flag & 15; from= flag & 15;
if(from == 0) if(from == 0)
from_text= " from CD Lead-in"; from_text= " from CD Lead-in";
else if(from == 1)
from_text= " from session and tracks";
printf("CD-TEXT data%s:\n", from_text); printf("CD-TEXT data%s:\n", from_text);
for(i= 0; i < num_packs; i++) { for(i= 0; i < num_packs; i++) {
pack= text_packs + 18 * i; pack= text_packs + 18 * i;
@ -6428,6 +6441,493 @@ int Cdrskin_grow_overwriteable_iso(struct CdrskiN *skin, int flag)
} }
int Cdrskin_cdtext_test(struct CdrskiN *skin, struct burn_write_opts *o,
struct burn_session *session, int flag)
{
int ret, num_packs;
unsigned char *text_packs = NULL;
ret= burn_cdtext_from_session(session, &text_packs, &num_packs, 0);
if(ret < 0)
goto ex;
if(ret > 0) {
Cdrskin_print_text_packs(skin, text_packs, num_packs, 1);
ret= 1; goto ex;
}
ret= 1;
ex:
if (text_packs != NULL)
free(text_packs);
return(ret);
}
/* @param flag bit0= allow two byte codes 0xNNNN or 0xNN 0xNN
*/
int Cdrskin__hexcode(char *payload, int flag)
{
unsigned int x;
int lo, hi, l;
char buf[10], *cpt;
l= strlen(payload);
if(strncmp(payload, "0x", 2) != 0)
return(-1);
if((l == 6 || l == 9) && (flag & 1))
goto double_byte;
if(strlen(payload) != 4)
return(-1);
if(!(isxdigit(payload[2]) && isxdigit(payload[3])))
return(-1);
sscanf(payload + 2, "%x", &x);
return(x);
double_byte:;
strcpy(buf, payload);
buf[4]= 0;
hi= Cdrskin__hexcode(buf, 0);
if(strlen(payload) == 6) {
buf[4]= payload[4];
buf[2]= '0';
buf[3]= 'x';
cpt= buf + 2;
} else {
if(payload[4] != 32 && payload[4] != 9)
return(-1);
cpt= buf + 5;
}
lo= Cdrskin__hexcode(cpt, 0);
if(lo < 0 || hi < 0)
return(-1);
return((hi << 8) | lo);
}
int Cdrskin__cdtext_char_code(char *payload, int flag)
{
int ret;
ret= Cdrskin__hexcode(payload, 0);
if(ret >= 0)
return(ret);
if(strstr(payload, "8859") != NULL)
return(0x00);
else if(strstr(payload, "ASCII") != NULL)
return(0x01);
else if(strstr(payload, "JIS") != NULL)
return(0x80);
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : Unknown Text Code '%s'.\n",
payload);
return(-1);
}
int Cdrskin__cdtext_lang_code(char *payload, int flag)
{
int i, ret;
static char *languages[128] = {
BURN_CDTEXT_LANGUAGES_0X00,
BURN_CDTEXT_FILLER,
BURN_CDTEXT_LANGUAGES_0X45
};
ret= Cdrskin__hexcode(payload, 0);
if(ret >= 0)
return(ret);
if(payload[0] != 0)
for(i= 0; i < 128; i++)
if(strcmp(languages[i], payload) == 0)
return(i);
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : Unknown Language Code '%s'.\n",
payload);
return(-1);
}
int Cdrskin__cdtext_genre_code(char *payload, int flag)
{
int i, ret;
static char *genres[BURN_CDTEXT_NUM_GENRES] = {
BURN_CDTEXT_GENRE_LIST
};
ret= Cdrskin__hexcode(payload, 1);
if(ret >= 0)
return(ret);
for(i= 0; i < BURN_CDTEXT_NUM_GENRES; i++)
if(strcmp(genres[i], payload) == 0)
return(i);
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : Unknown Genre Code '%s'.\n",
payload);
return(-1);
}
int Cdrskin__cdtext_len_db(char *payload, int char_code,
int *length, int *double_byte, int flag)
{
if(char_code < 0) {
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : No 'Text Code' seen before text lines.\n"
);
return(0);
}
*double_byte= (char_code == 0x80);
*length= strlen(payload) + 1 + *double_byte;
return(1);
}
int Cdrskin__cdtext_to_session(struct burn_session *session, int block,
char *payload, int char_code, int pack_type,
char *pack_type_name, int flag)
{
int length, double_byte, ret;
ret= Cdrskin__cdtext_len_db(payload, char_code, &length, &double_byte, 0);
if(ret <= 0)
return(ret);
ret= burn_session_set_cdtext(session, block, pack_type, pack_type_name,
(unsigned char *) payload, length, double_byte);
return(ret);
}
int Cdrskin__cdtext_to_track(struct burn_track *track, int block,
char *payload, int char_code, int pack_type,
char *pack_type_name, int flag)
{
int length, double_byte, ret;
ret= Cdrskin__cdtext_len_db(payload, char_code, &length, &double_byte, 0);
if(ret <= 0)
return(ret);
ret= burn_track_set_cdtext(track, block, pack_type, pack_type_name,
(unsigned char *) payload, length, double_byte);
return(ret);
}
int Cdrskin_read_input_sheet_v07t(struct CdrskiN *skin, char *path, int block,
struct burn_session *session, int flag)
{
int ret= 0, num_tracks, char_codes[8], copyrights[8], languages[8], i;
int genre_code= -1, track_offset= 1, length, pack_type, tno;
int session_attr_seen[16], track_attr_seen[16];
struct stat stbuf;
FILE *fp= NULL;
char line[4096], *eq_pos, *payload, genre_text[160], track_txt[3];
struct burn_track **tracks;
for(i= 0; i < 8; i++)
char_codes[i]= copyrights[i]= languages[i]= -1;
for(i= 0; i < 16; i++)
session_attr_seen[i] = track_attr_seen[i]= 0;
genre_text[0]= 0;
tracks= burn_session_get_tracks(session, &num_tracks);
if(stat(path, &stbuf) == -1) {
cannot_open:;
fprintf(stderr, "cdrskin: SORRY : Cannot open input_sheet_v07t='%s'\n",
path);
fprintf(stderr, "cdrskin: %s (errno=%d)\n", strerror(errno), errno);
ret= 0; goto ex;
}
if(!S_ISREG(stbuf.st_mode)) {
fprintf(stderr,
"cdrskin: SORRY : File is not of usable type or content: input_sheet_v07t='%s'\n",
path);
ret= 0; goto ex;
}
fp= fopen(path, "rb");
if(fp == NULL)
goto cannot_open;
while(1) {
if(Sfile_fgets(line, 4095, fp) == NULL) {
if(!ferror(fp))
break;
fprintf(stderr,
"cdrskin: SORRY : Cannot read all bytes from input_sheet_v07t='%s'\n",
path);
fprintf(stderr, "cdrskin: %s (errno=%d)\n", strerror(errno), errno);
ret= 0; goto ex;
}
if(strlen(line) == 0)
continue;
eq_pos= strchr(line, '=');
if(eq_pos == NULL) {
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : Line without '=' : '%s'.\n",
line);
ret= 0; goto ex;
}
for(payload= eq_pos + 1; *payload == 32 || *payload == 9;
payload++);
*eq_pos= 0;
for(eq_pos--; (*eq_pos == 32 || *eq_pos == 9) && eq_pos > line; eq_pos--)
*eq_pos= 0;
if(payload[0] == 0)
continue;
if(strcmp(line, "Text Code") == 0) {
ret= Cdrskin__cdtext_char_code(payload, 0);
if(ret < 0)
goto ex;
char_codes[block]= ret;
} else if(strcmp(line, "Language Code") == 0) {
ret= Cdrskin__cdtext_lang_code(payload, 0);
if(ret < 0)
goto ex;
languages[block]= ret;
} else if(strcmp(line, "0x80") == 0 || strcmp(line, "Album Title") == 0) {
ret= Cdrskin__cdtext_to_session(session, block, payload,
char_codes[block], 0, "TITLE", 0);
if(ret <= 0)
goto ex;
session_attr_seen[0x0]= 1;
} else if(strcmp(line, "0x81") == 0 || strcmp(line, "Artist Name") == 0) {
ret= Cdrskin__cdtext_to_session(session, block, payload,
char_codes[block], 0, "PERFORMER", 0);
if(ret <= 0)
goto ex;
session_attr_seen[0x1]= 1;
} else if(strcmp(line, "0x82") == 0 || strcmp(line, "Songwriter") == 0) {
ret= Cdrskin__cdtext_to_session(session, block, payload,
char_codes[block], 0, "SONGWRITER", 0);
if(ret <= 0)
goto ex;
session_attr_seen[0x2]= 1;
} else if(strcmp(line, "0x83") == 0 || strcmp(line, "Composer") == 0) {
ret= Cdrskin__cdtext_to_session(session, block, payload,
char_codes[block], 0, "COMPOSER", 0);
if(ret <= 0)
goto ex;
session_attr_seen[0x3]= 1;
} else if(strcmp(line, "0x84") == 0 || strcmp(line, "Arranger") == 0) {
ret= Cdrskin__cdtext_to_session(session, block, payload,
char_codes[block], 0, "ARRANGER", 0);
if(ret <= 0)
goto ex;
session_attr_seen[0x4]= 1;
} else if(strcmp(line, "0x85") == 0 || strcmp(line, "Album Message") == 0) {
ret= Cdrskin__cdtext_to_session(session, block, payload,
char_codes[block], 0, "MESSAGE", 0);
if(ret <= 0)
goto ex;
session_attr_seen[0x5]= 1;
} else if(strcmp(line, "0x86") == 0 ||
strcmp(line, "Catalog Number") == 0) {
ret= Cdrskin__cdtext_to_session(session, block, payload, 0x01, 0,
"DISCID", 0);
if(ret <= 0)
goto ex;
} else if(strcmp(line, "Genre Code") == 0) {
genre_code= Cdrskin__cdtext_genre_code(payload, 0);
if(genre_code < 0)
goto ex;
} else if(strcmp(line, "Genre Information") == 0) {
strncpy(genre_text, payload, sizeof(genre_text) - 1);
genre_text[sizeof(genre_text) - 1]= 0;
} else if(strcmp(line, "0x8d") == 0 ||
strcmp(line, "Closed Information") == 0) {
ret= Cdrskin__cdtext_to_session(session, block, payload, 0x00, 0,
"CLOSED", 0);
if(ret <= 0)
goto ex;
} else if(strcmp(line, "0x8e") == 0 || strcmp(line, "UPC / EAN") == 0) {
ret= Cdrskin__cdtext_to_session(session, block, payload, 0x01, 0,
"UPC_ISRC", 0);
if(ret <= 0)
goto ex;
session_attr_seen[0xe]= 1;
} else if(strncmp(line, "Disc Information ", 17) == 0) {
/* >>> ??? is this good for anything ? */;
} else if(strcmp(line, "Input Sheet Version") == 0) {
if(strcmp(payload, "0.7T") != 0) {
fprintf(stderr,
"cdrskin: WARNING : input_sheet_v07t : Input Sheet Version '%s', expected '0.7T'.\n",
payload);
}
} else if(strcmp(line, "Remarks") == 0) {
;
} else if(strcmp(line, "Text Data Copy Protection") == 0) {
ret = Cdrskin__hexcode(payload, 0);
if(ret >= 0)
copyrights[block]= ret;
else if(strcmp(payload, "ON") == 0)
copyrights[block]= 0x03;
else if(strcmp(payload, "OFF") == 0)
copyrights[block]= 0x00;
else {
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : Unknown Text Data Copy Protection '%s'.\n",
payload);
ret= 0; goto ex;
}
} else if(strcmp(line, "First Track Number") == 0) {
ret= -1;
sscanf(payload, "%d", &ret);
if(ret <= 0 || ret > 99) {
bad_tno:;
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : Inappropriate First Track Number '%s'.\n",
payload);
ret= 0; goto ex;
} else {
track_offset= ret;
if(ret != 1) {
fprintf(stderr,
"cdrskin: WARNING : input_sheet_v07t : First Track Number '%s' will be mapped to 1.\n",
payload);
}
}
} else if(strcmp(line, "Last Track Number") == 0) {
ret= -1;
sscanf(payload, "%d", &ret);
if(ret < 0) {
goto bad_tno;
} else {
/* >>> ??? Is it good for anything ? */;
}
} else if(strncmp(line, "Track ", 6) == 0) {
tno= -1;
sscanf(line + 6, "%d", &tno);
if(tno < 0 || tno - track_offset < 0 ||
tno - track_offset >= num_tracks) {
track_txt[0]= line[6];
track_txt[1]= line[7];
track_txt[2]= 0;
bad_track_no:;
if(track_offset != 1)
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : Inappropriate Track number '%s' (mapped to %2.2d)\n",
track_txt, tno - track_offset + 1);
else
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : Inappropriate Track number '%s'.\n",
track_txt);
fprintf(stderr, "cdrskin: (acceptable range: %2.2d to %2.2d)\n",
track_offset, num_tracks + track_offset - 1);
ret= 0; goto ex;
}
tno-= track_offset;
if(strcmp(line, "0x80") == 0 || strcmp(line + 9, "Title") == 0)
pack_type= 0x80;
else if(strcmp(line, "0x81") == 0 || strcmp(line + 9, "Artist") == 0)
pack_type= 0x81;
else if(strcmp(line, "0x82") == 0 || strcmp(line + 9, "Songwriter") == 0)
pack_type= 0x82;
else if(strcmp(line, "0x83") == 0 || strcmp(line + 9, "Composer") == 0)
pack_type= 0x83;
else if(strcmp(line, "0x84") == 0 || strcmp(line + 9, "Arranger") == 0)
pack_type= 0x84;
else if(strcmp(line, "0x85") == 0 || strcmp(line + 9, "Message") == 0)
pack_type= 0x85;
else if(strcmp(line, "0x8e") == 0 || strcmp(line + 9, "ISRC") == 0)
pack_type= 0x8e;
else {
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : Unknown Track header '%s'\n",
payload);
ret= 0; goto ex;
}
ret= Cdrskin__cdtext_to_track(tracks[tno], block, payload, 0x00,
pack_type, "", 0);
if(ret <= 0)
goto ex;
track_attr_seen[pack_type - 0x80]= 1;
} else if(strncmp(line, "ISRC ", 5) == 0) {
/* Track variation of UPC EAN = 0x8e */
tno= -1;
sscanf(line + 5, "%d", &tno);
if (tno < 0 || tno - track_offset < 0 ||
tno - track_offset >= num_tracks) {
track_txt[0]= line[5];
track_txt[1]= line[6];
track_txt[2]= 0;
goto bad_track_no;
}
tno-= track_offset;
ret= Cdrskin__cdtext_to_track(tracks[tno], block, payload, 0x00,
0x8e, "", 0);
if(ret <= 0)
goto ex;
track_attr_seen[0xe]= 1;
} else {
fprintf(stderr,
"cdrskin: SORRY : input_sheet_v07t : Unknown line header '%s'\n",
line);
ret= 0; goto ex;
}
}
for(i= 0x80; i <= 0x8e; i++) {
if(i > 0x85 && i != 0x8e)
continue;
if(session_attr_seen[i - 0x80] || !track_attr_seen[i - 0x80])
continue;
ret= Cdrskin__cdtext_to_session(session, block, "", char_codes[block],
i, NULL, 0);
if(ret <= 0)
goto ex;
}
if(genre_code >= 0 && genre_text[0]) {
line[0]= (genre_code >> 8) & 0xff;
line[1]= genre_code & 0xff;
strcpy(line + 2, genre_text);
length= 2 + strlen(line + 2) + 1;
ret= burn_session_set_cdtext(session, block, 0, "GENRE",
(unsigned char *) line, length, 0);
if(ret <= 0)
goto ex;
}
ret= burn_session_set_cdtext_par(session, char_codes, copyrights, languages,
0);
if(ret <= 0)
goto ex;
ret= 1;
ex:;
if(fp != NULL)
fclose(fp);
return(ret);
}
/** Burn data via libburn according to the parameters set in skin. /** Burn data via libburn according to the parameters set in skin.
@return <=0 error, 1 success @return <=0 error, 1 success
*/ */
@ -6448,6 +6948,7 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag)
char *doing; char *doing;
char *source_path; char *source_path;
int source_fd, is_from_stdin; int source_fd, is_from_stdin;
int text_flag= 4; /* Check CRCs and silently repair CRCs if all are 0 */
#ifndef Cdrskin_no_cdrfifO #ifndef Cdrskin_no_cdrfifO
double put_counter, get_counter, empty_counter, full_counter; double put_counter, get_counter, empty_counter, full_counter;
@ -6511,6 +7012,20 @@ burn_failed:;
skin->has_open_ended_track= 1; skin->has_open_ended_track= 1;
} }
if(skin->sheet_v07t_blocks > 0) {
if(skin->num_text_packs > 0) {
fprintf(stderr,
"cdrskin: WARNING : Option textfile= overrides option input_sheet_v07t=\n");
} else {
for(i= 0; i < skin->sheet_v07t_blocks; i++) {
ret= Cdrskin_read_input_sheet_v07t(skin, skin->sheet_v07t_paths[i], i,
session, 0);
if(ret <= 0)
goto burn_failed;
}
}
}
#ifndef Cdrskin_extra_leaN #ifndef Cdrskin_extra_leaN
/* Final decision on track size has to be made after eventual -isosize /* Final decision on track size has to be made after eventual -isosize
determination via fifo content. determination via fifo content.
@ -6622,14 +7137,28 @@ burn_failed:;
} }
burn_write_opts_set_underrun_proof(o,skin->burnfree); burn_write_opts_set_underrun_proof(o,skin->burnfree);
if(skin->num_text_packs > 0) { if(skin->num_text_packs > 0) {
if(!!skin->force_is_set)
text_flag= 1; /* No CRC verification or repairing */
ret= burn_write_opts_set_leadin_text(o, skin->text_packs, ret= burn_write_opts_set_leadin_text(o, skin->text_packs,
skin->num_text_packs, 0); skin->num_text_packs, text_flag);
if(ret <= 0) if(ret <= 0)
goto burn_failed; goto burn_failed;
} }
ret= Cdrskin_activate_write_mode(skin,o,disc,0); ret= Cdrskin_activate_write_mode(skin,o,disc,0);
if(ret<=0) if(ret<=0)
goto burn_failed; goto burn_failed;
if(skin->cdtext_test) {
ret= Cdrskin_cdtext_test(skin, o, session, (skin->cdtext_test == 1));
if(ret <= 0)
goto ex;
if(skin->cdtext_test >= 2) {
fprintf(stderr,
"cdrskin: Option --cdtext_dummy prevents actual burn run\n");
ret= 1; goto ex;
}
}
ret= Cdrskin_obtain_nwa(skin, &nwa,0); ret= Cdrskin_obtain_nwa(skin, &nwa,0);
if(ret<=0) if(ret<=0)
nwa= -1; nwa= -1;
@ -7331,6 +7860,12 @@ unsupported_blank_option:;
} else if(strcmp(argv[i],"--bragg_with_audio")==0) { } else if(strcmp(argv[i],"--bragg_with_audio")==0) {
/* OBSOLETE 0.2.3 : was handled in Cdrpreskin_setup() */; /* OBSOLETE 0.2.3 : was handled in Cdrpreskin_setup() */;
} else if(strcmp(argv[i],"--cdtext_dummy")==0) {
skin->cdtext_test= 2;
} else if(strcmp(argv[i],"--cdtext_test")==0) {
skin->cdtext_test= 1;
} else if(strcmp(argv[i],"-checkdrive")==0) { } else if(strcmp(argv[i],"-checkdrive")==0) {
skin->do_checkdrive= 1; skin->do_checkdrive= 1;
@ -7581,6 +8116,26 @@ gracetime_equals:;
skin->min_buffer_percent= 75; skin->min_buffer_percent= 75;
skin->max_buffer_percent= 95; skin->max_buffer_percent= 95;
} else if(strncmp(argv[i], "input_sheet_v07t=", 17)==0) {
if(skin->sheet_v07t_blocks >= 8) {
fprintf(stderr,
"cdrskin: SORRY : Too many input_sheet_v07t= options. (Max. 8)\n");
return(0);
}
if(argv[i][17] == 0) {
fprintf(stderr,
"cdrskin: SORRY : Missing file path after option input_sheet_v07t=\n");
return(0);
}
if(strlen(argv[i] + 17) > Cdrskin_adrleN) {
fprintf(stderr,
"cdrskin: SORRY : File path too long after option input_sheet_v07t=\n");
return(0);
}
strcpy(skin->sheet_v07t_paths[skin->sheet_v07t_blocks], argv[i] + 17);
skin->sheet_v07t_blocks++;
skin->preskin->demands_cdrskin_caps= 1;
} else if(strcmp(argv[i],"-inq")==0) { } else if(strcmp(argv[i],"-inq")==0) {
skin->do_checkdrive= 2; skin->do_checkdrive= 2;

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.12.14.124906" #define Cdrskin_timestamP "2011.12.14.132551"

View File

@ -18,6 +18,8 @@ Content:
- Content specifications of particular pack types - Content specifications of particular pack types
- Format of a CD-TEXT packs array - Format of a CD-TEXT packs array
- Overview of libburn API calls for CD-TEXT - Overview of libburn API calls for CD-TEXT
- Sony Text File Format (Input Sheet Version 0.7T):
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
CD-TEXT from the view of the user: CD-TEXT from the view of the user:
@ -30,9 +32,9 @@ Up to 8 blocks are possible.
There are 13 defined attribute categories, which are called Pack Types and are There are 13 defined attribute categories, which are called Pack Types and are
identified by a single-byte code: identified by a single-byte code:
0x80 = Title 0x80 = Title
0x81 = Names of performers 0x81 = Names of Performers
0x82 = Names of Songwriters 0x82 = Names of Songwriters
0x83 = Names of Composers, 0x83 = Names of Composers
0x84 = Names of Arrangers 0x84 = Names of Arrangers
0x85 = Messages 0x85 = Messages
0x86 = text-and-binary: Disc Identification 0x86 = text-and-binary: Disc Identification
@ -123,6 +125,8 @@ Always ISO-8859-1 encoded.
Pack type 0x8e is documented by Sony as "UPC/EAN Code (POS Code) of the album. Pack type 0x8e is documented by Sony as "UPC/EAN Code (POS Code) of the album.
This field typically consists of 13 characters." Always ASCII encoded. This field typically consists of 13 characters." Always ASCII encoded.
It applies to tracks as "ISRC code [which] typically consists of 12 characters"
and is always ISO-8859-1 encoded.
Pack type 0x8f summarizes the whole list of text packs of a block. Pack type 0x8f summarizes the whole list of text packs of a block.
See below, Format of CD-TEXT packs, for details. See below, Format of CD-TEXT packs, for details.
@ -132,9 +136,12 @@ See below, Format of CD-TEXT packs, for details.
Format of a CD-TEXT packs array: Format of a CD-TEXT packs array:
The attributes are represented on CD as Text Packs in the sub-channel of The attributes are represented on CD as Text Packs in the sub-channel of
the Lead-in of the disc. the Lead-in of the disc. See doc/cookbook.txt for a description how to write
the readily formatted CD-TEXT pack array to CD, and how to read CD-TEXT packs
from CD.
The format is explained in part in MMC-3 (mmc3r10g.pdf, Annex J) and in part by The format is explained in part in MMC-3 (mmc3r10g.pdf, Annex J) and in part by
the documentation of Sony's cdtext.zip. the documentation in Sony's cdtext.zip :
Each pack consists of a 4-byte header, 12 bytes of payload, and 2 bytes of CRC. Each pack consists of a 4-byte header, 12 bytes of payload, and 2 bytes of CRC.
@ -416,6 +423,15 @@ and burn_track:
int pack_type, char *pack_type_name, int pack_type, char *pack_type_name,
unsigned char *payload, int length, int flag); unsigned char *payload, int length, int flag);
Macros list the texts for genre and language codes:
BURN_CDTEXT_LANGUAGES_0X00
BURN_CDTEXT_FILLER
BURN_CDTEXT_LANGUAGES_0X45
BURN_CDTEXT_GENRE_LIST
BURN_CDTEXT_NUM_GENRES
These attributes can then be converted into an array of text packs by: These attributes can then be converted into an array of text packs by:
int burn_cdtext_from_session(struct burn_session *s, int burn_cdtext_from_session(struct burn_session *s,
@ -446,3 +462,138 @@ and for removing attached attributes:
int burn_track_dispose_cdtext(struct burn_track *t, int block); int burn_track_dispose_cdtext(struct burn_track *t, int block);
-------------------------------------------------------------------------------
Sony Text File Format (Input Sheet Version 0.7T):
This text file format provides comprehensive means to define the text
attributes of session and tracks for a single block. More than one
such file has to be read to form an attribute set with multiple blocks.
The information is given by text lines of the following form:
purpose specifier [whitespace] = [whitespace] content text
[whitespace] is zero or more ASCII 32 (space) or ASCII 9 (tab) characters.
The purpose specifier tells the meaning of the content text.
Empty content text does not cause a CD-TEXT attribute to be attached.
The following purpose specifiers apply to the session as a whole:
Specifier = Meaning
-------------------------------------------------------------------------
Text Code = Character code for pack type 0x8f
"ASCII", "8859"
Language Code = One of the language names for pack type 0x8f
Album Title = Content of pack type 0x80
Artist Name = Content of pack type 0x81
Songwriter = Content of pack type 0x82
Composer = Content of pack type 0x83
Arranger = Content of pack type 0x84
Album Message = Content of pack type 0x85
Catalog Number = Content of pack type 0x86
Genre Code = One of the genre names for pack type 0x87
Genre Information = Cleartext part of pack type 0x87
Input Sheet Version = "0.7T"
Closed Information = Content of pack type 0x8d
UPC / EAN = Content of pack type 0x8e
Text Data Copy Protection = Copyright value for pack type 0x8f
"ON" = 0x03, "OFF" = 0x00
First Track Number = The lowest track number used in the file
Last Track Number = The highest track number used in the file
The following purpose specifiers apply to particular tracks:
Track NN Title = Content of pack type 0x80
Track NN Artist = Content of pack type 0x81
Track NN Songwriter = Content of pack type 0x82
Track NN Composer = Content of pack type 0x83
Track NN Arranger = Content of pack type 0x84
Track NN Message = Content of pack type 0x85
ISRC NN = Content of pack type 0x8e
The following purpose specifiers have no effect on CD-TEXT:
Remarks = Comments with no influence on CD-TEXT
Disc Information NN = Supplementary information for use by record companies.
ISO-8859-1 encoded.
cdrskin peculiarties:
cdrskin reads files of the described format by its option input_sheet_v07t= .
The following purpose specifiers accept byte values of the form 0xXY.
Text Code , Language Code , Genre Code , Text Data Copy Protection
E.g. to indicate MS-JIS character code (of which the exact name is unknown):
Text Code = 0x80
Genre Code is settable by 0xXY or 0xXYZT or 0xXY 0xZT.
Genre Code = 0x001b
Purpose specifiers which have the meaning "Content of pack type 0xXY"
may be replaced by the pack type codes. E.g.:
0x80 = Session content of pack type 0x80
Track 02 0x80 = Track content of pack type 0x80 for track 2.
Applicable are pack types 0x80 to 0x86, 0x8d, 0x8e.
Text code has to be defined before any content is defined which depends
on the chosen encoding. I.e before any pack types 0x80 to 0x85.
If a track attribute is set but the corresponding session attribute is not
defined or defined with empty text, then the session attribute gets attached
as empty test. (Normally empty content is ignored.)
libburn will always start track numbering by 1. So cdrskin adjusts all track
numbers from the input sheet file by subtracting (First Track Number - 1).
cdrskin ignores Last Track number because libburn will always write its
own first and last track numbers to pack type 0x8f.
Example run with three tracks:
$ cdrskin dev=/dev/sr0 -v input_sheet_v07t=CDRSKIN_1.TXT \
-audio track_source_1 track_source_2 track_source_3
----------------------------------------------------------
Content of file CDRSKIN_1.TXT :
----------------------------------------------------------
Text Code = 8859
Language Code = English
Album Title = Joyful Nights
Artist Name = United Cat Orchestra
Songwriter = Various Songwriters
Composer = Various Composers
Arranger = Tom Cat
Album Message = For all our fans
Catalog Number = 1234567890
Genre Code = Classical
Genre Information = Feline classic music
Closed Information = This is not to be shown by CD players
UPC / EAN = 1234567890123
Text Data Copy Protection = OFF
First Track Number = 1
Last Track Number = 3
Track 01 Title = Song of Joy
Track 01 Artist = Felix and The Purrs
Track 01 Songwriter = Friedrich Schiller
Track 01 Composer = Ludwig van Beethoven
Track 01 Arranger = Tom Cat
Track 01 Message = Fritz and Louie were punks
ISRC 01 = XYBLG1101234
Track 02 Title = Humpty Dumpty
Track 02 Artist = Catwalk Beauties
Track 02 Songwriter = Mother Goose
Track 02 Composer = unknown
Track 02 Arranger = Tom Cat
Track 02 Message = Pluck the goose
ISRC 02 = XYBLG1100005
Track 03 Title = Mee Owwww
Track 03 Artist = Sicko Gang
Track 03 Songwriter = Sicko Gang
Track 03 Composer = Sicko Gang
Track 03 Arranger = Sicko Gang
Track 03 Message =
ISRC 03 = XYBLG1100006
----------------------------------------------------------
-------------------------------------------------------------------------------
This text is copyright 2011 Thomas Schmitt <scdbackup@gmx.net>.
Permission is granted to copy, modify, and distribute it, as long as the
references to the original information sources are maintained.
There is NO WARRANTY, to the extent permitted by law.
-------------------------------------------------------------------------------

View File

@ -1446,5 +1446,11 @@ written as rLBA nor as vLBA yet. So one should begin the vLBA of new sessions
at the NWA of a sufficiently sized track. at the NWA of a sufficiently sized track.
(mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9) (mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9)
-------------------------------------------------------------------------------
This text is copyright 2011 Thomas Schmitt <scdbackup@gmx.net>.
Permission is granted to copy, modify, and distribute it, as long as the
references to the original information sources are maintained.
There is NO WARRANTY, to the extent permitted by law.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------