diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index df7ea66..eee2587 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2011.12.02.100148" +#define Cdrskin_timestamP "2011.12.02.171436" diff --git a/libburn/drive.c b/libburn/drive.c index 0b016b0..9e563c3 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -3309,3 +3309,16 @@ int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag) } +/* ts B11201 : API */ +/* Read the CD-TEXT data from the Lead-in of an Audio CD +*/ +int burn_disc_get_leadin_text(struct burn_drive *d, + unsigned char **text_packs, int *num_packs, + int flag) +{ + int ret; + + ret = mmc_get_leadin_text(d, text_packs, num_packs, 0); + return ret; +} + diff --git a/libburn/libburn.h b/libburn/libburn.h index 557556a..ea6aab4 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -1290,6 +1290,63 @@ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80], unsigned int *disc_id, char bar_code[9], int *app_code, int *valid); +/* ts B11201 */ +/** Read CD-TEXT packs from the Lead-in of an audio CD. + Each pack consists of 18 bytes, of which 4 are header. 12 bytes are pieces + of 0-terminated texts or binary data. 2 bytes hold a CRC. + See also MMC-3 Annex J. + The first byte of each pack tells the pack type (text meaning): + 0x80 = Title + 0x81 = Names of performers + 0x82 = Songwriters + 0x83 = Composers, + 0x84 = Arrangers + 0x85 = Messages + 0x86 = text-and-binary: Disc Identification + 0x87 = text-and-binary: Genre Identification + 0x88 = binary: Table of Content information + 0x89 = binary: Second Table of Content information + 0x8e = UPC/EAN code of the album and ISRC code of each track + 0x8f = binary: Size Information of the Block + The second byte tells the track number to which the first text piece in + a pack is associated. Number 0 means the whole album. Higher numbers are + valid for types 0x80 to 0x85, and 0x8e. There should be one text for each + track with these types. + The third byte is a sequential counter. + The fourth byte is the Block Number and Character Position Indicator. + It consists of three bit fields: + bit7 = Double Bytes Character Code (0= single byte characters) + bit4-6 = Block Number (groups text packs in language blocks) + bit0-3 = Character position + (Still obscure. MMC-3 Appendix J says: + "It is the number of character in the strings that belongs + to the Text Data Field in the previous Pack. The Character + Position starts from 0 to 15 and 15 indicates that the + first character belongs to the one before the previous + Pack. When the character code is double byte code, a set + of 2 bytes in the Text Data Field is counted at one." + ) + The CRC bytes are optional. Polynomial is x^16 + x^12 + x^5 + 1. + + @param d The drive to query. + @param text_packs Will point to an allocated memory buffer with CD-TEXT. + It will only contain text packs, and not be prepended + by the TOC header of four bytes, which gets stored with + file cdtext.dat by cdrecord -vv -toc. The first two of + these bytes are supposed hold the number of CD-TEXT + bytes + 2. The other two bytes are supposed to be 0. + Dispose this buffer by free(), when no longer needed. + @param num_packs Will tell the number of text packs, i.e. the number of + bytes in text_packs divided by 18. + @param flag Bitfield for control purposes, + Unused yet. Submit 0. + @return 1 success, 0= no CD-TEXT found, < 0 an error occured + @since 1.2.0 +*/ +int burn_disc_get_leadin_text(struct burn_drive *d, + unsigned char **text_packs, int *num_packs, + int flag); + /* ts B00924 */ /** Read the current usage of the eventual BD Spare Area. This area gets reserved on BD media during formatting. During writing it is used to diff --git a/libburn/libburn.ver b/libburn/libburn.ver index c72b84e..90940f4 100644 --- a/libburn/libburn.ver +++ b/libburn/libburn.ver @@ -17,6 +17,7 @@ burn_disc_get_bd_spare_info; burn_disc_get_cd_info; burn_disc_get_format_descr; burn_disc_get_formats; +burn_disc_get_leadin_text; burn_disc_get_media_id; burn_disc_get_msc1; burn_disc_get_multi_caps; diff --git a/libburn/mmc.c b/libburn/mmc.c index 382352f..e5ec67f 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -174,6 +174,7 @@ static unsigned char MMC_GET_MSINFO[] = static unsigned char MMC_GET_TOC[] = { 0x43, 2, 2, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_GET_TOC_FMT0[] = { 0x43, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_GET_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 }; +static unsigned char MMC_GET_LEADTEXT[] = { 0x43, 2, 5, 0, 0, 0, 0, 4, 0, 0 }; static unsigned char MMC_GET_DISC_INFO[] = { 0x51, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_READ_CD[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -2028,6 +2029,77 @@ void mmc_read_disc_info(struct burn_drive *d) } +/* @param flag bit= do not allocate text_packs +*/ +static int mmc_get_leadin_text_al(struct burn_drive *d, + unsigned char **text_packs, int *alloc_len, + int flag) +{ + struct buffer *buf = NULL; + struct command *c = NULL; + unsigned char *data; + int ret, data_length; + + *text_packs = NULL; + + BURN_ALLOC_MEM(buf, struct buffer, 1); + BURN_ALLOC_MEM(c, struct command, 1); + + scsi_init_command(c, MMC_GET_LEADTEXT, sizeof(MMC_GET_LEADTEXT)); + c->dxfer_len = *alloc_len; + c->opcode[7]= (c->dxfer_len >> 8) & 0xff; + c->opcode[8]= c->dxfer_len & 0xff; + c->retry = 1; + c->page = buf; + c->page->bytes = 0; + c->page->sectors = 0; + + c->dir = FROM_DRIVE; + d->issue_command(d, c); + if (c->error) + {ret = 0; goto ex;} + + data = c->page->data; + data_length = (data[0] << 8) + data[1]; + *alloc_len = data_length + 2; + if (*alloc_len >= 22 && !(flag & 1)) { + BURN_ALLOC_MEM(*text_packs, unsigned char, *alloc_len - 4); + memcpy(*text_packs, data + 4, *alloc_len - 4); + } + ret = 1; +ex:; + BURN_FREE_MEM(c); + BURN_FREE_MEM(buf); + return ret; +} + + +/* ts B11201 */ +/* Read the CD-TEXT data from the Lead-in of an Audio CD +*/ +int mmc_get_leadin_text(struct burn_drive *d, + unsigned char **text_packs, int *num_packs, int flag) +{ + int alloc_len = 4, ret; + + *num_packs = 0; + if (mmc_function_spy(d, "mmc_get_leadin_text") <= 0) + return -1; + ret = mmc_get_leadin_text_al(d, text_packs, &alloc_len, 1); + if (ret <= 0 || alloc_len < 22) + return (ret > 0 ? 0 : ret); + ret = mmc_get_leadin_text_al(d, text_packs, &alloc_len, 0); + if (ret <= 0 || alloc_len < 22) { + if (*text_packs != NULL) + free(*text_packs); + *text_packs = NULL; + return (ret > 0 ? 0 : ret); + } + *num_packs = (alloc_len - 4) / 18; + return ret; +} + + void mmc_read_atip(struct burn_drive *d) { struct buffer *buf = NULL; diff --git a/libburn/mmc.h b/libburn/mmc.h index 55e557d..01a2bfa 100644 --- a/libburn/mmc.h +++ b/libburn/mmc.h @@ -115,4 +115,9 @@ int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category, char **book_name, int *part_version, int *num_layers, int *num_blocks, int flag); +/* ts B11201 */ +int mmc_get_leadin_text(struct burn_drive *d, + unsigned char **text_packs, int *num_packs, int flag); + + #endif /*__MMC*/