Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

cdaudio_win32.cpp

Go to the documentation of this file.
00001 
00002 #ifdef WIN32
00003 #pragma warning (disable:4786)
00004 #endif
00005 
00006 #include <windows.h>
00007 #include "API/Sound/cd_audio.h"
00008 #include <stdio.h>
00009 #include "cdaudio_win32.h"
00010 
00011 void CL_CDDrive_Win32::init_cdaudio()
00012 {
00013         int i;
00014         char drive[4];
00015 
00016         for (i='A'; i<='Z'; i++) 
00017         {
00018                 sprintf(drive, "%c:\\", i);
00019                 if (GetDriveType(drive) == DRIVE_CDROM ) 
00020                 {
00021                         char name[256];
00022                         GetVolumeInformation(drive, name, 256, NULL, NULL, NULL, NULL, 0);
00023 
00024                         CL_CDAudio::cd_drives.push_back(new CL_CDDrive_Win32(drive, name));
00025                 }
00026         }
00027 }
00028 
00029 /***************************************************
00030               class CL_CDDrive_Win32
00031 ****************************************************/
00032 
00033 CL_CDDrive_Win32::CL_CDDrive_Win32(std::string path, std::string name)
00034 {
00035         this->path = path;
00036         this->name = name;
00037         id = 0;
00038 }
00039 
00040 CL_CDDrive_Win32::~CL_CDDrive_Win32()
00041 {
00042 }
00043 
00044 bool CL_CDDrive_Win32::send_command(unsigned int msg, unsigned int flags, void *arg)
00045 {
00046         MCIERROR mci_error;
00047         mci_error = mciSendCommand(id, msg, flags, (DWORD) arg);
00048 
00049         return mci_error == 0;
00050 }
00051 
00052 bool CL_CDDrive_Win32::init()
00053 {
00054         MCI_OPEN_PARMS mci_open;
00055         memset(&mci_open, 0, sizeof(MCI_OPEN_PARMS));
00056         MCI_SET_PARMS mci_set;
00057         memset(&mci_set, 0, sizeof(MCI_SET_PARMS));
00058         DWORD flags;
00059 
00060         mci_open.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO;
00061         mci_open.lpstrElementName = path.c_str();
00062         
00063         flags = MCI_OPEN_TYPE |
00064                         MCI_OPEN_SHAREABLE |
00065                         MCI_OPEN_TYPE_ID |
00066                         MCI_OPEN_ELEMENT;
00067 
00068         if (!send_command(MCI_OPEN, flags, &mci_open))
00069         {
00070                 flags &= ~MCI_OPEN_SHAREABLE;
00071                 if (!send_command(MCI_OPEN, flags, &mci_open)) 
00072                 {
00073                         return false;
00074                 }
00075         }
00076         id = mci_open.wDeviceID;
00077 
00078         /* Set the minute-second-frame time format */
00079         mci_set.dwTimeFormat = MCI_FORMAT_MSF;
00080         send_command(MCI_SET, MCI_SET_TIME_FORMAT, &mci_set);
00081 
00082         return read_toc();
00083 }
00084 
00085 bool CL_CDDrive_Win32::read_toc()
00086 {
00087         MCI_STATUS_PARMS mci_status;
00088         int i;
00089         DWORD flags;
00090         bool retval = false;
00091 
00092         mci_status.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
00093         flags = MCI_STATUS_ITEM | MCI_WAIT;
00094 
00095         if (send_command(MCI_STATUS, flags, &mci_status)) 
00096         {
00097                 num_tracks = mci_status.dwReturn;
00098                 tracks.reserve(num_tracks+1);
00099 
00100                 flags = MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT;
00101                 for (i=0; i<num_tracks;i++) 
00102                 {
00103                         STrack track;
00104                         track.id = i+1;
00105 
00106                         mci_status.dwTrack = id;
00107                         mci_status.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
00108                         if (!send_command(MCI_STATUS, flags, &mci_status))
00109                         {
00110                                 break;
00111                         }
00112 
00113                         if (mci_status.dwReturn == MCI_CDA_TRACK_AUDIO ) 
00114                         {
00115                                 track.is_audio = true;
00116                         } else 
00117                         {
00118                                 track.is_audio = false;
00119                         }
00120 
00121                         mci_status.dwItem = MCI_STATUS_POSITION;
00122                         if (!send_command(MCI_STATUS, flags, &mci_status))
00123                         {
00124                                 break;
00125                         }
00126                         
00127                         track.start_frame = MSF_TO_FRAMES(
00128                                         MCI_MSF_MINUTE(mci_status.dwReturn),
00129                                         MCI_MSF_SECOND(mci_status.dwReturn),
00130                                         MCI_MSF_FRAME(mci_status.dwReturn));
00131                         track.length_frames = 0;
00132 
00133                         if (i > 0) 
00134                         {
00135                                 tracks[i-1].length_frames =     track.start_frame - tracks[i-1].start_frame;
00136                         }
00137                         tracks.push_back(track);
00138                 }
00139                 
00140                 if (i == num_tracks) 
00141                 {
00142                         flags &= ~MCI_TRACK;
00143                         mci_status.dwItem = MCI_STATUS_LENGTH;
00144                         if (send_command(MCI_STATUS, flags,     &mci_status)) 
00145                         {
00146                                 int offset = MSF_TO_FRAMES(
00147                                         MCI_MSF_MINUTE(mci_status.dwReturn),
00148                                         MCI_MSF_SECOND(mci_status.dwReturn),
00149                                         MCI_MSF_FRAME(mci_status.dwReturn));
00150                                 
00151                                 STrack track;
00152                                 track.is_audio = false;
00153                                 track.start_frame = offset;
00154                                 track.length_frames = 0;
00155                                 tracks.push_back(track);
00156 
00157                                 tracks[i-1].length_frames = offset - tracks[i-1].start_frame;
00158                                 retval = true;
00159                         }
00160                 }
00161         }
00162 
00163         return retval;
00164 }
00165 
00166 void CL_CDDrive_Win32::update_status()
00167 {
00168         MCI_STATUS_PARMS mci_status;
00169         DWORD flags;
00170 
00171         flags = MCI_STATUS_ITEM | MCI_WAIT;
00172         mci_status.dwItem = MCI_STATUS_MODE;
00173 
00174         bool update_position = false;
00175         
00176         cd_playing = false;
00177         cur_track = -1;
00178         cur_frame = -1;
00179 
00180         if (!send_command(MCI_STATUS, flags, &mci_status)) 
00181         {
00182                 throw "Failed to get CD status";
00183         }
00184         else
00185         {
00186 
00187                 switch (mci_status.dwReturn) 
00188                 {
00189                         case MCI_MODE_PLAY:
00190                                 cd_playing = true;
00191                                 update_position = true;
00192                                 break;
00193                         case MCI_MODE_PAUSE:
00194                                 update_position = true;
00195                                 break;
00196                 }
00197         }
00198 
00199         if (update_position) 
00200         {
00201                 mci_status.dwItem = MCI_STATUS_POSITION;
00202                 if (send_command(MCI_STATUS, flags,     &mci_status)) 
00203                 {
00204                         cur_frame = MSF_TO_FRAMES(
00205                                 MCI_MSF_MINUTE(mci_status.dwReturn),
00206                                 MCI_MSF_SECOND(mci_status.dwReturn),
00207                                 MCI_MSF_FRAME(mci_status.dwReturn));
00208 
00209                         cur_track = 0;
00210                         int t = 1;
00211                         for (std::vector<STrack>::iterator it = tracks.begin();it!=tracks.end();it++)
00212                         {
00213                                 if ((*it).start_frame < cur_frame && ((*it).start_frame+(*it).length_frames) > cur_frame)
00214                                 {
00215                                         cur_track = t;
00216                                         break;
00217                                 }
00218                         }
00219                 } 
00220         }
00221 }
00222 
00223 std::string CL_CDDrive_Win32::get_drive_path()
00224 {
00225         return path;
00226 }
00227 
00228 std::string CL_CDDrive_Win32::get_cd_name()
00229 {
00230         return name;
00231 }
00232 
00233 int CL_CDDrive_Win32::get_num_tracks()
00234 {
00235         return num_tracks;
00236 }
00237 
00238 bool CL_CDDrive_Win32::is_playing()
00239 {
00240         update_status();
00241         return cd_playing;
00242 }
00243 
00244 int CL_CDDrive_Win32::get_cur_track()
00245 {
00246         update_status();
00247         return cur_track;
00248 }
00249 
00250 int CL_CDDrive_Win32::get_cur_frame()
00251 {
00252         update_status();
00253         return cur_frame;
00254 }
00255 
00256 bool CL_CDDrive_Win32::play_tracks(int track, int end_track)
00257 {
00258         if (track < 1 || track > num_tracks) return false;
00259         if (end_track != 0 && end_track < track) return false;
00260         if (end_track == 0) end_track = num_tracks;
00261         if (end_track >= tracks.size()) end_track = tracks.size()-1;
00262 
00263         return play_frames(
00264                 tracks[track-1].start_frame,
00265                 tracks[end_track-1].start_frame+tracks[end_track-1].length_frames);
00266 }
00267 
00268 bool CL_CDDrive_Win32::play_frames(int frame, int end_frame)
00269 {
00270         MCI_PLAY_PARMS mci_play;
00271         int m, s, f;
00272         DWORD flags;
00273 
00274         flags = MCI_FROM | MCI_TO | MCI_NOTIFY;
00275         mci_play.dwCallback = 0;
00276         FRAMES_TO_MSF(frame, &m, &s, &f);
00277         mci_play.dwFrom = MCI_MAKE_MSF(m, s, f);
00278         FRAMES_TO_MSF(end_frame, &m, &s, &f);
00279         mci_play.dwTo = MCI_MAKE_MSF(m, s, f);
00280         
00281         return send_command(MCI_PLAY, flags, &mci_play);
00282 
00283 }
00284 
00285 bool CL_CDDrive_Win32::play_track(int track)
00286 {
00287         if (track < 1 || track > num_tracks) return false;
00288         return play_frames(
00289                 tracks[track-1].start_frame,
00290                 tracks[track-1].start_frame+tracks[track-1].length_frames);
00291 }
00292 
00293 void CL_CDDrive_Win32::stop()
00294 {
00295         send_command(MCI_STOP, MCI_WAIT, NULL);
00296 }
00297 
00298 void CL_CDDrive_Win32::pause()
00299 {
00300         send_command(MCI_PAUSE, MCI_WAIT, NULL);
00301 }
00302 
00303 void CL_CDDrive_Win32::resume()
00304 {
00305         send_command(MCI_RESUME, MCI_WAIT, NULL);
00306 }
00307 

Generated at Wed Apr 4 19:53:59 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001