1////////////////////////////////////////////////////////////////////////////////
2// Name:       cdwin.cpp
3// Purpose:    wxMMedia
4// Author:     Guilhem Lavaux
5// Created:    1997
6// Updated:    1998
7// Copyright:  (C) 1997, 1998, Guilhem Lavaux
8// License:    wxWindows license
9////////////////////////////////////////////////////////////////////////////////
10
11#include "wx/wxprec.h"
12
13#ifndef WX_PRECOMP
14    #include "wx/defs.h"
15#endif
16
17#ifdef __BORLANDC__
18#pragma hdrstop
19#endif
20
21#ifdef __WINDOWS__
22
23// ---------------------------------------------------------------------------
24// System headers
25// ---------------------------------------------------------------------------
26
27#include <windows.h>
28#include <stdio.h>
29#include <mmsystem.h>
30
31// ---------------------------------------------------------------------------
32// MMedia headers
33// ---------------------------------------------------------------------------
34
35#define WXMMEDIA_INTERNAL
36#include "wx/mmedia/cdbase.h"
37#include "wx/mmedia/cdwin.h"
38
39// ---------------------------------------------------------------------------
40// Implementation
41// ---------------------------------------------------------------------------
42
43IMPLEMENT_DYNAMIC_CLASS(wxCDAudioWin, wxCDAudio)
44
45wxCDAudioWin::wxCDAudioWin(void)
46  : wxCDAudio(), m_trksize(NULL), m_trkpos(NULL), m_toc(NULL), m_ok(true)
47{
48  MCI_OPEN_PARMS open_struct;
49  MCI_SET_PARMS set_struct;
50
51  m_internal = new CDAW_Internal;
52  open_struct.lpstrDeviceType = _T("cdaudio");
53  DWORD ret = mciSendCommand((MCIDEVICEID)NULL, MCI_OPEN, MCI_OPEN_TYPE,
54                       (DWORD)&open_struct);
55  if (ret) {
56    m_ok = false;
57    return;
58  }
59  m_internal->dev_id = open_struct.wDeviceID;
60
61  set_struct.dwTimeFormat = MCI_FORMAT_MSF;
62  mciSendCommand(m_internal->dev_id, MCI_SET, MCI_SET_TIME_FORMAT,
63                       (DWORD)(LPVOID)&set_struct);
64
65  PrepareToc();
66
67  set_struct.dwTimeFormat = MCI_FORMAT_TMSF;
68  mciSendCommand(m_internal->dev_id, MCI_SET, MCI_SET_TIME_FORMAT,
69                       (DWORD)(LPVOID)&set_struct);
70}
71
72wxCDAudioWin::~wxCDAudioWin(void)
73{
74  if (m_ok) {
75    mciSendCommand(m_internal->dev_id, MCI_CLOSE, 0,(DWORD_PTR)NULL);
76    delete m_toc;
77    delete[] m_trksize;
78    delete[] m_trkpos;
79  }
80  delete m_internal;
81}
82
83void wxCDAudioWin::PrepareToc(void)
84{
85  MCI_STATUS_PARMS status_struct;
86  wxUint16 i, nb_m_trksize;
87  wxCDtime total_time, *trk;
88  DWORD tmem;
89
90  if (!m_ok)
91    return;
92
93  status_struct.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
94  mciSendCommand(m_internal->dev_id, MCI_STATUS, MCI_STATUS_ITEM,
95                 (DWORD)&status_struct);
96  nb_m_trksize = status_struct.dwReturn;
97
98  m_trksize = new wxCDtime[nb_m_trksize+1];
99  m_trkpos = new wxCDtime[nb_m_trksize+1];
100
101  status_struct.dwItem = MCI_STATUS_LENGTH;
102  mciSendCommand(m_internal->dev_id, MCI_STATUS, MCI_STATUS_ITEM,
103                 (DWORD)&status_struct);
104  total_time.track = nb_m_trksize;
105  tmem = status_struct.dwReturn;
106  total_time.min = MCI_MSF_MINUTE(tmem);
107  total_time.sec = MCI_MSF_SECOND(tmem);
108  total_time.hour = total_time.min / 60;
109  total_time.min %= 60;
110
111  for (i=1;i<=nb_m_trksize;i++) {
112    status_struct.dwItem = MCI_STATUS_POSITION;
113    status_struct.dwTrack = i;
114    mciSendCommand(m_internal->dev_id, MCI_STATUS,
115                   MCI_STATUS_ITEM | MCI_TRACK,
116                   (DWORD)(LPVOID)&status_struct);
117    tmem = status_struct.dwReturn;
118
119    trk        = &m_trkpos[i];
120    trk->track = i;
121    trk->min   = MCI_MSF_MINUTE(tmem);
122    trk->sec   = MCI_MSF_SECOND(tmem);
123    trk->hour  = trk->min / 60;
124    trk->min  %= 60;
125
126    status_struct.dwItem = MCI_STATUS_LENGTH;
127    status_struct.dwTrack = i;
128    mciSendCommand(m_internal->dev_id, MCI_STATUS,
129                   MCI_STATUS_ITEM | MCI_TRACK,
130                   (DWORD)(LPVOID)&status_struct);
131    tmem = status_struct.dwReturn;
132
133    trk        = &m_trksize[i];
134    trk->track = i;
135    trk->min   = MCI_MSF_MINUTE(tmem);
136    trk->sec   = MCI_MSF_SECOND(tmem);
137    trk->hour  = trk->min / 60;
138    trk->min  %= 60;
139  }
140
141  m_toc = new CDtoc(total_time, m_trksize, m_trkpos);
142}
143
144bool wxCDAudioWin::Play(const wxCDtime& beg_time, const wxCDtime& end_time)
145{
146  DWORD tmsf;
147  MCI_PLAY_PARMS play_struct;
148
149  if (!m_ok)
150    return false;
151
152  tmsf = MCI_MAKE_TMSF(beg_time.track, beg_time.min,
153                       beg_time.sec, 0);
154  play_struct.dwFrom = tmsf;
155  tmsf = MCI_MAKE_TMSF(end_time.track, end_time.min,
156                       end_time.sec, 0);
157  play_struct.dwTo = tmsf;
158
159  mciSendCommand(m_internal->dev_id, MCI_PLAY, 0, (DWORD)&play_struct);
160  return true;
161}
162
163bool wxCDAudioWin::Pause(void)
164{
165  if (!m_ok)
166    return false;
167
168  return (mciSendCommand(m_internal->dev_id, MCI_PAUSE, 0, 0) == 0);
169}
170
171bool wxCDAudioWin::Resume(void)
172{
173  if (!m_ok)
174    return false;
175
176  return (mciSendCommand(m_internal->dev_id, MCI_RESUME, 0, 0) == 0);
177}
178
179wxCDAudio::CDstatus wxCDAudioWin::GetStatus(void)
180{
181  MCI_STATUS_PARMS status_struct;
182
183  if (!m_ok)
184    return STOPPED;
185
186  status_struct.dwItem = MCI_STATUS_MODE;
187  mciSendCommand(m_internal->dev_id, MCI_STATUS, MCI_STATUS_ITEM,
188                 (DWORD)&status_struct);
189  switch (status_struct.dwReturn) {
190  case MCI_MODE_PAUSE:
191    return PAUSED;
192  case MCI_MODE_PLAY:
193    return PLAYING;
194  }
195  return STOPPED;
196}
197
198wxCDtime wxCDAudioWin::GetTime(void)
199{
200  MCI_STATUS_PARMS status_struct;
201  wxCDtime cd_time = {0,0,0,0};
202
203  if (!m_ok)
204    return cd_time;
205
206  status_struct.dwItem = MCI_STATUS_TIME_FORMAT;
207  mciSendCommand(m_internal->dev_id, MCI_STATUS, MCI_STATUS_ITEM,
208                 (DWORD)&status_struct);
209  cd_time.track = MCI_TMSF_TRACK(status_struct.dwReturn);
210  cd_time.min = MCI_TMSF_MINUTE(status_struct.dwReturn);
211  cd_time.sec = MCI_TMSF_SECOND(status_struct.dwReturn);
212  cd_time.hour = cd_time.min / 60;
213  cd_time.min %= 60;
214  return cd_time;
215}
216
217const wxCDAudio::CDtoc& wxCDAudioWin::GetToc(void)
218{
219  return *m_toc;
220}
221
222#endif
223   // __WINDOWS__
224