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

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