Merge pull request #1512 from ctrlaltca/sound_themes

sound themes
This commit is contained in:
Zach 2015-09-13 15:37:00 -04:00
commit f97a7e8370
24 changed files with 239 additions and 123 deletions

View file

@ -137,14 +137,22 @@ set(COCKATRICE_LIBS)
# Qt4 stuff # Qt4 stuff
if(Qt4_FOUND) if(Qt4_FOUND)
if (NOT QT_QTMULTIMEDIA_FOUND)
FIND_PACKAGE(QtMobility REQUIRED)
endif()
SET(QT_USE_QTNETWORK TRUE) SET(QT_USE_QTNETWORK TRUE)
SET(QT_USE_QTMULTIMEDIA TRUE)
SET(QT_USE_QTSVG TRUE) SET(QT_USE_QTSVG TRUE)
# Include directories # Include directories
INCLUDE(${QT_USE_FILE}) INCLUDE(${QT_USE_FILE})
INCLUDE_DIRECTORIES(${QT_INCLUDES}) INCLUDE_DIRECTORIES(${QT_INCLUDES})
INCLUDE_DIRECTORIES(${QT_MOBILITY_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${QT_MOBILITY_MULTIMEDIAKIT_INCLUDE_DIR})
LIST(APPEND COCKATRICE_LIBS ${QT_LIBRARIES}) LIST(APPEND COCKATRICE_LIBS ${QT_LIBRARIES})
LIST(APPEND COCKATRICE_LIBS ${QT_QTMAIN_LIBRARY}) LIST(APPEND COCKATRICE_LIBS ${QT_QTMAIN_LIBRARY})
LIST(APPEND COCKATRICE_LIBS ${QT_MOBILITY_MULTIMEDIAKIT_LIBRARY})
# Let cmake chew Qt4's translations and resource files # Let cmake chew Qt4's translations and resource files
# Note: header files are MOC-ed automatically by cmake # Note: header files are MOC-ed automatically by cmake

View file

@ -638,12 +638,16 @@ SoundSettingsPage::SoundSettingsPage()
soundEnabledCheckBox.setChecked(settingsCache->getSoundEnabled()); soundEnabledCheckBox.setChecked(settingsCache->getSoundEnabled());
connect(&soundEnabledCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setSoundEnabled(int))); connect(&soundEnabledCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setSoundEnabled(int)));
soundPathEdit = new QLineEdit(settingsCache->getSoundPath()); QString themeName = settingsCache->getSoundThemeName();
soundPathEdit->setReadOnly(true);
QPushButton *soundPathClearButton = new QPushButton(QPixmap("theme:icons/delete"), QString()); QStringList themeDirs = soundEngine->getAvailableThemes().keys();
connect(soundPathClearButton, SIGNAL(clicked()), this, SLOT(soundPathClearButtonClicked())); for (int i = 0; i < themeDirs.size(); i++) {
QPushButton *soundPathButton = new QPushButton("..."); themeBox.addItem(themeDirs[i]);
connect(soundPathButton, SIGNAL(clicked()), this, SLOT(soundPathButtonClicked())); if (themeDirs[i] == themeName)
themeBox.setCurrentIndex(i);
}
connect(&themeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(themeBoxChanged(int)));
connect(&soundTestButton, SIGNAL(clicked()), soundEngine, SLOT(testSound())); connect(&soundTestButton, SIGNAL(clicked()), soundEngine, SLOT(testSound()));
masterVolumeSlider = new QSlider(Qt::Horizontal); masterVolumeSlider = new QSlider(Qt::Horizontal);
@ -655,8 +659,6 @@ SoundSettingsPage::SoundSettingsPage()
connect(masterVolumeSlider, SIGNAL(sliderReleased()), soundEngine, SLOT(testSound())); connect(masterVolumeSlider, SIGNAL(sliderReleased()), soundEngine, SLOT(testSound()));
connect(masterVolumeSlider, SIGNAL(valueChanged(int)), settingsCache, SLOT(setMasterVolume(int))); connect(masterVolumeSlider, SIGNAL(valueChanged(int)), settingsCache, SLOT(setMasterVolume(int)));
masterVolumeSpinBox = new QSpinBox(); masterVolumeSpinBox = new QSpinBox();
masterVolumeSpinBox->setMinimum(0); masterVolumeSpinBox->setMinimum(0);
masterVolumeSpinBox->setMaximum(100); masterVolumeSpinBox->setMaximum(100);
@ -670,14 +672,12 @@ SoundSettingsPage::SoundSettingsPage()
#endif #endif
QGridLayout *soundGrid = new QGridLayout; QGridLayout *soundGrid = new QGridLayout;
soundGrid->addWidget(&soundEnabledCheckBox, 0, 0, 1, 4); soundGrid->addWidget(&soundEnabledCheckBox, 0, 0, 1, 3);
soundGrid->addWidget(&masterVolumeLabel, 1, 0); soundGrid->addWidget(&masterVolumeLabel, 1, 0);
soundGrid->addWidget(masterVolumeSlider, 1, 1); soundGrid->addWidget(masterVolumeSlider, 1, 1);
soundGrid->addWidget(masterVolumeSpinBox, 1, 2); soundGrid->addWidget(masterVolumeSpinBox, 1, 2);
soundGrid->addWidget(&soundPathLabel, 2, 0); soundGrid->addWidget(&themeLabel, 2, 0);
soundGrid->addWidget(soundPathEdit, 2, 1); soundGrid->addWidget(&themeBox, 2, 1);
soundGrid->addWidget(soundPathClearButton, 2, 2);
soundGrid->addWidget(soundPathButton, 2, 3);
soundGrid->addWidget(&soundTestButton, 3, 1); soundGrid->addWidget(&soundTestButton, 3, 1);
soundGroupBox = new QGroupBox; soundGroupBox = new QGroupBox;
@ -689,29 +689,20 @@ SoundSettingsPage::SoundSettingsPage()
setLayout(mainLayout); setLayout(mainLayout);
} }
void SoundSettingsPage::themeBoxChanged(int index)
{
QStringList themeDirs = soundEngine->getAvailableThemes().keys();
if(index >= 0 && index < themeDirs.count())
settingsCache->setSoundThemeName(themeDirs.at(index));
}
void SoundSettingsPage::masterVolumeChanged(int value) { void SoundSettingsPage::masterVolumeChanged(int value) {
masterVolumeSlider->setToolTip(QString::number(value)); masterVolumeSlider->setToolTip(QString::number(value));
} }
void SoundSettingsPage::soundPathClearButtonClicked()
{
soundPathEdit->setText(QString());
settingsCache->setSoundPath(QString());
}
void SoundSettingsPage::soundPathButtonClicked()
{
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"));
if (path.isEmpty())
return;
soundPathEdit->setText(path);
settingsCache->setSoundPath(path);
}
void SoundSettingsPage::retranslateUi() { void SoundSettingsPage::retranslateUi() {
soundEnabledCheckBox.setText(tr("Enable &sounds")); soundEnabledCheckBox.setText(tr("Enable &sounds"));
soundPathLabel.setText(tr("Path to sounds directory:")); themeLabel.setText(tr("Current sounds theme:"));
soundTestButton.setText(tr("Test system sound engine")); soundTestButton.setText(tr("Test system sound engine"));
soundGroupBox->setTitle(tr("Sound settings")); soundGroupBox->setTitle(tr("Sound settings"));
#if QT_VERSION < 0x050000 #if QT_VERSION < 0x050000

View file

@ -174,20 +174,17 @@ public:
SoundSettingsPage(); SoundSettingsPage();
void retranslateUi(); void retranslateUi();
private: private:
QLabel themeLabel;
QComboBox themeBox;
QGroupBox *soundGroupBox; QGroupBox *soundGroupBox;
QPushButton soundTestButton; QPushButton soundTestButton;
QCheckBox soundEnabledCheckBox; QCheckBox soundEnabledCheckBox;
QLabel soundPathLabel;
QLineEdit *soundPathEdit;
QLabel masterVolumeLabel; QLabel masterVolumeLabel;
QSlider *masterVolumeSlider; QSlider *masterVolumeSlider;
QSpinBox *masterVolumeSpinBox; QSpinBox *masterVolumeSpinBox;
signals:
void soundPathChanged();
private slots: private slots:
void masterVolumeChanged(int value); void masterVolumeChanged(int value);
void soundPathClearButtonClicked(); void themeBoxChanged(int index);
void soundPathButtonClicked();
}; };
class DlgSettings : public QDialog { class DlgSettings : public QDialog {

View file

@ -190,20 +190,6 @@ int main(int argc, char *argv[])
qDebug() << "Could not create " + dataDir + "/customsets folder."; qDebug() << "Could not create " + dataDir + "/customsets folder.";
} }
if(settingsCache->getSoundPath().isEmpty() || !QDir(settingsCache->getSoundPath()).exists())
{
QDir tmpDir;
#ifdef Q_OS_MAC
tmpDir = app.applicationDirPath() + "/../Resources/sounds";
#elif defined(Q_OS_WIN)
tmpDir = app.applicationDirPath() + "/sounds";
#else // linux
tmpDir = app.applicationDirPath() + "/../share/cockatrice/sounds/";
#endif
settingsCache->setSoundPath(tmpDir.canonicalPath());
}
if (!settingsValid() || db->getLoadStatus() != Ok) { if (!settingsValid() || db->getLoadStatus() != Ok) {
qDebug("main(): invalid settings or load status"); qDebug("main(): invalid settings or load status");
DlgSettings dlgSettings; DlgSettings dlgSettings;

View file

@ -137,7 +137,6 @@ SettingsCache::SettingsCache()
setDeckPath(qApp->applicationDirPath() + "data/decks"); setDeckPath(qApp->applicationDirPath() + "data/decks");
setReplaysPath(qApp->applicationDirPath() +"data/replays"); setReplaysPath(qApp->applicationDirPath() +"data/replays");
setPicsPath(qApp->applicationDirPath() + "data/pics"); setPicsPath(qApp->applicationDirPath() + "data/pics");
setSoundPath(qApp->applicationDirPath() +"data/sounds");
#endif #endif
notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool(); notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool();
@ -198,7 +197,7 @@ SettingsCache::SettingsCache()
zoneViewPileView = settings->value("zoneview/pileview", true).toBool(); zoneViewPileView = settings->value("zoneview/pileview", true).toBool();
soundEnabled = settings->value("sound/enabled", false).toBool(); soundEnabled = settings->value("sound/enabled", false).toBool();
soundPath = settings->value("sound/path").toString(); soundThemeName = settings->value("sound/theme").toString();
priceTagFeature = settings->value("deckeditor/pricetags", false).toBool(); priceTagFeature = settings->value("deckeditor/pricetags", false).toBool();
priceTagSource = settings->value("deckeditor/pricetagsource", 0).toInt(); priceTagSource = settings->value("deckeditor/pricetagsource", 0).toInt();
@ -482,11 +481,11 @@ void SettingsCache::setSoundEnabled(int _soundEnabled)
emit soundEnabledChanged(); emit soundEnabledChanged();
} }
void SettingsCache::setSoundPath(const QString &_soundPath) void SettingsCache::setSoundThemeName(const QString &_soundThemeName)
{ {
soundPath = _soundPath; soundThemeName = _soundThemeName;
settings->setValue("sound/path", soundPath); settings->setValue("sound/theme", soundThemeName);
emit soundPathChanged(); emit soundThemeChanged();
} }
void SettingsCache::setPriceTagFeature(int _priceTagFeature) void SettingsCache::setPriceTagFeature(int _priceTagFeature)

