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
27 * Taken from the kscd distribution
30 * paul@orion.co.nz, or
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
50 #include <sys/types.h>
60 #include <dmedia/cdaudio.h>
61 #include <dmedia/audio.h>
64 #include "include/wm_struct.h"
66 #define WM_MSG_CLASS WM_MSG_CLASS_PLATFORM
74 extern char *cd_device
;
77 static int playing
= STOPPED
;
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} };
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
)
100 cbplayaudio(void *arg
, CDDATATYPES type
, short* audio
)
102 if(playing
!= PLAYING
) return;
103 ALwritesamps(audioport
, audio
, CDDA_NUMSAMPLES
);
106 static void alarmsignal()
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);
116 for( i
=0 ; i
<12 ; i
++ )
117 CDparseframe(icdp
, &cdbuf
[i
]);
119 signal(SIGALRM
, alarmsignal
);
120 setitimer(ITIMER_REAL
, &audiotimer
, NULL
);
124 /*--------------------------------------------------------*
125 * Initialize the drive. A no-op for the generic driver.
126 *--------------------------------------------------------*/
128 gen_init( struct wm_drive
*d
)
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
);
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
);
155 /*-------------------------------------*
156 * Get the number of tracks on the CD.
157 *-------------------------------------*/
159 gen_get_trackcount( struct wm_drive
*d
, int *tracks
)
162 if( CDgetstatus(d
->daux
, &s
)==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
)
175 int ret
= CDgettrackinfo(d
->daux
, track
, &i
);
179 *startframe
= CDmsftoframe(i
.start_min
,i
.start_sec
,i
.start_frame
);
183 /*-------------------------------------*
184 * Get the number of frames on the CD.
185 *-------------------------------------*/
187 gen_get_cdlen( struct wm_drive
*d
, int *frames
)
190 if( CDgetstatus(d
->daux
, &s
)==0 )
192 *frames
= CDmsftoframe(s
.total_min
,s
.total_sec
,s
.total_frame
);
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
,
213 if( CDgetstatus(d
->daux
, &s
)==0 )
215 *pos
= CDmsftoframe(s
.min
,s
.sec
,s
.frame
);
220 case CD_READY
: *mode
= WM_CDM_STOPPED
;
223 case CD_PAUSED
: *mode
= WM_CDM_PAUSED
;
225 case CD_PLAYING
: *mode
= WM_CDM_PLAYING
;
227 default: *mode
= WM_CDM_UNKNOWN
;
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
)
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);
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
)
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;
267 gen_pause( struct wm_drive
*d
)
270 playing
= WM_CDM_PAUSED
;
273 if( CDgetstatus(d
->daux
, &s
)==0 )
275 if(s
.state
== CD_PLAYING
)
276 CDtogglepause(d
->daux
);
281 /*-------------------------------------------------*
282 * Resume playing the CD (assuming it was paused.)
283 *-------------------------------------------------*/
285 gen_resume( struct wm_drive
*d
)
288 playing
= WM_CDM_PLAYING
;
289 signal(SIGALRM
, alarmsignal
);
290 setitimer(ITIMER_REAL
, &audiotimer
, NULL
);
293 if( CDgetstatus(d
->daux
, &s
)==0 )
295 if(s
.state
== CD_PAUSED
)
296 CDtogglepause(d
->daux
);
305 gen_stop( struct wm_drive
*d
)
308 playing
= WM_CDM_STOPPED
;
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
)
323 CDframetomsf(start
, &m
, &s
, &f
);
324 CDseek(icd
, m
, s
, f
);
327 signal(SIGALRM
, alarmsignal
);
328 setitimer(ITIMER_REAL
, &audiotimer
, NULL
);
331 CDframetomsf(start
, &m
, &s
, &f
);
332 CDplayabs(d
->daux
, m
, s
, f
, 1);
337 /*----------------------------------------*
338 * Eject the current CD, if there is one.
339 *----------------------------------------*/
341 gen_eject( struct wm_drive
*d
)
344 playing
= WM_CDM_STOPPED
;
350 /*----------------------------------------*
353 * Please edit and send changes to
354 * milliByte@Deathsdoor.com
355 *----------------------------------------*/
357 int gen_closetray(struct wm_drive
*d
)
363 return(wmcd_reopen(d
));
368 /* Always succeed if the drive can't close */
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
)
383 if (d
->fd
< 0) /* Device already open? */
385 if (cd_device
== NULL
)
386 cd_device
= DEFAULT_CD_DEVICE
;
390 /* Now fill in the relevant parts of the wm_drive structure. */
392 *d
= *(find_drive_struct("", "", ""));
396 d
->daux
= CDopen(cd_device
,"r");
407 CDgetstatus(d
->daux
, &s
);
408 if( s
.state
==CD_NODISC
|| s
.state
==CD_ERROR
)
415 * Re-Open the device if it is open.
418 wmcd_reopen( struct wm_drive
*d
)
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? */
432 wm_lib_message(WM_MSG_LEVEL_DEBUG
|WM_MSG_CLASS
, "calls wmcd_open()\n");
433 status
= wmcd_open( d
); /* open it as usual */
435 } while ( status
!= 0 );
437 } /* wmcd_reopen() */
440 /*----------------------------------*
441 * Send a SCSI command out the bus.
442 *----------------------------------*/
444 wm_scsi(d
, xcdb
, cdblen
, retbuf
, retbuflen
, getreply
)