1 /*
2     Copyright (C) 2018 Thomas Schmitt
3     Copyright (C) 2004, 2005, 2008, 2012, 2019 Rocky Bernstein <rocky@gnu.org>
4     adapted from cuetools
5     Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
6 
7     This program is free software: you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation, either version 3 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 /*!
21  * \file cdtext.h
22  *
23  * \brief The top-level header for CD-Text information. Applications
24  *  include this for CD-Text access.
25 */
26 
27 
28 #ifndef CDIO_CDTEXT_H_
29 #define CDIO_CDTEXT_H_
30 
31 #include <cdio/types.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif /* __cplusplus */
36 
37 #define MIN_CDTEXT_FIELD          0
38 #define MAX_CDTEXT_FIELDS         10
39 
40 /*! \typedef enum cdtext_field_t
41 
42   \brief Enumeration of CD-TEXT text fields.
43 */
44 typedef enum {
45   CDTEXT_FIELD_TITLE          =  0,   /**< title of album name or track titles */
46   CDTEXT_FIELD_PERFORMER      =  1,   /**< name(s) of the performer(s) */
47   CDTEXT_FIELD_SONGWRITER     =  2,   /**< name(s) of the songwriter(s) */
48   CDTEXT_FIELD_COMPOSER       =  3,   /**< name(s) of the composer(s) */
49   CDTEXT_FIELD_MESSAGE        =  4,   /**< message(s) from content provider or artist, ISO-8859-1 encoded*/
50   CDTEXT_FIELD_ARRANGER       =  5,   /**< name(s) of the arranger(s) */
51   CDTEXT_FIELD_ISRC           =  6,   /**< ISRC code of each track */
52   CDTEXT_FIELD_UPC_EAN        =  7,   /**< upc/european article number of disc, ISO-8859-1 encoded */
53   CDTEXT_FIELD_GENRE          =  8,   /**< genre identification and genre information, ASCII encoded */
54   CDTEXT_FIELD_DISCID         =  9,   /**< disc identification, ASCII encoded (may be non-printable) */
55   CDTEXT_FIELD_INVALID        =  MAX_CDTEXT_FIELDS /**< INVALID FIELD*/
56 } cdtext_field_t;
57 
58 /*! \typedef enum cdtext_genre_t
59 
60   \brief Enumeration of possible genre codes.
61 */
62 typedef enum {
63   CDTEXT_GENRE_UNUSED         =  0,   /**< field is not used. default */
64   CDTEXT_GENRE_UNDEFINED      =  1,   /**< not defined */
65   CDTEXT_GENRE_ADULT_CONTEMP  =  2,   /**< Adult Contemporary */
66   CDTEXT_GENRE_ALT_ROCK       =  3,   /**< Alternative Rock */
67   CDTEXT_GENRE_CHILDRENS      =  4,   /**< Childrens Music */
68   CDTEXT_GENRE_CLASSIC        =  5,   /**< Classical */
69   CDTEXT_GENRE_CHRIST_CONTEMP =  6,   /**< Contemporary Christian */
70   CDTEXT_GENRE_COUNTRY        =  7,   /**< Country */
71   CDTEXT_GENRE_DANCE          =  8,   /**< Dance */
72   CDTEXT_GENRE_EASY_LISTENING =  9,   /**< Easy Listening */
73   CDTEXT_GENRE_EROTIC         = 10,   /**< Erotic */
74   CDTEXT_GENRE_FOLK           = 11,   /**< Folk */
75   CDTEXT_GENRE_GOSPEL         = 12,   /**< Gospel */
76   CDTEXT_GENRE_HIPHOP         = 13,   /**< Hip Hop */
77   CDTEXT_GENRE_JAZZ           = 14,   /**< Jazz */
78   CDTEXT_GENRE_LATIN          = 15,   /**< Latin */
79   CDTEXT_GENRE_MUSICAL        = 16,   /**< Musical */
80   CDTEXT_GENRE_NEWAGE         = 17,   /**< New Age */
81   CDTEXT_GENRE_OPERA          = 18,   /**< Opera */
82   CDTEXT_GENRE_OPERETTA       = 19,   /**< Operetta */
83   CDTEXT_GENRE_POP            = 20,   /**< Pop Music */
84   CDTEXT_GENRE_RAP            = 21,   /**< RAP */
85   CDTEXT_GENRE_REGGAE         = 22,   /**< Reggae */
86   CDTEXT_GENRE_ROCK           = 23,   /**< Rock Music */
87   CDTEXT_GENRE_RYTHMANDBLUES  = 24,   /**< Rhythm & Blues */
88   CDTEXT_GENRE_SOUNDEFFECTS   = 25,   /**< Sound Effects */
89   CDTEXT_GENRE_SOUNDTRACK     = 26,   /**< Soundtrack */
90   CDTEXT_GENRE_SPOKEN_WORD    = 27,   /**< Spoken Word */
91   CDTEXT_GENRE_WORLD_MUSIC    = 28    /**< World Music */
92 } cdtext_genre_t;
93 
94 /*! \typedef typedef enum cdtext_lang_t
95 
96     \brief Enumeration of possible CD-TEXT languages.
97 
98   The language code is encoded as specified in ANNEX 1 to part 5 of EBU
99   Tech 32 58 -E (1991).
100  */
101 typedef enum {
102   CDTEXT_LANGUAGE_UNKNOWN     = 0x00,
103   CDTEXT_LANGUAGE_ALBANIAN    = 0x01,
104   CDTEXT_LANGUAGE_BRETON      = 0x02,
105   CDTEXT_LANGUAGE_CATALAN     = 0x03,
106   CDTEXT_LANGUAGE_CROATIAN    = 0x04,
107   CDTEXT_LANGUAGE_WELSH       = 0x05,
108   CDTEXT_LANGUAGE_CZECH       = 0x06,
109   CDTEXT_LANGUAGE_DANISH      = 0x07,
110   CDTEXT_LANGUAGE_GERMAN      = 0x08,
111   CDTEXT_LANGUAGE_ENGLISH     = 0x09,
112   CDTEXT_LANGUAGE_SPANISH     = 0x0A,
113   CDTEXT_LANGUAGE_ESPERANTO   = 0x0B,
114   CDTEXT_LANGUAGE_ESTONIAN    = 0x0C,
115   CDTEXT_LANGUAGE_BASQUE      = 0x0D,
116   CDTEXT_LANGUAGE_FAROESE     = 0x0E,
117   CDTEXT_LANGUAGE_FRENCH      = 0x0F,
118   CDTEXT_LANGUAGE_FRISIAN     = 0x10,
119   CDTEXT_LANGUAGE_IRISH       = 0x11,
120   CDTEXT_LANGUAGE_GAELIC      = 0x12,
121   CDTEXT_LANGUAGE_GALICIAN    = 0x13,
122   CDTEXT_LANGUAGE_ICELANDIC   = 0x14,
123   CDTEXT_LANGUAGE_ITALIAN     = 0x15,
124   CDTEXT_LANGUAGE_LAPPISH     = 0x16,
125   CDTEXT_LANGUAGE_LATIN       = 0x17,
126   CDTEXT_LANGUAGE_LATVIAN     = 0x18,
127   CDTEXT_LANGUAGE_LUXEMBOURGIAN = 0x19,
128   CDTEXT_LANGUAGE_LITHUANIAN  = 0x1A,
129   CDTEXT_LANGUAGE_HUNGARIAN   = 0x1B,
130   CDTEXT_LANGUAGE_MALTESE     = 0x1C,
131   CDTEXT_LANGUAGE_DUTCH       = 0x1D,
132   CDTEXT_LANGUAGE_NORWEGIAN   = 0x1E,
133   CDTEXT_LANGUAGE_OCCITAN     = 0x1F,
134   CDTEXT_LANGUAGE_POLISH      = 0x20,
135   CDTEXT_LANGUAGE_PORTUGUESE  = 0x21,
136   CDTEXT_LANGUAGE_ROMANIAN    = 0x22,
137   CDTEXT_LANGUAGE_ROMANSH     = 0x23,
138   CDTEXT_LANGUAGE_SERBIAN     = 0x24,
139   CDTEXT_LANGUAGE_SLOVAK      = 0x25,
140   CDTEXT_LANGUAGE_SLOVENIAN   = 0x26,
141   CDTEXT_LANGUAGE_FINNISH     = 0x27,
142   CDTEXT_LANGUAGE_SWEDISH     = 0x28,
143   CDTEXT_LANGUAGE_TURKISH     = 0x29,
144   CDTEXT_LANGUAGE_FLEMISH     = 0x2A,
145   CDTEXT_LANGUAGE_WALLON      = 0x2B,
146   CDTEXT_LANGUAGE_ZULU        = 0x45,
147   CDTEXT_LANGUAGE_VIETNAMESE  = 0x46,
148   CDTEXT_LANGUAGE_UZBEK       = 0x47,
149   CDTEXT_LANGUAGE_URDU        = 0x48,
150   CDTEXT_LANGUAGE_UKRAINIAN   = 0x49,
151   CDTEXT_LANGUAGE_THAI        = 0x4A,
152   CDTEXT_LANGUAGE_TELUGU      = 0x4B,
153   CDTEXT_LANGUAGE_TATAR       = 0x4C,
154   CDTEXT_LANGUAGE_TAMIL       = 0x4D,
155   CDTEXT_LANGUAGE_TADZHIK     = 0x4E,
156   CDTEXT_LANGUAGE_SWAHILI     = 0x4F,
157   CDTEXT_LANGUAGE_SRANANTONGO = 0x50,
158   CDTEXT_LANGUAGE_SOMALI      = 0x51,
159   CDTEXT_LANGUAGE_SINHALESE   = 0x52,
160   CDTEXT_LANGUAGE_SHONA       = 0x53,
161   CDTEXT_LANGUAGE_SERBO_CROAT = 0x54,
162   CDTEXT_LANGUAGE_RUTHENIAN   = 0x55,
163   CDTEXT_LANGUAGE_RUSSIAN     = 0x56,
164   CDTEXT_LANGUAGE_QUECHUA     = 0x57,
165   CDTEXT_LANGUAGE_PUSHTU      = 0x58,
166   CDTEXT_LANGUAGE_PUNJABI     = 0x59,
167   CDTEXT_LANGUAGE_PERSIAN     = 0x5A,
168   CDTEXT_LANGUAGE_PAPAMIENTO  = 0x5B,
169   CDTEXT_LANGUAGE_ORIYA       = 0x5C,
170   CDTEXT_LANGUAGE_NEPALI      = 0x5D,
171   CDTEXT_LANGUAGE_NDEBELE     = 0x5E,
172   CDTEXT_LANGUAGE_MARATHI     = 0x5F,
173   CDTEXT_LANGUAGE_MOLDAVIAN   = 0x60,
174   CDTEXT_LANGUAGE_MALAYSIAN   = 0x61,
175   CDTEXT_LANGUAGE_MALAGASAY   = 0x62,
176   CDTEXT_LANGUAGE_MACEDONIAN  = 0x63,
177   CDTEXT_LANGUAGE_LAOTIAN     = 0x64,
178   CDTEXT_LANGUAGE_KOREAN      = 0x65,
179   CDTEXT_LANGUAGE_KHMER       = 0x66,
180   CDTEXT_LANGUAGE_KAZAKH      = 0x67,
181   CDTEXT_LANGUAGE_KANNADA     = 0x68,
182   CDTEXT_LANGUAGE_JAPANESE    = 0x69,
183   CDTEXT_LANGUAGE_INDONESIAN  = 0x6A,
184   CDTEXT_LANGUAGE_HINDI       = 0x6B,
185   CDTEXT_LANGUAGE_HEBREW      = 0x6C,
186   CDTEXT_LANGUAGE_HAUSA       = 0x6D,
187   CDTEXT_LANGUAGE_GURANI      = 0x6E,
188   CDTEXT_LANGUAGE_GUJURATI    = 0x6F,
189   CDTEXT_LANGUAGE_GREEK       = 0x70,
190   CDTEXT_LANGUAGE_GEORGIAN    = 0x71,
191   CDTEXT_LANGUAGE_FULANI      = 0x72,
192   CDTEXT_LANGUAGE_DARI        = 0x73,
193   CDTEXT_LANGUAGE_CHURASH     = 0x74,
194   CDTEXT_LANGUAGE_CHINESE     = 0x75,
195   CDTEXT_LANGUAGE_BURMESE     = 0x76,
196   CDTEXT_LANGUAGE_BULGARIAN   = 0x77,
197   CDTEXT_LANGUAGE_BENGALI     = 0x78,
198   CDTEXT_LANGUAGE_BIELORUSSIAN = 0x79,
199   CDTEXT_LANGUAGE_BAMBORA     = 0x7A,
200   CDTEXT_LANGUAGE_AZERBAIJANI = 0x7B,
201   CDTEXT_LANGUAGE_ASSAMESE    = 0x7C,
202   CDTEXT_LANGUAGE_ARMENIAN    = 0x7D,
203   CDTEXT_LANGUAGE_ARABIC      = 0x7E,
204   CDTEXT_LANGUAGE_AMHARIC     = 0x7F,
205 
206   /* libcdio-internal pseudo codes: */
207 
208   CDTEXT_LANGUAGE_INVALID      = 0x100, /**< Invalid language code */
209   CDTEXT_LANGUAGE_BLOCK_UNUSED = 0x101  /**< Language code should be ignored */
210 
211 } cdtext_lang_t;
212 
213 /*!
214   \typedef struct cdtext_s cdtext_t
215 
216   \brief Opaque type for CD-Text.
217 */
218 typedef struct cdtext_s cdtext_t;
219 
220 /*!
221   Return string representation of the given genre code.
222 */
223 const char *cdtext_genre2str (cdtext_genre_t i);
224 
225 /*!
226   Return string representation of the given language code.
227 */
228 const char *cdtext_lang2str (cdtext_lang_t i);
229 
230 /*!
231   Return the language code of a given language string representation.
232   This is the inverse of cdtext_lang2str().
233 
234   @param lang language to look up
235 
236   @return if lang is among the possible results of cdtext_lang2str():
237           the \p cdtext_lang_t which is associated, or \p
238           CDTEXT_LANGUAGE_INVALID otherwise.
239 */
240 cdtext_lang_t cdtext_str2lang (const char *lang);
241 
242 /*!
243   Return string representation of given field type.
244 */
245 const char *cdtext_field2str (cdtext_field_t i);
246 
247 /*!
248   Initialize a new \p cdtext_t structure.
249 
250   When the structure is no longer needed, release the
251   resources using cdtext_delete.
252 */
253 cdtext_t *cdtext_init (void);
254 
255 /*!
256   Fill a cdtext_t object with text pack bytes as they were handed out by the
257   CD drive, but without the 4-byte header which the drive prepended.
258 
259   The text pack data can be obtained by the calls
260 
261     - cdio_get_cdtext_raw()
262     - mmc_read_cdtext()
263     - mmc_read_toc_cdtext()
264 
265   Each sets in the buffer passed into values that begin with a 4-byte header. This should
266   be skipped. Here is some sample code:
267 
268   @code
269     #include <cdio/mmc_ll_cmds.h>
270     if (DRIVER_OP_SUCCESS == mmc_read_toc_cdtext (p_cdio, &i_length, p_buf, 0)
271         && 4 < i_length)
272         cdtext_data_init(p_cdtext, p_buf + 4, (size_t) i_length - 4);
273   @endcode
274 
275   Instead of calling cdtext_data_init(), you can call
276   cdio_get_cdtext() which returns a pointer to the \p cdtext_t object
277   that is attached to the inquired \p CdIo_t object. This \p cdtext_t
278   object gets created and filled if none is yet attached to the
279   inquired \p CdIo_t object.
280 
281   @param p_cdtext the CD-TEXT object
282   @param wdata the data
283   @param i_data size of wdata
284 
285   @returns 0 on success, non-zero on failure
286 */
287 int cdtext_data_init(cdtext_t *p_cdtext, uint8_t *wdata, size_t i_data);
288 
289 /*!
290   Free memory associated with the given \p cdtext_t object.
291 
292   @param p_cdtext the CD-TEXT object
293 */
294 void cdtext_destroy (cdtext_t *p_cdtext);
295 
296 /*!
297   Returns a copy of the return value of cdtext_get_const or NULL.
298 
299   Must be freed using cdio_free() when done.
300   @see cdtext_get_const
301 */
302 char *cdtext_get (const cdtext_t *p_cdtext, cdtext_field_t key, track_t track);
303 
304 /*!
305   Returns value of the given field.
306 
307   NULL is returned if key is CDTEXT_INVALID or the field is not set.
308   Strings are encoded in UTF-8.
309 
310   @param p_cdtext the CD-TEXT object
311   @param field type of the field to return
312   @param track specifies the track, 0 stands for disc
313 */
314 const char *cdtext_get_const (const cdtext_t *p_cdtext, cdtext_field_t field,
315                               track_t track);
316 
317 /*!
318   Returns the discs genre code.
319 
320   @param p_cdtext the CD-TEXT object
321 */
322 cdtext_genre_t cdtext_get_genre (const cdtext_t *p_cdtext);
323 
324 /*!
325   Returns the currently active language.
326 
327   @param p_cdtext the CD-TEXT object
328 */
329 cdtext_lang_t cdtext_get_language (const cdtext_t *p_cdtext);
330 
331 /*!
332   Returns the first track number.
333 
334   @param p_cdtext the CD-TEXT object
335 */
336 track_t cdtext_get_first_track(const cdtext_t *p_cdtext);
337 
338 /*!
339   Returns the last track number.
340 
341   @param p_cdtext the CD-TEXT object
342 */
343 track_t cdtext_get_last_track(const cdtext_t *p_cdtext);
344 
345 /*!
346   Try to select the given language.
347 
348   @param p_cdtext the CD-TEXT object
349   @param language string representation of the language
350 
351   @return true on success, false if language is not available
352 */
353 bool cdtext_select_language(cdtext_t *p_cdtext, cdtext_lang_t language);
354 
355 /*!
356 
357   @deprecated Use cdtext_list_languages_v2()
358 
359   Returns a list of available languages or NULL.
360 
361   __WARNING__: The indices in the returned array _do not_ match the indexing
362            as expected by cdtext_set_language_index().
363            Use cdtext_select_language() with the values of array elements.
364 
365   Internally the list is stored in a static array.
366 
367   @param p_cdtext the CD-TEXT object
368   @return NULL if p_cdtext is NULL, or an array of 8 cdtext_lang_t elements:
369           CDTEXT_LANGUAGE_UNKNOWN not only marks language code 0x00
370           but also invalid language codes and invalid language blocks.
371 */
372 cdtext_lang_t *cdtext_list_languages (const cdtext_t *p_cdtext);
373 
374 /*!
375   Returns an array of available languages or NULL.
376   The index of an array element may be used to select the corresponding
377   language block by call cdtext_set_language_index().
378 
379   The return value is a pointer into the memory range of *p_cdtext.
380   Do not use it after having freed that memory range.
381 
382   @param p_cdtext the CD-TEXT object
383   @return NULL if p_cdtext is NULL, or an array of 8 cdtext_lang_t elements.
384 
385   If an enumeration is CDTEXT_LANGUAGE_INVALID, then the language block has an invalid
386   language code.
387 
388   If an enumeration is CDTEXT_LANGUAGE_BLOCK_UNUSED, then the block does not
389   exist on CD or could not be read in CD-TEXT for some reason.
390 
391   Otherwise, the enumeration of element will be a value in
392   CDTEXT_LANGUAGE_UNKNOWN to CDTEXT_LANGUAGE_AMHARIC, and is a block
393   in that language.
394 */
395 cdtext_lang_t *cdtext_list_languages_v2(cdtext_t *p_cdtext);
396 
397 /*!
398   Select the given language by block index. See cdtext_list_languages_v2().
399   If the index is bad, or no language block with that index was read:
400   select the default language at index 0 and return false.
401 
402   @param p_cdtext the CD-TEXT object
403   @param idx      the desired index: 0 to 7.
404 
405   @return true on success, false if no language block is associated to \p idx.
406 */
407 bool
408 cdtext_set_language_index(cdtext_t *p_cdtext, int idx);
409 
410 /*!
411   Sets the given field at the given track to the given value.
412 
413   Recodes to UTF-8 if charset is not \p NULL.
414 
415   @param p_cdtext the CD-TEXT object
416   @param key field to set
417   @param value value to set
418   @param track track to work on
419   @param charset charset to convert from
420  */
421 void cdtext_set (cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value, track_t track, const char *charset);
422 
423 #ifdef __cplusplus
424 }
425 #endif /* __cplusplus */
426 
427 #endif /* CDIO_CDTEXT_H_ */
428 
429 /*
430  * Local variables:
431  *  c-file-style: "gnu"
432  *  tab-width: 8
433  *  indent-tabs-mode: nil
434  * End:
435  */
436