diff options
| author | 2010-05-24 03:56:03 +0000 | |
|---|---|---|
| committer | 2010-05-24 03:56:03 +0000 | |
| commit | 9b215ef20624244d41078605e1ea3f8b892091f7 (patch) | |
| tree | 5051329962d6cc683b181bf776c66b69127c7d65 /src/modules/snd/libkvisnd.cpp | |
| parent | Tweak avatar selection a bit (diff) | |
| download | KVIrc-9b215ef20624244d41078605e1ea3f8b892091f7.tar.gz KVIrc-9b215ef20624244d41078605e1ea3f8b892091f7.tar.bz2 KVIrc-9b215ef20624244d41078605e1ea3f8b892091f7.zip | |
Kill some debug noise.
Fix painting of themed input editor under some styles (hm.. do we *REALLY* need to theme this ? under some themes it's ugly)
Some work on the sound module: fixes for the Oss+Audiofile and Phonon systems.
Add support for testing the sound system from the option dialog.
Add a basic jingle sound that can be used for the test above (maybe we could find something nicer and smaller ?)
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@4371 17fca916-40b9-46aa-a4ea-0a15b648b75c
Diffstat (limited to 'src/modules/snd/libkvisnd.cpp')
| -rw-r--r-- | src/modules/snd/libkvisnd.cpp | 240 |
1 files changed, 189 insertions, 51 deletions
diff --git a/src/modules/snd/libkvisnd.cpp b/src/modules/snd/libkvisnd.cpp index d7f53ecdd..0a4441239 100644 --- a/src/modules/snd/libkvisnd.cpp +++ b/src/modules/snd/libkvisnd.cpp @@ -40,7 +40,6 @@ #include <phonon/mediaobject.h> #include <phonon/mediasource.h> #include <phonon/path.h> - Phonon::MediaObject * g_pPhononPlayer=0; #include <QUrl> #endif //!COMPILE_PHONON_SUPPORT @@ -87,49 +86,85 @@ KviSoundPlayer::KviSoundPlayer() m_pThreadList = new KviPointerList<KviSoundThread>; m_pThreadList->setAutoDelete(true); - m_pSoundSystemDict = new KviPointerHashTable<QString,SoundSystemRoutine>(17,false); +#ifdef COMPILE_PHONON_SUPPORT + m_pPhononPlayer = NULL; +#endif //!COMPILE_PHONON_SUPPORT + + m_pLastUsedSoundPlayerEntry = NULL; + + m_pSoundSystemDict = new KviPointerHashTable<QString,KviSoundPlayerEntry>(17,false); m_pSoundSystemDict->setAutoDelete(true); + #ifdef COMPILE_PHONON_SUPPORT - m_pSoundSystemDict->insert("phonon",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playPhonon))); + m_pSoundSystemDict->insert("phonon",new KviSoundPlayerEntry(KVI_PTR2MEMBER(KviSoundPlayer::playPhonon),KVI_PTR2MEMBER(KviSoundPlayer::cleanupPhonon))); #endif //!COMPILE_PHONON_SUPPORT + #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - m_pSoundSystemDict->insert("winmm",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playWinmm))); + m_pSoundSystemDict->insert("winmm",new KviSoundPlayerEntry(KVI_PTR2MEMBER(KviSoundPlayer::playWinmm),KVI_PTR2MEMBER(KviSoundPlayer::cleanupWinmm))); #else //!COMPILE_ON_WINDOWS + #ifdef COMPILE_OSS_SUPPORT #ifdef COMPILE_AUDIOFILE_SUPPORT - m_pSoundSystemDict->insert("oss+audiofile",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playOssAudiofile))); + m_pSoundSystemDict->insert("oss+audiofile",new KviSoundPlayerEntry(KVI_PTR2MEMBER(KviSoundPlayer::playOssAudiofile),KVI_PTR2MEMBER(KviSoundPlayer::cleanupOssAudiofile))); #endif //COMPILE_AUDIOFILE_SUPPORT - m_pSoundSystemDict->insert("oss",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playOss))); + m_pSoundSystemDict->insert("oss",new KviSoundPlayerEntry(KVI_PTR2MEMBER(KviSoundPlayer::playOss),KVI_PTR2MEMBER(KviSoundPlayer::cleanupOss))); #endif //COMPILE_OSS_SUPPORT + #ifdef COMPILE_ESD_SUPPORT - m_pSoundSystemDict->insert("esd",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playEsd))); + m_pSoundSystemDict->insert("esd",new KviSoundPlayerEntry(KVI_PTR2MEMBER(KviSoundPlayer::playEsd),KVI_PTR2MEMBER(KviSoundPlayer::cleanupEsd))); #endif //COMPILE_ESD_SUPPORT -#endif //!COMPILE_ON_WINDOWS - if(QSound::isAvailable()) - m_pSoundSystemDict->insert("qt",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playQt))); +#endif //!COMPILE_ON_WINDOWS - m_pSoundSystemDict->insert("null",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playNull))); + m_pSoundSystemDict->insert("qt",new KviSoundPlayerEntry(KVI_PTR2MEMBER(KviSoundPlayer::playQt),KVI_PTR2MEMBER(KviSoundPlayer::cleanupQt))); + m_pSoundSystemDict->insert("null",new KviSoundPlayerEntry(KVI_PTR2MEMBER(KviSoundPlayer::playNull),KVI_PTR2MEMBER(KviSoundPlayer::cleanupNull))); } KviSoundPlayer::~KviSoundPlayer() { - m_pThreadList->setAutoDelete(false); - while(KviSoundThread * t = m_pThreadList->first())delete t; + if(m_pLastUsedSoundPlayerEntry) + cleanupAfterLastPlayerEntry(); + + stopAllSoundThreads(); delete m_pThreadList; + KviThreadManager::killPendingEvents(this); + delete m_pSoundSystemDict; #ifdef COMPILE_PHONON_SUPPORT - if(g_pPhononPlayer) - g_pPhononPlayer->deleteLater(); -#endif + if(m_pPhononPlayer) + delete m_pPhononPlayer; +#endif //COMPILE_PHONON_SUPPORT + g_pSoundPlayer = 0; } +void KviSoundPlayer::stopAllSoundThreads() +{ + // kill any running sound thread + m_pThreadList->setAutoDelete(false); + + while(KviSoundThread * t = m_pThreadList->first()) + delete t; + + m_pThreadList->setAutoDelete(true); +} + +void KviSoundPlayer::cleanupAfterLastPlayerEntry() +{ + stopAllSoundThreads(); + if(!m_pLastUsedSoundPlayerEntry) + return; + SoundSystemCleanupRoutine r = m_pLastUsedSoundPlayerEntry->cleanupRoutine(); + if(r) + (this->*r)(); + m_pLastUsedSoundPlayerEntry = NULL; +} + void KviSoundPlayer::getAvailableSoundSystems(QStringList *l) { - KviPointerHashTableIterator<QString,SoundSystemRoutine> it(*m_pSoundSystemDict); + KviPointerHashTableIterator<QString,KviSoundPlayerEntry> it(*m_pSoundSystemDict); while(it.current()) { l->append(it.currentKey()); @@ -139,7 +174,13 @@ void KviSoundPlayer::getAvailableSoundSystems(QStringList *l) bool KviSoundPlayer::havePlayingSounds() { - return (m_pThreadList->count() > 0); + if(m_pThreadList->count() > 0) + return true; +#ifdef COMPILE_PHONON_SUPPORT + if(m_pPhononPlayer->state() == Phonon::PlayingState) + return true; +#endif //COMPILE_PHONON_SUPPORT + return false; } void KviSoundPlayer::registerSoundThread(KviSoundThread * t) @@ -167,8 +208,9 @@ bool KviSoundPlayer::event(QEvent * e) void KviSoundPlayer::detectSoundSystem() { #ifdef COMPILE_PHONON_SUPPORT - if(!g_pPhononPlayer) g_pPhononPlayer= Phonon::createPlayer(Phonon::MusicCategory); - if(g_pPhononPlayer->state() != Phonon::ErrorState) + if(!m_pPhononPlayer) + m_pPhononPlayer = Phonon::createPlayer(Phonon::MusicCategory); + if(m_pPhononPlayer->state() != Phonon::ErrorState) { KVI_OPTION_STRING(KviOption_stringSoundSystem) = "phonon"; return; @@ -207,24 +249,52 @@ void KviSoundPlayer::detectSoundSystem() #ifdef COMPILE_PHONON_SUPPORT bool KviSoundPlayer::playPhonon(const QString &szFileName) { - if(isMuted()) return true; + if(isMuted()) + return true; + Phonon::MediaSource media(szFileName); - if(!g_pPhononPlayer) - g_pPhononPlayer= Phonon::createPlayer(Phonon::MusicCategory,media); - else g_pPhononPlayer->setCurrentSource(media); - if(g_pPhononPlayer->state()!=Phonon::ErrorState) - { - g_pPhononPlayer->play(); - } + + if(!m_pPhononPlayer) + m_pPhononPlayer = Phonon::createPlayer(Phonon::MusicCategory,media); + else + m_pPhononPlayer->setCurrentSource(media); + + if(m_pPhononPlayer->state() == Phonon::ErrorState) + { + QString szError = m_pPhononPlayer->errorString(); + if(szError.isEmpty()) + qDebug("Phonon player in error state: can't play media '%s'",szFileName.isEmpty() ? "" : szFileName.toUtf8().data()); + else + qDebug("Phonon player in error state: %s (can't play media '%s')",szError.toUtf8().data(),szFileName.isEmpty() ? "" : szFileName.toUtf8().data()); + + return false; + } + + m_pPhononPlayer->play(); + return true; } + +void KviSoundPlayer::cleanupPhonon() +{ + if(!m_pPhononPlayer) + return; + delete m_pPhononPlayer; // must be stopped + m_pPhononPlayer = NULL; +} #endif //!COMPILE_PHONON_SUPPORT + #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) bool KviSoundPlayer::playWinmm(const QString &szFileName) { sndPlaySound(szFileName.toLocal8Bit().data(),SND_ASYNC | SND_NODEFAULT); return true; } + + void KviSoundPlayer::cleanupWinmm() + { + // FIXME: how to stop playing on windows ? + } #else //!COMPILE_ON_WINDOWS #ifdef COMPILE_OSS_SUPPORT #ifdef COMPILE_AUDIOFILE_SUPPORT @@ -239,6 +309,10 @@ bool KviSoundPlayer::playPhonon(const QString &szFileName) } return true; } + + void KviSoundPlayer::cleanupOssAudiofile() + { + } #endif //COMPILE_AUDIOFILE_SUPPORT bool KviSoundPlayer::playOss(const QString &szFileName) { @@ -251,11 +325,16 @@ bool KviSoundPlayer::playPhonon(const QString &szFileName) } return true; } + + void KviSoundPlayer::cleanupOss() + { + } #endif //COMPILE_OSS_SUPPORT #ifdef COMPILE_ESD_SUPPORT bool KviSoundPlayer::playEsd(const QString &szFileName) { - if(isMuted()) return true; + if(isMuted()) + return true; KviEsdSoundThread * t = new KviEsdSoundThread(szFileName); if(!t->start()) { @@ -264,40 +343,75 @@ bool KviSoundPlayer::playPhonon(const QString &szFileName) } return true; } + + void KviSoundPlayer::cleanupEsd() + { + } #endif //COMPILE_ESD_SUPPORT #endif //!COMPILE_ON_WINDOWS bool KviSoundPlayer::playQt(const QString &szFileName) { - if(isMuted()) return true; + if(isMuted()) + return true; QSound::play(szFileName); return true; } +void KviSoundPlayer::cleanupQt() +{ + // how to stop Qt sounds ? +} + bool KviSoundPlayer::playNull(const QString &) { // null sound system return true; } +void KviSoundPlayer::cleanupNull() +{ +} + bool KviSoundPlayer::play(const QString &szFileName) { - if(isMuted()) return true; - SoundSystemRoutine * r = m_pSoundSystemDict->find(KVI_OPTION_STRING(KviOption_stringSoundSystem)); + if(isMuted()) + return true; - if(!r) + KviSoundPlayerEntry * e = m_pSoundSystemDict->find(KVI_OPTION_STRING(KviOption_stringSoundSystem)); + + if(!e) { - if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringSoundSystem),"unknown")) + if( + (!KVI_OPTION_STRING(KviOption_stringSoundSystem).isEmpty()) && + (!KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringSoundSystem),"unknown")) + ) { - detectSoundSystem(); - r = m_pSoundSystemDict->find(KVI_OPTION_STRING(KviOption_stringSoundSystem)); - if(!r)return false; - } else { - return false; + qDebug( + "Sound system '%s' is not valid, you may want to re-configure it in the options dialog...", + KVI_OPTION_STRING(KviOption_stringSoundSystem).toUtf8().data() + ); + return false; // detection already attempted (and failed?) } + + detectSoundSystem(); + e = m_pSoundSystemDict->find(KVI_OPTION_STRING(KviOption_stringSoundSystem)); + if(!e) + return false; + } + + if(e != m_pLastUsedSoundPlayerEntry) + { + // if the sound player changed, cleanup after the previous one + if(m_pLastUsedSoundPlayerEntry) + cleanupAfterLastPlayerEntry(); + m_pLastUsedSoundPlayerEntry = e; } - return (this->*(*r))(szFileName); + SoundSystemPlayRoutine r = e->playRoutine(); + Q_ASSERT(r); // MUST BE THERE + + return (this->*r)(szFileName); } @@ -306,13 +420,20 @@ KviSoundThread::KviSoundThread(const QString &szFileName) { g_pSoundPlayer->registerSoundThread(this); m_szFileName = szFileName; + m_bTerminate = false; } KviSoundThread::~KviSoundThread() { + m_bTerminate = true; // force a termination request (since the base class will wait()) g_pSoundPlayer->unregisterSoundThread(this); } +void KviSoundThread::terminate() +{ + m_bTerminate = true; +} + void KviSoundThread::play() { } @@ -372,7 +493,7 @@ void KviSoundThread::run() channelCount = afGetVirtualChannels(file, AF_DEFAULT_TRACK); buffer = kvi_malloc(int(BUFFER_FRAMES * frameSize)); - int audiofd_c = open("/dev/dsp", O_WRONLY | /*O_EXCL |*/ O_NDELAY); + int audiofd_c = open("/dev/dsp", O_WRONLY /*| O_EXCL | O_NDELAY*/); QFile audiofd; @@ -385,16 +506,18 @@ void KviSoundThread::run() audiofd.open(audiofd_c,QIODevice::WriteOnly); // ???? what the heck is this for ? - if (sampleWidth == 8) format = AFMT_U8; - else if (sampleWidth == 16)format = AFMT_S16_NE; + if (sampleWidth == 8) + format = AFMT_U8; + else if(sampleWidth == 16) + format = AFMT_S16_NE; - if (ioctl(audiofd.handle(),SNDCTL_DSP_SETFMT, &format) == -1) + if(ioctl(audiofd.handle(),SNDCTL_DSP_SETFMT, &format) == -1) { debug("Could not set format width to DSP! [OSS]"); goto exit_thread; } - if (ioctl(audiofd.handle(), SNDCTL_DSP_CHANNELS, &channelCount) == -1) + if (ioctl(audiofd.handle(),SNDCTL_DSP_CHANNELS, &channelCount) == -1) { debug("Could not set DSP channels! [OSS]"); goto exit_thread; @@ -409,7 +532,7 @@ void KviSoundThread::run() framesRead = afReadFrames(file, AF_DEFAULT_TRACK, buffer, BUFFER_FRAMES); - while(framesRead > 0) + while(!m_bTerminate && (framesRead > 0)) { audiofd.write((char *)buffer,(int)(framesRead * frameSize)); framesRead = afReadFrames(file, AF_DEFAULT_TRACK, buffer,BUFFER_FRAMES); @@ -437,6 +560,12 @@ void KviSoundThread::run() { #define OSS_BUFFER_SIZE 16384 + if(!m_szFileName.endsWith(QString(".au"))) + { + debug("Oss only player supports only *.au files"); + return; + } + QFile f(m_szFileName); int fd = -1; char buf[OSS_BUFFER_SIZE]; @@ -465,7 +594,7 @@ void KviSoundThread::run() iSize -= 24; - fd = open("/dev/audio", O_WRONLY | /*O_EXCL |*/ O_NDELAY); + fd = open("/dev/audio", O_WRONLY /* | O_EXCL | O_NDELAY*/); if(fd < 0) { debug("Could not open device file /dev/audio!"); @@ -474,7 +603,7 @@ void KviSoundThread::run() } - while(iSize > 0) + while(!m_bTerminate && (iSize > 0)) { int iCanRead = OSS_BUFFER_SIZE - iDataLen; if(iCanRead > 0) @@ -529,7 +658,7 @@ void KviSoundThread::run() void KviEsdSoundThread::play() { // ESD has a really nice API - if(!esd_play_file(NULL,m_szFileName.toUtf8().data(),1)) + if(!esd_play_file(NULL,m_szFileName.toUtf8().data(),1)) // this is sync.. FIXME: it can't be stopped! debug("Could not play sound %s! [ESD]",m_szFileName.toUtf8().data()); } @@ -569,13 +698,15 @@ static bool snd_kvs_cmd_play(KviKvsModuleCommandCall * c) KVSM_PARAMETERS_END(c) if(szFile.isEmpty() || (!KviFileUtils::fileExists(szFile))) { - if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("Sound file '%Q' not found"),&szFile); + if(!c->hasSwitch('q',"quiet")) + c->warning(__tr2qs("Sound file '%Q' not found"),&szFile); return true; } if(!g_pSoundPlayer->play(szFile)) { - if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("Unable to play sound '%Q'"),&szFile); + if(!c->hasSwitch('q',"quiet")) + c->warning(__tr2qs("Unable to play sound '%Q'"),&szFile); } return true; @@ -699,6 +830,13 @@ static bool snd_module_ctrl(KviModule *,const char * operation,void * param) g_pSoundPlayer->detectSoundSystem(); return true; } + if(kvi_strEqualCI(operation,"play")) + { + QString * pszFileName = (QString *)param; + if(pszFileName) + return g_pSoundPlayer->play(*pszFileName); + return false; + } return false; } |
