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