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