]> icculus.org git repositories - taylor/freespace2.git/blob - src/sound/rbaudio.cpp
Fix net_addr vs net_addr_t
[taylor/freespace2.git] / src / sound / rbaudio.cpp
1 /*
2  * $Logfile: /Freespace2/code/Sound/RBAudio.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * source file for redbook audio playback
8  *
9  * $Log$
10  * Revision 1.2  2002/05/07 03:16:52  theoddone33
11  * The Great Newline Fix
12  *
13  * Revision 1.1.1.1  2002/05/03 03:28:10  root
14  * Initial import.
15  *
16  * 
17  * 2     10/07/98 10:54a Dave
18  * Initial checkin.
19  * 
20  * 1     10/07/98 10:51a Dave
21  * 
22  * 6     6/13/98 1:45p Sandeep
23  * 
24  * 5     5/15/98 4:12p Allender
25  * removed redbook code.  Put back in ingame join timer.  Major fixups for
26  * stats in multiplayer.  Pass correct score, medals, etc when leaving
27  * game.  Be sure clients display medals, badges, etc.
28  * 
29  * 4     1/19/98 11:37p Lawrance
30  * Fixing Optimization build warnings
31  * 
32  * 3     9/09/97 3:39p Sandeep
33  * warning level 4 bugs
34  * 
35  * 2     4/28/97 5:13p John
36  * more moving sound/movie code out of osapi.
37  * 
38  * 1     4/28/97 4:45p John
39  * Initial version of ripping sound & movie out of OsAPI.
40  * 
41  * 3     2/03/97 2:05p Allender
42  * don't stop playing redbook when exiting
43  * 
44  * 2     1/30/97 9:57a Allender
45  * basic Redbook audio implemented.
46  * 
47  * 1     1/28/97 9:54a Allender
48  *
49  * $NoKeywords: $
50 */
51
52 #if 0
53 #include "pstypes.h"
54
55 #include <windows.h>
56 #include <mmsystem.h>
57
58 #include <stdlib.h>
59 #include <string.h>
60
61
62 #include "monopub.h"
63 //#include "error.h"
64 #include "rbaudio.h"
65 #include "fix.h"
66 #include "timer.h"
67 //#include "winapp.h"
68
69
70 #define HSG_CD_PLAYBACK 0
71 #define MSF_CD_PLAYBACK 1
72
73
74 #pragma pack(1)
75
76 typedef struct CDTrack {
77         DWORD msf;
78         DWORD length;
79 } CDTrack;
80
81 int RBCDROM_State = 0;                                                  // CD is not used = 0
82                                                                                                                 // CD is used = 1
83                                                                                                                 // CD is already used = -1
84
85 static CDTrack  CDTrackInfo[255];
86 static UINT CDDiscID = 0;
87
88 static int              RedBookEnabled=0, RedBookInstalled = 0;
89 static UINT     CDDeviceID = 0;
90 static DWORD    CDNumTracks = 0;
91 static fix Playback_Start_Time = 0;
92 static fix Playback_Pause_Time = 0;
93 static fix Playback_Length = 0;
94 static int Playback_first_track,Playback_last_track;
95 static int AUXDevice = -1;
96 static char MCIErrorMsg[256];
97
98 //      Function Prototypes
99
100 unsigned long lsn_to_msf(unsigned long lsn);
101 unsigned long msf_to_lsn(unsigned long msf);
102 unsigned long msf_add(unsigned long msf1, unsigned long msf2);
103 unsigned long msf_sub(unsigned long msf1, unsigned long msf2);
104
105 UINT MakeCDDiscID(int tracks, unsigned long msflen, unsigned long msftrack1);
106 UINT GetCDDiscID();
107
108
109 //      Functions
110
111 void RBClose()
112 {
113         if (RedBookInstalled) {
114                 //RBAStop();                    // removed by  MWA 2/3 -- will probably be handled by higher level code
115                 mciSendCommand(CDDeviceID, MCI_CLOSE, 0, NULL);
116                 RedBookEnabled = 0;
117                 RedBookInstalled = 0;
118         }
119 }
120
121
122 void RBAInit(void)
123 {
124         MCI_OPEN_PARMS  mciOpenParms;
125         MCI_SET_PARMS   mciSetParms;
126         DWORD                           retval = 0;
127
128         atexit(RBClose);
129
130         // removed by MWA since we can't seem to get this to work under NT...needs a little work I guess
131 /*
132         int                             num_devs, i;
133
134   num_devs = auxGetNumDevs();
135         
136 //      Find CD-AUDIO device if there is one.
137         for (i = 0; i < num_devs; i++)
138         {
139                 AUXCAPS caps;
140                 auxGetDevCaps(i, &caps, sizeof(caps));
141                 if (caps.wTechnology == AUXCAPS_CDAUDIO) {
142                         AUXDevice = i;
143                         mprintf(("CD operating on AUX %d.\n", AUXDevice));
144                         //break;
145                 }
146         }
147                                         
148         if (AUXDevice == -1) {
149                 mprintf(("Unable to find CD-AUDIO device. No Redbook music.\n"));
150                 RedBookEnabled = 0;
151                 return;
152         }
153 */
154
155 //      We need to identify that a cd audio driver exists
156         mciOpenParms.lpstrDeviceType = NOX("cdaudio");
157
158         retval = mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE, (DWORD)(LPVOID)&mciOpenParms);
159         if (retval) {
160                 if (retval == MCIERR_MUST_USE_SHAREABLE) RBCDROM_State = -1;
161                 else RBCDROM_State = 0;
162                 mciGetErrorString(retval, MCIErrorMsg, 256);
163                 mprintf(("RBA (%x) MCI:%s.\n", retval, MCIErrorMsg));
164                 RedBookEnabled = 0;
165         }
166         else {
167         // Now we need to set the time format to MSF for Redbook Compatablity.
168                 RedBookInstalled = 1;
169                 RBCDROM_State = 1;
170                 CDDeviceID = mciOpenParms.wDeviceID;
171
172 // mwa ??               logentry("Initializing Redbook device %d.\n", CDDeviceID);
173
174                 mciSetParms.dwTimeFormat = MCI_FORMAT_MSF;
175                 retval = mciSendCommand(CDDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID)&mciSetParms);
176                 if (retval) {
177                         mciSendCommand(CDDeviceID, MCI_CLOSE, 0, NULL);
178                         mprintf(("Error %d.  Unable to set Redbook Format.\n", retval));
179                         RedBookEnabled = 0;
180                 }
181                 else RedBookEnabled = 1;
182         }
183 }
184
185
186 void RBARegisterCD(void)
187 {
188         DWORD                                   i, numtracks, retval = 0;
189         MCI_STATUS_PARMS        mciStatusParms;
190
191 //      Insure that CD is Redbook, then get track information
192         mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; 
193         retval = mciSendCommand(CDDeviceID, MCI_STATUS, MCI_STATUS_ITEM, 
194                                                 (DWORD)(LPVOID)&mciStatusParms);
195         if (retval) {
196                 mciGetErrorString(retval, MCIErrorMsg, 256);
197                 mprintf(("RBA MCI:%s.\n", MCIErrorMsg));
198                 CDNumTracks = 0;
199                 return;
200         }
201         
202         CDNumTracks = numtracks = mciStatusParms.dwReturn;
203
204         for (i = 0; i < numtracks; i++)
205         {
206                 mciStatusParms.dwTrack = i+1;
207                 mciStatusParms.dwItem = MCI_STATUS_POSITION;
208                 retval = mciSendCommand(CDDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK, (DWORD)(LPVOID)&mciStatusParms);   
209                 if (retval) {
210                         mprintf(("Could not retrieve information on track %d.\n", i+1));
211                 }
212                 CDTrackInfo[i].msf = mciStatusParms.dwReturn;
213                 
214                 mciStatusParms.dwTrack = i+1;
215                 mciStatusParms.dwItem = MCI_STATUS_LENGTH;
216                 retval = mciSendCommand(CDDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK, (DWORD)(LPVOID)&mciStatusParms);
217                 if (retval) { 
218                         mprintf(("Couldn't get length of track %d.\n", i+1));
219                 }
220                 CDTrackInfo[i].length = mciStatusParms.dwReturn;
221
222 //              logentry("[%d] (%d:%d):(%d:%d)\n", i+1, MCI_MSF_MINUTE(CDTrackInfo[i].msf), MCI_MSF_SECOND(CDTrackInfo[i].msf), MCI_MSF_MINUTE(CDTrackInfo[i].length), MCI_MSF_SECOND(CDTrackInfo[i].length));
223         }       
224
225         CDDiscID = GetCDDiscID();
226
227
228
229 long RBAGetDeviceStatus()
230 {
231         return 0;
232 }
233
234
235 int get_track_time(int first,int last)
236 {
237         unsigned long playlen;
238         int min, sec;
239
240         playlen = msf_sub(msf_add(CDTrackInfo[last-1].msf,CDTrackInfo[last-1].length), CDTrackInfo[first-1].msf);
241
242         min   = MCI_MSF_MINUTE(playlen);
243         sec   = MCI_MSF_SECOND(playlen);
244
245         return (min*60+sec);
246 }
247
248
249 int RBAPlayTrack(int track)
250 {
251         MCI_PLAY_PARMS  mciPlayParms;
252         int min=0; 
253         int retval;
254
255 //      Register CD if media has changed
256         if (!RedBookEnabled) return 0;
257         if (RBACheckMediaChange()) {
258                 mprintf(("Unable to play track due to CD change.\n"));
259                 return 0;
260         }
261
262 //      Play the track
263         min = min + MCI_MSF_MINUTE(CDTrackInfo[track-1].msf) + MCI_MSF_MINUTE(CDTrackInfo[track-1].length);
264         mciPlayParms.dwFrom = CDTrackInfo[track-1].msf; // MCI_MAKE_TMSF(track, 0, 0, 0);
265         mciPlayParms.dwTo = msf_add(CDTrackInfo[track-1].msf, CDTrackInfo[track-1].length);
266         retval = mciSendCommand(CDDeviceID, MCI_PLAY, MCI_FROM | MCI_TO, (DWORD)(LPVOID)&mciPlayParms);
267
268         if (retval) {
269                 mciGetErrorString(retval, MCIErrorMsg, 256);
270                 mprintf(("RBA MCI:%s.\n", MCIErrorMsg));
271                 mprintf(("Unable to play CD track %d.\n", track));
272                 return 0;
273         }
274         else {
275                 Playback_Length = i2f(get_track_time(track,track));
276                 Playback_Start_Time = timer_get_fixed_seconds();
277
278                 Playback_first_track = Playback_last_track = track;
279
280                 mprintf( ("Playing Track %d (len: %d secs)\n", track, f2i(Playback_Length)) );
281         }
282
283         return 1;
284 }
285
286
287 int RBAPlayTracks(int start, int end)
288 {
289         MCI_PLAY_PARMS  mciPlayParms;
290         int retval;
291
292         Playback_Start_Time = 0;
293         Playback_Length = 0;
294
295 //      Register CD if media has changed
296         if (!RedBookEnabled) return 0;
297         if (RBACheckMediaChange()) {
298                 mprintf(("Unable to play track due to CD change.\n"));
299                 return 0;
300         }
301
302 //      Play the track
303         mciPlayParms.dwFrom = CDTrackInfo[start-1].msf; // MCI_MAKE_TMSF(track, 0, 0, 0);
304         mciPlayParms.dwTo = msf_add(CDTrackInfo[end-1].msf, CDTrackInfo[end-1].length);
305         retval = mciSendCommand(CDDeviceID, MCI_PLAY, MCI_FROM | MCI_TO, (DWORD)(LPVOID)&mciPlayParms);
306
307         if (retval) {
308                 mciGetErrorString(retval, MCIErrorMsg, 256);
309                 mprintf(("RBA MCI:%s.\n", MCIErrorMsg));
310                 mprintf(("Unable to play CD tracks %d-%d.\n", start,end));
311                 return 0;               
312         }
313         else {
314                 Playback_Length = i2f(get_track_time(start,end));
315                 Playback_Start_Time = timer_get_fixed_seconds();
316
317                 Playback_first_track = start;
318                 Playback_last_track = end;
319
320                 mprintf( ("Playing Tracks %d-%d (len: %d secs)\n", start,end,f2i(Playback_Length)) );
321         }
322
323         return 1;
324 }
325
326
327 void RBAStop()
328 {
329         int retval;
330
331         if (!RedBookEnabled) return;
332         
333         retval = mciSendCommand(CDDeviceID, MCI_STOP,0,NULL);
334         if (retval) {
335                 mciGetErrorString(retval, MCIErrorMsg, 256);
336                 mprintf(("RBA MCI:%s.\n", MCIErrorMsg));
337                 mprintf(("CD Stop command failed.\n"));
338         } 
339 }
340
341
342 void RBASetStereoAudio(RBACHANNELCTL *channels)
343 {
344
345 }
346
347
348 void RBASetQuadAudio(RBACHANNELCTL *channels)
349 {
350
351 }
352
353
354 void RBAGetAudioInfo(RBACHANNELCTL *channels)
355 {
356
357 }
358
359
360 static unsigned rba_paused_head_loc = 0;
361
362 void RBAPause()
363 {
364         int retval;
365         MCI_GENERIC_PARMS mciGenParms;
366         int frame, sec, min;
367
368
369   if (!RedBookEnabled) return;
370
371         rba_paused_head_loc = RBAGetHeadLoc(&min, &sec, &frame);        
372
373 // mwa ???      mciGenParms.dwCallback = GetLibraryWindow();
374         retval = mciSendCommand(CDDeviceID, MCI_PAUSE, MCI_NOTIFY, 
375                 (DWORD)(LPVOID)&mciGenParms);
376         if (retval)     {
377                 mprintf(("ERROR: Unable to pause CD.\n"));
378         }
379         else {
380                 mprintf(("Pausing CD...\n"));
381                 Playback_Pause_Time = timer_get_fixed_seconds();
382         }
383
384 }
385
386
387 int RBAResume()
388 {
389         int retval;
390         MCI_PLAY_PARMS mciPlayParms;
391
392         if (!RedBookEnabled) return 0;
393    
394         if (RBACheckMediaChange()) {
395                 RBARegisterCD();
396                 return RBA_MEDIA_CHANGED;
397         }
398
399         mciPlayParms.dwFrom = rba_paused_head_loc; // MCI_MAKE_TMSF(track, 0, 0, 0);
400         mciPlayParms.dwTo = msf_add(CDTrackInfo[Playback_last_track-1].msf, 
401                                                                         CDTrackInfo[Playback_last_track-1].length);
402         retval = mciSendCommand(CDDeviceID, MCI_PLAY, MCI_FROM | MCI_TO, (DWORD)(LPVOID)&mciPlayParms);
403
404         if (retval) {
405                 mprintf(("ERROR: Resume CD play failed.\n"));
406         }
407         else 
408                 Playback_Start_Time += timer_get_fixed_seconds() - Playback_Pause_Time;
409
410         return 1;
411 }
412
413
414 void RBASetChannelVolume(int channel, int volume) 
415 {
416         DWORD vol=0;
417         
418         if ( AUXDevice == -1 )          // added because we might not be able to do this under NT
419                 return;
420
421         volume = volume << 8;
422         
423         if (channel == 0) 
424                 vol = MAKELONG(0,volume);
425         else if (channel == 1) 
426                 vol = MAKELONG(volume,0);
427
428         auxSetVolume(AUXDevice, vol);
429 }
430
431
432 void RBASetVolume(int volume)
433 {
434         DWORD vol;
435         WORD wvol;
436
437         if ( AUXDevice == -1 )          // added because we might not be able to do this under NT
438                 return;
439
440         wvol = (unsigned short)((volume) << 8);
441
442         vol = MAKELONG(wvol, wvol);
443         auxSetVolume(AUXDevice, vol);
444 }
445
446
447 long RBAGetHeadLoc(int *min, int *sec, int *frame)
448 {
449         MCI_STATUS_PARMS mciStatusParms;
450         int retval;
451
452         if (!RedBookEnabled) return 0;
453
454         if (RBACheckMediaChange())
455                 return RBA_MEDIA_CHANGED;
456
457         mciStatusParms.dwItem = MCI_STATUS_POSITION;
458         retval = mciSendCommand(CDDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD)(LPVOID)&mciStatusParms);
459         
460         if (retval) {
461                 mprintf(("Couldn't get location of CD head.\n"));
462         }
463
464         *min = MCI_MSF_MINUTE(mciStatusParms.dwReturn);
465         *sec = MCI_MSF_SECOND(mciStatusParms.dwReturn);
466         *frame = MCI_MSF_FRAME(mciStatusParms.dwReturn);
467
468         return mciStatusParms.dwReturn;
469 }               
470
471
472 int RBAGetTrackNum()
473 {
474         int track;
475         int delta_time; //in seconds
476
477         if (!RBAPeekPlayStatus())
478                 return 0;
479
480         delta_time = f2i(timer_get_fixed_seconds()-Playback_Start_Time+f1_0/2);
481
482         for (track=Playback_first_track;track<=Playback_last_track && delta_time>0;track++) {
483
484                 delta_time -= get_track_time(track,track);
485
486                 if (delta_time < 0)
487                         break;
488         }
489
490         Assert(track <= Playback_last_track);
491
492         return track;
493 }
494
495
496 int RBAPeekPlayStatus()
497 {
498 //@@    MCI_STATUS_PARMS mciStatusParms;
499 //@@    int retval;
500
501         if (!RedBookEnabled) return 0;
502
503
504         if ((timer_get_fixed_seconds()-Playback_Start_Time) > Playback_Length) return 0;
505         else return 1; 
506
507
508 //@@    mciStatusParms.dwItem = MCI_STATUS_MODE;
509 //@@    retval = mciSendCommand(CDDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD)(LPVOID)&mciStatusParms);
510 //@@    if (retval) {
511 //@@            mprintf((0, "Unable to obtain current status of CD.\n"));
512 //@@    }
513 //@@    
514 //@@    if (mciStatusParms.dwReturn == MCI_MODE_PLAY) return 1;
515 //@@    else return 0;
516 }
517         
518
519
520 int RBAEnabled()
521 {
522         if (RedBookEnabled < 1) return 0;
523         else return 1;
524 }
525
526
527 void RBAEnable()
528 {
529         RedBookEnabled = 1;
530         mprintf(("Enabling Redbook...\n"));
531 }
532
533
534 void RBADisable()
535 {
536         RedBookEnabled = 0;
537         mprintf(("Disabling Redbook...\n"));
538 }
539
540
541 int RBAGetNumberOfTracks(void)
542 {
543         MCI_STATUS_PARMS        mciStatusParms;
544         int retval;     
545
546         if (!RedBookEnabled) return 0;
547
548         if (RBACheckMediaChange())  
549                 RBARegisterCD();
550                 
551         mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; 
552         retval = mciSendCommand(CDDeviceID, MCI_STATUS, MCI_STATUS_ITEM, 
553                                                 (DWORD)(LPVOID)&mciStatusParms);
554
555         if (retval) {
556                 mprintf(("Get number of CD tracks failed.\n"));
557                 return 0;
558         }
559
560         return mciStatusParms.dwReturn;
561 }
562
563
564 //      RB functions:  Internal to RBA library  -----------------------------
565
566 int RBACheckMediaChange()
567 {
568         if (!RedBookEnabled) return 0;
569
570         if (CDDiscID != GetCDDiscID() || !CDDiscID) return 1;
571         else return 0;
572 }
573
574
575 //      Converts Logical Sector Number to Minutes Seconds Frame Format
576
577 unsigned long lsn_to_msf(unsigned long lsn)
578 {
579    unsigned long min,sec,frame;
580    lsn += 150;
581
582         min   =  lsn / (60*75);
583    lsn   =  lsn % (60*75);
584         sec   =  lsn / 75;
585    lsn   =  lsn % 75;
586         frame =  lsn;
587
588         return((min << 16) + (sec << 8) + (frame << 0));
589 }
590
591 // convert minutes seconds frame format to a logical sector number.
592
593 unsigned long msf_to_lsn(unsigned long msf)
594 {
595         unsigned long min,sec,frame;
596
597         min   = (msf >> 16) & 0xFF;
598    sec   = (msf >>  8) & 0xFF;
599    frame = (msf >>  0) & 0xFF;
600
601         return(  (min * 60*75) + (sec * 75) + frame - 150  );
602 }
603
604 unsigned long msf_add(unsigned long msf1, unsigned long msf2)
605 {
606         uint min1, sec1, frame1;
607         uint min2, sec2, frame2;
608
609 //      we don't take frames into account, which may not be right.
610         min1 = MCI_MSF_MINUTE(msf1);
611         sec1 = MCI_MSF_SECOND(msf1);
612         frame1 = MCI_MSF_FRAME(msf1);
613
614         frame2 = 0;
615         min2 = 0;
616
617         if ((sec1 + MCI_MSF_SECOND(msf2)) > 59) {
618                 sec2 = (sec1+MCI_MSF_SECOND(msf2)) - 60;
619                 min1++;
620         }
621         else sec2 = sec1 + MCI_MSF_SECOND(msf2);
622         min2 = min1+MCI_MSF_MINUTE(msf2);
623         frame2 = 0;
624         
625 //      logentry("msf_add:(%d:%d)\n", min2, sec2);
626
627         return MCI_MAKE_MSF(min2, sec2, 0);
628
629
630
631 unsigned long msf_sub(unsigned long msf1, unsigned long msf2)
632 {
633         int min1, sec1, frame1;
634         int min2, sec2, frame2;
635
636 //      we don't take frames into account, which may not be right.
637         min1 = MCI_MSF_MINUTE(msf1);
638         sec1 = MCI_MSF_SECOND(msf1);
639         frame1 = MCI_MSF_FRAME(msf1);
640
641         frame2 = 0;
642         min2 = 0;
643
644         if ((sec1 - (int)MCI_MSF_SECOND(msf2)) < 0) {
645                 sec2 = 60 - ((int)MCI_MSF_SECOND(msf2)-sec1);
646                 min1--;                                 // This is a shortcut to min2 = min1-(MSF_MIN(msf2)-1)
647         }
648         else sec2 = sec1 - (int)MCI_MSF_SECOND(msf2);
649         min2 = min1-(int)MCI_MSF_MINUTE(msf2);
650         frame2 = 0;
651
652 //      logentry("msf_sub:(%d:%d)\n", min2, sec2);
653         
654         return MCI_MAKE_MSF(min2, sec2, 0);
655
656
657
658 unsigned long msf_to_sec(unsigned long msf)
659 {
660         unsigned long min,sec,frame;
661
662         min   = (msf >> 16) & 0xFF;
663    sec   = (msf >>  8) & 0xFF;
664    frame = (msf >>  0) & 0xFF;
665
666         return (min*60) + sec;  
667 }
668
669
670 UINT GetCDDiscID()
671 {
672         MCI_STATUS_PARMS        mciStatusParms;
673         int retval;     
674         unsigned long msflen, tracks, msftrack1;
675
676         mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; 
677         if ((retval = mciSendCommand(CDDeviceID, MCI_STATUS, MCI_STATUS_ITEM, 
678                                                 (DWORD)(LPVOID)&mciStatusParms))>0) {
679                 mprintf(("RBA: Get number of CD tracks failed.\n"));
680                 return 0;
681         }
682         tracks = mciStatusParms.dwReturn;
683
684         mciStatusParms.dwItem = MCI_STATUS_LENGTH;
685         if ((retval = mciSendCommand(CDDeviceID, MCI_STATUS, MCI_STATUS_ITEM, 
686                                                 (DWORD)(LPVOID)&mciStatusParms))>0) {
687                 mprintf(("RBA: Get media length failed.\n"));
688                 return 0;
689         }
690         msflen = mciStatusParms.dwReturn;
691
692         mciStatusParms.dwTrack = 1;
693         mciStatusParms.dwItem = MCI_STATUS_POSITION;
694         if ( (retval = mciSendCommand(CDDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK, (DWORD)(LPVOID)&mciStatusParms)) >0) {       
695                 mprintf(("Could not retrieve information on track %d.\n", 1));
696                 return 0;
697         }
698         msftrack1 = mciStatusParms.dwReturn;
699
700         return MakeCDDiscID(tracks, msflen, msftrack1);
701 }
702
703
704 UINT MakeCDDiscID(int tracks, unsigned long msflen, unsigned long msftrack1)
705 {
706         UINT code=0;
707         
708         code = (UINT)(msf_to_sec(msftrack1) << 19);
709         code |= (UINT)(msf_to_sec(msflen) << 6);
710
711         code |= (UINT)(tracks&0xffffffc0);
712
713         return code;
714 }
715         
716 #endif
717