* discid field extraction
 * genre field extraction (experimental)
 * blocksize field extraction
 * read charcode from blocksize field
 * some unneeded comments removed
 * unneeded local variables removed
 * typos
This commit is contained in:
R. Bernstein
2011-04-23 14:43:21 -04:00
parent 610a9153e2
commit a20dbc952c
3 changed files with 269 additions and 89 deletions

View File

@@ -1,5 +1,6 @@
/*
Copyright (C) 2004, 2005, 2006, 2008, 2009 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2004, 2005, 2006, 2008, 2009, 2011
Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,7 +32,7 @@
static void
print_cdtext_track_info(CdIo_t *p_cdio, track_t i_track, const char *psz_msg) {
const cdtext_t *cdtext = cdio_get_cdtext(p_cdio, 0);
const cdtext_t *cdtext = cdio_get_cdtext(p_cdio, i_track);
if (NULL != cdtext) {
cdtext_field_t i;

View File

@@ -1,7 +1,5 @@
/*
$Id: cdtext.c,v 1.7 2008/06/16 22:41:44 flameeyes Exp $
Copyright (C) 2004, 2005, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2004, 2005, 2008, 2011 Rocky Bernstein <rocky@gnu.org>
toc reading routine adapted from cuetools
Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
@@ -35,6 +33,7 @@
#include <string.h>
#endif
#include <stdio.h>
/*! Note: the order and number items (except CDTEXT_INVALID) should
match the cdtext_field_t enumeration. */
@@ -55,6 +54,37 @@ static const char cdtext_keywords[][16] =
"UPC_EAN",
};
static const char cdtext_genre[][30] =
{
"Not Used",
"Not Defined",
"Adult Contemporary",
"Alternative Rock",
"Childrens Music",
"Classical",
"Contemporary Christian",
"Country",
"Dance",
"Easy Listening",
"Erotic",
"Folk",
"Gospel",
"Hip Hop",
"Jazz",
"Latin",
"Musical",
"New Age",
"Opera",
"Operetta",
"Pop Music",
"Rap",
"Reggae",
"Rock Music",
"Rhythm & Blues",
"Sound Effects",
"Spoken Word",
"World Music"
} ;
/*! Return string representation of the enum values above */
const char *
@@ -173,28 +203,16 @@ cdtext_data_init(void *p_user_data, track_t i_first_track,
int i_track;
bool b_ret = false;
char block = 0;
char encoding[16];
CDText_blocksize_t p_blocksize;
memset( buffer, 0x00, sizeof(buffer) );
idx = 0;
p_data = (CDText_data_t *) (&wdata[4]);
bzero(encoding,16);
bzero(&p_blocksize, sizeof(CDText_blocksize_t));
/* For reasons I don't understand - incorrect CDROM TOC reading?
we are off sometimes by 4.
*/
/*
* Leon Lohse: can anybody confirm this problem?
*
if( (p_data->type < 0x80) || (p_data->type > 0x85)
|| (p_data->block == 0) ) {
CDText_data_t *p_data_test = (CDText_data_t *) (&wdata[8]);
if( (p_data_test->type >= 0x80)
&& (p_data_test->type <= 0x85) && (p_data_test->block == 0) ) {
p_data = p_data_test;
i_data -= 4;
}
}
*/
p_data = (CDText_data_t *) (&wdata[4]);
for( ; i_data > 0;
i_data -= sizeof(CDText_data_t), p_data++ ) {
@@ -206,23 +224,19 @@ cdtext_data_init(void *p_user_data, track_t i_first_track,
}
#endif
/* we should increment i here and not just when we get a char string */
if ( p_data->seq != ++i || p_data->block != block ) break;
/* only handle character packs */
if( ((p_data->type >= 0x80) && (p_data->type <= 0x85)) ||
if ( ((p_data->type >= 0x80) && (p_data->type <= 0x86)) ||
(p_data->type == 0x8E)) {
i_track = p_data->i_track;
/* can we somehow use p_data->characterPosition to make this simpler? */
for( j=0; j < CDIO_CDTEXT_MAX_TEXT_DATA; (p_data->bDBC ? j+=2 : j++) ) {
if( p_data->text[j] == 0x00 && (!p_data->bDBC || p_data->text[j+1] == 0x00)) {
/* omit empty strings */
if((buffer[0] != 0x00) && (!p_data->bDBC || buffer[1] != 0x00)) {
bool b_field_set=true;
switch( p_data->type) {
case CDIO_CDTEXT_TITLE:
SET_CDTEXT_FIELD(CDTEXT_TITLE);
@@ -242,6 +256,11 @@ cdtext_data_init(void *p_user_data, track_t i_first_track,
case CDIO_CDTEXT_MESSAGE:
SET_CDTEXT_FIELD(CDTEXT_MESSAGE);
break;
case CDIO_CDTEXT_DISCID:
if(i_track == 0) {
SET_CDTEXT_FIELD(CDTEXT_DISCID);
}
break;
case CDIO_CDTEXT_UPC:
if(i_track == 0) {
SET_CDTEXT_FIELD(CDTEXT_UPC_EAN);
@@ -250,25 +269,90 @@ cdtext_data_init(void *p_user_data, track_t i_first_track,
SET_CDTEXT_FIELD(CDTEXT_ISRC);
}
break;
default : b_field_set = false;
}
if (b_field_set) {
b_ret = true;
i_track++;
idx = 0;
}
}
} else {
buffer[idx++] = p_data->text[j];
if(p_data->bDBC)
buffer[idx++] = p_data->text[j+1];
}
buffer[idx] = 0x00;
if(p_data->bDBC)
buffer[idx+1] = 0x00;
}
} else {
/* not a character pack */
if (p_data->type == CDIO_CDTEXT_GENRE) {
i_track = p_data->i_track;
/* seems like it is a uint_16 in the first 2 bytes */
if((p_data->text[0] << 8) + p_data->text[1] != CDIO_CDTEXT_GENRE_UNUSED) {
sprintf(buffer,"%s",cdtext_genre[(p_data->text[0] << 8) + p_data->text[1]]);
SET_CDTEXT_FIELD(CDTEXT_GENRE);
}
}
return b_ret;
#ifdef _DEBUG_CDTEXT
printf("GENRE information present: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
p_data->text[0],p_data->text[1],p_data->text[2],p_data->text[3],
p_data->text[4],p_data->text[5],p_data->text[6],p_data->text[7],
p_data->text[8],p_data->text[9],p_data->text[10],p_data->text[11]);
#endif
}
if(p_data->type == CDIO_CDTEXT_TOC) {
#ifdef _DEBUG_CDTEXT
printf("TOC information present: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
p_data->text[0],p_data->text[1],p_data->text[2],p_data->text[3],
p_data->text[4],p_data->text[5],p_data->text[6],p_data->text[7],
p_data->text[8],p_data->text[9],p_data->text[10],p_data->text[11]);
#endif
}
if (p_data->type == CDIO_CDTEXT_TOC2) {
#ifdef _DEBUG_CDTEXT
printf("TOC2 information present: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
p_data->text[0],p_data->text[1],p_data->text[2],p_data->text[3],
p_data->text[4],p_data->text[5],p_data->text[6],p_data->text[7],
p_data->text[8],p_data->text[9],p_data->text[10],p_data->text[11]);
#endif
}
/* i got this info from cdrtools' cdda2wav; all the tests i ran so far were successful */
if (p_data->type == CDIO_CDTEXT_BLOCKSIZE) {
/* i_track is the pack element number in this case */
switch(p_data->i_track){
case 0:
memcpy((char*)&p_blocksize,p_data->text,0x0c);
break;
case 1:
memcpy(((char*)&p_blocksize)+0x0c,p_data->text,0x0c);
break;
case 2:
memcpy(((char*)&p_blocksize)+0x18,p_data->text,0x0c);
break;
}
}
}
}
if (p_blocksize.packcount[15] >= 3) {
/* BLOCKSIZE packs present */
switch (p_blocksize.charcode){
case CDIO_CDTEXT_CHARCODE_ISO_8859_1:
sprintf(encoding,"ISO-8859-1");
break;
case CDIO_CDTEXT_CHARCODE_ASCII:
sprintf(encoding,"ASCII");
break;
case CDIO_CDTEXT_CHARCODE_KANJI:
sprintf(encoding,"Shift-JIS");
break;
}
}
return b_ret;
}

View File

@@ -1,7 +1,5 @@
/*
$Id: cdtext_private.h,v 1.3 2008/04/22 15:29:11 karl Exp $
Copyright (C) 2004, 2005, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2004, 2005, 2008, 2011 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -28,7 +26,7 @@
to be helpful in debuggers where wants just to refer to the
ISO_*_ names and get something.
*/
extern enum cdtext_enum1_s {
extern const enum cdtext_enum1_s {
CDIO_CDTEXT_MAX_PACK_DATA = 255,
CDIO_CDTEXT_MAX_TEXT_DATA = 12,
CDIO_CDTEXT_TITLE = 0x80,
@@ -45,13 +43,91 @@ extern enum cdtext_enum1_s {
CDIO_CDTEXT_BLOCKSIZE = 0x8F
} cdtext_enums1;
/*!
* CD-Text Genre Codes
*/
extern const enum cdtext_genre_enum_s {
CDIO_CDTEXT_GENRE_UNUSED = 0, /**< not used */
CDIO_CDTEXT_GENRE_UNDEFINED = 1, /**< not defined */
CDIO_CDTEXT_GENRE_ADULT_CONTEMP = 2, /**< Adult Contemporary */
CDIO_CDTEXT_GENRE_ALT_ROCK = 3, /**< Alternative Rock */
CDIO_CDTEXT_GENRE_CHILDRENS = 4, /**< Childrens Music */
CDIO_CDTEXT_GENRE_CLASSIC = 5, /**< Classical */
CDIO_CDTEXT_GENRE_CHRIST_CONTEMP = 6, /**< Contemporary Christian */
CDIO_CDTEXT_GENRE_COUNTRY = 7, /**< Country */
CDIO_CDTEXT_GENRE_DANCE = 8, /**< Dance */
CDIO_CDTEXT_GENRE_EASY_LISTENING = 9, /**< Easy Listening */
CDIO_CDTEXT_GENRE_EROTIC = 10, /**< Erotic */
CDIO_CDTEXT_GENRE_FOLK = 11, /**< Folk */
CDIO_CDTEXT_GENRE_GOSPEL = 12, /**< Gospel */
CDIO_CDTEXT_GENRE_HIPHOP = 13, /**< Hip Hop */
CDIO_CDTEXT_GENRE_JAZZ = 14, /**< Jazz */
CDIO_CDTEXT_GENRE_LATIN = 15, /**< Latin */
CDIO_CDTEXT_GENRE_MUSICAL = 16, /**< Musical */
CDIO_CDTEXT_GENRE_NEWAGE = 17, /**< New Age */
CDIO_CDTEXT_GENRE_OPERA = 18, /**< Opera */
CDIO_CDTEXT_GENRE_OPERETTA = 19, /**< Operetta */
CDIO_CDTEXT_GENRE_POP = 20, /**< Pop Music */
CDIO_CDTEXT_GENRE_RAP = 21, /**< RAP */
CDIO_CDTEXT_GENRE_REGGAE = 22, /**< Reggae */
CDIO_CDTEXT_GENRE_ROCK = 23, /**< Rock Music */
CDIO_CDTEXT_GENRE_RYTHMANDBLUES = 24, /**< Rhythm & Blues */
CDIO_CDTEXT_GENRE_SOUNDEFFECTS = 25, /**< Sound Effects */
CDIO_CDTEXT_GENRE_SOUNDTRACK = 26, /**< Soundtrack */
CDIO_CDTEXT_GENRE_SPOKEN_WORD = 27, /**< Spoken Word */
CDIO_CDTEXT_GENRE_WORLD_MUSIC = 28 /**< World Music */
} cdtext_genre_enum;
/*!
* CD-Text character codes
*/
extern const enum cdtext_charcode_enum_s {
CDIO_CDTEXT_CHARCODE_ISO_8859_1 = 0x00, /**< ISO-8859-1 */
CDIO_CDTEXT_CHARCODE_ASCII = 0x01, /**< ASCII - 7 bit */
CDIO_CDTEXT_CHARCODE_KANJI = 0x80, /**< Music Shift-JIS Kanji -
double byte */
CDIO_CDTEXT_CHARCODE_KOREAN = 0x81, /**< Korean */
CDIO_CDTEXT_CHARCODE_CHINESE = 0x82, /**< Mandarin Chinese */
CDIO_CDTEXT_CHARCODE_UNDEFINED = 0xFF, /**< everything else */
} cdtext_charcode_enum;
/*!
* The language code is encoded as specified in ANNEX 1 to part 5 of EBU
* Tech 32 58 -E (1991).
*/
extern const enum cdtext_lang_enum_s
{
CDIO_CDTEXT_LANG_CZECH = 0x06,
CDIO_CDTEXT_LANG_DANISH = 0x07,
CDIO_CDTEXT_LANG_GERMAN = 0x08,
CDIO_CDTEXT_LANG_ENGLISH = 0x09,
CDIO_CDTEXT_LANG_SPANISH = 0x0A,
CDIO_CDTEXT_LANG_FRENCH = 0x0F,
CDIO_CDTEXT_LANG_ITALIAN = 0x15,
CDIO_CDTEXT_LANG_HUNGARIAN = 0x1b,
CDIO_CDTEXT_LANG_DUTCH = 0x1d,
CDIO_CDTEXT_LANG_NORWEGIAN = 0x1e,
CDIO_CDTEXT_LANG_POLISH = 0x20,
CDIO_CDTEXT_LANG_PORTUGUESE = 0x21,
CDIO_CDTEXT_LANG_SLOVENE = 0x26,
CDIO_CDTEXT_LANG_FINNISH = 0x27,
CDIO_CDTEXT_LANG_SWEDISH = 0x28,
CDIO_CDTEXT_LANG_RUSSIAN = 0x56,
CDIO_CDTEXT_LANG_KOREAN = 0x65,
CDIO_CDTEXT_LANG_JAPANESE = 0x69,
CDIO_CDTEXT_LANG_GREEK = 0x70,
CDIO_CDTEXT_LANG_CHINESE = 0x75,
} cdtext_lang_enum;
#define CDIO_CDTEXT_MAX_PACK_DATA 255
#define CDIO_CDTEXT_MAX_TEXT_DATA 12
/* From table J.2 - Pack Type Indicator Definitions from
Working Draft NCITS XXX T10/1364-D Revision 10G. November 12, 2001.
*/
/* Title of Alubm name (ID=0) or Track Titles (ID != 0) */
/* Title of Album name (ID=0) or Track Titles (ID != 0) */
#define CDIO_CDTEXT_TITLE 0x80
/* Name(s) of the performer(s) in ASCII */
@@ -113,6 +189,25 @@ struct CDText_data
PRAGMA_END_PACKED
/*
* content of BLOCKSIZE packs
*/
typedef struct CDText_blocksize
{
uint8_t charcode; /* character code */
uint8_t i_firstTrack; /* first track number */
uint8_t i_lastTrack; /* last track number */
uint8_t copyright; /* cd-text information copyright byte */
uint8_t packcount[16];/* number of packs of each type
* 0 TITLE; 1 PERFORMER; 2 SONGWRITER; 3 COMPOSER;
* 4 ARRANGER; 5 MESSAGE; 6 DISCID; 7 GENRE;
* 8 TOC; 9 TOC2; 10-12 RESERVED; 13 CLOSED;
* 14 UPC_ISRC; 15 BLOCKSIZE */
uint8_t lastseq[8]; /* last sequence for block 0..7 */
uint8_t langcode[8]; /* language code for block 0..7 */
} CDText_blocksize_t;
typedef struct CDText_data CDText_data_t;
typedef void (*set_cdtext_field_fn_t) (void *user_data, track_t i_track,