#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) 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)); } /* --------------------------------------------------------------- */ 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); }