1 ////////////////////////////////////////////////////////////
2 //
3 // SFML - Simple and Fast Multimedia Library
4 // Copyright (C) 2007-2018 Laurent Gomila (laurent@sfml-dev.org)
5 //
6 // This software is provided 'as-is', without any express or implied warranty.
7 // In no event will the authors be held liable for any damages arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it freely,
11 // subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented;
14 // you must not claim that you wrote the original software.
15 // If you use this software in a product, an acknowledgment
16 // in the product documentation would be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such,
19 // and must not be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source distribution.
22 //
23 ////////////////////////////////////////////////////////////
24
25 ////////////////////////////////////////////////////////////
26 // Headers
27 ////////////////////////////////////////////////////////////
28 #include <SFML/Audio/Sound.hpp>
29 #include <SFML/Audio/SoundBuffer.hpp>
30 #include <SFML/Audio/ALCheck.hpp>
31
32
33 namespace sf
34 {
35 ////////////////////////////////////////////////////////////
Sound()36 Sound::Sound() :
37 m_buffer(NULL)
38 {
39 }
40
41
42 ////////////////////////////////////////////////////////////
Sound(const SoundBuffer & buffer)43 Sound::Sound(const SoundBuffer& buffer) :
44 m_buffer(NULL)
45 {
46 setBuffer(buffer);
47 }
48
49
50 ////////////////////////////////////////////////////////////
Sound(const Sound & copy)51 Sound::Sound(const Sound& copy) :
52 SoundSource(copy),
53 m_buffer (NULL)
54 {
55 if (copy.m_buffer)
56 setBuffer(*copy.m_buffer);
57 setLoop(copy.getLoop());
58 }
59
60
61 ////////////////////////////////////////////////////////////
~Sound()62 Sound::~Sound()
63 {
64 stop();
65 if (m_buffer)
66 m_buffer->detachSound(this);
67 }
68
69
70 ////////////////////////////////////////////////////////////
play()71 void Sound::play()
72 {
73 alCheck(alSourcePlay(m_source));
74 }
75
76
77 ////////////////////////////////////////////////////////////
pause()78 void Sound::pause()
79 {
80 alCheck(alSourcePause(m_source));
81 }
82
83
84 ////////////////////////////////////////////////////////////
stop()85 void Sound::stop()
86 {
87 alCheck(alSourceStop(m_source));
88 }
89
90
91 ////////////////////////////////////////////////////////////
setBuffer(const SoundBuffer & buffer)92 void Sound::setBuffer(const SoundBuffer& buffer)
93 {
94 // First detach from the previous buffer
95 if (m_buffer)
96 {
97 stop();
98 m_buffer->detachSound(this);
99 }
100
101 // Assign and use the new buffer
102 m_buffer = &buffer;
103 m_buffer->attachSound(this);
104 alCheck(alSourcei(m_source, AL_BUFFER, m_buffer->m_buffer));
105 }
106
107
108 ////////////////////////////////////////////////////////////
setLoop(bool loop)109 void Sound::setLoop(bool loop)
110 {
111 alCheck(alSourcei(m_source, AL_LOOPING, loop));
112 }
113
114
115 ////////////////////////////////////////////////////////////
setPlayingOffset(Time timeOffset)116 void Sound::setPlayingOffset(Time timeOffset)
117 {
118 alCheck(alSourcef(m_source, AL_SEC_OFFSET, timeOffset.asSeconds()));
119 }
120
121
122 ////////////////////////////////////////////////////////////
getBuffer() const123 const SoundBuffer* Sound::getBuffer() const
124 {
125 return m_buffer;
126 }
127
128
129 ////////////////////////////////////////////////////////////
getLoop() const130 bool Sound::getLoop() const
131 {
132 ALint loop;
133 alCheck(alGetSourcei(m_source, AL_LOOPING, &loop));
134
135 return loop != 0;
136 }
137
138
139 ////////////////////////////////////////////////////////////
getPlayingOffset() const140 Time Sound::getPlayingOffset() const
141 {
142 ALfloat secs = 0.f;
143 alCheck(alGetSourcef(m_source, AL_SEC_OFFSET, &secs));
144
145 return seconds(secs);
146 }
147
148
149 ////////////////////////////////////////////////////////////
getStatus() const150 Sound::Status Sound::getStatus() const
151 {
152 return SoundSource::getStatus();
153 }
154
155
156 ////////////////////////////////////////////////////////////
operator =(const Sound & right)157 Sound& Sound::operator =(const Sound& right)
158 {
159 // Here we don't use the copy-and-swap idiom, because it would mess up
160 // the list of sound instances contained in the buffers and unnecessarily
161 // destroy/create OpenAL sound sources
162
163 // Delegate to base class, which copies all the sound attributes
164 SoundSource::operator=(right);
165
166 // Detach the sound instance from the previous buffer (if any)
167 if (m_buffer)
168 {
169 stop();
170 m_buffer->detachSound(this);
171 m_buffer = NULL;
172 }
173
174 // Copy the remaining sound attributes
175 if (right.m_buffer)
176 setBuffer(*right.m_buffer);
177 setLoop(right.getLoop());
178
179 return *this;
180 }
181
182
183 ////////////////////////////////////////////////////////////
resetBuffer()184 void Sound::resetBuffer()
185 {
186 // First stop the sound in case it is playing
187 stop();
188
189 // Detach the buffer
190 if (m_buffer)
191 {
192 alCheck(alSourcei(m_source, AL_BUFFER, 0));
193 m_buffer->detachSound(this);
194 m_buffer = NULL;
195 }
196 }
197
198 } // namespace sf
199