Browse Source

Implemented cdrskin option textfile=

1.2.0
Thomas Schmitt 11 years ago
parent
commit
7b0a23d553
  1. 48
      cdrskin/cdrskin.1
  2. 111
      cdrskin/cdrskin.c
  3. 2
      cdrskin/cdrskin_timestamp.h

48
cdrskin/cdrskin.1

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "Dec 02, 2011"
.TH CDRSKIN 1 "Dec 05, 2011"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -760,6 +760,48 @@ the only mode which allows -multi.
.br
Mode -tao is not usable for minimally blanked DVD-RW and for DVD-R DL.
.TP
.BI textfile= path
Read CD-TEXT packs from the file depicted by path and put them into the
Lead-in of the emerging session. This session has to be done by Session At Once
(SAO) mode and should contain audio tracks.
.br
path must lead to a regular file, which consists of an optional header of four
bytes and one or more text packs of 18 bytes each. Suitable would be the
file 'cdtext.dat' which gets extracted from CD media by options -vv -toc
and shown in human readable form by -vvv -toc.
.br
The header, if present, must tell the file size minus 2, encoded as big-endian
16 bit word. The other two bytes must be 0.
.br
A text pack consists of a pack type byte, a track number byte, a counter byte,
a Block Number and Character Indicator byte, 12 text characters or data bytes,
two optional CRC bytes.
.br
Pack types are: 0x80=Title, 0x81=Performers, 0x82=Songwriters,
0x83=Composers, 0x84=Arranger, 0x85=Messages, 0x86=Disc Identification,
0x87=Genre Identification, 0x88=Table of Content Information,
0x89=Second Table of Content Information, 0x8e=UPC/EAN resp. ISRC,
0x8f=Size Information of the Block.
.br
Track number 0 means the whole disc. Higher numbers are valid for types 0x80
to 0x85, and 0x8e. With these types, there has to be one text for the disc
and one for each track.
.br
Block Number and Character Position Indicator consists of three bit fields:
Bit 7 indicates two-byte characters. Bit 4 to bit 6 record the block number,
which groups texts into language blocks.
Bit 0 to bit 3 is either the number of characters which the current text
inherited from the previous pack, or 15 if the current text started before
the previous pack.
.br
The texts are terminated by 0 bytes. A text may span over several packs.
Unused characters in a pack are used for the next text of the same pack type.
If no text of the same type follows, then the remaining text bytes are
set to 0.
.br
The CRC algorithm is known as CRC-16-CCITT with divisor 0x11021.
MMC-3 says: "All bits shall be inverted."
.TP
.BI \-toc
Print the table of content (TOC) which describes the tracks recorded on disc.
The output contains all info from option -atip plus lines which begin with
@ -768,13 +810,15 @@ start address of the track. Addresses are counted in CD sectors which with
SAO or TAO data tracks hold 2048 bytes each.
.br
If verbosity is set to level 2 (-v -v) then the CD-TEXT packs from the lead-in
of an audio CD gets extracted and written into file 'cdtext.dat', if that file
of an audio CD get extracted and written into file 'cdtext.dat', if that file
does not yet exist. Prepended is a 4 byte header, followed by one or more
packs of 18 bytes each.
.br
Verbosity level 3 causes the CD-TEXT packs to be printed as hex numbers to
standard output. Bytes 4 to 15 of certain pack types are printed as ASCII
characters if they have values in the range of 32 to 126.
.br
See option textfile= for more information about the text pack format.
.RS
.TP
Example. Retrieve an afio archive from track number 2:

111
cdrskin/cdrskin.c

