2 * Sample MCI CDAUDIO Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
7 static char Copyright
[] = "Copyright Martin Ayotte, 1994";
20 #include <sys/ioctl.h>
22 #include <linux/soundcard.h>
23 #include <linux/cdrom.h>
26 #define SOUND_DEV "/dev/dsp"
27 #define CDAUDIO_DEV "/dev/sbpcd"
30 #define IOCTL(a,b,c) ioctl(a,b,&c)
32 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
35 #define MAX_CDAUDIODRV 2
36 #define MAX_CDAUDIO_TRACKS 256
38 #define CDFRAMES_PERSEC 75
39 #define CDFRAMES_PERMIN 4500
40 #define SECONDS_PERMIN 60
44 int nUseCount
; /* Incremented for each shared open */
45 BOOL fShareable
; /* TRUE if first open was shareable */
46 WORD wNotifyDeviceID
; /* MCI device ID with a pending notification */
47 HANDLE hCallback
; /* Callback handle for pending notification */
48 MCI_OPEN_PARMS openParms
;
51 struct cdrom_subchnl sc
;
62 static LINUX_CDAUDIO CDADev
[MAX_CDAUDIODRV
];
65 UINT
CDAUDIO_GetNumberOfTracks(UINT wDevID
);
66 BOOL
CDAUDIO_GetTracksInfo(UINT wDevID
);
67 BOOL
CDAUDIO_GetCDStatus(UINT wDevID
);
68 DWORD
CDAUDIO_CalcTime(UINT wDevID
, DWORD dwFormatType
, DWORD dwFrame
);
71 /*-----------------------------------------------------------------------*/
74 /**************************************************************************
75 * CDAUDIO_mciOpen [internal]
77 DWORD
CDAUDIO_mciOpen(DWORD dwFlags
, LPMCI_OPEN_PARMS lpParms
)
83 printf("CDAUDIO_mciOpen(%08X, %08X);\n", dwFlags
, lpParms
);
85 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
86 wDevID
= lpParms
->wDeviceID
;
87 if (CDADev
[wDevID
].nUseCount
> 0) {
88 /* The driver already open on this channel */
89 /* If the driver was% op, ened shareable before and this open specifies */
90 /* shareable then increment the use count */
91 if (CDADev
[wDevID
].fShareable
&& (dwFlags
& MCI_OPEN_SHAREABLE
))
92 ++CDADev
[wDevID
].nUseCount
;
94 return MCIERR_MUST_USE_SHAREABLE
;
97 CDADev
[wDevID
].nUseCount
= 1;
98 CDADev
[wDevID
].fShareable
= dwFlags
& MCI_OPEN_SHAREABLE
;
100 if (dwFlags
& MCI_OPEN_ELEMENT
) {
101 printf("CDAUDIO_mciOpen // MCI_OPEN_ELEMENT !\n");
102 /* return MCIERR_NO_ELEMENT_ALLOWED; */
104 memcpy(&CDADev
[wDevID
].openParms
, lpParms
, sizeof(MCI_OPEN_PARMS
));
105 CDADev
[wDevID
].wNotifyDeviceID
= lpParms
->wDeviceID
;
106 CDADev
[wDevID
].unixdev
= open (CDAUDIO_DEV
, O_RDONLY
, 0);
107 if (CDADev
[wDevID
].unixdev
== -1) {
108 printf("CDAUDIO_mciOpen // can't open '%s' !\n", CDAUDIO_DEV
);
109 return MCIERR_HARDWARE
;
111 CDADev
[wDevID
].mode
= 0;
112 CDADev
[wDevID
].dwTimeFormat
= MCI_FORMAT_TMSF
;
113 CDADev
[wDevID
].nCurTrack
= 0;
114 CDADev
[wDevID
].nTracks
= 0;
115 CDADev
[wDevID
].dwTotalLen
= 0;
116 CDADev
[wDevID
].dwFirstOffset
= 0;
117 CDADev
[wDevID
].lpdwTrackLen
= NULL
;
118 CDADev
[wDevID
].lpdwTrackPos
= NULL
;
119 if (!CDAUDIO_GetTracksInfo(wDevID
)) {
120 printf("CDAUDIO_mciOpen // error reading TracksInfo !\n");
121 /* return MCIERR_INTERNAL; */
123 if (dwFlags
& MCI_NOTIFY
) {
124 printf("CDAUDIO_mciOpen // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
125 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
126 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
130 return MCIERR_HARDWARE
;
134 /**************************************************************************
135 * CDAUDIO_mciClose [internal]
137 DWORD
CDAUDIO_mciClose(UINT wDevID
, DWORD dwParam
, LPMCI_GENERIC_PARMS lpParms
)
141 printf("CDAUDIO_mciClose(%u, %08X, %08X);\n", wDevID
, dwParam
, lpParms
);
143 if (CDADev
[wDevID
].lpdwTrackLen
!= NULL
) free(CDADev
[wDevID
].lpdwTrackLen
);
144 if (CDADev
[wDevID
].lpdwTrackPos
!= NULL
) free(CDADev
[wDevID
].lpdwTrackPos
);
145 close(CDADev
[wDevID
].unixdev
);
149 /**************************************************************************
150 * CDAUDIO_mciGetDevCaps [internal]
152 DWORD
CDAUDIO_mciGetDevCaps(UINT wDevID
, DWORD dwFlags
,
153 LPMCI_GETDEVCAPS_PARMS lpParms
)
157 printf("CDAUDIO_mciGetDevCaps(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
159 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
160 if (dwFlags
& MCI_GETDEVCAPS_ITEM
) {
161 printf("CDAUDIO_mciGetDevCaps // MCI_GETDEVCAPS_ITEM dwItem=%08X);\n",
163 switch(lpParms
->dwItem
) {
164 case MCI_GETDEVCAPS_CAN_RECORD
:
165 lpParms
->dwReturn
= FALSE
;
167 case MCI_GETDEVCAPS_HAS_AUDIO
:
168 lpParms
->dwReturn
= TRUE
;
170 case MCI_GETDEVCAPS_HAS_VIDEO
:
171 lpParms
->dwReturn
= FALSE
;
173 case MCI_GETDEVCAPS_DEVICE_TYPE
:
174 lpParms
->dwReturn
= MCI_DEVTYPE_CD_AUDIO
;
176 case MCI_GETDEVCAPS_USES_FILES
:
177 lpParms
->dwReturn
= FALSE
;
179 case MCI_GETDEVCAPS_COMPOUND_DEVICE
:
180 lpParms
->dwReturn
= FALSE
;
182 case MCI_GETDEVCAPS_CAN_EJECT
:
183 lpParms
->dwReturn
= TRUE
;
185 case MCI_GETDEVCAPS_CAN_PLAY
:
186 lpParms
->dwReturn
= TRUE
;
188 case MCI_GETDEVCAPS_CAN_SAVE
:
189 lpParms
->dwReturn
= FALSE
;
192 return MCIERR_UNRECOGNIZED_COMMAND
;
195 printf("CDAUDIO_mciGetDevCaps // lpParms->dwReturn=%08X);\n", lpParms
->dwReturn
);
198 return MCIERR_INTERNAL
;
202 /**************************************************************************
203 * CDAUDIO_mciInfo [internal]
205 DWORD
CDAUDIO_mciInfo(UINT wDevID
, DWORD dwFlags
, LPMCI_INFO_PARMS lpParms
)
209 printf("CDAUDIO_mciInfo(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
211 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
212 lpParms
->lpstrReturn
= NULL
;
214 case MCI_INFO_PRODUCT
:
215 lpParms
->lpstrReturn
= "Linux CDROM 0.5";
218 return MCIERR_UNRECOGNIZED_COMMAND
;
220 if (lpParms
->lpstrReturn
!= NULL
)
221 lpParms
->dwRetSize
= strlen(lpParms
->lpstrReturn
);
223 lpParms
->dwRetSize
= 0;
226 return MCIERR_INTERNAL
;
230 /**************************************************************************
231 * CDAUDIO_mciStatus [internal]
233 DWORD
CDAUDIO_mciStatus(UINT wDevID
, DWORD dwFlags
, LPMCI_STATUS_PARMS lpParms
)
237 printf("CDAUDIO_mciStatus(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
239 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
240 if (CDADev
[wDevID
].unixdev
== 0) return MMSYSERR_NOTENABLED
;
241 if (dwFlags
& MCI_NOTIFY
) {
243 printf("CDAUDIO_mciStatus // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
245 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
246 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
248 if (dwFlags
& MCI_STATUS_ITEM
) {
249 switch(lpParms
->dwItem
) {
250 case MCI_STATUS_CURRENT_TRACK
:
251 if (!CDAUDIO_GetCDStatus(wDevID
)) return MCIERR_INTERNAL
;
252 lpParms
->dwReturn
= CDADev
[wDevID
].nCurTrack
;
254 printf("CDAUDIO_mciStatus // CURRENT_TRACK=%u!\n", lpParms
->dwReturn
);
257 case MCI_STATUS_LENGTH
:
258 if (CDADev
[wDevID
].nTracks
== 0) {
259 if (!CDAUDIO_GetTracksInfo(wDevID
)) {
260 printf("CDAUDIO_mciStatus // error reading TracksInfo !\n");
261 return MCIERR_INTERNAL
;
264 if (dwFlags
& MCI_TRACK
) {
265 printf("CDAUDIO_mciStatus // MCI_TRACK #%u LENGTH=??? !\n",
267 if (lpParms
->dwTrack
> CDADev
[wDevID
].nTracks
)
268 return MCIERR_OUTOFRANGE
;
269 lpParms
->dwReturn
= CDADev
[wDevID
].lpdwTrackLen
[lpParms
->dwTrack
];
272 lpParms
->dwReturn
= CDADev
[wDevID
].dwTotalLen
;
273 lpParms
->dwReturn
= CDAUDIO_CalcTime(wDevID
,
274 CDADev
[wDevID
].dwTimeFormat
, lpParms
->dwReturn
);
275 printf("CDAUDIO_mciStatus // LENGTH=%u !\n", lpParms
->dwReturn
);
277 case MCI_STATUS_MODE
:
278 if (!CDAUDIO_GetCDStatus(wDevID
)) return MCIERR_INTERNAL
;
279 lpParms
->dwReturn
= CDADev
[wDevID
].mode
;
281 printf("CDAUDIO_mciStatus // MCI_STATUS_MODE=%08X !\n",
285 case MCI_STATUS_MEDIA_PRESENT
:
286 lpParms
->dwReturn
= (CDADev
[wDevID
].nTracks
> 0) ? TRUE
: FALSE
;
287 if (lpParms
->dwReturn
== FALSE
)
288 printf("CDAUDIO_mciStatus // MEDIA_NOT_PRESENT !\n");
290 printf("CDAUDIO_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
292 case MCI_STATUS_NUMBER_OF_TRACKS
:
293 lpParms
->dwReturn
= CDAUDIO_GetNumberOfTracks(wDevID
);
294 printf("CDAUDIO_mciStatus // MCI_STATUS_NUMBER_OF_TRACKS = %u !\n",
296 if (lpParms
->dwReturn
== (WORD
)-1) return MCIERR_INTERNAL
;
298 case MCI_STATUS_POSITION
:
299 if (!CDAUDIO_GetCDStatus(wDevID
)) return MCIERR_INTERNAL
;
300 lpParms
->dwReturn
= CDADev
[wDevID
].dwCurFrame
;
301 if (dwFlags
& MCI_STATUS_START
) {
302 lpParms
->dwReturn
= CDADev
[wDevID
].dwFirstOffset
;
304 printf("CDAUDIO_mciStatus // get MCI_STATUS_START !\n");
307 if (dwFlags
& MCI_TRACK
) {
308 if (lpParms
->dwTrack
> CDADev
[wDevID
].nTracks
)
309 return MCIERR_OUTOFRANGE
;
310 lpParms
->dwReturn
= CDADev
[wDevID
].lpdwTrackPos
[lpParms
->dwTrack
- 1];
312 printf("CDAUDIO_mciStatus // get MCI_TRACK #%u !\n", lpParms
->dwTrack
);
315 lpParms
->dwReturn
= CDAUDIO_CalcTime(wDevID
,
316 CDADev
[wDevID
].dwTimeFormat
, lpParms
->dwReturn
);
318 printf("CDAUDIO_mciStatus // MCI_STATUS_POSITION=%08X !\n",
322 case MCI_STATUS_READY
:
323 printf("CDAUDIO_mciStatus // MCI_STATUS_READY !\n");
324 lpParms
->dwReturn
= TRUE
;
326 case MCI_STATUS_TIME_FORMAT
:
327 printf("CDAUDIO_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
328 lpParms
->dwReturn
= MCI_FORMAT_MILLISECONDS
;
331 printf("CDAUDIO_mciStatus // unknowm command %04X !\n", lpParms
->dwItem
);
332 return MCIERR_UNRECOGNIZED_COMMAND
;
335 printf("CDAUDIO_mciStatus // not MCI_STATUS_ITEM !\n");
338 return MMSYSERR_NOTENABLED
;
343 /**************************************************************************
344 * CDAUDIO_CalcTime [internal]
346 DWORD
CDAUDIO_CalcTime(UINT wDevID
, DWORD dwFormatType
, DWORD dwFrame
)
355 printf("CDAUDIO_CalcTime(%u, %08X, %lu);\n", wDevID
, dwFormatType
, dwFrame
);
358 switch (dwFormatType
) {
359 case MCI_FORMAT_MILLISECONDS
:
360 dwTime
= dwFrame
/ CDFRAMES_PERSEC
* 1000;
362 printf("CDAUDIO_CalcTime // MILLISECONDS %u\n", dwTime
);
366 wMinutes
= dwFrame
/ CDFRAMES_PERMIN
;
367 wSeconds
= (dwFrame
- CDFRAMES_PERMIN
* wMinutes
) / CDFRAMES_PERSEC
;
368 wFrames
= dwFrame
- CDFRAMES_PERMIN
* wMinutes
-
369 CDFRAMES_PERSEC
* wSeconds
;
370 dwTime
= MCI_MAKE_MSF(wMinutes
, wSeconds
, wFrames
);
372 printf("CDAUDIO_CalcTime // MSF %02u:%02u:%02u -> dwTime=%u\n",
373 wMinutes
, wSeconds
, wFrames
, dwTime
);
376 case MCI_FORMAT_TMSF
:
377 for (wTrack
= 0; wTrack
< CDADev
[wDevID
].nTracks
; wTrack
++) {
378 /* dwTime += CDADev[wDevID].lpdwTrackLen[wTrack - 1];
379 printf("Adding trk#%u curpos=%u \n", dwTime);
380 if (dwTime >= dwFrame) break; */
381 if (CDADev
[wDevID
].lpdwTrackPos
[wTrack
- 1] >= dwFrame
) break;
383 wMinutes
= dwFrame
/ CDFRAMES_PERMIN
;
384 wSeconds
= (dwFrame
- CDFRAMES_PERMIN
* wMinutes
) / CDFRAMES_PERSEC
;
385 wFrames
= dwFrame
- CDFRAMES_PERMIN
* wMinutes
-
386 CDFRAMES_PERSEC
* wSeconds
;
387 dwTime
= MCI_MAKE_TMSF(wTrack
, wMinutes
, wSeconds
, wFrames
);
389 printf("CDAUDIO_CalcTime // %02u-%02u:%02u:%02u\n",
390 wTrack
, wMinutes
, wSeconds
, wFrames
);
394 /* unknown format ! force TMSF ! ... */
395 dwFormatType
= MCI_FORMAT_TMSF
;
403 /**************************************************************************
404 * CDAUDIO_CalcFrame [internal]
406 DWORD
CDAUDIO_CalcFrame(UINT wDevID
, DWORD dwFormatType
, DWORD dwTime
)
412 printf("CDAUDIO_CalcFrame(%u, %08X, %lu);\n", wDevID
, dwFormatType
, dwTime
);
415 switch (dwFormatType
) {
416 case MCI_FORMAT_MILLISECONDS
:
417 dwFrame
= dwTime
* CDFRAMES_PERSEC
/ 1000;
419 printf("CDAUDIO_CalcFrame // MILLISECONDS %u\n", dwFrame
);
424 printf("CDAUDIO_CalcFrame // MSF %02u:%02u:%02u\n",
425 MCI_MSF_MINUTE(dwTime
), MCI_MSF_SECOND(dwTime
),
426 MCI_MSF_FRAME(dwTime
));
428 dwFrame
+= CDFRAMES_PERMIN
* MCI_MSF_MINUTE(dwTime
);
429 dwFrame
+= CDFRAMES_PERSEC
* MCI_MSF_SECOND(dwTime
);
430 dwFrame
+= MCI_MSF_FRAME(dwTime
);
432 case MCI_FORMAT_TMSF
:
433 wTrack
= MCI_TMSF_TRACK(dwTime
);
435 printf("CDAUDIO_CalcFrame // TMSF %02u-%02u:%02u:%02u\n",
436 MCI_TMSF_TRACK(dwTime
), MCI_TMSF_MINUTE(dwTime
),
437 MCI_TMSF_SECOND(dwTime
), MCI_TMSF_FRAME(dwTime
));
438 printf("CDAUDIO_CalcFrame // TMSF trackpos[%u]=%u\n",
439 wTrack
, CDADev
[wDevID
].lpdwTrackPos
[wTrack
- 1]);
441 dwFrame
= CDADev
[wDevID
].lpdwTrackPos
[wTrack
- 1];
442 dwFrame
+= CDFRAMES_PERMIN
* MCI_TMSF_MINUTE(dwTime
);
443 dwFrame
+= CDFRAMES_PERSEC
* MCI_TMSF_SECOND(dwTime
);
444 dwFrame
+= MCI_TMSF_FRAME(dwTime
);
447 /* unknown format ! force TMSF ! ... */
448 dwFormatType
= MCI_FORMAT_TMSF
;
456 /**************************************************************************
457 * CDAUDIO_GetNumberOfTracks [internal]
459 UINT
CDAUDIO_GetNumberOfTracks(UINT wDevID
)
462 struct cdrom_tochdr hdr
;
463 if (CDADev
[wDevID
].nTracks
== 0) {
464 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMREADTOCHDR
, &hdr
)) {
465 printf("GetNumberOfTracks(%u) // Error occured !\n", wDevID
);
468 CDADev
[wDevID
].nTracks
= hdr
.cdth_trk1
;
470 return CDADev
[wDevID
].nTracks
;
476 /**************************************************************************
477 * CDAUDIO_GetNumberOfTracks [internal]
479 BOOL
CDAUDIO_GetTracksInfo(UINT wDevID
)
483 int start
, last_start
;
484 int total_length
= 0;
485 struct cdrom_tocentry entry
;
486 if (CDADev
[wDevID
].nTracks
== 0) {
487 if (CDAUDIO_GetNumberOfTracks(wDevID
) == (WORD
)-1) return FALSE
;
489 if (CDADev
[wDevID
].lpdwTrackLen
!= NULL
)
490 free(CDADev
[wDevID
].lpdwTrackLen
);
491 CDADev
[wDevID
].lpdwTrackLen
= (LPDWORD
)malloc(
492 (CDADev
[wDevID
].nTracks
+ 1) * sizeof(DWORD
));
493 if (CDADev
[wDevID
].lpdwTrackPos
!= NULL
)
494 free(CDADev
[wDevID
].lpdwTrackPos
);
495 CDADev
[wDevID
].lpdwTrackPos
= (LPDWORD
)malloc(
496 (CDADev
[wDevID
].nTracks
+ 1) * sizeof(DWORD
));
497 if (CDADev
[wDevID
].lpdwTrackLen
== NULL
||
498 CDADev
[wDevID
].lpdwTrackPos
== NULL
) {
499 printf("CDAUDIO_GetTracksInfo // error allocating track table !\n");
502 memset(CDADev
[wDevID
].lpdwTrackLen
, 0,
503 (CDADev
[wDevID
].nTracks
+ 1) * sizeof(DWORD
));
504 memset(CDADev
[wDevID
].lpdwTrackPos
, 0,
505 (CDADev
[wDevID
].nTracks
+ 1) * sizeof(DWORD
));
506 for (i
= 0; i
<= CDADev
[wDevID
].nTracks
; i
++) {
507 if (i
== CDADev
[wDevID
].nTracks
)
508 entry
.cdte_track
= CDROM_LEADOUT
;
510 entry
.cdte_track
= i
+ 1;
511 entry
.cdte_format
= CDROM_MSF
;
512 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMREADTOCENTRY
, &entry
)) {
513 printf("CDAUDIO_GetTracksInfo // error read entry\n");
516 start
= CDFRAMES_PERSEC
* (SECONDS_PERMIN
*
517 entry
.cdte_addr
.msf
.minute
+ entry
.cdte_addr
.msf
.second
) +
518 entry
.cdte_addr
.msf
.frame
;
520 CDADev
[wDevID
].dwFirstOffset
= last_start
= start
;
521 printf("CDAUDIO_GetTracksInfo // dwFirstOffset=%u\n", start
);
524 length
= start
- last_start
;
526 start
= last_start
- length
;
527 total_length
+= length
;
528 CDADev
[wDevID
].lpdwTrackLen
[i
- 1] = length
;
529 CDADev
[wDevID
].lpdwTrackPos
[i
- 1] = start
;
530 printf("CDAUDIO_GetTracksInfo // track #%u start=%u len=%u\n",
534 CDADev
[wDevID
].dwTotalLen
= total_length
;
535 printf("CDAUDIO_GetTracksInfo // total_len=%u\n", total_length
);
543 /**************************************************************************
544 * CDAUDIO_GetNumberOfTracks [internal]
546 BOOL
CDAUDIO_GetCDStatus(UINT wDevID
)
549 int oldmode
= CDADev
[wDevID
].mode
;
550 CDADev
[wDevID
].sc
.cdsc_format
= CDROM_MSF
;
551 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMSUBCHNL
, &CDADev
[wDevID
].sc
)) {
553 printf("CDAUDIO_GetCDStatus // opened or no_media !\n");
555 CDADev
[wDevID
].mode
= MCI_MODE_OPEN
;
558 switch (CDADev
[wDevID
].sc
.cdsc_audiostatus
) {
559 case CDROM_AUDIO_INVALID
:
560 printf("CDAUDIO_GetCDStatus // device doesn't support status !\n");
562 case CDROM_AUDIO_NO_STATUS
:
563 CDADev
[wDevID
].mode
= MCI_MODE_STOP
;
565 printf("CDAUDIO_GetCDStatus // MCI_MODE_STOP !\n");
568 case CDROM_AUDIO_PLAY
:
569 CDADev
[wDevID
].mode
= MCI_MODE_PLAY
;
571 printf("CDAUDIO_GetCDStatus // MCI_MODE_PLAY !\n");
574 case CDROM_AUDIO_PAUSED
:
575 CDADev
[wDevID
].mode
= MCI_MODE_PAUSE
;
577 printf("CDAUDIO_GetCDStatus // MCI_MODE_PAUSE !\n");
581 printf("CDAUDIO_GetCDStatus // status=%02X !\n",
582 CDADev
[wDevID
].sc
.cdsc_audiostatus
);
584 CDADev
[wDevID
].nCurTrack
= CDADev
[wDevID
].sc
.cdsc_trk
;
585 CDADev
[wDevID
].dwCurFrame
=
586 CDFRAMES_PERMIN
* CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.minute
+
587 CDFRAMES_PERSEC
* CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.second
+
588 CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.frame
;
590 printf("CDAUDIO_GetCDStatus // %02u-%02u:%02u:%02u \n",
591 CDADev
[wDevID
].sc
.cdsc_trk
,
592 CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.minute
,
593 CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.second
,
594 CDADev
[wDevID
].sc
.cdsc_absaddr
.msf
.frame
);
596 if (oldmode
!= CDADev
[wDevID
].mode
&& oldmode
== MCI_MODE_OPEN
) {
597 if (!CDAUDIO_GetTracksInfo(wDevID
)) {
598 printf("CDAUDIO_GetCDStatus // error updating TracksInfo !\n");
599 return MCIERR_INTERNAL
;
608 /**************************************************************************
609 * CDAUDIO_mciPlay [internal]
611 DWORD
CDAUDIO_mciPlay(UINT wDevID
, DWORD dwFlags
, LPMCI_PLAY_PARMS lpParms
)
615 struct cdrom_msf msf
;
617 printf("CDAUDIO_mciPlay(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
619 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
620 if (CDADev
[wDevID
].unixdev
== 0) return MMSYSERR_NOTENABLED
;
621 start
= 0; end
= CDADev
[wDevID
].dwTotalLen
;
622 CDADev
[wDevID
].nCurTrack
= 1;
623 if (dwFlags
& MCI_FROM
) {
624 start
= CDAUDIO_CalcFrame(wDevID
,
625 CDADev
[wDevID
].dwTimeFormat
, lpParms
->dwFrom
);
627 printf("CDAUDIO_mciPlay // MCI_FROM=%08X -> %u \n",
628 lpParms
->dwFrom
, start
);
631 if (dwFlags
& MCI_TO
) {
632 end
= CDAUDIO_CalcFrame(wDevID
,
633 CDADev
[wDevID
].dwTimeFormat
, lpParms
->dwTo
);
635 printf("CDAUDIO_mciPlay // MCI_TO=%08X -> %u \n",
639 start
+= CDADev
[wDevID
].dwFirstOffset
;
640 end
+= CDADev
[wDevID
].dwFirstOffset
;
641 msf
.cdmsf_min0
= start
/ CDFRAMES_PERMIN
;
642 msf
.cdmsf_sec0
= (start
% CDFRAMES_PERMIN
) / CDFRAMES_PERSEC
;
643 msf
.cdmsf_frame0
= start
% CDFRAMES_PERSEC
;
644 msf
.cdmsf_min1
= end
/ CDFRAMES_PERMIN
;
645 msf
.cdmsf_sec1
= (end
% CDFRAMES_PERMIN
) / CDFRAMES_PERSEC
;
646 msf
.cdmsf_frame1
= end
% CDFRAMES_PERSEC
;
647 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMSTART
)) {
648 printf("CDAUDIO_mciPlay // motor doesn't start !\n");
649 return MCIERR_HARDWARE
;
651 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMPLAYMSF
, &msf
)) {
652 printf("CDAUDIO_mciPlay // device doesn't play !\n");
653 return MCIERR_HARDWARE
;
656 printf("CDAUDIO_mciPlay // msf = %d:%d:%d %d:%d:%d\n",
657 msf
.cdmsf_min0
, msf
.cdmsf_sec0
, msf
.cdmsf_frame0
,
658 msf
.cdmsf_min1
, msf
.cdmsf_sec1
, msf
.cdmsf_frame1
);
660 CDADev
[wDevID
].mode
= MCI_MODE_PLAY
;
661 if (dwFlags
& MCI_NOTIFY
) {
662 printf("CDAUDIO_mciPlay // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
663 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
664 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
668 return MCIERR_HARDWARE
;
672 /**************************************************************************
673 * CDAUDIO_mciStop [internal]
675 DWORD
CDAUDIO_mciStop(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
679 printf("CDAUDIO_mciStop(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
681 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
682 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMSTOP
)) return MCIERR_HARDWARE
;
683 CDADev
[wDevID
].mode
= MCI_MODE_STOP
;
684 if (dwFlags
& MCI_NOTIFY
) {
685 printf("CDAUDIO_mciStop // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
686 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
687 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
691 return MCIERR_HARDWARE
;
695 /**************************************************************************
696 * CDAUDIO_mciPause [internal]
698 DWORD
CDAUDIO_mciPause(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
702 printf("CDAUDIO_mciPause(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
704 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
705 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMPAUSE
)) return MCIERR_HARDWARE
;
706 CDADev
[wDevID
].mode
= MCI_MODE_PAUSE
;
707 if (dwFlags
& MCI_NOTIFY
) {
708 printf("CDAUDIO_mciPause // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
709 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
710 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
714 return MCIERR_HARDWARE
;
718 /**************************************************************************
719 * CDAUDIO_mciResume [internal]
721 DWORD
CDAUDIO_mciResume(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
725 printf("CDAUDIO_mciResume(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
727 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
728 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMRESUME
)) return MCIERR_HARDWARE
;
729 CDADev
[wDevID
].mode
= MCI_MODE_STOP
;
730 if (dwFlags
& MCI_NOTIFY
) {
731 printf("CDAUDIO_mciResume // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
732 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
733 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
737 return MCIERR_HARDWARE
;
741 /**************************************************************************
742 * CDAUDIO_mciSeek [internal]
744 DWORD
CDAUDIO_mciSeek(UINT wDevID
, DWORD dwFlags
, LPMCI_SEEK_PARMS lpParms
)
748 MCI_PLAY_PARMS PlayParms
;
750 printf("CDAUDIO_mciSeek(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
752 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
753 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMRESUME
)) return MCIERR_HARDWARE
;
754 CDADev
[wDevID
].mode
= MCI_MODE_SEEK
;
756 case MCI_SEEK_TO_START
:
757 PlayParms
.dwFrom
= 0;
759 case MCI_SEEK_TO_END
:
760 PlayParms
.dwFrom
= CDADev
[wDevID
].dwTotalLen
;
763 PlayParms
.dwFrom
= lpParms
->dwTo
;
766 dwRet
= CDAUDIO_mciPlay(wDevID
, MCI_WAIT
| MCI_FROM
, &PlayParms
);
767 if (dwRet
!= 0) return dwRet
;
768 dwRet
= CDAUDIO_mciStop(wDevID
, MCI_WAIT
, (LPMCI_GENERIC_PARMS
)&PlayParms
);
769 if (dwFlags
& MCI_NOTIFY
) {
770 printf("CDAUDIO_mciSeek // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
771 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
772 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
776 return MCIERR_HARDWARE
;
781 /**************************************************************************
782 * CDAUDIO_mciSet [internal]
784 DWORD
CDAUDIO_mciSet(UINT wDevID
, DWORD dwFlags
, LPMCI_SET_PARMS lpParms
)
788 printf("CDAUDIO_mciSet(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
790 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
792 printf("CDAUDIO_mciSet // dwTimeFormat=%08X\n", lpParms->dwTimeFormat);
793 printf("CDAUDIO_mciSet // dwAudio=%08X\n", lpParms->dwAudio);
795 if (dwFlags
& MCI_SET_TIME_FORMAT
) {
796 switch (lpParms
->dwTimeFormat
) {
797 case MCI_FORMAT_MILLISECONDS
:
799 printf("CDAUDIO_mciSet // MCI_FORMAT_MILLISECONDS !\n");
804 printf("CDAUDIO_mciSet // MCI_FORMAT_MSF !\n");
807 case MCI_FORMAT_TMSF
:
809 printf("CDAUDIO_mciSet // MCI_FORMAT_TMSF !\n");
813 printf("CDAUDIO_mciSet // bad time format !\n");
814 return MCIERR_BAD_TIME_FORMAT
;
816 CDADev
[wDevID
].dwTimeFormat
= lpParms
->dwTimeFormat
;
818 if (dwFlags
& MCI_SET_DOOR_OPEN
) {
819 printf("CDAUDIO_mciSet // MCI_SET_DOOR_OPEN !\n");
820 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMEJECT
)) return MCIERR_HARDWARE
;
821 CDADev
[wDevID
].nTracks
= 0;
823 if (dwFlags
& MCI_SET_DOOR_CLOSED
) {
824 printf("CDAUDIO_mciSet // MCI_SET_DOOR_CLOSED !\n");
825 if (ioctl(CDADev
[wDevID
].unixdev
, CDROMEJECT
)) return MCIERR_HARDWARE
;
826 CDADev
[wDevID
].nTracks
= 0;
828 if (dwFlags
& MCI_SET_VIDEO
) return MCIERR_UNSUPPORTED_FUNCTION
;
829 if (dwFlags
& MCI_SET_ON
) return MCIERR_UNSUPPORTED_FUNCTION
;
830 if (dwFlags
& MCI_SET_OFF
) return MCIERR_UNSUPPORTED_FUNCTION
;
831 if (dwFlags
& MCI_NOTIFY
) {
832 printf("CDAUDIO_mciSet // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
833 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
834 CDADev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
838 return MCIERR_HARDWARE
;
843 /**************************************************************************
844 * CDAUDIO_DriverProc [sample driver]
846 LRESULT
CDAUDIO_DriverProc(DWORD dwDevID
, HDRVR hDriv
, WORD wMsg
,
847 DWORD dwParam1
, DWORD dwParam2
)
856 case MCI_OPEN_DRIVER
:
858 return CDAUDIO_mciOpen(dwParam1
, (LPMCI_OPEN_PARMS
)dwParam2
);
860 case MCI_CLOSE_DRIVER
:
862 return CDAUDIO_mciClose(dwDevID
, dwParam1
,
863 (LPMCI_GENERIC_PARMS
)dwParam2
);
868 case DRV_QUERYCONFIGURE
:
871 MessageBox((HWND
)NULL
, "Sample MultiMedia Linux Driver !",
872 "MMLinux Driver", MB_OK
);
875 return (LRESULT
)DRVCNF_RESTART
;
877 return (LRESULT
)DRVCNF_RESTART
;
879 return CDAUDIO_mciGetDevCaps(dwDevID
, dwParam1
,
880 (LPMCI_GETDEVCAPS_PARMS
)dwParam2
);
882 return CDAUDIO_mciInfo(dwDevID
, dwParam1
,
883 (LPMCI_INFO_PARMS
)dwParam2
);
885 return CDAUDIO_mciStatus(dwDevID
, dwParam1
,
886 (LPMCI_STATUS_PARMS
)dwParam2
);
888 return CDAUDIO_mciSet(dwDevID
, dwParam1
,
889 (LPMCI_SET_PARMS
)dwParam2
);
891 return CDAUDIO_mciPlay(dwDevID
, dwParam1
,
892 (LPMCI_PLAY_PARMS
)dwParam2
);
894 return CDAUDIO_mciStop(dwDevID
, dwParam1
,
895 (LPMCI_GENERIC_PARMS
)dwParam2
);
897 return CDAUDIO_mciPause(dwDevID
, dwParam1
,
898 (LPMCI_GENERIC_PARMS
)dwParam2
);
900 return CDAUDIO_mciResume(dwDevID
, dwParam1
,
901 (LPMCI_GENERIC_PARMS
)dwParam2
);
903 return CDAUDIO_mciSeek(dwDevID
, dwParam1
,
904 (LPMCI_SEEK_PARMS
)dwParam2
);
905 case MCI_SET_DOOR_OPEN
:
906 printf("CDAUDIO_DriverProc // MCI_SET_DOOR_OPEN !\n");
907 if (ioctl(CDADev
[dwDevID
].unixdev
, CDROMEJECT
)) return MCIERR_HARDWARE
;
908 CDADev
[dwDevID
].nTracks
= 0;
910 case MCI_SET_DOOR_CLOSED
:
911 printf("CDAUDIO_DriverProc // MCI_SET_DOOR_CLOSED !\n");
912 if (ioctl(CDADev
[dwDevID
].unixdev
, CDROMEJECT
, 1)) return MCIERR_HARDWARE
;
913 CDADev
[dwDevID
].nTracks
= 0;
916 return DefDriverProc(dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
919 return MCIERR_HARDWARE
;
924 /*-----------------------------------------------------------------------*/