Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cWaveDevice.h
Go to the documentation of this file.
1 //
4 //
5 
6 #ifndef _INC_cWaveDevice_H
7 #define _INC_cWaveDevice_H
8 #ifndef NO_PRAGMA_ONCE
9 #pragma once
10 #endif
11 
12 #include "../AV/cWaveFormat.h"
13 
14 #ifdef _WIN32
15 #include "../WinAPI/cWinResource.h"
18 #include "GrayCore/include/cHeap.h"
22 
23 namespace Gray
24 {
25  template <> inline void cHandlePtr<HWAVEIN>::CloseHandle(HWAVEIN h) // static
26  {
28  ::waveInClose(h);
29  }
30  template <> inline void cHandlePtr<HWAVEOUT>::CloseHandle(HWAVEOUT h) // static
31  {
33  ::waveOutClose(h);
34  }
35 }
36 
37 namespace GrayLib
38 {
39  typedef UINT WAVE_DEVICEID_t;
40  typedef UINT WAVE_DEVPID_t;
41  class cWaveDevice;
42 
43  class GRAYLIB_LINK cWaveHeaderBase
44  {
50 
51  public:
52  cRefPtr<cWaveDevice> m_pDevice;
53 
54  private:
55  CWinGlobalT<WAVEHDR> m_wh;
56  bool m_bManageDataBuffer;
57 
58  public:
59  cWaveHeaderBase(void* pDataBuffer = nullptr, size_t dwBufferLength = 0);
60  ~cWaveHeaderBase();
61 
62  void UnprepareDevice(); // release from device. (NOT WHILE WHDR_INQUEUE !)
63  HRESULT PrepareDevice(cWaveDevice* pDevice);
64 
65  void DetachData();
66  bool AttachData(void* pDataBuffer, size_t dwBufferLength);
67 
68  WAVEHDR* get_wh() const noexcept
69  {
70  return m_wh.get_Data();
71  }
72  bool isValid() const noexcept
73  {
74  WAVEHDR* pwh = get_wh();
75  if (pwh == nullptr)
76  return false;
77  if (pwh->lpData == nullptr)
78  return false;
79  ASSERT(pwh->dwUser == (DWORD_PTR)this);
80  return true;
81  }
82  bool isValidCheck() const noexcept
83  {
84  return isValid();
85  }
86  bool isInQueue() const noexcept
87  {
89  if (!isValid())
90  return false;
91  if (get_wh()->dwFlags & WHDR_INQUEUE)
92  return true;
93  return false;
94  }
95  };
96 
97  class GRAYLIB_LINK cWaveDevice : public cRefBase, public cSoundBase
98  {
103 
104  friend class cWaveHeaderBase;
105 
106  protected:
107  WAVE_DEVICEID_t m_uDeviceID;
108  HWAVE m_hDevice;
109  bool m_bActive;
110  int m_iHeadersInQueue;
111 
112  private:
113  virtual HRESULT PrepareHeader(WAVEHDR* pwh) = 0;
114  virtual HRESULT UnprepareHeader(WAVEHDR* pwh) = 0;
115 
116  public:
117  static const WAVE_DEVICEID_t k_NO_ID = ((WAVE_DEVICEID_t)(WAVE_MAPPER - 1)); // no device at all.
118 
119  cWaveDevice(WAVE_DEVICEID_t uDeviceID = WAVE_MAPPER);
120  virtual ~cWaveDevice();
121 
122  static WAVE_DEVICEID_t GRAYCALL FindDeviceByPersistID(bool bInput, WAVE_DEVPID_t nPersistId);
123  static inline WAVE_DEVPID_t MakePersistID(WORD wPid, WORD wMid)
124  {
125  return (WAVE_DEVPID_t)MAKEDWORD(wPid, wMid); // get full product id = product + manufacturer
126  }
127  operator HWAVE() const noexcept
128  {
129  return m_hDevice;
130  }
131  bool isOpen() const noexcept
132  {
133  return m_hDevice != HANDLE_NULL;
134  }
135  HWAVE get_Handle() const noexcept
136  {
137  return m_hDevice;
138  }
139  void DetachHandle() noexcept
140  {
142  m_hDevice = HANDLE_NULL;
143  }
144 
145  WAVE_DEVICEID_t get_DeviceID() const noexcept
146  {
148  return m_uDeviceID;
149  }
150 
151  virtual HRESULT put_DeviceID(WAVE_DEVICEID_t uDeviceID) = 0;
152  virtual WAVE_DEVICEID_t QueryDeviceID() const = 0; // if WAVE_MAPPER, what device are we mapped to ?
153 
154  bool isActive() const noexcept
155  {
156  return m_bActive;
157  }
158  int get_HeadersInQueue() const noexcept
159  {
160  return m_iHeadersInQueue;
161  }
162  int& ref_HeadersInQueue() noexcept
163  {
164  return m_iHeadersInQueue;
165  }
166 
167  virtual HRESULT OpenWave(const cWaveFormat& format, DWORD_PTR dwCallback, DWORD_PTR dwInstanceData, DWORD dwOpenFlags) = 0;
168  virtual void CloseWave() = 0;
169 
170  virtual HRESULT Start() = 0;
171  virtual HRESULT Stop() = 0;
172  virtual HRESULT Reset() = 0;
173 
174  virtual HRESULT GetPosition(MMTIME& Info) const = 0;
175  virtual HRESULT WriteHeader(cWaveHeaderBase* pHdr) = 0;
176 
177  // Driver returns headers when it is done with it.
178  static cWaveHeaderBase* GRAYCALL OnHeaderReturn(WAVEHDR* pHdr);
179 
180  UNITTEST_FRIEND(cWaveDevice);
181  };
182 
183  class GRAYLIB_LINK cWaveRecorder : public cWaveDevice
184  {
187  public:
188  _GTNSND(WAVEINCAPS) m_Caps;
189  private:
190  virtual HRESULT PrepareHeader(WAVEHDR* pwh) override;
191  virtual HRESULT UnprepareHeader(WAVEHDR* pwh) override;
192  public:
193  cWaveRecorder(WAVE_DEVICEID_t uDeviceID = WAVE_MAPPER);
194  virtual ~cWaveRecorder();
195 
196  operator HWAVEIN() const
197  {
198  return((HWAVEIN)m_hDevice);
199  }
200  HWAVEIN get_Handle() const
201  {
202  return((HWAVEIN)m_hDevice);
203  }
204  WAVE_DEVPID_t get_PersistID() const
205  {
207  return MakePersistID(m_Caps.wPid, m_Caps.wMid);
208  }
209 
210  virtual HRESULT put_DeviceID(WAVE_DEVICEID_t uDeviceID) override;
211  virtual WAVE_DEVICEID_t QueryDeviceID() const override;
212 
213  static UINT GRAYCALL GetNumDevs();
214  static HRESULT GRAYCALL QueryCaps(WAVE_DEVICEID_t uDeviceID, OUT _GTNSND(WAVEINCAPS)* pCaps);
215  HRESULT QueryCaps();
216 
217  virtual HRESULT OpenWave(const cWaveFormat& format, DWORD_PTR dwCallback, DWORD_PTR dwInstanceData, DWORD fdwOpenFlags) override;
218  virtual void CloseWave() override;
219 
220  HRESULT SetLowPri(); // background recorder.
221  virtual HRESULT Start() override;
222  virtual HRESULT Stop() override;
223  virtual HRESULT Reset() override;
224 
225  virtual HRESULT GetPosition(MMTIME& Info) const override;
226  virtual HRESULT WriteHeader(cWaveHeaderBase* pHdr) override;
227  };
228 
229  class GRAYLIB_LINK cWavePlayer : public cWaveDevice
230  {
233  public:
234  _GTNSND(WAVEOUTCAPS) m_Caps;
235  private:
236  virtual HRESULT PrepareHeader(WAVEHDR* pwh) override;
237  virtual HRESULT UnprepareHeader(WAVEHDR* pwh) override;
238  public:
239  cWavePlayer(WAVE_DEVICEID_t uDeviceID = WAVE_MAPPER);
240  virtual ~cWavePlayer();
241 
242  operator HWAVEOUT() const
243  {
244  return((HWAVEOUT)m_hDevice);
245  }
246  HWAVEOUT get_Handle() const
247  {
248  return((HWAVEOUT)m_hDevice);
249  }
250  WAVE_DEVPID_t get_PersistID() const
251  {
253  return MakePersistID(m_Caps.wPid, m_Caps.wMid);
254  }
255  virtual HRESULT put_DeviceID(WAVE_DEVICEID_t uDeviceID) override;
256  virtual WAVE_DEVICEID_t QueryDeviceID() const override;
257 
258  static UINT GRAYCALL GetNumDevs();
259  static HRESULT GRAYCALL QueryCaps(WAVE_DEVICEID_t uDeviceID, OUT _GTNSND(WAVEOUTCAPS)* pCaps);
260 
261  HRESULT QueryCaps();
262 
263  virtual HRESULT OpenWave(const cWaveFormat& format, DWORD_PTR dwCallback, DWORD_PTR dwInstanceData, DWORD fdwOpenFlags) override;
264  virtual void CloseWave() override;
265 
266  virtual HRESULT GetPosition(MMTIME& Info) const override;
267  virtual HRESULT Start() override;
268  virtual HRESULT Stop() override;
269  virtual HRESULT Reset() override;
270  virtual HRESULT WriteHeader(cWaveHeaderBase* pHdr) override;
271 
272  // 0 to 0xffff per stereo channel volume
273  HRESULT get_Volume(SOUND_VOL2_t& dwVolume);
274  HRESULT put_Volume(SOUND_VOL2_t dwVolume);
275  HRESULT put_VolumeStereo(SOUND_VOL_t wVolumeLeft, SOUND_VOL_t wVolumeRight);
276 
277  // Very rarely supported feature.
278  HRESULT get_PlaybackRate(DWORD& dwRate);
279  HRESULT put_PlaybackRate(DWORD dwRate);
280  };
281 };
282 #endif // _WIN32
283 #endif //_INC_cWaveDevice_H
#define GRAYCALL
declare calling convention for static functions so everyone knows the arg passing scheme....
Definition: GrayCore.h:36
#define GRAYLIB_LINK
Definition: GrayLibBase.h:35
INT32 HRESULT
_WIN32 style error codes. INT32
Definition: SysTypes.h:465
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define HANDLE_NULL
Invalid OS handle for _WIN32. Not invalid OS handle for linux.
Definition: cOSHandle.h:21
#define _GTNSND
Definition: cSoundBase.h:26
#define MAKEDWORD(low, high)
Definition: cTypes.h:32
#define UNITTEST_FRIEND(n)
Define this in the class body to be unit tested. Allow the unit test to access private/protected stuf...
Definition: cUnitTestDecl.h:17
void CloseHandle()
Definition: cHandlePtr.h:79
Definition: cMesh.h:22
WORD SOUND_VOL_t
Mono Attenuation of the audio. linear perception 0 to k_VOL_MAX(0xffff). NOT decibels.
Definition: cSoundBase.h:29
DWORD SOUND_VOL2_t
Stereo linear perceived volume. LOWORD(left) HIWORD(right)
Definition: cSoundBase.h:30
< The main namespace for all Core functions.
Definition: GrayCore.cpp:14