diff --git a/INSTALL.md b/INSTALL.md index e7be4dd..ea6f0af 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -3,7 +3,7 @@ You will need the following dependencies (Ubuntu, Debian): sudo apt-get update -qq - sudo apt-get install -y build-essential g++ qt5-default qt5-qmake qtmultimedia5-dev libqt5xmlpatterns5-dev libqt5svg5-dev qttools5-dev-tools + sudo apt-get install -y build-essential g++ qt5-default qt5-qmake qtmultimedia5-dev libqt5xmlpatterns5-dev libqt5svg5-dev qttools5-dev-tools libsfml-dev # Compiling on Linux diff --git a/docs/RELEASES b/docs/RELEASES index 506a352..1e90293 100644 --- a/docs/RELEASES +++ b/docs/RELEASES @@ -1,3 +1,11 @@ +0.9.7 - Switched to SFML/OpenAL for the audio engine. WAV, + OGG/Vorbis and FLAC sounds are currently supported. MP3 + is not yet supported due to licensing issues with the + underlying library, but I expect it to be implemented in + the near future now that the patents have expired. + + + 0.9.6 - Fixes following for users of the German-language client. Fix KOS check bug for some corps where there are partial @@ -397,3 +405,4 @@ Coming soon: - Don't cache every potential sound. - Add queue-play option to queue sounds. - Reload internal list when rules updated. +- Doublecheck windows file update hook diff --git a/src/audio.cpp b/src/audio.cpp index e34e58c..7616dd3 100755 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -21,7 +21,6 @@ #include "audio.h" #include "abstract_os.h" -//#include #include #include #include @@ -30,117 +29,144 @@ ImpAudio::ImpAudio(QObject *parent) : QObject(parent) { - cacheSounds(); } -void ImpAudio::cacheSounds() +bool ImpAudio::cacheEffect(const QString& fileName) { - QString path = appFilesPath() + "/audio/"; - - QDir audioDir(path); - audioDir.setFilter(QDir::Files); - - // Load up style combo - foreach(QFileInfo fileInfo, audioDir.entryInfoList()) + if(!buffers.contains(fileName)) { - if(fileInfo.fileName().endsWith(".dll")) - continue; + QString fullPath = appFilesPath() + "/audio/" + fileName; - QSoundEffect* effect = new QSoundEffect(this); - effect->setSource(QUrl::fromLocalFile(fileInfo.absoluteFilePath())); + qDebug() << " Sound not in buffer, caching" << fullPath; - if(!effects.contains(fileInfo.fileName())) - effects.insert(fileInfo.fileName(), effect); + if(!buffers[fileName].loadFromFile(fullPath.toStdString())) + return false; } + + return true; } -void ImpAudio::playLocalFile(const QString& fileName) +QVector::iterator ImpAudio::allocateSound(const QString& fileName) { - if(!effects.contains(fileName)) + QVector::iterator i = sounds.end(); + if(sounds.count() > 0) { - QString path = appFilesPath() + "/audio/" + fileName; - QSoundEffect* effect = new QSoundEffect(this); - effect->setSource(QUrl::fromLocalFile(path)); - effects.insert(fileName, effect); + for(i = sounds.begin(); i < sounds.end(); i++) + { + // Reuse a sound if a previous one is free + if((*i).getStatus() != sf::Sound::Playing) + { + qDebug() << " Reusing existing sf::Sound."; + (*i).setBuffer(buffers[fileName]); + break; + } + } } - effects[fileName]->setVolume(m_volume); - effects[fileName]->play(); + if(i == sounds.end()) + { + // No free sound in the set, add a new one. + qDebug() << " Adding new sound to set."; + sounds.append(sf::Sound(buffers[fileName])); + + // Reinitialize iterator to point to last item in set. + i = sounds.end(); + --i; + } + + return i; +} + +void ImpAudio::changeAudio(AudioEngine ae) +{ + engine = ae; + qDebug() << "ImpAudio::changeAudio(" << ae << ")"; +} + +AudioEngine ImpAudio::getEngine() +{ + return engine; } void ImpAudio::playLocalFile(const QString& fileName, float volume) { - if(!effects.contains(fileName)) + switch(engine) { - QString path = appFilesPath() + "/audio/" + fileName; - QSoundEffect* effect = new QSoundEffect(this); - effect->setSource(QUrl::fromLocalFile(path)); - effects.insert(fileName, effect); + case AudioEngine::AE_Qt: + playLocalFileQt(fileName, volume); + break; + default: // case AudioEngine::AE_SFML: + playLocalFileSFML(fileName, volume); } - - effects[fileName]->setVolume(volume); - effects[fileName]->play(); } -/* -QSoundEffect* ImpAudio::oldPlayLocalFile(const QString& fileName) +void ImpAudio::playLocalFileSFML(const QString& fileName, float volume) { - QString path = appFilesPath() + "/audio/" + fileName; - - qDebug() << "ImpAudio::playLocalFile - Playing " << path; - + qDebug() << "ImpAudio::playLocalFileSFML(" << fileName << "," << volume << ")"; + if(!cacheEffect(fileName)) + { + qDebug() << " Caching failed for " << fileName; + return; + } - QSoundEffect* effect = new QSoundEffect(this); - effect->setSource(QUrl::fromLocalFile(path)); + qDebug() << " Setting buffer and playing."; + QVector::iterator i = allocateSound(fileName); + (*i).setVolume(volume * 100); + (*i).play(); +} - qDebug() << "ImpAudio::playLocalFile - Setting volume on effect to " << QString::number(volume, 'g', 2); - effect->setVolume(volume); - connect(effect, &QSoundEffect::playingChanged, this, &ImpAudio::playingChanged); - effect->play(); - qDebug() << "ImpAudio::playLocalFile - played " << &effect; - return effect; -} -*/ -void ImpAudio::playingChanged() +void ImpAudio::playLocalFileQt(const QString& fileName, float volume) { - QSoundEffect *s = qobject_cast (sender()); - if (!s->isPlaying()) + qDebug() << "ImpAudio::playLocalFileQt(" << fileName << "," << volume << ")"; + if(!effects.contains(fileName)) { - qDebug() << "ImpAudio::playingChanged - cleaning up " << &s; - s->deleteLater(); + QString path = appFilesPath() + "/audio/" + fileName; + QSoundEffect* effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(path)); + effects.insert(fileName, effect); } -} -void ImpAudio::setVolume(int i) -{ - // Docs said Qt supports logarithmic volume scale... - // but doesn't appear implemented. - -/* volume = QAudio::convertVolume(i / qreal(100.0), - QAudio::LogarithmicVolumeScale, - QAudio::LinearVolumeScale); -*/ - m_volume = i / qreal(100.0); - qDebug() << "Volume changed to " << QString::number(m_volume, 'g', 2); + effects[fileName]->setVolume(volume); + effects[fileName]->play(); } -void ImpAudio::playLocalMedia(const QString& fileName) +void ImpAudio::playLocalMedia(const QString& fileName, float volume) { QString path = appFilesPath() + "/audio/" + fileName; qDebug() << "Playing " << path; - player = new QMediaPlayer; - player->setMedia(QUrl::fromLocalFile(path)); - player->setVolume(50); - player->play(); + switch(engine) { + case AudioEngine::AE_Qt: + player = new QMediaPlayer; + player->setMedia(QUrl::fromLocalFile(path)); + player->setVolume(50); + player->play(); + break; + + default: + if (!music.openFromFile(path.toStdString())) + return; // error + + music.setVolume(volume*100); + music.play(); + break; + } } void ImpAudio::stopMusic() { - if(player != NULL && player->state() == player->PlayingState) - { - player->stop(); + switch(engine) { + case AudioEngine::AE_Qt: + if(player != NULL && player->state() == player->PlayingState) + { + player->stop(); + } + break; + + case AudioEngine::AE_SFML: + music.stop(); + break; } } diff --git a/src/audio.h b/src/audio.h index 83fb033..d98ae5d 100755 --- a/src/audio.h +++ b/src/audio.h @@ -22,9 +22,15 @@ #define IMPAUDIO_H #include +#include #include -#include -#include +#include +#include // Qt engine +#include // Qt engine +#include // SFML engine + +enum AudioEngine { AE_SFML, AE_Qt }; +Q_DECLARE_METATYPE(AudioEngine) class ImpAudio : public QObject { @@ -32,28 +38,38 @@ class ImpAudio : public QObject public: explicit ImpAudio(QObject *parent = 0); - void playLocalFile(const QString& fileName); - void playLocalFile(const QString& fileName, float volume); - - //QSoundEffect* oldPlayLocalFile(const QString& fileName); + AudioEngine getEngine(); - void playLocalMedia(const QString& fileName); + void playLocalMedia(const QString& fileName, float volume = 1.0); void stopMusic(); void setVolume(int i); - void cacheSounds(); - signals: public slots: - void playingChanged(); + //void playingChanged(); + void playLocalFile(const QString& fileName, float volume = 1.0); + void changeAudio(AudioEngine); private: + void playLocalFileSFML(const QString& fileName, float volume); + void playLocalFileQt(const QString& fileName, float volume); + + QVector::iterator allocateSound(const QString& fileName); + bool cacheEffect(const QString& fileName); + + AudioEngine engine = AudioEngine::AE_SFML; qreal m_volume = 1.0f; QMediaPlayer* player; QMap effects; + + // SFML sound structures + QMap buffers; + QVector sounds; + + sf::Music music; }; #endif // AUDIO_H diff --git a/src/imp.pro b/src/imp.pro index fdbd5ce..f1b0ffd 100644 --- a/src/imp.pro +++ b/src/imp.pro @@ -4,7 +4,8 @@ # #------------------------------------------------- -QT += core gui multimedia #opengl +QT += core gui #opengl +QT += multimedia # Qt audio engine QT += xml xmlpatterns svg widgets #greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -12,7 +13,7 @@ QT += xml xmlpatterns svg widgets TARGET = imp TEMPLATE = app -VERSION = 0.9.6 +VERSION = 0.9.6.1 QMAKE_TARGET_COMPANY = EternalDusk QMAKE_TARGET_DESCRIPTION = Eve Online Intelligence Management Program QMAKE_TARGET_COPYRIGHT = (c) Copyright 2016-2017 Jesse Litton @@ -22,6 +23,21 @@ DEFINES += VERSION=\\\"$VERSION\\\" include(../ThirdParty/QSimpleUpdater/QSimpleUpdater.pri) +win32 { + LIBS += -LC:/SFML/lib + + CONFIG(release, debug|release): LIBS += -lsfml-audio -lsfml-graphics -lsfml-main -lsfml-network -lsfml-window -lsfml-system + CONFIG(debug, debug|release): LIBS += -lsfml-audio-d -lsfml-graphics-d -lsfml-main-d -lsfml-network-d -lsfml-window-d -lsfml-system-d + + INCLUDEPATH += C:/SFML/include + DEPENDPATH += C:/SFML/include +} +unix { + CONFIG(release, debug|release): LIBS += -lsfml-audio -lsfml-graphics -lsfml-network -lsfml-window -lsfml-system + CONFIG(debug, debug|release): LIBS += -lsfml-audio -lsfml-graphics -lsfml-network -lsfml-window -lsfml-system + #CONFIG(debug, debug|release): LIBS += -lsfml-audio-d -lsfml-graphics-d -lsfml-network-d -lsfml-window-d -lsfml-system-d +} + SOURCES += \ main.cpp\ mainwindow.cpp \ diff --git a/src/info.cpp b/src/info.cpp index 8ad1876..4adab14 100755 --- a/src/info.cpp +++ b/src/info.cpp @@ -58,5 +58,5 @@ void Info::reject() void Info::startMusic(ImpAudio *audio) { m_audio = audio; - audio->playLocalMedia("info/1 dont kn0w.m4a"); + audio->playLocalMedia("info/1 dont kn0w.ogg", 0.6); } diff --git a/src/info.h b/src/info.h index 513b943..bffea4d 100755 --- a/src/info.h +++ b/src/info.h @@ -47,7 +47,7 @@ private slots: private: Ui::Info *ui; - QSoundEffect* music; + //QSoundEffect* music; ImpAudio* m_audio = NULL; }; diff --git a/src/logcatcher.cpp b/src/logcatcher.cpp index 9dac20b..70bcc96 100644 --- a/src/logcatcher.cpp +++ b/src/logcatcher.cpp @@ -47,7 +47,7 @@ void LogCatcher::setLogDir(QString logDir) lastSizes = new QMap; fallbackPollTimer = new QTimer(this); - fallbackPollTimer->setInterval(1000); + fallbackPollTimer->setInterval(pollerInterval); connect(fallbackPollTimer, &QTimer::timeout, this, &LogCatcher::fallbackPoller); fallbackPollTimer->start(); @@ -132,7 +132,6 @@ void LogCatcher::findCurrentLogs(const QString& dirName) // are in them. QString channelName = logNameRegEx.cap(1); - //if(m_options->getIntelChannels().contains(channelName)) if(!localChannels.contains(channelName)) { QMutableListIterator i(infoList); diff --git a/src/logcatcher.h b/src/logcatcher.h index feb4afc..f65a34f 100644 --- a/src/logcatcher.h +++ b/src/logcatcher.h @@ -43,7 +43,7 @@ * files. */ -#ifdef Q_OS_WIN32 // Q_OS_LINUX +#ifdef Q_OS_WIN32 #define USE_FALLBACK_POLLER #endif @@ -78,7 +78,7 @@ public slots: QTimer* fallbackPollTimer; QMap* fileSizes; QMap* lastSizes; - int pollerInterval; + int pollerInterval = 1000; bool rebuilding = false; bool firstPass = true; }; diff --git a/src/meta.h b/src/meta.h index 58453f7..4dedd6b 100644 --- a/src/meta.h +++ b/src/meta.h @@ -27,8 +27,8 @@ static const struct Version { Version(){} - QString release = "0.9.6"; //VERSION; - QString name = "Russian Cookie Monster"; + QString release = "0.9.6.1"; //VERSION; + QString name = "SFML OpenAL FML"; QString styleHeader1 = ""; QString styleFooter1 = ""; diff --git a/src/options.cpp b/src/options.cpp index b57da7b..d890e0c 100755 --- a/src/options.cpp +++ b/src/options.cpp @@ -42,8 +42,6 @@ Options::Options(QWidget *parent) : comboDelegate = new ComboDelegate(this); volumeDelegate = new VolumeDelegate(this); playDelegate = new PlayDelegate(this); - connect(playDelegate, &PlayDelegate::playSound, - this, &Options::testSound); rebuildAudioFileList(); rebuildStyleFileList(); @@ -246,6 +244,13 @@ void Options::loadSettings(QSettings& settings) QStringList dpList = settings.value("disabledPilots", QStringList()).toStringList(); m_disabledPilots = m_disabledPilots.fromList(dpList); + AudioEngine ae = settings.value("audioEngine", AudioEngine::AE_SFML).value(); + emit changeAudio(ae); + if(ae == AudioEngine::AE_Qt) + { + ui->radioAudioQt->setChecked(true); + } + ui->avatarBox->setValue(settings.value("avatarExpiration", 0).toInt()); ui->historySpinBox->setValue(settings.value("historyCount", 0).toInt()); @@ -265,11 +270,11 @@ void Options::loadSettings(QSettings& settings) ui->checkOldIntel->setChecked(settings.value("initOldIntel", true).toBool()); // Deprecated - remove after a few versions - _alarmDistance = settings.value("alarmDistance", 1).toInt(); +/* _alarmDistance = settings.value("alarmDistance", 1).toInt(); _volume = settings.value("volume", 100).toInt(); audio->setVolume(_volume); m_soundAlarm = settings.value("soundAlarm", "red-alert.wav").toString(); - +*/ // On Linux, you can just setCurrentText(), but there appears to be a Qt bug on Windows // such that it doesn't update the index. ui->essCombo->setCurrentIndex( @@ -588,7 +593,8 @@ void Options::saveSettings() //QSettings& settings) settings.setValue("smoothAutofollow", getSmoothAutofollow()); settings.setValue("essAndKos", getEssAndKos()); - //settings.setValue("soundAlarm", getSoundAlarm()); + settings.setValue("audioEngine", audio->getEngine()); + settings.setValue("soundStatus", getSoundStatus()); settings.setValue("soundIncomplete", getSoundIncompleteKos()); settings.setValue("soundIsKos", getSoundIsKos()); @@ -667,6 +673,11 @@ void Options::saveSettings() //QSettings& settings) void Options::setAudio(ImpAudio* impAudio) { audio = impAudio; + playDelegate->connect(playDelegate, &PlayDelegate::playSound, + audio, &ImpAudio::playLocalFile); + connect(this, &Options::changeAudio, + audio, &ImpAudio::changeAudio); + } int Options::getAvatarExpiration() @@ -1061,3 +1072,13 @@ const Alarm& Options::getAlarmForDistance(int distance) { return alarmModel->at(distance); } + +void Options::on_radioAudioQt_clicked() +{ + emit changeAudio(AudioEngine::AE_Qt); +} + +void Options::on_radioAudioSFML_clicked() +{ + emit changeAudio(AudioEngine::AE_SFML); +} diff --git a/src/options.h b/src/options.h index c58a36c..eb3c615 100755 --- a/src/options.h +++ b/src/options.h @@ -136,12 +136,15 @@ class Options : public QDialog void fontChanged(const QString& fontName, int fontSize); void styleChanged(const QString styleName); void okayPressed(); + void changeAudio(AudioEngine); + +public slots: + void testSound(const QString& soundFileName, float volume); protected: bool eventFilter(QObject *, QEvent *evt); private slots: - void testSound(const QString& soundFileName, float volume); void on_buttonBox_accepted(); void on_buttonBox_rejected(); void on_statusTestButton_clicked(); @@ -160,6 +163,8 @@ private slots: void on_buttonCheck_clicked(); void on_btnInsertProx_clicked(); void on_btnRemoveProx_clicked(); + void on_radioAudioQt_clicked(); + void on_radioAudioSFML_clicked(); private: Ui::Options *ui; diff --git a/src/options.ui b/src/options.ui index 3a2a32c..3c4024f 100755 --- a/src/options.ui +++ b/src/options.ui @@ -40,7 +40,7 @@ QTabWidget::Rounded - 0 + 8 @@ -1210,30 +1210,65 @@ - Updates + Advanced - + - - - - 0 - 0 - - - - Check for application updates at startup. - - - true - + + + Updates + + + + + + + 0 + 0 + + + + Check for application updates at startup. + + + true + + + + + + + Check Now + + + + - - - Check Now - + + + Audio Back-end + + + + + + SFML (OpenAL) + + + true + + + + + + + &Qt + + + + diff --git a/src/playdelegate.cpp b/src/playdelegate.cpp index 57c7820..086c322 100644 --- a/src/playdelegate.cpp +++ b/src/playdelegate.cpp @@ -21,6 +21,7 @@ #include "playdelegate.h" #include +#include #include PlayDelegate::PlayDelegate(QObject *parent) : QStyledItemDelegate(parent) @@ -35,7 +36,6 @@ void PlayDelegate::paint(QPainter *painter, QStyleOptionButton button; button.rect = option.rect; button.icon = QIcon(":/graphics/volume-icon.png"); - //button.text = "=^.^="; button.state = QStyle::State_Enabled; QApplication::style()->drawControl( QStyle::CE_PushButton, &button, painter); } @@ -50,6 +50,8 @@ void PlayDelegate::paint(QPainter *painter, QMouseEvent * e = (QMouseEvent *)event; if (option.rect.contains(e->x(),e->y())) { + qDebug() << "PlayDelegate signaling" << model->index(index.row(), 1).data(Qt::DisplayRole).toString() + << "@" << model->index(index.row(), 2).data(Qt::DisplayRole).toFloat(); emit playSound(model->index(index.row(), 1).data(Qt::DisplayRole).toString(), model->index(index.row(), 2).data(Qt::DisplayRole).toFloat()); return true; diff --git a/src/themecustomizer.ui b/src/themecustomizer.ui index 889db2d..12dddb5 100644 --- a/src/themecustomizer.ui +++ b/src/themecustomizer.ui @@ -53,7 +53,7 @@ false - 5 + 0 6 @@ -274,7 +274,7 @@ - + 0 @@ -974,7 +974,7 @@ 0 - -40 + 0 374 204 @@ -1242,7 +1242,7 @@ 0 - -40 + 0 374 204 @@ -1501,7 +1501,7 @@ 0 - -40 + 0 374 204