@ -2891,11 +2891,13 @@ see_cdrskin_eng_html:;
fprintf(stderr,"\ttsize=#\t\tannounces exact size of source data\n");
fprintf(stderr,"\tpadsize=#\tAmount of padding\n");
fprintf(stderr,
"\ttextfile=name\tSet the file with CD-Text data to 'name'\n");
fprintf(stderr,"\t-audio\t\tSubsequent tracks are CD-DA audio tracks\n");
fprintf(stderr,
"\t-data\t\tSubsequent tracks are CD-ROM data mode 1 (default)\n");
fprintf(stderr,
"\t-xa1\t\tSubsequent tracks are CD-ROM XA mode 2 form 1 - 2056 bytes\n");
"\t-xa1\t\tSubsequent tracks are CD-ROM XA mode 2 form 1 - 2056 bytes\n");
fprintf(stderr,
"\t-isosize\tUse iso9660 file system size for next data track\n");
fprintf(stderr,"\t-pad\t\tpadsize=30k\n");
@ -3310,6 +3312,10 @@ struct CdrskiN {
int track_type_by_default; /* 0= explicit, 1=not set, 2=by file extension */
int swap_audio_bytes;
/** CD-TEXT */
unsigned char *text_packs;
int num_text_packs;
/** The list of tracks with their data sources and parameters */
struct CdrtracK *tracklist[Cdrskin_track_maX];
int track_counter;
@ -3461,6 +3467,8 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
o->fill_up_media= 0;
o->track_type= BURN_MODE1;
o->swap_audio_bytes= 1; /* cdrecord default is big-endian (msb_first) */
o->text_packs= NULL;
o->num_text_packs= 0;
o->track_type_by_default= 1;
for(i=0;i<Cdrskin_track_maX;i++)
o->tracklist[i]= NULL;
@ -3527,6 +3535,8 @@ int Cdrskin_destroy(struct CdrskiN **o, int flag)
Cdradrtrn_destroy(&(skin->adr_trn),0);
#endif /* ! Cdrskin_extra_leaN */
if(skin->text_packs != NULL)
free(skin->text_packs);
Cdrpreskin_destroy(&(skin->preskin),0);
if(skin->drives!=NULL)
burn_drive_info_free(skin->drives);
@ -4601,7 +4611,7 @@ int Cdrskin_print_text_packs(struct CdrskiN *skin, unsigned char *text_packs,
printf("CD-TEXT data%s:\n", from_text);
for(i= 0; i < num_packs; i++) {
pack= text_packs + 18 * i;
printf("%3d :", i);
printf("%4d :", i);
for(j= 0; j < 18; j++) {
if(j >= 4 && j <= 15 && pack[j] >= 32 && pack[j] <= 126 &&
pack[0] != 0x88 && pack[0] != 0x89 && pack[0] != 0x8f)
@ -4768,6 +4778,10 @@ int Cdrskin_toc(struct CdrskiN *skin, int flag)
free(text_packs);
if(ret <= 0 && ret < final_ret)
final_ret= ret;
if(ret > 0)
printf("CD-Text len: %d\n", num_packs * 18 + 4);
} else {
fprintf(stderr, "cdrskin: No CD-Text or CD-Text unaware drive.\n");
}
}
@ -5298,6 +5312,81 @@ ex:;
}
int Cdrskin_read_textfile(struct CdrskiN *skin, char *path, int flag)
{
int ret= 0, num_packs= 0, residue= 0;
struct stat stbuf;
FILE *fp= NULL;
unsigned char *text_packs = NULL, head[4];
if(stat(path, &stbuf) == -1) {
cannot_open:;
fprintf(stderr, "cdrskin: SORRY : Cannot open textfile='%s'\n", path);
fprintf(stderr, "cdrskin: %s (errno=%d)\n", strerror(errno), errno);
ret= 0; goto ex;
}
if(!S_ISREG(stbuf.st_mode))
goto not_a_textfile;
residue= (stbuf.st_size % 18);
if(residue != 4 && residue != 0) {
not_a_textfile:;
fprintf(stderr,
"cdrskin: SORRY : File is not of usable type or content: textfile='%s'\n",
path);
ret= 0; goto ex;
}
if(stbuf.st_size < 18)
goto not_a_textfile;
fp= fopen(path, "rb");
if(fp == NULL)
goto cannot_open;
if(residue == 4) {
ret= fread(head, 4, 1, fp);
if(ret != 1) {
cannot_read:;
fprintf(stderr,
"cdrskin: SORRY : Cannot read all bytes from textfile='%s'\n", path);
fprintf(stderr, "cdrskin: %s (errno=%d)\n", strerror(errno), errno);
ret= 0; goto ex;
}
if(head[0] * 256 + head[1] != stbuf.st_size - 2)
goto not_a_textfile;
}
num_packs= (stbuf.st_size - residue) / 18;
if(num_packs > 3640) {
/* READ TOC/PMA/ATIP can at most return 65534 bytes = 3640.78 packs */
fprintf(stderr,
"cdrskin: SORRY : File too large (max. 65524 bytes): textfile='%s'\n",
path);
goto not_a_textfile;
}
text_packs= calloc(num_packs, 18);
if(text_packs == NULL) {
fprintf(stderr,
"cdrskin: FATAL : Cannot allocate %d bytes of memory for CD-TEXT\n",
num_packs * 18);
ret= -1; goto ex;
}
ret= fread(text_packs, num_packs * 18, 1, fp);
if(ret != 1)
goto cannot_read;
if(skin->text_packs != NULL)
free(skin->text_packs);
skin->text_packs= text_packs;
skin->num_text_packs= num_packs;
ret= 1;
ex:;
if(ret <= 0 && text_packs != NULL)
free(text_packs);
if(fp != NULL)
fclose(fp);
return(ret);
}
#ifndef Cdrskin_extra_leaN
/* A70324: proposal by Eduard Bloch */
@ -6525,6 +6614,12 @@ burn_failed:;
burn_write_opts_set_simulate(o, 1);
}
burn_write_opts_set_underrun_proof(o,skin->burnfree);
if(skin->num_text_packs > 0) {
ret= burn_write_opts_set_leadin_text(o, skin->text_packs,
skin->num_text_packs, 0);
if(ret <= 0)
goto burn_failed;
}
ret= Cdrskin_activate_write_mode(skin,o,disc,0);
if(ret<=0)
goto burn_failed;
@ -6987,7 +7082,7 @@ int Cdrskin_setup(struct CdrskiN *skin, int argc, char **argv, int flag)
/* cdrecord 2.01 options which are not scheduled for implementation, yet */
static char ignored_partial_options[][41]= {
"timeout=", "debug=", "kdebug=", "kd=", "driver=", "ts=",
"pregap=", "defpregap=", "mcn=", "isrc=", "index=", "textfile=",
"pregap=", "defpregap=", "mcn=", "isrc=", "index=",
"pktsize=", "cuefile=",
""
};
@ -7750,6 +7845,16 @@ set_stream_recording:;
skin->tell_media_space= 1;
skin->preskin->demands_cdrskin_caps= 1;
} else if(strncmp(argv[i],"-textfile=", 10)==0) {
value_pt= argv[i] + 10;
goto set_textfile;
} else if(strncmp(argv[i],"textfile=", 9)==0) {
value_pt= argv[i] + 9;
set_textfile:;
ret= Cdrskin_read_textfile(skin, value_pt, 0);
if(ret <= 0)
return(ret);
} else if(strcmp(argv[i],"-toc")==0) {
skin->do_atip= 2;
if(skin->verbosity>=Cdrskin_verbose_cmD)

2
cdrskin/cdrskin_timestamp.h

@ -1 +1 @@
#define Cdrskin_timestamP "2011.12.05.203600"
#define Cdrskin_timestamP "2011.12.05.203821"

Loading…
Cancel
Save