From ce48af53646cd9e7ec762fc1ac176b3aa620b11d Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 5 May 2011 00:57:07 +0200 Subject: - refactorized the whole project and made a few subprojects - replaced tcp with enet - added connect dialog - some smaller bugfixes --- pacman-c++/common/audio.cpp | 355 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 pacman-c++/common/audio.cpp (limited to 'pacman-c++/common/audio.cpp') 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 @@ +#include "audio.h" +#include "constants.h" +#include +#include +#include +#include +#include +#include + +/* the universe's only audio manager */ +AudioManager *AudioManager::m_instance = NULL; +bool AudioManager::m_working = false; + +AudioManager::AudioManager() + : m_muted(true) +{ + if (Constants::server) + { + qDebug() << "Server has no sound"; + m_players.append(new AudioPlayer(this)); + } + else + { + preload(); + AudioPlayer *firstplayer = new AudioPlayer(this); + firstplayer->test(m_sounds[Sound::WakaWaka]); + m_working = firstplayer->m_working; + m_players.append(firstplayer); + } + m_muted = false; +} + +AudioManager *AudioManager::self() +{ + if (m_instance == NULL) + m_instance = new AudioManager(); + return m_instance; +} + +bool AudioManager::isWorking() const +{ + return m_working; +} + +void AudioManager::setMuted(bool mute) +{ + if (!isWorking()) + return; + + if (mute == m_muted) + return; + + for(int i = 0; i < m_players.count(); ++i) + m_players.at(i)->setMuted(mute); + m_muted = mute; + emit mutedChanged(mute); +} + +bool AudioManager::isMuted() const +{ + return m_muted; +} + +void AudioManager::pause() +{ + if (!isWorking()) + return; + for(int i = 0; i < m_players.count(); ++i) + m_players.at(i)->pause(); +} + +void AudioManager::stop() +{ + if (!isWorking()) + return; + for(int i = 0; i < m_players.count(); ++i) + m_players.at(i)->stop(); +} + +void AudioManager::clear() +{ + if (!isWorking()) + return; + for(int i = 0; i < m_players.count(); ++i) + m_players.at(i)->clear(); +} + +void AudioManager::clearQueue() const +{ + if (!isWorking()) + return; + for(int i = 0; i < m_players.count(); ++i) + m_players.at(i)->clearQueue(); +} + +AudioPlayer *AudioManager::audioPlayer() +{ + return m_players.at(0); +} + +void AudioManager::play(Sound::Type sound, bool wait) +{ + audioPlayer()->play(sound, wait); +} + +void AudioManager::enqueue(Sound::Type sound) +{ + if (!isWorking()) + return; + audioPlayer()->enqueue(Phonon::MediaSource(m_sounds[sound])); +} + +void AudioManager::registerAudioPlayer(AudioPlayer *player) +{ + player->setMuted(m_muted); + connect(player, SIGNAL(destroyed(QObject *)), this, SLOT(unregisterAudioPlayer_helper(QObject *))); + m_players.append(player); +} + +void AudioManager::unregisterAudioPlayer(AudioPlayer *player) +{ + disconnect(player, SIGNAL(destroyed(QObject *)), this, SLOT(unregisterAudioPlayer_helper(QObject *))); + m_players.removeAll(player); +} + +void AudioManager::unregisterAudioPlayer_helper(QObject *player) +{ + unregisterAudioPlayer(static_cast(player)); +} + +void AudioManager::preload() +{ + m_sounds.clear(); + QDir sounds(":/sound"); + for(unsigned i = 1; i <= sounds.count(); ++i) + m_sounds.append(new QFile(QString(":/sound/sound%1").arg(i), this)); +} + +QFile *AudioManager::sound(Sound::Type sound) +{ + if (!isWorking()) + return NULL; + return m_sounds.at(sound); +} + +/* --------------------------------------------------------------- */ + +AudioPlayer::AudioPlayer(QObject *parent) + : Phonon::MediaObject(parent), m_working(false) +{ + if (!Constants::server) + { + m_working = AudioManager::m_working; + m_output = new Phonon::AudioOutput(Phonon::MusicCategory, this); + Phonon::createPath(this, m_output); + } +} + +bool AudioPlayer::isWorking() const +{ + return m_working; +} + +void AudioPlayer::setMuted(bool mute) +{ + m_output->setMuted(mute); +} + +bool AudioPlayer::isMuted() const +{ + return m_output->isMuted(); +} + +void AudioPlayer::setLoop(QFile *sound) +{ + if (!isWorking()) + return; + + if (sound == NULL) + { + disconnect(this, SIGNAL(aboutToFinish()), this, SLOT(loopEnqueue())); + return; + } + + m_loopsound = sound; + connect(this, SIGNAL(aboutToFinish()), this, SLOT(loopEnqueue())); + setCurrentSource(Phonon::MediaSource(m_loopsound)); + enqueue(Phonon::MediaSource(m_loopsound)); +} + +void AudioPlayer::setLoop(Sound::Type sound) +{ + setLoop(AudioManager::self()->sound(sound)); +} + +void AudioPlayer::play() +{ + Phonon::MediaObject::play(); +} + +void AudioPlayer::play(Sound::Type sound, bool wait) +{ + if (m_working) + { + setCurrentSource(Phonon::MediaSource(AudioManager::self()->sound(sound))); + play(); + } + else if (wait) + { + QTimer *timer = new QTimer(this); + timer->setSingleShot(true); + unsigned int interval = Sound::length[sound]; + /* add a small delay server side only */ + if (Constants::server) + interval += Constants::tick; + timer->setInterval(interval); + connect(timer, SIGNAL(timeout()), this, SLOT(finished_ex())); + timer->start(); + } +} + +/* this is a simple hack to check if phonon can actually play sounds.. */ +void AudioPlayer::test(QFile *testsound) +{ + stop(); + m_output->setVolume(0); + setCurrentSource(Phonon::MediaSource(testsound)); + connect(this, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(stateChanged_ex(Phonon::State,Phonon::State))); + play(); + + QTimer timer; + timer.setSingleShot(true); + connect(&timer, SIGNAL(timeout()), this, SLOT(testFinished())); + timer.start(500); + while(timer.isActive()) + { + qApp->processEvents(); + Sleeper::msleep(1); + } + clear(); +} + +void AudioPlayer::finished_ex() +{ + emit finished(); +} + +void AudioPlayer::stateChanged_ex(Phonon::State newstate, Phonon::State /* oldstate */) +{ + if (newstate != Phonon::ErrorState) + { + m_working = true; + m_output->setVolume(1); + qDebug() << "Sound is working for you!"; + } + disconnect(this, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged_ex(Phonon::State, Phonon::State))); + stop(); +} + +void AudioPlayer::testFinished() +{ + if (!m_working) + qWarning() << "There's no sound for you :("; + disconnect(this, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged_ex(Phonon::State, Phonon::State))); +} + +void AudioPlayer::loopEnqueue() +{ + enqueue(Phonon::MediaSource(m_loopsound)); +} + +/* --------------------------------------------------------------- */ + +GaplessAudioPlayer::GaplessAudioPlayer(Sound::Type sound, qint32 mark, QObject *parent) + : QObject(parent), m_sound(sound) +{ + m_working = AudioManager::m_working; + if (!m_working) + return; + + m_player1 = new AudioPlayer(this); + m_player2 = new AudioPlayer(this); + + m_player2->setPrefinishMark(mark); + m_player1->setPrefinishMark(mark); + + connect(m_player1, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer2())); + connect(m_player2, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(startPlayer1())); + + AudioManager::self()->registerAudioPlayer(m_player1); + AudioManager::self()->registerAudioPlayer(m_player2); +} + +bool GaplessAudioPlayer::isWorking() const +{ + return m_working; +} + +void GaplessAudioPlayer::setMuted(bool mute) +{ + if (!m_working) + return; + m_player1->setMuted(mute); + m_player2->setMuted(mute); +} + +bool GaplessAudioPlayer::isMuted() const +{ + return m_player1->isMuted() && m_player2->isMuted(); +} + +void GaplessAudioPlayer::play() +{ + if (!m_working) + return; + if (m_player1->state() != Phonon::PlayingState && m_player2->state() != Phonon::PlayingState) + startPlayer1(); +} + +void GaplessAudioPlayer::pause() +{ + if (!m_working) + return; + if (m_player1->state() != Phonon::PausedState) + m_player1->pause(); + if (m_player2->state() != Phonon::PausedState) + m_player2->pause(); +} + +void GaplessAudioPlayer::startPlayer1() +{ + m_player1->play(m_sound); +} + +void GaplessAudioPlayer::startPlayer2() +{ + m_player2->play(m_sound); +} + +/* --------------------------------------------------------------- */ + +void AudioPlayer::Sleeper::sleep(unsigned long secs) +{ + QThread::sleep(secs); +} + +void AudioPlayer::Sleeper::msleep(unsigned long msecs) +{ + QThread::msleep(msecs); +} + +void AudioPlayer::Sleeper::usleep(unsigned long usecs) +{ + QThread::usleep(usecs); +} -- cgit v1.2.3