From d0eafb0124a39eeda6c00595a943ce9811d589c4 Mon Sep 17 00:00:00 2001 From: manuel Date: Sun, 10 Apr 2011 20:50:54 +0200 Subject: major audio rewrite --- pacman-c++/audio.cpp | 262 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 pacman-c++/audio.cpp (limited to 'pacman-c++/audio.cpp') diff --git a/pacman-c++/audio.cpp b/pacman-c++/audio.cpp new file mode 100644 index 0000000..0692cd1 --- /dev/null +++ b/pacman-c++/audio.cpp @@ -0,0 +1,262 @@ +#include "audio.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) +{ +#ifndef SERVER + preload(); + + AudioPlayer *firstplayer = new AudioPlayer(this); + firstplayer->test(m_sounds[Sound::WakaWaka]); + m_working = firstplayer->m_working; + m_players.append(firstplayer); + + m_muted = false; +#endif // SERVER +} + +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; + + qDebug() << "mute"; + 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; + qDebug() << "pause"; + for(int i = 0; i < m_players.count(); ++i) + m_players.at(i)->pause(); +} + +void AudioManager::stop() +{ + if (!isWorking()) + return; + qDebug() << "stop"; + for(int i = 0; i < m_players.count(); ++i) + m_players.at(i)->stop(); +} + +void AudioManager::clear() +{ + if (!isWorking()) + return; + qDebug() << "clear"; + 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) +{ + if (!isWorking()) + { + emit audioPlayer()->finished(); + return; + } + + qDebug() << "play"; + AudioPlayer *player = audioPlayer(); + player->setCurrentSource(Phonon::MediaSource(m_sounds[sound])); + player->play(); +} + +void AudioManager::enqueue(Sound::Type sound) +{ + if (!isWorking()) + return; + qDebug() << "manager enqueue"; + 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_output = new Phonon::AudioOutput(Phonon::MusicCategory, this); + Phonon::createPath(this, m_output); + m_working = AudioManager::m_working; +} + +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)); +} + +/* 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::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) + qDebug() << "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)); +} + +/* --------------------------------------------------------------- */ + +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