View file

@ -39,7 +39,7 @@ signals:
void invertVerticalCoordinateChanged(); void invertVerticalCoordinateChanged();
void minPlayersForMultiColumnLayoutChanged(); void minPlayersForMultiColumnLayoutChanged();
void soundEnabledChanged(); void soundEnabledChanged();
void soundPathChanged(); void soundThemeChanged();
void priceTagFeatureChanged(int enabled); void priceTagFeatureChanged(int enabled);
void ignoreUnregisteredUsersChanged(); void ignoreUnregisteredUsersChanged();
void ignoreUnregisteredUserMessagesChanged(); void ignoreUnregisteredUserMessagesChanged();
@ -81,7 +81,7 @@ private:
bool chatHighlightForeground; bool chatHighlightForeground;
bool zoneViewSortByName, zoneViewSortByType, zoneViewPileView; bool zoneViewSortByName, zoneViewSortByType, zoneViewPileView;
bool soundEnabled; bool soundEnabled;
QString soundPath; QString soundThemeName;
bool priceTagFeature; bool priceTagFeature;
int priceTagSource; int priceTagSource;
bool ignoreUnregisteredUsers; bool ignoreUnregisteredUsers;
@ -153,7 +153,7 @@ public:
*/ */
bool getZoneViewPileView() const { return zoneViewPileView; } bool getZoneViewPileView() const { return zoneViewPileView; }
bool getSoundEnabled() const { return soundEnabled; } bool getSoundEnabled() const { return soundEnabled; }
QString getSoundPath() const { return soundPath; } QString getSoundThemeName() const { return soundThemeName; }
bool getPriceTagFeature() const { return false; /* #859; priceTagFeature;*/ } bool getPriceTagFeature() const { return false; /* #859; priceTagFeature;*/ }
int getPriceTagSource() const { return priceTagSource; } int getPriceTagSource() const { return priceTagSource; }
bool getIgnoreUnregisteredUsers() const { return ignoreUnregisteredUsers; } bool getIgnoreUnregisteredUsers() const { return ignoreUnregisteredUsers; }
@ -223,7 +223,7 @@ public slots:
void setZoneViewSortByType(int _zoneViewSortByType); void setZoneViewSortByType(int _zoneViewSortByType);
void setZoneViewPileView(int _zoneViewPileView); void setZoneViewPileView(int _zoneViewPileView);
void setSoundEnabled(int _soundEnabled); void setSoundEnabled(int _soundEnabled);
void setSoundPath(const QString &_soundPath); void setSoundThemeName(const QString &_soundThemeName);
void setPriceTagFeature(int _priceTagFeature); void setPriceTagFeature(int _priceTagFeature);
void setPriceTagSource(int _priceTagSource); void setPriceTagSource(int _priceTagSource);
void setIgnoreUnregisteredUsers(int _ignoreUnregisteredUsers); void setIgnoreUnregisteredUsers(int _ignoreUnregisteredUsers);

