1 /* 2 * libdi - CD Audio Device Interface Library 3 * 4 * Copyright (C) 1993-2004 Ti Kan 5 * E-mail: xmcd@amb.org 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 2 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, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 #ifndef __LIBDI_H__ 22 #define __LIBDI_H__ 23 24 #ifndef lint 25 static char *_libdi_h_ident_ = "@(#)libdi.h 6.94 04/03/05"; 26 #endif 27 28 /* Max number of libdi modules */ 29 #define MAX_METHODS 4 30 31 /* 32 * Supported libdi methods 33 * 34 * Comment out any of these to remove support for a method. 35 * Removing unused methods can reduce the executable 36 * binary size and run-time memory usage. At least one 37 * method must be defined. 38 * 39 * Note: If compiling for DEMO_ONLY or on a non-supported OS 40 * platform, DI_SCSIPT must be defined. 41 */ 42 #if !defined(__QNX__) 43 #define DI_SCSIPT 0 /* SCSI pass-through method */ 44 #endif 45 #if defined(_SUNOS4) || defined(_SOLARIS) || \ 46 defined(_LINUX) || defined(__QNX__) 47 #define DI_SLIOC 1 /* SunOS/Solaris/Linux/QNX ioctl method */ 48 #endif 49 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) 50 #define DI_FBIOC 2 /* FreeBSD/NetBSD/OpenBSD ioctl method */ 51 #endif 52 #if defined(_AIX) && defined(AIX_IDE) 53 #define DI_AIXIOC 3 /* AIX IDE ioctl method */ 54 #endif 55 56 57 /* 58 * Multi-CD medium change methods 59 */ 60 #define MAX_CHG_METHODS 4 61 62 #define CHG_NONE 0 /* Changer controls not supported */ 63 #define CHG_SCSI_LUN 1 /* SCSI LUN addressing method */ 64 #define CHG_SCSI_MEDCHG 2 /* SCSI Medium changer device method */ 65 #define CHG_OS_IOCTL 3 /* OS-ioctl method */ 66 67 68 /* Application name */ 69 #define APPNAME "CD audio" 70 71 72 /* Play audio format codes */ 73 #define ADDR_BLK 0x01 /* block address specified */ 74 #define ADDR_MSF 0x02 /* MSF address specified */ 75 #define ADDR_TRKIDX 0x04 /* track/index numbers specified */ 76 #define ADDR_OPTEND 0x80 /* End address can be ignored */ 77 78 79 /* Slider control flags */ 80 #define WARP_VOL 0x1 /* Set volume slider thumb */ 81 #define WARP_BAL 0x2 /* Set balance slider thumb */ 82 83 84 /* Device capabilities: These should match similar defines in cdda_d/cdda.h */ 85 #define CAPAB_PLAYAUDIO 0x01 /* Can play CD audio */ 86 #define CAPAB_RDCDDA 0x02 /* Can read CDDA from drive */ 87 #define CAPAB_WRDEV 0x10 /* Can write audio stream to sound device */ 88 #define CAPAB_WRFILE 0x20 /* Can write audio stream to file */ 89 #define CAPAB_WRPIPE 0x40 /* Can pipe audio stream to a program */ 90 91 92 /* Misc constants */ 93 #define MAX_SRCH_BLKS 225 /* max search play blks per sample */ 94 #define MAX_RECOVERR 20 /* Max number of err recovery tries */ 95 #define ERR_SKIPBLKS 10 /* Number of frame to skip on error */ 96 #define ERR_CLRTHRESH 1500 /* If there hasn't been any errors 97 * for this many blocks of audio 98 * playback, then the previous errors 99 * count is cleared. 100 */ 101 #define CLIP_FRAMES 10 /* Frames to clip from end */ 102 #define DEF_CACHE_TIMEOUT 7 /* Default local cache timeout (days) */ 103 #define DEF_SRV_TIMEOUT 60 /* Default service timeout (seconds) */ 104 105 106 107 /* CDDB/Program macros */ 108 #define DBCLEAR(s, b) { \ 109 if (di_clinfo != NULL && di_clinfo->dbclear != NULL) \ 110 di_clinfo->dbclear((s), (b)); \ 111 } 112 #define DBGET(s) { \ 113 if (di_clinfo != NULL && di_clinfo->dbget != NULL) \ 114 di_clinfo->dbget(s); \ 115 } 116 #define PROGCLEAR(s) { \ 117 if (di_clinfo != NULL && di_clinfo->progclear != NULL) \ 118 di_clinfo->progclear(s); \ 119 } 120 #define PROGGET(s) { \ 121 if (di_clinfo != NULL && di_clinfo->progget != NULL) \ 122 di_clinfo->progget(s); \ 123 } 124 #define STOPSCAN(s) { \ 125 if (di_clinfo != NULL && di_clinfo->chgr_scan_stop != NULL) \ 126 di_clinfo->chgr_scan_stop(s); \ 127 } 128 129 130 /* Message dialog macros */ 131 #define DI_FATAL(msg) { \ 132 if (di_clinfo != NULL && di_clinfo->fatal_msg != NULL) \ 133 di_clinfo->fatal_msg(app_data.str_fatal, (msg)); \ 134 else { \ 135 (void) fprintf(errfp, "Fatal: %s\n", (msg)); \ 136 _exit(1); \ 137 } \ 138 } 139 #define DI_WARNING(msg) { \ 140 if (di_clinfo != NULL && di_clinfo->warning_msg != NULL) \ 141 di_clinfo->warning_msg(app_data.str_warning, (msg)); \ 142 else \ 143 (void) fprintf(errfp, "Warning: %s\n", (msg)); \ 144 } 145 #define DI_INFO(msg) { \ 146 if (di_clinfo != NULL && di_clinfo->info_msg != NULL) \ 147 di_clinfo->info_msg(app_data.str_info, (msg)); \ 148 else \ 149 (void) fprintf(errfp, "Info: %s\n", (msg)); \ 150 } 151 #define DI_INFO2(msg, txt) { \ 152 if (di_clinfo != NULL && di_clinfo->info2_msg != NULL) \ 153 di_clinfo->info2_msg(app_data.str_info, (msg), (txt)); \ 154 else \ 155 (void) fprintf(errfp, "Info: %s\n%s\n", (msg), (txt)); \ 156 } 157 158 159 /* GUI macros */ 160 #define DO_BEEP() { \ 161 if (di_clinfo != NULL && di_clinfo->beep != NULL) \ 162 di_clinfo->beep(); \ 163 } 164 #define SET_LOCK_BTN(state) { \ 165 if (di_clinfo != NULL && di_clinfo->set_lock_btn != NULL) \ 166 di_clinfo->set_lock_btn(state); \ 167 } 168 #define SET_SHUFFLE_BTN(state) { \ 169 if (di_clinfo != NULL && di_clinfo->set_shuffle_btn != NULL) \ 170 di_clinfo->set_shuffle_btn(state); \ 171 } 172 #define SET_VOL_SLIDER(val) { \ 173 if (di_clinfo != NULL && di_clinfo->set_vol_slider != NULL) \ 174 di_clinfo->set_vol_slider(val); \ 175 } 176 #define SET_BAL_SLIDER(val) { \ 177 if (di_clinfo != NULL && di_clinfo->set_bal_slider != NULL) \ 178 di_clinfo->set_bal_slider(val); \ 179 } 180 #define DPY_ALL(s) { \ 181 if (di_clinfo != NULL && di_clinfo->dpy_all != NULL) \ 182 di_clinfo->dpy_all(s); \ 183 } 184 #define DPY_DISC(s) { \ 185 if (di_clinfo != NULL && di_clinfo->dpy_disc != NULL) \ 186 di_clinfo->dpy_disc(s); \ 187 } 188 #define DPY_TRACK(s) { \ 189 if (di_clinfo != NULL && di_clinfo->dpy_track != NULL) \ 190 di_clinfo->dpy_track(s); \ 191 } 192 #define DPY_INDEX(s) { \ 193 if (di_clinfo != NULL && di_clinfo->dpy_index != NULL) \ 194 di_clinfo->dpy_index(s); \ 195 } 196 #define DPY_TIME(s, b) { \ 197 if (di_clinfo != NULL && di_clinfo->dpy_time != NULL) \ 198 di_clinfo->dpy_time((s), (b)); \ 199 } 200 #define DPY_PROGMODE(s, b) { \ 201 if (di_clinfo != NULL && di_clinfo->dpy_progmode != NULL) \ 202 di_clinfo->dpy_progmode((s), (b)); \ 203 } 204 #define DPY_PLAYMODE(s, b) { \ 205 if (di_clinfo != NULL && di_clinfo->dpy_playmode != NULL) \ 206 di_clinfo->dpy_playmode((s), (b)); \ 207 } 208 #define DPY_RPTCNT(s) { \ 209 if (di_clinfo != NULL && di_clinfo->dpy_rptcnt != NULL) \ 210 di_clinfo->dpy_rptcnt(s); \ 211 } 212 213 214 /* 215 * CD-TEXT information structures 216 */ 217 typedef struct { 218 char *title; /* Title */ 219 char *performer; /* Performer name */ 220 char *songwriter; /* Songwriter name */ 221 char *composer; /* Composer name */ 222 char *arranger; /* Arranger name */ 223 char *message; /* Message */ 224 char *catno; /* UPC/EAN or ISRC code */ 225 } di_cdtext_inf_t; 226 227 typedef struct { 228 bool_t cdtext_valid; /* Has CD-TEXT data */ 229 bool_t rsvd[3]; /* reserved */ 230 char *ident; /* Disc identification info */ 231 di_cdtext_inf_t disc; /* Disc information */ 232 di_cdtext_inf_t track[MAXTRACK]; /* Track information */ 233 } di_cdtext_t; 234 235 236 /* 237 * Jump table structure for libdi interface 238 */ 239 typedef struct { 240 void (*load_cdtext)(curstat_t *, di_cdtext_t *); 241 bool_t (*playmode)(curstat_t *); 242 bool_t (*check_disc)(curstat_t *); 243 void (*status_upd)(curstat_t *); 244 void (*lock)(curstat_t *, bool_t); 245 void (*repeat)(curstat_t *, bool_t); 246 void (*shuffle)(curstat_t *, bool_t); 247 void (*load_eject)(curstat_t *); 248 void (*ab)(curstat_t *); 249 void (*sample)(curstat_t *); 250 void (*level)(curstat_t *, byte_t, bool_t); 251 void (*play_pause)(curstat_t *); 252 void (*stop)(curstat_t *, bool_t); 253 void (*chgdisc)(curstat_t *); 254 void (*prevtrk)(curstat_t *); 255 void (*nexttrk)(curstat_t *); 256 void (*previdx)(curstat_t *); 257 void (*nextidx)(curstat_t *); 258 void (*rew)(curstat_t *, bool_t); 259 void (*ff)(curstat_t *, bool_t); 260 void (*warp)(curstat_t *); 261 void (*route)(curstat_t *); 262 void (*mute_on)(curstat_t *); 263 void (*mute_off)(curstat_t *); 264 void (*cddajitter)(curstat_t *); 265 void (*debug)(void); 266 void (*start)(curstat_t *); 267 void (*icon)(curstat_t *, bool_t); 268 void (*halt)(curstat_t *); 269 char * (*methodstr)(void); 270 } di_tbl_t; 271 272 273 /* 274 * Jump table for libdi initialization 275 */ 276 typedef struct { 277 void (*init)(curstat_t *, di_tbl_t *); 278 } diinit_tbl_t; 279 280 281 /* 282 * Callbacks into the application 283 */ 284 typedef struct { 285 word32_t capab; /* Device capabilities bitmask */ 286 curstat_t * (*curstat_addr)(void); /* Required */ 287 void (*quit)(curstat_t *); /* Required */ 288 long (*timeout)(word32_t, void (*)(), byte_t *); 289 void (*untimeout)(long); 290 void (*dbclear)(curstat_t *, bool_t); 291 void (*dbget)(curstat_t *); 292 void (*progclear)(curstat_t *); 293 void (*progget)(curstat_t *); 294 void (*chgr_scan_stop)(curstat_t *); 295 bool_t (*mkoutpath)(curstat_t *); 296 bool_t (*ckpipeprog)(curstat_t *); 297 void (*fatal_msg)(char *, char *); 298 void (*warning_msg)(char *, char *); 299 void (*info_msg)(char *, char *); 300 void (*info2_msg)(char *, char *, char *); 301 void (*beep)(void); 302 void (*set_lock_btn)(bool_t); 303 void (*set_shuffle_btn)(bool_t); 304 void (*set_vol_slider)(int); 305 void (*set_bal_slider)(int); 306 void (*dpy_all)(curstat_t *); 307 void (*dpy_disc)(curstat_t *); 308 void (*dpy_track)(curstat_t *); 309 void (*dpy_index)(curstat_t *); 310 void (*dpy_time)(curstat_t *, bool_t); 311 void (*dpy_progmode)(curstat_t *, bool_t); 312 void (*dpy_playmode)(curstat_t *, bool_t); 313 void (*dpy_rptcnt)(curstat_t *); 314 } di_client_t; 315 316 317 /* Used for the role field of di_dev_t */ 318 #define DI_ROLE_MAIN 1 /* main control thread */ 319 #define DI_ROLE_READER 2 /* CD reader thread */ 320 321 322 /* 323 * Device descriptor structure, returned by pthru_open() 324 */ 325 typedef struct di_dev { 326 int fd; /* primary file descriptor */ 327 int fd2; /* secondary file descriptor */ 328 int role; /* enable I/O for which role */ 329 word32_t flags; /* flags */ 330 char *path; /* path name string */ 331 char *auxpath; /* secondary path name string */ 332 void *auxdesc; /* secondary descriptor */ 333 int bus; /* bus number */ 334 int target; /* target id number */ 335 int lun; /* logical unit number */ 336 int val; /* platform-specific field */ 337 int val2; /* platform-specific field */ 338 } di_dev_t; 339 340 341 /* 342 * Public function prototypes: libdi external calling interface. 343 */ 344 extern void di_init(di_client_t *); 345 extern bool_t di_bitrate_valid(int); 346 extern void di_load_cdtext(curstat_t *, di_cdtext_t *); 347 extern void di_clear_cdtext(di_cdtext_t *); 348 extern bool_t di_playmode(curstat_t *); 349 extern bool_t di_check_disc(curstat_t *); 350 extern void di_status_upd(curstat_t *); 351 extern void di_lock(curstat_t *, bool_t); 352 extern void di_repeat(curstat_t *, bool_t); 353 extern void di_shuffle(curstat_t *, bool_t); 354 extern void di_load_eject(curstat_t *); 355 extern void di_ab(curstat_t *); 356 extern void di_sample(curstat_t *); 357 extern void di_level(curstat_t *, byte_t, bool_t); 358 extern void di_play_pause(curstat_t *); 359 extern void di_stop(curstat_t *, bool_t); 360 extern void di_chgdisc(curstat_t *); 361 extern void di_prevtrk(curstat_t *); 362 extern void di_nexttrk(curstat_t *); 363 extern void di_previdx(curstat_t *); 364 extern void di_nextidx(curstat_t *); 365 extern void di_rew(curstat_t *, bool_t); 366 extern void di_ff(curstat_t *, bool_t); 367 extern void di_warp(curstat_t *); 368 extern void di_route(curstat_t *); 369 extern void di_mute_on(curstat_t *); 370 extern void di_mute_off(curstat_t *); 371 extern void di_cddajitter(curstat_t *); 372 extern void di_debug(void); 373 extern void di_start(curstat_t *); 374 extern void di_icon(curstat_t *, bool_t); 375 extern void di_halt(curstat_t *); 376 extern void di_dump_curstat(curstat_t *); 377 extern void di_common_parmload(char *, bool_t, bool_t); 378 extern void di_devspec_parmload(char *, bool_t, bool_t); 379 extern void di_common_parmsave(char *); 380 extern void di_devspec_parmsave(char *); 381 extern bool_t di_devlock(curstat_t *, char *); 382 extern void di_devunlock(curstat_t *); 383 extern di_dev_t *di_devalloc(char *); 384 extern void di_devfree(di_dev_t *); 385 extern char *di_methodstr(void); 386 extern bool_t di_isdemo(void); 387 extern int di_curtrk_pos(curstat_t *); 388 extern int di_curprog_pos(curstat_t *); 389 extern void di_clear_cdinfo(curstat_t *, bool_t); 390 extern byte_t di_get_cdinfo(curstat_t *); 391 extern bool_t di_prepare_cdda(curstat_t *); 392 extern void di_reset_curstat(curstat_t *, bool_t, bool_t); 393 extern void di_reset_shuffle(curstat_t *); 394 395 #endif /* __LIBDI_H__ */ 396 397