1 /*
2  * sound.h
3  *
4  * Sound class.
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 28275 $
30  * $Author: rjongbloed $
31  * $Date: 2012-08-29 21:42:35 -0500 (Wed, 29 Aug 2012) $
32  */
33 
34 
35 ///////////////////////////////////////////////////////////////////////////////
36 // PSound
37 
38 #ifndef _PSOUND_WIN32
39 #define _PSOUND_WIN32
40 
41 #include <mmsystem.h>
42 #ifndef _WIN32_WCE
43 #ifdef _MSC_VER
44 #pragma comment(lib, "winmm.lib")
45 #endif
46 #endif
47 
48 class PWaveFormat : public PObject
49 {
50   PCLASSINFO(PWaveFormat, PObject)
51   public:
52     PWaveFormat();
53     ~PWaveFormat();
54     PWaveFormat(const PWaveFormat & fmt);
55     PWaveFormat & operator=(const PWaveFormat & fmt);
56 
57     void PrintOn(ostream &) const;
58     void ReadFrom(istream &);
59 
60     void SetFormat(unsigned numChannels, unsigned sampleRate, unsigned bitsPerSample);
61     void SetFormat(const void * data, PINDEX size);
62 
63     PBoolean           SetSize   (PINDEX sz);
GetSize()64     PINDEX         GetSize   () const { return  size;       }
GetPointer()65     void         * GetPointer() const { return  waveFormat; }
66     WAVEFORMATEX * operator->() const { return  waveFormat; }
67     WAVEFORMATEX & operator *() const { return *waveFormat; }
68     operator   WAVEFORMATEX *() const { return  waveFormat; }
69 
70   protected:
71     PINDEX         size;
72     WAVEFORMATEX * waveFormat;
73 };
74 
75 
76 class PMultiMediaFile
77 {
78   public:
79     PMultiMediaFile();
80     ~PMultiMediaFile();
81 
82     PBoolean CreateWaveFile(const PFilePath & filename,
83                         const PWaveFormat & waveFormat,
84                         DWORD dataSize);
85     PBoolean OpenWaveFile(const PFilePath & filename,
86                       PWaveFormat & waveFormat,
87                       DWORD & dataSize);
88 
89     PBoolean Open(const PFilePath & filename, DWORD dwOpenFlags, LPMMIOINFO lpmmioinfo = NULL);
90     PBoolean Close(UINT wFlags = 0);
91     PBoolean Ascend(MMCKINFO & ckinfo, UINT wFlags = 0);
92     PBoolean Descend(UINT wFlags, MMCKINFO & ckinfo, LPMMCKINFO lpckParent = NULL);
93     PBoolean Read(void * data, PINDEX len);
94     PBoolean CreateChunk(MMCKINFO & ckinfo, UINT wFlags = 0);
95     PBoolean Write(const void * data, PINDEX len);
96 
GetLastError()97     DWORD GetLastError() const { return dwLastError; }
98 
99   protected:
100     HMMIO hmmio;
101     DWORD dwLastError;
102 };
103 
104 
105 class PWaveBuffer : public PBYTEArray
106 {
107   PCLASSINFO(PWaveBuffer, PBYTEArray);
108   private:
109     PWaveBuffer(PINDEX sz = 0);
110     ~PWaveBuffer();
111 
112     PWaveBuffer & operator=(const PSound & sound);
113 
114     DWORD Prepare(HWAVEOUT hWaveOut, PINDEX & count);
115     DWORD Prepare(HWAVEIN hWaveIn);
116     DWORD Release();
117 
118     void PrepareCommon(PINDEX count);
119 
120     HWAVEOUT hWaveOut;
121     HWAVEIN  hWaveIn;
122     WAVEHDR  header;
123 
124   friend class PSoundChannelWin32;
125 };
126 
127 PARRAY(PWaveBufferArray, PWaveBuffer);
128 
129 
130 class PSoundChannelWin32: public PSoundChannel
131 {
132  public:
133     PSoundChannelWin32();
134     void Construct();
135     PSoundChannelWin32(const PString &device,
136                      PSoundChannel::Directions dir,
137                      unsigned numChannels,
138                      unsigned sampleRate,
139                      unsigned bitsPerSample);
140     ~PSoundChannelWin32();
141     static PStringArray GetDeviceNames(PSoundChannel::Directions = Player);
142     PBoolean Open(
143       const PString & device,
144       Directions dir,
145       unsigned numChannels,
146       unsigned sampleRate,
147       unsigned bitsPerSample
148     );
149     PBoolean Setup();
150     PBoolean Close();
151     PBoolean IsOpen() const;
152     PBoolean Write(const void * buf, PINDEX len);
153     PBoolean Read(void * buf, PINDEX len);
154     PBoolean SetFormat(unsigned numChannels,
155                    unsigned sampleRate,
156                    unsigned bitsPerSample);
157     unsigned GetChannels() const;
158     unsigned GetSampleRate() const;
159     unsigned GetSampleSize() const;
160     PBoolean SetBuffers(PINDEX size, PINDEX count);
161     PBoolean GetBuffers(PINDEX & size, PINDEX & count);
162     PBoolean PlaySound(const PSound & sound, PBoolean wait);
163     PBoolean PlayFile(const PFilePath & filename, PBoolean wait);
164     PBoolean HasPlayCompleted();
165     PBoolean WaitForPlayCompletion();
166     PBoolean RecordSound(PSound & sound);
167     PBoolean RecordFile(const PFilePath & filename);
168     PBoolean StartRecording();
169     PBoolean IsRecordBufferFull();
170     PBoolean AreAllRecordBuffersFull();
171     PBoolean WaitForRecordBufferFull();
172     PBoolean WaitForAllRecordBuffersFull();
173     PBoolean Abort();
174     PBoolean SetVolume(unsigned newVal);
175     PBoolean GetVolume(unsigned &devVol);
176     PBoolean SetMute(bool mute);
177     PBoolean GetMute(bool & mute);
178 
179   public:
180     // Overrides from class PChannel
181     virtual PString GetName() const;
182       // Return the name of the channel.
183 
184 
185     PString GetErrorText(ErrorGroup group = NumErrorGroups) const;
186     // Get a text form of the last error encountered.
187 
188     PBoolean SetFormat(const PWaveFormat & format);
189 
190     PBoolean Open(const PString & device, Directions dir,const PWaveFormat & format);
191     // Open with format other than PCM
192 
193   protected:
194     PString      deviceName;
195     Directions   direction;
196     HWAVEIN      hWaveIn;
197     HWAVEOUT     hWaveOut;
198     HMIXER       hMixer;
199     MIXERCONTROL volumeControl;
200     MIXERCONTROL muteControl;
201     HANDLE       hEventDone;
202     PWaveFormat  waveFormat;
203     bool         opened;
204 
205     PWaveBufferArray buffers;
206     PINDEX           bufferIndex;
207     PINDEX           bufferByteOffset;
208     PMutex           bufferMutex;
209 
210   private:
211     PBoolean OpenDevice(unsigned id);
212     PBoolean GetDeviceID(const PString & device, Directions dir, unsigned& id);
213 };
214 
215 
216 #endif
217 
218 // End Of File ///////////////////////////////////////////////////////////////
219