View file

@ -1,11 +1,164 @@
#include "soundengine.h" #include "soundengine.h"
#include "settingscache.h" #include "settingscache.h"
#include <QApplication>
#include <QAudioOutput>
#include <QBuffer>
#include <QDebug>
#include <QFileInfo> #include <QFileInfo>
#include <QSound> #include <QLibraryInfo>
#if QT_VERSION < 0x050000
#include <QDesktopServices>
#else
#include <QStandardPaths>
#endif
/* #define DEFAULT_THEME_NAME "Default"
fileNames = QStringList() #define TEST_SOUND_FILENAME "player_join"
SoundEngine::SoundEngine(QObject *parent)
: QObject(parent), player(0)
{
inputBuffer = new QBuffer(this);
ensureThemeDirectoryExists();
connect(settingsCache, SIGNAL(soundThemeChanged()), this, SLOT(themeChangedSlot()));
connect(settingsCache, SIGNAL(soundEnabledChanged()), this, SLOT(soundEnabledChanged()));
soundEnabledChanged();
themeChangedSlot();
}
SoundEngine::~SoundEngine()
{
if(player)
{
player->deleteLater();
player = 0;
}
inputBuffer->deleteLater();
}
void SoundEngine::soundEnabledChanged()
{
if (settingsCache->getSoundEnabled()) {
qDebug("SoundEngine: enabling sound");
if(!player)
{
QAudioFormat format;
#if QT_VERSION < 0x050000
format.setFrequency(44100);
format.setChannels(1);
#else
format.setSampleRate(44100);
format.setChannelCount(1);
#endif
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
player = new QAudioOutput(format, this);
}
} else {
qDebug("SoundEngine: disabling sound");
if(player)
{
player->stop();
player->deleteLater();
player = 0;
}
}
}
void SoundEngine::playSound(QString fileName)
{
if(!player)
return;
// still playing the previous sound?
if(player->state() == QAudio::ActiveState)
return;
if(!audioData.contains(fileName))
return;
qDebug() << "playing" << fileName;
inputBuffer->close();
inputBuffer->setData(audioData[fileName]);
inputBuffer->open(QIODevice::ReadOnly);
#if QT_VERSION >= 0x050000
player->setVolume(settingsCache->getMasterVolume());
#endif
player->stop();
player->start(inputBuffer);
}
void SoundEngine::testSound()
{
playSound(TEST_SOUND_FILENAME);
}
void SoundEngine::ensureThemeDirectoryExists()
{
if(settingsCache->getSoundThemeName().isEmpty() ||
!getAvailableThemes().contains(settingsCache->getSoundThemeName()))
{
qDebug() << "Sounds theme name not set, setting default value";
settingsCache->setSoundThemeName(DEFAULT_THEME_NAME);
}
}
QStringMap & SoundEngine::getAvailableThemes()
{
QDir dir;
availableThemes.clear();
// load themes from user profile dir
dir =
#ifdef PORTABLE_BUILD
qApp->applicationDirPath() +
#elif QT_VERSION < 0x050000
QDesktopServices::storageLocation(QDesktopServices::DataLocation) +
#else
QStandardPaths::standardLocations(QStandardPaths::DataLocation).first() +
#endif
"/sounds";
foreach(QString themeName, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name))
{
if(!availableThemes.contains(themeName))
availableThemes.insert(themeName, dir.absoluteFilePath(themeName));
}
// load themes from cockatrice system dir
#ifdef Q_OS_MAC
dir = qApp->applicationDirPath() + "/../Resources/sounds";
#elif defined(Q_OS_WIN)
dir = qApp->applicationDirPath() + "/sounds";
#else // linux
dir = qApp->applicationDirPath() + "/../share/cockatrice/sounds";
#endif
foreach(QString themeName, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name))
{
if(!availableThemes.contains(themeName))
availableThemes.insert(themeName, dir.absoluteFilePath(themeName));
}
return availableThemes;
}
void SoundEngine::themeChangedSlot()
{
QString themeName = settingsCache->getSoundThemeName();
qDebug() << "Sound theme changed:" << themeName;
QDir dir = getAvailableThemes().value(themeName);
audioData.clear();
static const QStringList fileNames = QStringList()
// Phases // Phases
<< "untap_step" << "upkeep_step" << "draw_step" << "main_1" << "untap_step" << "upkeep_step" << "draw_step" << "main_1"
<< "start_combat" << "attack_step" << "block_step" << "damage_step" << "end_combat" << "start_combat" << "attack_step" << "block_step" << "damage_step" << "end_combat"
@ -18,56 +171,19 @@
// Spectator // Spectator
<< "spectator_join" << "spectator_leave" << "spectator_join" << "spectator_leave"
// Chat & UI // Chat & UI
<< "chat_mention" << "all_mention" << "private_message"; << "chat_mention" << "all_mention" << "private_message"
*/ << "end_step" << "tap" << "player_joined" << "attack";
#define TEST_SOUND_FILENAME "player_join" for (int i = 0; i < fileNames.size(); ++i) {
if(!dir.exists(fileNames[i] + ".wav"))
continue;
SoundEngine::SoundEngine(QObject *parent) QFile file(dir.filePath(fileNames[i] + ".wav"));
: QObject(parent), enabled(false) file.open(QIODevice::ReadOnly);
{ // 44 = length of wav header
connect(settingsCache, SIGNAL(soundEnabledChanged()), this, SLOT(soundEnabledChanged())); audioData.insert(fileNames[i], file.readAll().mid(44));
file.close();
}
soundEnabledChanged(); soundEnabledChanged();
}
void SoundEngine::soundEnabledChanged()
{
if (settingsCache->getSoundEnabled()) {
#if QT_VERSION < 0x050000 //QT4
if(QSound::isAvailable())
{
qDebug("SoundEngine: enabling sound");
enabled = true;
} else {
qDebug("SoundEngine: sound not available");
enabled = false;
}
#else
qDebug("SoundEngine: enabling sound");
enabled = true;
#endif
} else {
qDebug("SoundEngine: disabling sound");
enabled = false;
}
}
#include <QDebug>
void SoundEngine::playSound(QString fileName)
{
if(!enabled)
return;
QFileInfo fi(settingsCache->getSoundPath() + "/" + fileName + ".wav");
qDebug() << "playing" << fi.absoluteFilePath();
if(!fi.exists())
return;
QSound::play(fi.absoluteFilePath());
}
void SoundEngine::testSound()
{
playSound(TEST_SOUND_FILENAME);
} }

