1 /* 2 * cdda - CD Digital Audio support 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 __CDDA_H__ 22 #define __CDDA_H__ 23 24 #ifndef lint 25 static char *_cdda_h_ident_ = "@(#)cdda.h 7.114 04/03/05"; 26 #endif 27 28 29 /* 30 * Whether to enable the SYSV IPC and/or the POSIX threads support 31 * based on OS feature capability. 32 */ 33 #if defined(SVR4) || defined(SYSV) || defined(_LINUX) || \ 34 defined(_SUNOS4) || defined(_SOLARIS) || defined(sgi) || \ 35 defined(__hpux) || defined(_AIX) || \ 36 defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \ 37 defined(__bsdi__) || defined(_OSF1) 38 #define HAS_SYSVIPC 39 #endif 40 41 #if defined(_POSIX_THREADS) && !defined(NO_PTHREADS) 42 /* If <unistd.h> defines _POSIX_THREADS, then POSIX 1003.1c threads 43 * are supported. NO_PTHREADS allows a user to disable POSIX thread 44 * support code from the makefile. 45 */ 46 #define HAS_PTHREADS 47 #endif 48 49 #ifdef HAS_PTHREADS 50 /* Hack: Some platforms lack the necessary pthread_cancel(3) */ 51 #include <pthread.h> 52 #ifndef PTHREAD_CANCELED 53 #undef HAS_PTHREADS 54 #endif 55 #endif 56 57 58 /* 59 * CDDA methods 60 */ 61 #define CDDA_METHODS 3 /* Total number of CDDA methods */ 62 63 #define CDDA_NONE 0 /* Don't use CDDA method */ 64 #ifdef HAS_SYSVIPC 65 #define CDDA_SYSVIPC 1 /* SYSV IPC method */ 66 #endif 67 #ifdef HAS_PTHREADS 68 #define CDDA_PTHREADS 2 /* POSIX threads method */ 69 #endif 70 71 72 /* 73 * CDDA read methods 74 */ 75 #define CDDA_RD_METHODS 6 /* Total number of CDDA read methods */ 76 77 #define CDDA_RD_NONE 0 /* Don't use CDDA read method */ 78 #define CDDA_RD_SCSIPT 1 /* SCSI pass-through method */ 79 #ifdef _SOLARIS 80 #define CDDA_RD_SOL 2 /* Solaris ioctl method */ 81 #endif 82 #ifdef _LINUX 83 #define CDDA_RD_LINUX 3 /* Linux ioctl method */ 84 #endif 85 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) 86 #define CDDA_RD_FBSD 4 /* FreeBSD/OpenBSD/NetBSD ioctl method */ 87 #endif 88 #if defined(_AIX) && defined(AIX_IDE) 89 #define CDDA_RD_AIX 5 /* AIX ATAPI/IDE ioctl method */ 90 #endif 91 92 93 /* 94 * CDDA write methods 95 */ 96 #define CDDA_WR_METHODS 9 /* Total number of CDDA write methods */ 97 98 #define CDDA_WR_NONE 0 /* Don't use CDDA write method */ 99 #ifndef __VMS 100 #define CDDA_WR_OSS 1 /* OSS & Linux sound driver method */ 101 #endif 102 #ifdef _SOLARIS 103 #define CDDA_WR_SOL 2 /* Solaris audio driver method */ 104 #endif 105 #ifdef sgi 106 #define CDDA_WR_IRIX 3 /* IRIX audio driver method */ 107 #endif 108 #ifdef __hpux 109 #define CDDA_WR_HPUX 4 /* HP-UX audio driver method */ 110 #endif 111 #ifdef _AIX 112 #define CDDA_WR_AIX 5 /* AIX Ultimedia audio driver method */ 113 #endif 114 #if defined(_LINUX) && defined(HAS_ALSA) 115 #define CDDA_WR_ALSA 6 /* ALSA sound driver method */ 116 #endif 117 #if defined(_OSF1) || defined(__VMS) 118 #define CDDA_WR_OSF1 7 /* Tru64 UNIX and OpenVMS MME method */ 119 #endif 120 #define CDDA_WR_FP 8 /* File & pipe method: No audio playback */ 121 122 123 /* Whether a CDDA method is configured */ 124 #if defined(CDDA_SYSVIPC) || defined(CDDA_PTHREADS) 125 #define CDDA_SUPPORTED 126 #endif 127 128 129 /* Check for ALSA version due to API changes */ 130 #ifdef CDDA_WR_ALSA 131 #include <alsa/asoundlib.h> 132 #if !defined(SND_LIB_MAJOR) || !defined(SND_LIB_MINOR) || \ 133 (SND_LIB_MAJOR == 0 && SND_LIB_MINOR < 9) 134 #undef CDDA_WR_ALSA /* ALSA version prior to 0.9.0 not supported */ 135 #endif 136 #endif /* CDDA_WR_ALSA */ 137 138 139 /* Basic CDDA read unit (number of bytes per CDDA sector) */ 140 #define CDDA_BLKSZ 2352 141 142 /* Default CDDA read size: Note that different platforms' CDROM drivers 143 * may impose different limits which require that this be externally 144 * tuned via the cddaReadChunkBlocks parameter. 145 */ 146 #define DEF_CDDA_CHUNK_BLKS 8 /* 8 blocks */ 147 #define MIN_CDDA_CHUNK_BLKS 1 /* 1 block */ 148 #define MAX_CDDA_CHUNK_BLKS (3 * FRAME_PER_SEC) /* 3 seconds */ 149 150 /* CDDA data is queued up in memory. Here we define (in 151 * seconds) the amount of queued data. This is not a 152 * modifiable resource. 153 */ 154 #define DEF_CDDA_BUFFER_SECS 5 155 156 /* During jitter correction we search through DEFAULT_SEARCH_BLOCKS 157 * for a match. This is not a modifiable resource. 158 */ 159 #define DEF_CDDA_SRCH_BLKS 2 160 161 /* In order to perform jitter correction we need to 162 * read more CDDA data than we "need". Below we define 163 * the amount of extra data required. So each CDDA 164 * read will comprise CHUNK_BLOCKS + OLAP_BLOCKS. 165 */ 166 #define DEF_CDDA_OLAP_BLKS (DEF_CDDA_SRCH_BLKS * 2) 167 168 /* We have found a match when DEFAULT_STR_LENGTH bytes are 169 * identical in the data and the overlap. 170 */ 171 #define DEF_CDDA_STR_LEN 20 172 173 /* Maximum number of interrupts before system call fails */ 174 #define CDDA_INTR_MAX 200 175 176 /* Maximum number of times to retry a failed CDDA read */ 177 #define MAX_CDDAREAD_RETRIES 3 178 179 /* CDDA heartbeat types */ 180 #define CDDA_HB_READER 1 /* Reader */ 181 #define CDDA_HB_WRITER 2 /* Writer */ 182 183 /* Reader/writer heartbeat timeout values in seconds */ 184 #define MIN_HB_TIMEOUT 5 /* Minimum */ 185 #define DEF_HB_TIMEOUT 15 /* Default */ 186 187 /* Number of heartbeat checks to skip after a pause/resume operation, 188 * in order to allow the reader and writer threads to catch up. 189 */ 190 #define CDDA_HB_SKIP 5 191 192 /* CDDA supported features bitmask values, returned by cdda_capab() 193 * These should match the similar CAPAB_xxx defines in libdi_d/libdi.h 194 */ 195 #define CDDA_READAUDIO 0x02 196 #define CDDA_WRITEDEV 0x10 197 #define CDDA_WRITEFILE 0x20 198 #define CDDA_WRITEPIPE 0x40 199 200 /* CDDA audio output port bitmask values */ 201 #define CDDA_OUT_SPEAKER 0x01 /* Internal speaker */ 202 #define CDDA_OUT_HEADPHONE 0x02 /* Headphone */ 203 #define CDDA_OUT_LINEOUT 0x04 /* Line Out */ 204 205 /* Read and write process priority flags */ 206 #define CDDA_RDPRI 0x01 /* Elevate read priority */ 207 #define CDDA_WRPRI 0x02 /* Elevate write priority */ 208 209 /* Macros for encoder version storage */ 210 #define ENCVER_MK(x,y,z) (((x) * 1000000) + ((y) * 1000) + (z)) 211 #define ENCVER_MAJ(v) ((v) / 1000000) 212 #define ENCVER_MIN(v) (((v) / 1000) % 1000) 213 #define ENCVER_TINY(v) ((v) % 1000) 214 215 216 /* Call table structure for branching into a read-method. */ 217 typedef struct cdda_rd_tbl { 218 word32_t (*readinit)(void); 219 bool_t (*readfunc)(di_dev_t *); 220 void (*readdone)(bool_t); 221 void (*readinfo)(char *); 222 } cdda_rd_tbl_t; 223 224 225 /* Call table structure for branching into a write-method. */ 226 typedef struct cdda_wr_tbl { 227 word32_t (*writeinit)(void); 228 bool_t (*writefunc)(curstat_t *); 229 void (*writedone)(bool_t); 230 void (*writeinfo)(char *); 231 } cdda_wr_tbl_t; 232 233 234 /* Generic thread or process ID type */ 235 typedef void * thid_t; 236 237 238 /* Buffer for audio data transfer */ 239 typedef struct cd_buffer { 240 int occupied; 241 unsigned int nextin; 242 unsigned int nextout; 243 byte_t *olap; 244 byte_t *data; 245 byte_t *b; 246 } cd_buffer_t; 247 248 249 /* Various sizes */ 250 typedef struct cd_size { 251 /* Chunk */ 252 unsigned int chunk_blocks; 253 unsigned int chunk_bytes; 254 255 /* Buffer */ 256 unsigned int buffer_chunks; 257 unsigned int buffer_blocks; 258 unsigned int buffer_bytes; 259 260 /* Overlap */ 261 unsigned int olap_blocks; 262 unsigned int olap_bytes; 263 264 /* Searching */ 265 unsigned int search_blocks; 266 unsigned int search_bytes; 267 unsigned int str_length; 268 269 /* Overall size */ 270 size_t size; 271 } cd_size_t; 272 273 274 /* CD info */ 275 typedef struct cd_info { 276 int state; /* CDSTAT_PLAYING, etc. */ 277 int chroute; /* CHROUTE_NORMAL etc. */ 278 int att; /* CDDA attenuator value */ 279 int outport; /* CDDA output port */ 280 int vol_taper; /* Volume control taper */ 281 int vol; /* Current volume level */ 282 int vol_left; /* Current left vol % */ 283 int vol_right; /* Current right vol % */ 284 int jitter; /* 1 = on, 0 = off */ 285 int cdda_done; /* 1 = yes, 0 = no */ 286 word32_t debug; /* Debug level */ 287 288 sword32_t start_lba; /* Start position */ 289 sword32_t end_lba; /* End position */ 290 word32_t frm_played; /* Frames written */ 291 word32_t frm_per_sec; /* Frames per sec stats */ 292 size_t trk_len; /* Track length in bytes */ 293 int trk_idx; /* Current track array index */ 294 295 thid_t reader; /* Reader thread id */ 296 thid_t writer; /* Writer thread id */ 297 298 time_t reader_hb; /* Reader heartbeat */ 299 time_t writer_hb; /* Writer heartbeat */ 300 int reader_hb_timeout; /* reader heartbeat timeout */ 301 int writer_hb_timeout; /* writer heartbeat timeout */ 302 303 char msgbuf[ERR_BUF_SZ]; /* Message buffer */ 304 } cd_info_t; 305 306 307 /* CD state structure - pointers to the size, info and buffer areas */ 308 typedef struct cd_state { 309 cd_size_t *cds; /* Sizes */ 310 cd_info_t *i; /* Info */ 311 cd_buffer_t *cdb; /* Data buffer */ 312 } cd_state_t ; 313 314 315 /* Message dialog macros */ 316 #define CDDA_FATAL(msg) { \ 317 if (cdda_clinfo != NULL && cdda_clinfo->fatal_msg != NULL) \ 318 cdda_clinfo->fatal_msg(app_data.str_fatal, (msg)); \ 319 else { \ 320 (void) fprintf(errfp, "Fatal: %s\n", (msg)); \ 321 _exit(1); \ 322 } \ 323 } 324 #define CDDA_WARNING(msg) { \ 325 if (cdda_clinfo != NULL && cdda_clinfo->warning_msg != NULL) \ 326 cdda_clinfo->warning_msg(app_data.str_warning, (msg)); \ 327 else \ 328 (void) fprintf(errfp, "Warning: %s\n", (msg)); \ 329 } 330 #define CDDA_INFO(msg) { \ 331 if (cdda_clinfo != NULL && cdda_clinfo->info_msg != NULL) \ 332 cdda_clinfo->info_msg(app_data.str_info, (msg)); \ 333 else \ 334 (void) fprintf(errfp, "Info: %s\n", (msg)); \ 335 } 336 #define CDDA_INFO2(msg, txt) { \ 337 if (cdda_clinfo != NULL && cdda_clinfo->info2_msg != NULL) \ 338 cdda_clinfo->info2_msg(app_data.str_info,(msg),(txt)); \ 339 else \ 340 (void) fprintf(errfp, "Info: %s\n%s\n", (msg), (txt)); \ 341 } 342 343 344 /* Client registration structure */ 345 typedef struct cdda_client { 346 curstat_t * (*curstat_addr)(void); 347 void (*fatal_msg)(char *, char *); 348 void (*warning_msg)(char *, char *); 349 void (*info_msg)(char *, char *); 350 void (*info2_msg)(char *, char *, char *); 351 } cdda_client_t; 352 353 354 /* File format description structure */ 355 typedef struct filefmt { 356 int fmt; /* Format code */ 357 char *name; /* Format name */ 358 char *suf; /* File Suffix */ 359 char *desc; /* Description */ 360 } filefmt_t; 361 362 363 /* Function prototypes */ 364 extern word32_t cdda_capab(void); 365 extern void cdda_preinit(void); 366 extern bool_t cdda_init(curstat_t *, cdda_client_t *); 367 extern void cdda_halt(di_dev_t *, curstat_t *); 368 extern bool_t cdda_play(di_dev_t *, curstat_t *, sword32_t, 369 sword32_t); 370 extern bool_t cdda_pause_resume(di_dev_t *, curstat_t *, bool_t); 371 extern bool_t cdda_stop(di_dev_t *, curstat_t *); 372 extern int cdda_vol(di_dev_t *, curstat_t *, int, bool_t); 373 extern bool_t cdda_chroute(di_dev_t *, curstat_t *); 374 extern void cdda_att(curstat_t *); 375 extern void cdda_outport(void); 376 extern bool_t cdda_getstatus(di_dev_t *, curstat_t *, cdstat_t *); 377 extern void cdda_debug(word32_t); 378 extern char *cdda_info(void); 379 extern int cdda_initipc(cd_state_t *); 380 extern void cdda_waitsem(int, int); 381 extern void cdda_postsem(int, int); 382 extern void cdda_yield(void); 383 extern void cdda_kill(thid_t, int); 384 extern bool_t cdda_filefmt_supp(int); 385 extern filefmt_t *cdda_filefmt(int); 386 extern int cdda_bitrates(void); 387 extern int cdda_bitrate_val(int); 388 extern char *cdda_bitrate_name(int); 389 extern int cdda_heartbeat_interval(int); 390 extern void cdda_heartbeat(time_t *, int); 391 392 #endif /* __CDDA_H__ */ 393 394