From 47e5ce5da2f26d384933932b66aefae0fa2e1063 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Wed, 28 Dec 2011 10:41:05 +0000 Subject: [PATCH] Transmitting CATALOG by mode page 5. ISRC too, if TAO. --- cdrskin/cdrskin_timestamp.h | 2 +- doc/cdtext.txt | 17 ++++++++------ doc/cookbook.txt | 10 ++++++--- libburn/drive.c | 6 ++--- libburn/libburn.h | 6 ++--- libburn/mmc.c | 45 +++++++++++++++++++++++++++++++++---- libburn/mmc.h | 1 + libburn/spc.c | 6 ++--- libburn/spc.h | 3 ++- libburn/transport.h | 3 ++- 10 files changed, 72 insertions(+), 27 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index f42286f..6018fe1 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2011.12.27.133733" +#define Cdrskin_timestamP "2011.12.28.104044" diff --git a/doc/cdtext.txt b/doc/cdtext.txt index b5d67fb..8c887a6 100644 --- a/doc/cdtext.txt +++ b/doc/cdtext.txt @@ -4,7 +4,7 @@ Guided by Leon Merten Lohse via libcdio-devel@gnu.org by reading mmc3r10g.pdf from http://www.t10.org/ftp/t10/drafts/mmc3/ by docs and results of cdtext.zip from http://www.sonydadc.com/file/ -by reading syntax from http://digitalx.org/cue-sheet/ +by reading http://digitalx.org/cue-sheet/syntax by reading source of libcdio from http://www.gnu.org/s/libcdio which quotes source of cdrecord from ftp://ftp.berlios.de/pub/cdrecord/alpha @@ -132,6 +132,10 @@ 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. It applies to tracks as "ISRC code [which] typically consists of 12 characters" and is always ISO-8859-1 encoded. +MMC calls these information entities Media Catalog Number and ISRC. +The catalog number consists of 13 decimal digits. +ISRC consists of 12 characters: 2 country code [0-9A-Z], 3 owner code [0-9A-Z], +2 year digits (00 to 99), 5 serial number digits (00000 to 99999). Pack type 0x8f summarizes the whole list of text packs of a block. See below, Format of CD-TEXT packs, for details. @@ -631,12 +635,12 @@ attributes (CATALOG, TITLE, PERFORMER, SONGWRITER, ISRC), track block types The rules for CDRWIN cue sheet files are described at http://digitalx.org/cue-sheet/syntax/ ----------------------------------------------------------- -Example of a CDRWIN cue sheet file : ----------------------------------------------------------- +-------------------------------------- +Example of a CDRWIN cue sheet file : +-------------------------------------- -FILE "cdtext.bin" BINARY CATALOG 1234567890123 +FILE "cdtext.bin" BINARY TITLE "Joyful Nights" TRACK 01 AUDIO TITLE "Song of Joy" @@ -657,14 +661,13 @@ TITLE "Joyful Nights" ISRC XYBLG1100006 INDEX 01 13:20:33 ----------------------------------------------------------- +-------------------------------------- Several restrictions apply in the libburn call burn_session_by_cue_file(): Commands FLAGS, POSTGAP, PREGAP are ignored. Only FILE types BINARY, MOTOROLA are allowed. Only TRACK datatypes AUDIO, MODE1/2048 are allowed. They may not be mixed in the same session. INDEX numbers 00, 02 to 99 are ignored. -CATALOG and ISRC are not yet written into Q sub-channel, but only into CD-TEXT. ------------------------------------------------------------------------------- diff --git a/doc/cookbook.txt b/doc/cookbook.txt index e619221..8f9952c 100644 --- a/doc/cookbook.txt +++ b/doc/cookbook.txt @@ -98,6 +98,10 @@ parameters: Data Block Type Layout of payload blocks 8 for 2048 byte data blocks 0 for 2352 byte audio blocks Audio Pause Length 150 = 2 seconds + Media Catalog Number A property of the disc 0x80 if valid + 13 decimal digits as ASCII + ISRC A property of the track 0x80 if valid + 12 letters and digits, ASCII Any other parameters may be set to 0. Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header as of SPC-3 table 240. This 8-byte header may be filled with zeros. @@ -347,9 +351,9 @@ A Write Parameters mode page 05h has to be composed and transmitted via Track Mode Describes frame type 0 (is ignored) Data Block Type Layout of payload blocks 0 (is ignored) Audio Pause Length 150 = 2 seconds (ignored ?) - ->>> CATALOG ->>> no ISRC with SAO + Media Catalog Number 0x80 if valid + See also Cue Sheet ADR 02h 13 decimal digits as ASCII + (With SAO, ISRC is transmitted only by the Cue Sheet.) Any other parameters may be set to 0. Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header diff --git a/libburn/drive.c b/libburn/drive.c index 9e563c3..140881f 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -340,7 +340,7 @@ int burn_drive_send_default_page_05(struct burn_drive *d, int flag) else burn_write_opts_set_write_type(opts, BURN_WRITE_SAO, BURN_BLOCK_SAO); - d->send_write_parameters(d, opts); + d->send_write_parameters(d, NULL, 0, opts); burn_write_opts_free(opts); d->sent_default_page_05 = 1; return 1; @@ -2469,7 +2469,7 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o, if (d->drive_role != 1) return 0; if (o != NULL) - d->send_write_parameters(d, o); + d->send_write_parameters(d, NULL, 0, o); ret = d->get_nwa(d, trackno, lba, nwa); return ret; } @@ -2522,7 +2522,7 @@ off_t burn_disc_available_space(struct burn_drive *d, (off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048); } else { if (o != NULL) - d->send_write_parameters(d, o); + d->send_write_parameters(d, NULL, 0, o); d->get_nwa(d, -1, &lba, &nwa); } if (o != NULL) { diff --git a/libburn/libburn.h b/libburn/libburn.h index b0e2394..75232bb 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -1855,15 +1855,13 @@ 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/ ->>> supported commands: CDTEXTFILE PERFORMER REM SONGWRITER TITLE ->>> partly supported commands: CATALOG FILE ISRC INDEX TRACK +>>> supported commands: CATALOG CDTEXTFILE ISRC PERFORMER REM SONGWRITER TITLE +>>> partly supported commands: FILE INDEX TRACK >>> supported FILE types: BINARY MOTOROLA >>> supported FLAGS: >>> supported TRACK datatypes: AUDIO MODE1/2048 >>> ignored commands: POSTGAP PREGAP FLAGS >>> ignored INDEX numbers: 00, 02 to 99 ->>> ignored CUE SHEET features: CATALOG and ISRC ->>> (not yet transmitted by mode page 5) >>> ignored FLAGS: DCP 4CH PRE SCMS >>> not allowed: mixing of ADUIO and MODE1/2048 >>> not allowed: unsupported FILE types diff --git a/libburn/mmc.c b/libburn/mmc.c index 8f5113e..8beb3b4 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -539,7 +539,7 @@ void mmc_close_disc(struct burn_write_opts *o) /* a ssert(o->drive == d); */ o->multi = 0; - spc_select_write_params(d, o); + spc_select_write_params(d, NULL, 0, o); mmc_close(d, 1, 0); } @@ -560,7 +560,7 @@ void mmc_close_session(struct burn_write_opts *o) /* a ssert(o->drive == d); */ o->multi = 3; - spc_select_write_params(d, o); + spc_select_write_params(d, NULL, 0, o); mmc_close(d, 1, 0); } @@ -3981,10 +3981,14 @@ int mmc_get_write_performance(struct burn_drive *d) memset(pd, 0, 2 + d->mdata->write_page_length); is the eventual duty of the caller. */ -int mmc_compose_mode_page_5(struct burn_drive *d, - const struct burn_write_opts *o, +int mmc_compose_mode_page_5(struct burn_drive *d, struct burn_session *s, + int tno, const struct burn_write_opts *o, unsigned char *pd) { + unsigned char *catalog = NULL; + char isrc_text[13]; + struct isrc *isrc; + pd[0] = 5; pd[1] = d->mdata->write_page_length; @@ -4094,6 +4098,39 @@ fprintf(stderr, "libburn_EXPERIMENTAL: block_type = %d, pd[4]= %u\n", /*XXX need session format! */ /* ts A61229 : but session format (pd[8]) = 0 seems ok */ + /* Media Catalog Number at byte 16 to 31, + MMC-5, 7.5, Tables 664, 670 + */ + if (o->has_mediacatalog) + catalog = (unsigned char *) o->mediacatalog; + else if (s != NULL) { + if (s->mediacatalog[0]) + catalog = s->mediacatalog; + } + if (catalog != NULL && d->mdata->write_page_length >= 30) { + pd[16] = 0x80; /* MCVAL */ + memcpy(pd + 17, catalog, 13); + } + + /* ISRC at bytes 32 to 47. Tables 664, 671 */ + isrc_text[0] = 0; + if (s != NULL && o->write_type == BURN_WRITE_TAO) + if (tno >= 1 && tno <= s->tracks) + if (s->track[tno - 1]->isrc.has_isrc) { + isrc = &(s->track[tno - 1]->isrc); + isrc_text[0] = isrc->country[0]; + isrc_text[1] = isrc->country[1]; + isrc_text[2] = isrc->owner[0]; + isrc_text[3] = isrc->owner[1]; + isrc_text[4] = isrc->owner[2]; + sprintf(isrc_text + 5, "%-2.2u%-5.5u", + (unsigned int) isrc->year, + isrc->serial); + } + if (isrc_text[0] != 0 && d->mdata->write_page_length >= 46) { + pd[32] = 0x80; /* TCVAL */ + memcpy(pd + 33, isrc_text, 12); + } } return 1; } diff --git a/libburn/mmc.h b/libburn/mmc.h index 01a2bfa..4b9c744 100644 --- a/libburn/mmc.h +++ b/libburn/mmc.h @@ -71,6 +71,7 @@ int mmc_get_write_performance(struct burn_drive *d); is the eventual duty of the caller. */ int mmc_compose_mode_page_5(struct burn_drive *d, + struct burn_session *s, int tno, const struct burn_write_opts *o, unsigned char *pd); diff --git a/libburn/spc.c b/libburn/spc.c index 8a53a69..cc58f0d 100644 --- a/libburn/spc.c +++ b/libburn/spc.c @@ -721,8 +721,8 @@ Although command MODE SELECT is SPC, the content of the Write Parameters Mode Page (05h) is MMC (Table 108 in MMC-1). Thus the filling of the mode page is done by mmc_compose_mode_page_5(). */ -void spc_select_write_params(struct burn_drive *d, - const struct burn_write_opts *o) +void spc_select_write_params(struct burn_drive *d, struct burn_session *s, + int tno, const struct burn_write_opts *o) { struct buffer *buf = NULL; struct command *c = NULL; @@ -779,7 +779,7 @@ void spc_select_write_params(struct burn_drive *d, c->page->bytes = alloc_len; /* ts A61229 */ - if (mmc_compose_mode_page_5(d, o, c->page->data + 8) <= 0) + if (mmc_compose_mode_page_5(d, s, tno, o, c->page->data + 8) <= 0) goto ex; c->dir = TO_DRIVE; diff --git a/libburn/spc.h b/libburn/spc.h index ca4c95d..28467d6 100644 --- a/libburn/spc.h +++ b/libburn/spc.h @@ -1,7 +1,7 @@ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens - Copyright (c) 2006 - 2010 Thomas Schmitt + Copyright (c) 2006 - 2011 Thomas Schmitt Provided under GPL version 2 or later. */ @@ -21,6 +21,7 @@ void spc_select_error_params(struct burn_drive *, void spc_getcaps(struct burn_drive *d); void spc_sense_write_params(struct burn_drive *); void spc_select_write_params(struct burn_drive *, + struct burn_session *, int, const struct burn_write_opts *); void spc_probe_write_modes(struct burn_drive *); void spc_request_sense(struct burn_drive *d, struct buffer *buf); diff --git a/libburn/transport.h b/libburn/transport.h index c99d3a4..3c79ea4 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -1,7 +1,7 @@ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens - Copyright (c) 2006 - 2010 Thomas Schmitt + Copyright (c) 2006 - 2011 Thomas Schmitt Provided under GPL version 2 or later. */ @@ -381,6 +381,7 @@ struct burn_drive void (*send_parameters) (struct burn_drive *, const struct burn_read_opts *); void (*send_write_parameters) (struct burn_drive *, + struct burn_session *, int tno, const struct burn_write_opts *); void (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *);