summaryrefslogtreecommitdiffstats
path: root/pacman-c++/common/audio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pacman-c++/common/audio.cpp')
-rw-r--r--pacman-c++/common/audio.cpp355
1 files changed, 355 insertions, 0 deletions
diff --git a/pacman-c++/common/audio.cpp b/pacman-c++/common/audio.cpp
new file mode 100644
index 0000000..70cd37e
--- /dev/null
+++ b/pacman-c++/common/audio.cpp
@@ -0,0 +1,355 @@
1#include "audio.h"
2#include "constants.h"
3#include <phonon/AudioOutput>
4#include <QCoreApplication>
5#include <QTimer>
6#include <QFile>
7#include <QDir>
8#include <QDebug>
9
10/* the universe's only audio manager */
11AudioManager *AudioManager::m_instance = NULL;
12bool AudioManager::m_working = false;
13
14AudioManager::AudioManager()
15 : m_muted(true)
16{
17 if (Constants::server)
18 {
19 qDebug() << "Server has no sound";
20 m_players.append(new AudioPlayer(this));
21 }
22 else
23 {
24 preload();
25 AudioPlayer *firstplayer = new AudioPlayer(this);
26 firstplayer->test(m_sounds[Sound::WakaWaka]);
27 m_working = firstplayer->m_working;
28 m_players.append(firstplayer);
29 }
30 m_muted = false;
31}
32
33AudioManager *AudioManager::self()
34{
35 if (m_instance == NULL)
36 m_instance = new AudioManager();
37 return m_instance;
38}
39
40bool AudioManager::isWorking() const
41{
42 return m_working;
43}
44
45void AudioManager::setMuted(bool mute)
46{
47 if (!isWorking())
48 return;
49
50 if (mute == m_muted)
51 return;
52
53 for(int i = 0; i < m_players.count(); ++i)
54 m_players.at(i)->setMuted(mute);
55 m_muted = mute;
56 emit mutedChanged(mute);
57}
58
59bool AudioManager::isMuted() const
60{
61 return m_muted;
62}
63
64void AudioManager::pause()
65{
66 if (!isWorking())
67 return;
68 for(int i = 0; i < m_players.count(); ++i)
69 m_players.at(i)->pause();
70}
71
72void AudioManager::stop()
73{
74 if (!isWorking())
75 return;
76 for(int i = 0; i < m_players.count(); ++i)
77 m_players.at(i)->stop();
78}
79
80void AudioManager::clear()
81{
82 if (!isWorking())
83 return;
84 for(int i = 0; i < m_players.count(); ++i)
85 m_players.at(i)->clear();
86}
87
88void AudioManager::clearQueue() const
89{
90 if (!isWorking())
91 return;
92 for(int i = 0; i < m_players.count(); ++i)
93 m_players.at(i)->clearQueue();
94}
95
96AudioPlayer *AudioManager::audioPlayer()
97{
98 return m_players.at(0);
99}
100
101void AudioManager::play(Sound::Type sound, bool wait)
102{
103 audioPlayer()->play(sound, wait);
104}
105
106void AudioManager::enqueue(Sound::Type sound)
107{
108 if (!isWorking())
109 return;
110 audioPlayer()->enqueue(Phonon::MediaSource(m_sounds[sound]));
111}
112
113void AudioManager::registerAudioPlayer(AudioPlayer *player)
114{
115 player->setMuted(m_muted);
116 connect(player, SIGNAL(destroyed(QObject *)), this, SLOT(unregisterAudioPlayer_helper(QObject *)));
117 m_players.append(player);
118}
119
120void AudioManager::unregisterAudioPlayer(AudioPlayer *player)
121{
122 disconnect(player, SIGNAL(destroyed(QObject *)), this, SLOT(unregisterAudioPlayer_helper(QObject *)));
123 m_players.removeAll(player);
124}
125
126void AudioManager::unregisterAudioPlayer_helper(QObject *player)
127{
128 unregisterAudioPlayer(static_cast<AudioPlayer *>(player));
129}
130
131void AudioManager::preload()
132{
133 m_sounds.clear();
134 QDir sounds(":/sound");
135 for(unsigned i = 1; i <= sounds.count(); ++i)
136 m_sounds.append(new QFile(QString(":/sound/sound%1").arg(i), this));
137}
138
139QFile *AudioManager::sound(Sound::Type sound)
140{
141 if (!isWorking())
142 return NULL;
143 return m_sounds.at(sound);
144}
145
146/* --------------------------------------------------------------- */
147
148AudioPlayer::AudioPlayer(QObject *parent)
149 : Phonon::MediaObject(parent), m_working(false)
150{
151 if (!Constants::server)
152 {
153 m_working = AudioManager::m_working;
154 m_output = new Phonon::AudioOutput(Phonon::MusicCategory, this);
155 Phonon::createPath(this, m_output);
156 }
157}
158
159bool AudioPlayer::isWorking() const
160{
161 return m_working;
162}
163
164void AudioPlayer::setMuted(bool mute)
165{
166 m_output->setMuted(mute);
167}
168
169bool AudioPlayer::isMuted() const
170{
171 return m_output->isMuted();
172}
173
174void AudioPlayer::setLoop(QFile *sound)
175{
176 if (!isWorking())
177 return;
178
179 if (sound == NULL)
180 {
181 disconnect(this, SIGNAL(aboutToFinish()), this, SLOT(loopEnqueue()));
182 return;
183 }
184
185 m_loopsound = sound;
186 connect(this, SIGNAL(aboutToFinish()), this, SLOT(loopEnqueue()));
187 setCurrentSource(Phonon::MediaSource(m_loopsound));
188 enqueue(Phonon::MediaSource(m_loopsound));
189}
190
191void AudioPlayer::setLoop(Sound::Type sound)
192{
193 setLoop(AudioManager::self()->sound(sound));
194}
195
196void AudioPlayer::play()
197{
198 Phonon::MediaObject::play();
199}
200
201void AudioPlayer::play(Sound::Type sound, bool wait)
202{
203 if (m_working)
204 {
205 setCurrentSource(Phonon::MediaSource(AudioManager::self()->sound(sound)));
206 play();
207 }
208 else if (wait)
209 {
210 QTimer *timer = new QTimer(this);
211 timer->setSingleShot(true);
212 unsigned int interval = Sound::length[sound];
213 /* add a small delay server side only */
214 if (Constants::server)
215 interval += Constants::tick;
216 timer->setInterval(interval);
217 connect(timer, SIGNAL(timeout()), this, SLOT(finished_ex()));
218 timer->start();
219 }
220}
221
222/* this is a simple hack to check if phonon can actually play sounds.. */
223void AudioPlayer::test(QFile *testsound)
224{
225 stop();
226 m_output->setVolume(0);
227 setCurrentSource(Phonon::MediaSource(testsound));
228 connect(this, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(stateChanged_ex(Phonon::State,Phonon::State)));
229 play();
230
231 QTimer timer;
232 timer.setSingleShot(true);
233 connect(&timer, SIGNAL(timeout()), this, SLOT(testFinished()));
234 timer.start(500);
235 while(timer.isActive())
236 {
237 qApp->processEvents();
238 Sleeper::msleep(1);
239 }
240 clear();
241}
242
243void AudioPlayer::finished_ex()
244{
245 emit finished();
246}
247
248void AudioPlayer::stateChanged_ex(Phonon::State newstate, Phonon::State /* oldstate */)
249{
250 if (newstate != Phonon::ErrorState)
251 {
252 m_working = true;
253 m_output->setVolume(1);
254 qDebug() << "Sound is working for you!";
255 }
256 disconnect(this, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged_ex(Phonon::State, Phonon::State)));
257 stop();
258}
259
260void AudioPlayer::testFinished()
261{
262 if (!m_working)
263 qWarning() << "There's no sound for you :(";
264 disconnect(this, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged_ex(Phonon::State, Phonon::State)));
265}
266
267void AudioPlayer::loopEnqueue()
268{
269 enqueue(Phonon::MediaSource(m_loopsound));
270}
271
272/* --------------------------------------------------------------- */
273
274GaplessAudioPlayer::GaplessAudioPlayer(Sound::Type sound, qint32 mark, QObject *parent)
275 : QObject(parent), m_sound(sound)
276{
277 m_working = AudioManager::m_working;
278 if (!m_working)
279 return;
280
281 m_player1 = new AudioPlayer(this);
282 m_player2 = new AudioPlayer(this);
283
284 m_player2->setPrefinishMark(mark);
285 m_player1->setPrefinishMark(mark);
286
287 connect(m_player1, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer2()));
288 connect(m_player2, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer1()));
289
290 AudioManager::self()->registerAudioPlayer(m_player1);
291 AudioManager::self()->registerAudioPlayer(m_player2);
292}
293
294bool GaplessAudioPlayer::isWorking() const
295{
296 return m_working;
297}
298
299void GaplessAudioPlayer::setMuted(bool mute)
300{
301 if (!m_working)
302 return;
303 m_player1->setMuted(mute);
304 m_player2->setMuted(mute);
305}
306
307bool GaplessAudioPlayer::isMuted() const
308{
309 return m_player1->isMuted() && m_player2->isMuted();
310}
311
312void GaplessAudioPlayer::play()
313{
314 if (!m_working)
315 return;
316 if (m_player1->state() != Phonon::PlayingState && m_player2->state() != Phonon::PlayingState)
317 startPlayer1();
318}
319
320void GaplessAudioPlayer::pause()
321{
322 if (!m_working)
323 return;
324 if (m_player1->state() != Phonon::PausedState)
325 m_player1->pause();
326 if (m_player2->state() != Phonon::PausedState)
327 m_player2->pause();
328}
329
330void GaplessAudioPlayer::startPlayer1()
331{
332 m_player1->play(m_sound);
333}
334
335void GaplessAudioPlayer::startPlayer2()
336{
337 m_player2->play(m_sound);
338}
339
340/* --------------------------------------------------------------- */
341
342void AudioPlayer::Sleeper::sleep(unsigned long secs)
343{
344 QThread::sleep(secs);
345}
346
347void AudioPlayer::Sleeper::msleep(unsigned long msecs)
348{
349 QThread::msleep(msecs);
350}
351
352void AudioPlayer::Sleeper::usleep(unsigned long usecs)
353{
354 QThread::usleep(usecs);
355}