wmclockmon: update change-log
[dockapps.git] / ascd / libworkman / plat_irix.c
blob149cc0a0bfb421c64c2473784a1113e6fa2067d0
1 /*
2 * $Id: plat_irix.c,v 1.6 1999/03/07 08:36:40 dirk Exp $
4 * This file is part of WorkMan, the civilized CD player library
5 * (c) 1991-1997 by Steven Grimm (original author)
6 * (c) by Dirk Försterling (current 'author' = maintainer)
7 * The maintainer can be contacted by his e-mail address:
8 * milliByte@DeathsDoor.com
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the Free
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * IRIX specific.
27 * Taken from the kscd distribution
29 * Paul Kendall
30 * paul@orion.co.nz, or
31 * paul@kcbbs.gen.nz
34 #ifdef sgi
36 static char plat_irix_id[] = "$Id: plat_irix.c,v 1.6 1999/03/07 08:36:40 dirk Exp $";
38 #include "include/wm_config.h"
41 * Yes, it was designed for WorkMan 1.4b3
42 * Because I did start over from 1.3a, I disable it here.
43 * There is no guarantee of getting working code by defining
44 * CDDA yourself.
47 #undef CDDA
48 /*#define CDDA*/
50 #include <sys/types.h>
51 #include <sys/time.h>
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <string.h>
55 #include <fcntl.h>
56 #include <stdlib.h>
57 #include <unistd.h>
58 #include <signal.h>
59 #include <sigfpe.h>
60 #include <dmedia/cdaudio.h>
61 #include <dmedia/audio.h>
62 #include <errno.h>
64 #include "include/wm_struct.h"
66 #define WM_MSG_CLASS WM_MSG_CLASS_PLATFORM
68 void *malloc();
69 char *strchr();
71 int min_volume = 0;
72 int max_volume = 255;
74 extern char *cd_device;
76 #ifdef CDDA
77 static int playing = STOPPED;
78 static CDPLAYER *icd;
79 static CDPARSER *icdp;
80 static CDFRAME cdbuf[12];
81 static ALport audioport;
82 static ALconfig aconfig;
83 static struct itimerval audiotimer = { {0,0}, {0,25000} };
84 static int cdtrack=0;
85 static int cdframe=0;
86 static int cdstopframe=0;
88 cbprognum(void *arg, CDDATATYPES type, CDPROGNUM* prognum)
90 cdtrack = prognum->value;
93 cbabstime(void *arg, CDDATATYPES type, struct cdtimecode* atime)
95 cdframe = CDtctoframe(atime);
96 if( cdframe == cdstopframe )
97 playing = STOPPED;
100 cbplayaudio(void *arg, CDDATATYPES type, short* audio)
102 if(playing != PLAYING) return;
103 ALwritesamps(audioport, audio, CDDA_NUMSAMPLES);
106 static void alarmsignal()
108 int n, i;
109 if(playing != PLAYING) return;
110 if( ALgetfilled(audioport) < CDDA_NUMSAMPLES*8 ) {
111 /* Only get more samples and play them if we're getting low
112 * this ensures that the CD stays close to the sound
114 n = CDreadda(icd, cdbuf, 12);
115 if( n == 0 ) return;
116 for( i=0 ; i<12 ; i++ )
117 CDparseframe(icdp, &cdbuf[i]);
119 signal(SIGALRM, alarmsignal);
120 setitimer(ITIMER_REAL, &audiotimer, NULL);
122 #endif
124 /*--------------------------------------------------------*
125 * Initialize the drive. A no-op for the generic driver.
126 *--------------------------------------------------------*/
128 gen_init( struct wm_drive *d )
130 #ifdef CDDA
131 long Param[4];
132 /* Set the audio rate to 44100Hz 16bit 2s-comp stereo */
133 aconfig = ALnewconfig();
134 ALsetwidth(aconfig, AL_SAMPLE_16);
135 ALsetsampfmt(aconfig, AL_SAMPFMT_TWOSCOMP);
136 ALsetchannels(aconfig, 2);
137 Param[0] = AL_OUTPUT_RATE; Param[1] = AL_RATE_44100;
138 Param[2] = AL_CHANNEL_MODE; Param[3] = AL_STEREO;
139 ALsetparams(AL_DEFAULT_DEVICE, Param, 4);
140 audioport = ALopenport("KDE KSCD Audio", "w", aconfig);
142 /* setup cdparser */
143 icdp = CDcreateparser();
144 CDaddcallback(icdp, cd_audio, (CDCALLBACKFUNC)cbplayaudio, 0);
145 CDaddcallback(icdp, cd_pnum, (CDCALLBACKFUNC)cbprognum, 0);
146 CDaddcallback(icdp, cd_atime, (CDCALLBACKFUNC)cbabstime, 0);
148 /* Lets handle those floating point exceptions expeditiously. */
149 sigfpe_[_UNDERFL].repls = _ZERO;
150 handle_sigfpes(_ON, _EN_UNDERFL, NULL, _ABORT_ON_ERROR, NULL);
151 #endif
152 return 0;
155 /*-------------------------------------*
156 * Get the number of tracks on the CD.
157 *-------------------------------------*/
159 gen_get_trackcount( struct wm_drive *d, int *tracks )
161 CDSTATUS s;
162 if( CDgetstatus(d->daux, &s)==0 )
163 return -1;
164 *tracks = s.last;
165 return 0;
168 /*---------------------------------------------------------*
169 * Get the start time and mode (data or audio) of a track.
170 *---------------------------------------------------------*/
172 gen_get_trackinfo( struct wm_drive *d, int track, int *data, int *startframe)
174 CDTRACKINFO i;
175 int ret = CDgettrackinfo(d->daux, track, &i);
176 if( ret == 0 )
177 return -1;
178 *data = 0;
179 *startframe = CDmsftoframe(i.start_min,i.start_sec,i.start_frame);
180 return 0;
183 /*-------------------------------------*
184 * Get the number of frames on the CD.
185 *-------------------------------------*/
187 gen_get_cdlen( struct wm_drive *d, int *frames )
189 CDSTATUS s;
190 if( CDgetstatus(d->daux, &s)==0 )
191 return -1;
192 *frames = CDmsftoframe(s.total_min,s.total_sec,s.total_frame);
193 return 0;
196 /*--------------------------------------------------------------------------*
197 * Get the current status of the drive: the current play mode, the absolute
198 * position from start of disc (in frames), and the current track and index
199 * numbers if the CD is playing or paused.
200 *--------------------------------------------------------------------------*/
202 gen_get_drive_status( struct wm_drive *d, enum wm_cd_modes oldmode,
203 enum wm_cd_modes *mode, int *pos, int *track,
204 int *index )
206 #ifdef CDDA
207 *mode = playing;
208 *track = cdtrack;
209 *pos = cdframe;
210 *index = 0;
211 #else
212 CDSTATUS s;
213 if( CDgetstatus(d->daux, &s)==0 )
214 return -1;
215 *pos = CDmsftoframe(s.min,s.sec,s.frame);
216 *track = s.track;
217 *index = 0;
218 switch( s.state )
220 case CD_READY: *mode = WM_CDM_STOPPED;
221 break;
222 case CD_STILL:
223 case CD_PAUSED: *mode = WM_CDM_PAUSED;
224 break;
225 case CD_PLAYING: *mode = WM_CDM_PLAYING;
226 break;
227 default: *mode = WM_CDM_UNKNOWN;
229 #endif
230 return 0;
233 /*---------------------------------------------------------------------*
234 * Set the volume level for the left and right channels. Their values
235 * range from 0 to 100.
236 *---------------------------------------------------------------------*/
238 gen_set_volume( struct wm_drive *d, int left, int right )
240 long Param[4];
241 Param[0] = AL_LEFT_SPEAKER_GAIN; Param[1] = left*255/100;
242 Param[2] = AL_RIGHT_SPEAKER_GAIN; Param[3] = right*255/100;
243 ALsetparams(AL_DEFAULT_DEVICE, Param, 4);
244 return 0;
247 /*---------------------------------------------------------------------*
248 * Read the initial volume from the drive, if available. Each channel
249 * ranges from 0 to 100, with -1 indicating data not available.
250 *---------------------------------------------------------------------*/
252 gen_get_volume( struct wm_drive *d, int *left, int *right )
254 long Param[4];
255 Param[0] = AL_LEFT_SPEAKER_GAIN; Param[1] = 0;
256 Param[2] = AL_RIGHT_SPEAKER_GAIN; Param[3] = 0;
257 ALgetparams(AL_DEFAULT_DEVICE, Param, 4);
258 *left = Param[1] * 100 / 255;
259 *right = Param[3] * 100 / 255;
260 return 0;
263 /*---------------*
264 * Pause the CD.
265 *---------------*/
267 gen_pause( struct wm_drive *d )
269 #ifdef CDDA
270 playing = WM_CDM_PAUSED;
271 #else
272 CDSTATUS s;
273 if( CDgetstatus(d->daux, &s)==0 )
274 return -1;
275 if(s.state == CD_PLAYING)
276 CDtogglepause(d->daux);
277 #endif
278 return 0;
281 /*-------------------------------------------------*
282 * Resume playing the CD (assuming it was paused.)
283 *-------------------------------------------------*/
285 gen_resume( struct wm_drive *d )
287 #ifdef CDDA
288 playing = WM_CDM_PLAYING;
289 signal(SIGALRM, alarmsignal);
290 setitimer(ITIMER_REAL, &audiotimer, NULL);
291 #else
292 CDSTATUS s;
293 if( CDgetstatus(d->daux, &s)==0 )
294 return -1;
295 if(s.state == CD_PAUSED)
296 CDtogglepause(d->daux);
297 #endif
298 return 0;
301 /*--------------*
302 * Stop the CD.
303 *--------------*/
305 gen_stop( struct wm_drive *d )
307 #ifdef CDDA
308 playing = WM_CDM_STOPPED;
309 #else
310 CDstop(d->daux);
311 #endif
312 return 0;
315 /*------------------------------------------------------------*
316 * Play the CD from one position to another (both in frames.)
317 *------------------------------------------------------------*/
319 gen_play( struct wm_drive *d, int start, int end )
321 #ifdef CDDA
322 int m, s, f;
323 CDframetomsf(start, &m, &s, &f);
324 CDseek(icd, m, s, f);
325 cdstopframe = end;
326 playing = PLAYING;
327 signal(SIGALRM, alarmsignal);
328 setitimer(ITIMER_REAL, &audiotimer, NULL);
329 #else
330 int m, s, f;
331 CDframetomsf(start, &m, &s, &f);
332 CDplayabs(d->daux, m, s, f, 1);
333 #endif
334 return 0;
337 /*----------------------------------------*
338 * Eject the current CD, if there is one.
339 *----------------------------------------*/
341 gen_eject( struct wm_drive *d )
343 #ifdef CDDA
344 playing = WM_CDM_STOPPED;
345 #endif
346 CDeject(d->daux);
347 return 0;
350 /*----------------------------------------*
351 * Close the CD tray
353 * Please edit and send changes to
354 * milliByte@Deathsdoor.com
355 *----------------------------------------*/
357 int gen_closetray(struct wm_drive *d)
359 #ifdef CAN_CLOSE
360 if(!close(d->fd))
362 d->fd=-1;
363 return(wmcd_reopen(d));
364 } else {
365 return(-1);
367 #else
368 /* Always succeed if the drive can't close */
369 return(0);
370 #endif /* CAN_CLOSE */
371 } /* gen_closetray() */
374 /*-------------------------------------------------------------*
375 * Open the CD and figure out which kind of drive is attached.
376 *-------------------------------------------------------------*/
378 wmcd_open( struct wm_drive *d )
380 int fd;
381 CDSTATUS s;
383 if (d->fd < 0) /* Device already open? */
385 if (cd_device == NULL)
386 cd_device = DEFAULT_CD_DEVICE;
388 d->fd = 1;
390 /* Now fill in the relevant parts of the wm_drive structure. */
391 fd = d->fd;
392 *d = *(find_drive_struct("", "", ""));
393 d->fd = fd;
394 (d->init)(d);
396 d->daux = CDopen(cd_device,"r");
397 if (d->daux == 0)
399 perror(cd_device);
400 exit(1);
402 #ifdef CDDA
403 icd = d->daux;
404 #endif
407 CDgetstatus(d->daux, &s);
408 if( s.state==CD_NODISC || s.state==CD_ERROR )
409 return 1;
411 return (0);
412 } /* wmcd_open() */
415 * Re-Open the device if it is open.
418 wmcd_reopen( struct wm_drive *d )
420 int status;
422 do {
423 wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "wmcd_reopen ");
424 if (d->fd >= 0) /* Device really open? */
426 wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "closes the device and ");
427 status = close( d->fd ); /* close it! */
428 /* we know, that the file is closed, do we? */
429 d->fd = -1;
431 wm_susleep( 1000 );
432 wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "calls wmcd_open()\n");
433 status = wmcd_open( d ); /* open it as usual */
434 wm_susleep( 1000 );
435 } while ( status != 0 );
436 return status;
437 } /* wmcd_reopen() */
440 /*----------------------------------*
441 * Send a SCSI command out the bus.
442 *----------------------------------*/
444 wm_scsi(d, xcdb, cdblen, retbuf, retbuflen, getreply)
445 struct wm_drive *d;
446 unsigned char *xcdb;
447 int cdblen;
448 int getreply;
449 char *retbuf;
450 int retbuflen;
452 return -1;
455 #endif