Change wxSound ctor from in-memory data to use size_t/void *.
[wxWidgets.git] / src / msw / sound.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/sound.cpp
3 // Purpose: wxSound
4 // Author: Julian Smart
5 // Modified by: 2005-07-29: Vadim Zeitlin: redesign
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #if defined(__BORLANDC__)
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_SOUND
28
29 #include "wx/sound.h"
30 #include "wx/msw/private.h"
31
32 #include <mmsystem.h>
33
34 // ----------------------------------------------------------------------------
35 // wxSoundData
36 // ----------------------------------------------------------------------------
37
38 // ABC for different sound data representations
39 class wxSoundData
40 {
41 public:
42 wxSoundData() { }
43
44 // return true if we had been successfully initialized
45 virtual bool IsOk() const = 0;
46
47 // get the flag corresponding to our content for PlaySound()
48 virtual DWORD GetSoundFlag() const = 0;
49
50 // get the data to be passed to PlaySound()
51 virtual LPCTSTR GetSoundData() const = 0;
52
53 virtual ~wxSoundData() { }
54 };
55
56 // class for in-memory sound data
57 class wxSoundDataMemory : public wxSoundData
58 {
59 public:
60 // we copy the data
61 wxSoundDataMemory(size_t size, const void* buf);
62
63 void *GetPtr() const { return m_waveDataPtr; }
64
65 virtual bool IsOk() const { return GetPtr() != NULL; }
66 virtual DWORD GetSoundFlag() const { return SND_MEMORY; }
67 virtual LPCTSTR GetSoundData() const { return (LPCTSTR)GetPtr(); }
68
69 private:
70 GlobalPtr m_waveData;
71 GlobalPtrLock m_waveDataPtr;
72
73 wxDECLARE_NO_COPY_CLASS(wxSoundDataMemory);
74 };
75
76 // class for sound files and resources
77 class wxSoundDataFile : public wxSoundData
78 {
79 public:
80 wxSoundDataFile(const wxString& filename, bool isResource);
81
82 virtual bool IsOk() const { return !m_name.empty(); }
83 virtual DWORD GetSoundFlag() const
84 {
85 return m_isResource ? SND_RESOURCE : SND_FILENAME;
86 }
87 virtual LPCTSTR GetSoundData() const { return m_name.c_str(); }
88
89 private:
90 const wxString m_name;
91 const bool m_isResource;
92
93 wxDECLARE_NO_COPY_CLASS(wxSoundDataFile);
94 };
95
96 // ============================================================================
97 // implementation
98 // ============================================================================
99
100 // ----------------------------------------------------------------------------
101 // wxSoundData-derived classes
102 // ----------------------------------------------------------------------------
103
104 wxSoundDataMemory::wxSoundDataMemory(size_t size, const void* buf)
105 : m_waveData(size),
106 m_waveDataPtr(m_waveData)
107 {
108 if ( IsOk() )
109 ::CopyMemory(m_waveDataPtr, buf, size);
110 }
111
112 wxSoundDataFile::wxSoundDataFile(const wxString& filename, bool isResource)
113 : m_name(filename),
114 m_isResource(isResource)
115 {
116 // check for file/resource existence?
117 }
118
119 // ----------------------------------------------------------------------------
120 // wxSound
121 // ----------------------------------------------------------------------------
122
123 wxSound::wxSound()
124 {
125 Init();
126 }
127
128 wxSound::wxSound(const wxString& filename, bool isResource)
129 {
130 Init();
131 Create(filename, isResource);
132 }
133
134 wxSound::wxSound(size_t size, const void* data)
135 {
136 Init();
137 Create(size, data);
138 }
139
140 wxSound::~wxSound()
141 {
142 Free();
143 }
144
145 void wxSound::Free()
146 {
147 wxDELETE(m_data);
148 }
149
150 bool wxSound::CheckCreatedOk()
151 {
152 if ( m_data && !m_data->IsOk() )
153 Free();
154
155 return m_data != NULL;
156 }
157
158 bool wxSound::Create(const wxString& filename, bool isResource)
159 {
160 Free();
161
162 m_data = new wxSoundDataFile(filename, isResource);
163
164 return CheckCreatedOk();
165 }
166
167 bool wxSound::Create(size_t size, const void* data)
168 {
169 Free();
170
171 m_data = new wxSoundDataMemory(size, data);
172
173 return CheckCreatedOk();
174 }
175
176 bool wxSound::DoPlay(unsigned flags) const
177 {
178 if ( !IsOk() || !m_data->IsOk() )
179 return false;
180
181 DWORD flagsMSW = m_data->GetSoundFlag();
182 HMODULE hmod = flagsMSW == SND_RESOURCE ? wxGetInstance() : NULL;
183
184 // we don't want replacement default sound
185 flagsMSW |= SND_NODEFAULT;
186
187 // NB: wxSOUND_SYNC is 0, don't test for it
188 flagsMSW |= (flags & wxSOUND_ASYNC) ? SND_ASYNC : SND_SYNC;
189 if ( flags & wxSOUND_LOOP )
190 {
191 // looping only works with async flag
192 flagsMSW |= SND_LOOP | SND_ASYNC;
193 }
194
195 return ::PlaySound(m_data->GetSoundData(), hmod, flagsMSW) != FALSE;
196 }
197
198 /* static */
199 void wxSound::Stop()
200 {
201 ::PlaySound(NULL, NULL, 0);
202 }
203
204 #endif // wxUSE_SOUND
205