1
/***************************************************************************
4
begin : Mon Feb 12 2001
5
copyright : (C) 2001 by Alex Kern
6
email : alex.kern@gmx.de
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
16
***************************************************************************/
23
#include <sys/types.h>
27
/* #include <sys/time.h> */
29
#include "include/wm_config.h"
30
#include "include/wm_struct.h"
31
/*#include "include/wm_cdrom.h"*/
32
#include "include/wm_database.h"
33
#include "include/wm_platform.h"
34
#include "include/wm_helpers.h"
35
#include "include/wm_cdinfo.h"
36
#include "include/wm_cdtext.h"
38
struct cdtext_info wm_cdtext_info;
39
static int first_initialise = 1;
41
int free_cdtext_info_block(struct cdtext_info_block* cdtextinfoblock)
45
if(cdtextinfoblock->name)
46
free(cdtextinfoblock->name);
47
if(cdtextinfoblock->performer)
48
free(cdtextinfoblock->performer);
49
if(cdtextinfoblock->songwriter)
50
free(cdtextinfoblock->songwriter);
51
if(cdtextinfoblock->composer)
52
free(cdtextinfoblock->composer);
53
if(cdtextinfoblock->arranger)
54
free(cdtextinfoblock->arranger);
55
if(cdtextinfoblock->message)
56
free(cdtextinfoblock->message);
57
if(cdtextinfoblock->UPC_EAN_ISRC_code)
58
free(cdtextinfoblock->UPC_EAN_ISRC_code);
60
if(cdtextinfoblock->block_encoding_text)
61
free(cdtextinfoblock->block_encoding_text);
67
int free_cdtext_info(struct cdtext_info* cdtextinfo)
70
printf("CDTEXT INFO: free_cdtext_info() called\n");
73
for(i = 0; i < 8; i++)
75
if(cdtextinfo->blocks[i])
77
free_cdtext_info_block(cdtextinfo->blocks[i]);
85
struct cdtext_info_block* malloc_cdtext_info_block(int count_of_tracks)
88
struct cdtext_info_block* lp_block;
90
lp_block = malloc(sizeof(struct cdtext_info_block));
93
return (struct cdtext_info_block*)0;
95
memset(lp_block, 0, sizeof(struct cdtext_info_block));
97
memamount = count_of_tracks * sizeof(cdtext_string);
99
lp_block->name = malloc(memamount);
101
return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
102
memset(lp_block->name, 0, memamount);
104
lp_block->performer = malloc(memamount);
105
if(!lp_block->performer)
106
return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
107
memset(lp_block->performer, 0, memamount);
109
lp_block->songwriter = malloc(memamount);
110
if(!lp_block->songwriter)
111
return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
112
memset(lp_block->songwriter, 0, memamount);
114
lp_block->composer = malloc(memamount);
115
if(!lp_block->composer)
116
return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
117
memset(lp_block->composer, 0, memamount);
119
lp_block->arranger = malloc(memamount);
120
if(!lp_block->arranger)
121
return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
122
memset(lp_block->arranger, 0, memamount);
124
lp_block->message = malloc(memamount);
125
if(!lp_block->message)
126
return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
127
memset(lp_block->message, 0, memamount);
129
lp_block->UPC_EAN_ISRC_code = malloc(memamount);
130
if(!lp_block->UPC_EAN_ISRC_code)
131
return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
132
memset(lp_block->UPC_EAN_ISRC_code, 0, memamount);
137
void get_data_from_cdtext_pack(
138
const struct cdtext_pack_data_header *pack,
139
const struct cdtext_pack_data_header *pack_previous,
140
cdtext_string *p_componente)
143
int arr = pack->header_field_id2_tracknumber;
148
language_block = (pack->header_field_id4_block_no >> 4) & 0x07;
149
unicode = pack->header_field_id4_block_no & 0x80;
153
for(i = 0; i < DATAFIELD_LENGHT_IN_PACK; i++)
155
if(pack->text_data_field[i] == 0x00) /* end marker */
159
else if(pack->text_data_field[i] == 0x09) /* repeat last marker */
161
/* ASSERT(arr > 0) */
162
strcat((char*)(p_componente[arr]), (char*)(p_componente[arr-1]));
167
strncat((char*)(p_componente[arr]), (char*)(&(pack->text_data_field[i])), 1);
172
else /* doublebytes ;-) */
174
for(i = 0; i < DATAFIELD_LENGHT_IN_PACK; i += 2)
176
if((Uchar)(pack->text_data_field[i]) == 0x0000) /* end marker */
180
else if((Uchar)(pack->text_data_field[i]) == 0x0909) /* repeat last marker */
182
/* ASSERT(arr > 0) */
183
strcat((char*)(p_componente[arr]), (char*)(p_componente[arr-1]));
188
strncat((char*)(p_componente[arr]), u_uc_to_utf8((Uchar*)(&(pack->text_data_field[i]))), 1);
194
fprintf( stderr, "can't handle unicode");
199
int wm_get_cdtext(struct wm_drive *d)
201
/* alloc cdtext_info */
203
unsigned char *buffer;
207
struct cdtext_pack_data_header *pack, *pack_previous;
208
cdtext_string *p_componente;
209
struct cdtext_info_block *lp_block;
211
if(1 == first_initialise)
213
memset(&wm_cdtext_info, 0, sizeof(struct cdtext_info));
214
first_initialise = 0;
222
ret = (d->get_cdtext)(d, &buffer, &buffer_lenght);
224
free_cdtext_info(&wm_cdtext_info);
225
memset(&wm_cdtext_info, 0, sizeof(struct cdtext_info));
228
(d->get_trackcount)(d, &(wm_cdtext_info.count_of_entries));
229
if( wm_cdtext_info.count_of_entries < 0 )
230
wm_cdtext_info.count_of_entries = 1;
232
wm_cdtext_info.count_of_entries++;
236
pack = 0; /* NULL pointer*/
237
while(i < buffer_lenght)
239
pack_previous = pack;
240
pack = (struct cdtext_pack_data_header*)(buffer+i);
241
/* to implement: check_crc(pack); */
243
/* only for valid packs */
244
if(pack->header_field_id1_typ_of_pack >= 0x80 && pack->header_field_id1_typ_of_pack < 0x90)
247
printf("CDTEXT DEBUG: valid packet at 0x%08X: 0x %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
249
pack->header_field_id1_typ_of_pack,
250
pack->header_field_id2_tracknumber,
251
pack->header_field_id3_sequence,
252
pack->header_field_id4_block_no,
253
pack->text_data_field[0],
254
pack->text_data_field[1],
255
pack->text_data_field[2],
256
pack->text_data_field[3],
257
pack->text_data_field[4],
258
pack->text_data_field[5],
259
pack->text_data_field[6],
260
pack->text_data_field[7],
261
pack->text_data_field[8],
262
pack->text_data_field[9],
263
pack->text_data_field[10],
264
pack->text_data_field[11],
267
wm_cdtext_info.count_of_valid_packs++;
269
code = (pack->header_field_id4_block_no >> 4) & 0x07;
270
if(0 == lp_block || lp_block->block_code != code) /* find or create one new block */
273
for(j = 0; j < MAX_LANGUAGE_BLOCKS && wm_cdtext_info.blocks[j] != 0 && 0 == lp_block; i++)
275
if(wm_cdtext_info.blocks[j]->block_code == code)
277
lp_block = wm_cdtext_info.blocks[j];
281
if(MAX_LANGUAGE_BLOCKS <= j)
283
free_cdtext_info(&wm_cdtext_info);
284
printf("CDTEXT ERROR: more as 8 languageblocks defined\n");
290
/* make next new block */
291
lp_block = malloc_cdtext_info_block(wm_cdtext_info.count_of_entries);
294
printf("CDTEXT ERROR: out of memory, can't create a new language block\n");
295
free_cdtext_info(&wm_cdtext_info);
300
wm_cdtext_info.blocks[j] = lp_block;
301
wm_cdtext_info.blocks[j]->block_code = code;
302
wm_cdtext_info.blocks[j]->block_unicode = pack->header_field_id4_block_no & 0x80;
303
printf("CDTEXT INFO: created a new language block; code %i, %s characters\n", code, lp_block->block_unicode?"doublebyte":"singlebyte");
305
unsigned char block_encoding; not jet!
306
cdtext_string* block_encoding_text;
313
switch(pack->header_field_id1_typ_of_pack)
316
p_componente = (lp_block->name);
317
get_data_from_cdtext_pack(pack, pack_previous, p_componente);
320
p_componente = (lp_block->performer);
321
get_data_from_cdtext_pack(pack, pack_previous, p_componente);
324
p_componente = (lp_block->songwriter);
325
get_data_from_cdtext_pack(pack, pack_previous, p_componente);
328
p_componente = (lp_block->composer);
329
get_data_from_cdtext_pack(pack, pack_previous, p_componente);
332
p_componente = (lp_block->arranger);
333
get_data_from_cdtext_pack(pack, pack_previous, p_componente);
336
p_componente = (lp_block->message);
337
get_data_from_cdtext_pack(pack, pack_previous, p_componente);
340
memcpy((char*)(lp_block->binary_disc_identification_info),
341
(char*)(pack->text_data_field), DATAFIELD_LENGHT_IN_PACK);
344
memcpy((char*)(lp_block->binary_genreidentification_info),
345
(char*)(pack->text_data_field), DATAFIELD_LENGHT_IN_PACK);
348
printf("CDTEXT INFO: PACK with code 0x88 (TOC)\n");
351
printf("CDTEXT INFO: PACK with code 0x89 (second TOC)\n");
356
printf("CDTEXT INFO: PACK with code 0x%02X (reserved)\n", pack->header_field_id1_typ_of_pack);
359
printf("CDTEXT INFO: PACK with code 0x8D (for content provider only)\n");
362
p_componente = (lp_block->UPC_EAN_ISRC_code);
363
get_data_from_cdtext_pack(pack, pack_previous, p_componente);
366
memcpy((char*)(lp_block->binary_size_information),
367
(char*)(pack->text_data_field), DATAFIELD_LENGHT_IN_PACK);
370
printf("CDTEXT ERROR: invalid packet at 0x%08X: 0x %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
372
pack->header_field_id1_typ_of_pack,
373
pack->header_field_id2_tracknumber,
374
pack->header_field_id3_sequence,
375
pack->header_field_id4_block_no,
376
pack->text_data_field[0],
377
pack->text_data_field[1],
378
pack->text_data_field[2],
379
pack->text_data_field[3],
380
pack->text_data_field[4],
381
pack->text_data_field[5],
382
pack->text_data_field[6],
383
pack->text_data_field[7],
384
pack->text_data_field[8],
385
pack->text_data_field[9],
386
pack->text_data_field[10],
387
pack->text_data_field[11],
390
wm_cdtext_info.count_of_invalid_packs++;
392
i += sizeof(struct cdtext_pack_data_header);
396
if(0 == ret && wm_cdtext_info.count_of_valid_packs > 0)
397
wm_cdtext_info.valid = 1;
402
void wm_free_cdtext(void)
404
printf("CDTEXT INFO: wm_free_cdtext() called, this function will be called at the end from USERSPACE(KSCD etc.)\n");
405
if (0 == first_initialise)
406
free_cdtext_info(&wm_cdtext_info);
408
first_initialise = 1;