View file

@ -2,16 +2,32 @@
#define SOUNDENGINE_H #define SOUNDENGINE_H
#include <QObject> #include <QObject>
#include <QMap>
#include <QDir>
#include <QString>
class QAudioOutput;
class QBuffer;
typedef QMap<QString, QString> QStringMap;
class SoundEngine : public QObject { class SoundEngine : public QObject {
Q_OBJECT Q_OBJECT
private:
bool enabled;
private slots:
void soundEnabledChanged();
public: public:
SoundEngine(QObject *parent = 0); SoundEngine(QObject *parent = 0);
~SoundEngine();
void playSound(QString fileName); void playSound(QString fileName);
QStringMap &getAvailableThemes();
private:
QMap<QString, QByteArray> audioData;
QBuffer *inputBuffer;
QAudioOutput * player;
QStringMap availableThemes;
protected:
void ensureThemeDirectoryExists();
private slots:
void soundEnabledChanged();
void themeChangedSlot();
public slots: public slots:
void testSound(); void testSound();
}; };

View file

@ -1,16 +1,19 @@
# CMakeLists for sounds/ directory # CMakeLists for sounds directory
# #
# Installs default sound files # add sounds subfolders
FILE(GLOB sounds "${CMAKE_CURRENT_SOURCE_DIR}/*.wav") SET(defsounds
Default
Legacy
)
if(UNIX) if(UNIX)
if(APPLE) if(APPLE)
INSTALL(FILES ${sounds} DESTINATION cockatrice.app/Contents/Resources/sounds/) INSTALL(DIRECTORY ${defsounds} DESTINATION cockatrice.app/Contents/Resources/sounds/)
else() else()
# Assume linux # Assume linux
INSTALL(FILES ${sounds} DESTINATION share/cockatrice/sounds/) INSTALL(DIRECTORY ${defsounds} DESTINATION share/cockatrice/sounds/)
endif() endif()
elseif(WIN32) elseif(WIN32)
INSTALL(FILES ${sounds} DESTINATION sounds/) INSTALL(DIRECTORY ${defsounds} DESTINATION sounds/)
endif() endif()

Binary file not shown.

Binary file not shown.

BIN
sounds/Legacy/draw_step.wav Normal file

Binary file not shown.

BIN
sounds/Legacy/play_card.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sounds/Legacy/shuffle.wav Normal file

Binary file not shown.

BIN
sounds/Legacy/tap_card.wav Normal file

Binary file not shown.

Binary file not shown.

View file

@ -10,7 +10,7 @@ if [[ $TRAVIS_OS_NAME == "osx" ]] ; then
else else
if (( QT4 )); then if (( QT4 )); then
sudo apt-get update -qq sudo apt-get update -qq
sudo apt-get install -y libprotobuf-dev protobuf-compiler libqt4-dev sudo apt-get install -y qtmobility-dev libprotobuf-dev protobuf-compiler libqt4-dev
else else
sudo add-apt-repository -y ppa:beineri/opt-qt521 sudo add-apt-repository -y ppa:beineri/opt-qt521
sudo add-apt-repository -y ppa:kalakris/cmake sudo add-apt-repository -y ppa:kalakris/cmake