From eb96c8b75b48ce1580408d9971fad1ebee3734c3 Mon Sep 17 00:00:00 2001 From: Thomas Frauendorfer Date: Sun, 12 Oct 2008 22:47:55 +0200 Subject: [PATCH] OTHER: make balance slider work Implemented balance handling and moved volume slider handling to lib/xplayback.cpp --- lib/xplayback.cpp | 155 +++++++++++++++++++++++++++++++++ lib/xplayback.h | 17 ++++ src/XMMSHandler.cpp | 69 +-------------- src/XMMSHandler.h | 14 --- src/mainwindow/maindisplay.cpp | 29 +++--- src/mainwindow/maindisplay.h | 2 - 6 files changed, 184 insertions(+), 102 deletions(-) diff --git a/lib/xplayback.cpp b/lib/xplayback.cpp index b523df0..01ff31c 100644 --- a/lib/xplayback.cpp +++ b/lib/xplayback.cpp @@ -22,10 +22,17 @@ #include #include +#include + +#include + XPlayback::XPlayback (XClient *client) { m_client = client; + m_volume = 0; + m_balance = 0; + connect (client, SIGNAL (gotConnection (XClient *)), this, SLOT (on_connect (XClient *))); @@ -41,6 +48,11 @@ XPlayback::on_connect (XClient *client) (Xmms::bind (&XPlayback::playback_status, this)); client->playback ()->broadcastStatus () (Xmms::bind (&XPlayback::playback_status, this)); + + client->playback ()->volumeGet () + (Xmms::bind (&XPlayback::volume_changed, this)); + client->playback ()->broadcastVolumeChanged () + (Xmms::bind (&XPlayback::volume_changed, this)); } void @@ -136,3 +148,146 @@ XPlayback::playback_status (const Xmms::Playback::Status &status) return true; } +/* + * Volume + */ +inline int +calcBalance (int left, int right) +{ + if (left == right) + return 0; + if (left == 0) + return MAX_BALANCE; + if (right == 0) + return -MAX_BALANCE; + + //FIXME: This somehow works, but I'm not happy with it as + // QStyle::sliderValueFromPosition is not intended for this + if (left > right) + return -QStyle::sliderValueFromPosition(0, MAX_BALANCE, right, left, true); + else + return QStyle::sliderValueFromPosition(0, MAX_BALANCE, left, right, true); +} + +bool +XPlayback::volume_changed (const Xmms::Dict &volDict) +{ + QHash levels = XClient::convert_dict (volDict); + + if (levels.size () == 1) { + m_onechannel = true; + newVolume (levels.values ().first ().toInt ()); + newBalance (0); + } else { + /* + * I might add a configure option later, to map arbitrary keys to + * left and right + */ + if (!levels.contains ("left") || !levels.contains ("right")) { + qWarning () << "Could not get volume levels, dict contains keys: " + << levels.keys (); + // disable further updates. Otherwise we would spam the console + return false; + } + int left = levels["left"].toInt (); + int right = levels["right"].toInt (); + newVolume (qMax (right, left)); + newBalance (calcBalance (left, right)); + } + + + return true; +} + +void +XPlayback::newVolume (int new_volume) +{ + // only emit signal if the volume really changed + if (new_volume == m_volume) + return; + + m_volume = new_volume; + emit volumeChanged (new_volume); +} + +void +XPlayback::newBalance (int new_balance) +{ + // only emit signal if balance really changed + if (new_balance == m_balance) + return; + + m_balance = new_balance; + emit balanceChanged (new_balance); +} + + +int +calcVolume (int volume, int balance) +{ + balance = qAbs (balance); + if (balance > MAX_BALANCE) { + qWarning () << "Error in calculating balance, value " << balance + << "is outside valid range"; + return 0; + } + + if (balance == 0) + return volume; + if (balance == MAX_BALANCE) + return 0; + + //FIXME: this somehow works, but I'm not happy with it as + // QStyle::sliderPositionFromValue is not intended for this + return QStyle::sliderPositionFromValue(0, MAX_BALANCE, balance, volume, true); +} + +void +XPlayback::setVolume (int new_volume) +{ + // Don't echo values the server sent us back to it + if (m_volume == new_volume) + return; + + //TODO: some error checking + if (m_onechannel) { + m_client->playback ()->volumeSet ("master", new_volume); + } else { + int right, left; + if (m_balance < 0) { + left = new_volume; + right = calcVolume (new_volume, m_balance); + } else { + left = calcVolume (new_volume, m_balance); + right = new_volume; + } + m_client->playback ()->volumeSet ("left", left); + m_client->playback ()->volumeSet ("right", right); + } + + m_volume = new_volume; +} + +void +XPlayback::setBalance (int new_balance) +{ + // Don't echo values the server sent back to the server + if ((m_balance == new_balance) || m_onechannel) + return; + + if (new_balance < 0) { + if (m_balance > 0) { + m_client->playback ()->volumeSet ("left", m_volume); + } + m_client->playback ()->volumeSet ("right", + calcVolume (m_volume, new_balance)); + } else { + if (m_balance < 0) { + m_client->playback ()->volumeSet ("right", m_volume); + } + m_client->playback ()->volumeSet ("left", + calcVolume (m_volume, new_balance)); + } + + m_balance = new_balance; +} diff --git a/lib/xplayback.h b/lib/xplayback.h index be0b89d..279b1ae 100644 --- a/lib/xplayback.h +++ b/lib/xplayback.h @@ -22,6 +22,7 @@ class XClient; #include #include +static const int MAX_BALANCE = 20; /** * @class XPlayback @@ -34,6 +35,9 @@ class XPlayback : public QObject { public: XPlayback (XClient *); + int getVolume () {return m_volume;} + int getBalance () {return m_balance;} + public slots: void play (); void pause (); @@ -46,16 +50,29 @@ class XPlayback : public QObject { void seekMs (uint milliseconds); void seekMsRel (int milliseconds); + void setVolume (int new_volume); + void setBalance (int new_balance); + + // callbacks for clientlib bool playback_status (const Xmms::Playback::Status &status); + bool volume_changed (const Xmms::Dict &volDict); void on_connect (XClient *); signals: void playbackStatusChanged (Xmms::Playback::Status status); + void volumeChanged (int volume); + void balanceChanged (int balance); private: XClient *m_client; Xmms::Playback::Status m_status; + + void newVolume (int new_volume); + void newBalance (int new_balance); + int m_volume; + int m_balance; + bool m_onechannel; }; #endif diff --git a/src/XMMSHandler.cpp b/src/XMMSHandler.cpp index 0286d88..b058d54 100644 --- a/src/XMMSHandler.cpp +++ b/src/XMMSHandler.cpp @@ -61,8 +61,8 @@ XMMSHandler::connect_handler (const char *ipcpath, const bool &sync, QWidget *pa connect(ipcpath, sync, parent); using Xmms::bind; - m_client->playback.broadcastVolumeChanged () ( - bind (&XMMSHandler::volume_changed, this)); +// m_client->playback.broadcastVolumeChanged () ( +// bind (&XMMSHandler::volume_changed, this)); return true; } @@ -132,68 +132,3 @@ XMMSHandler::medialib_select (XMMSResultDictList *res) } */ -bool -XMMSHandler::volume_error (const std::string &error) -{ - qWarning ("couldn't get volume levels!"); - return false; -} - -void -XMMSHandler::volumeGet () -{ - m_client->playback.volumeGet () (Xmms::bind (&XMMSHandler::volume_get, this), - Xmms::bind (&XMMSHandler::volume_error, this)); -} - -void -XMMSHandler::volumeSet (uint volume) -{ - if(m_masterchan) - { - m_client->playback.volumeSet ("master", volume) (); - } - else - { - m_client->playback.volumeSet ("left", volume) (); - m_client->playback.volumeSet ("right", volume) (); - } -} - -bool -XMMSHandler::volume_changed (const Xmms::Dict &levels) -{ - volume_get (levels); - return true; -} - -bool -XMMSHandler::volume_get (const Xmms::Dict &levels) -{ - QHash hash; - levels.each (boost::bind (&XMMSHandler::DictToQHash, this, - _1, _2, boost::ref (hash))); - QList Values = hash.values(); - QListIterator vol (Values); - - uint right = atol (vol.next().toAscii()); - if(vol.hasNext()) - { - uint left = atol (vol.next().toAscii()); - - if(left > right) - emit getVolume (left); - else - emit getVolume (right); - - m_masterchan = false; - } - else - { - emit getVolume (right); - m_masterchan = true; - } - return false; - -} - diff --git a/src/XMMSHandler.h b/src/XMMSHandler.h index f7446b3..0e28b16 100644 --- a/src/XMMSHandler.h +++ b/src/XMMSHandler.h @@ -36,22 +36,16 @@ class XMMSHandler : public XClient { bool connect_handler (const char *ipcpath = NULL, const bool &sync = false, QWidget *parent = NULL); - bool volume_changed (const Xmms::Dict &levels); - void playlistAddURL (const QString& url); /* void medialib_select (XMMSResultDictList *res); - - */ /* uint medialibQuery (QString); void medialibQueryAdd (QString q) { delete m_xmmsc->medialib_add_to_playlist (q.toUtf8 ()); } */ - void volumeGet (); - //const XMMSClient *getXMMS () { return m_xmmsc; } void updateSettings () { emit settingsSaved (); } @@ -60,15 +54,11 @@ class XMMSHandler : public XClient { PlaylistModel *getPlaylistModel () {return m_playlist_model; } - public slots: - void volumeSet (uint volume); - signals: void settingsSaved (); /* void medialibResponse (uint, const QList > &); */ - void getVolume (uint); private: void DictToQHash (const std::string &key, @@ -79,12 +69,8 @@ class XMMSHandler : public XClient { // const std::string &source, // QHash &hash); - bool volume_get (const Xmms::Dict &levels); - bool volume_error (const std::string &error); - XmmsQT4 *m_qt4; PlaylistModel *m_playlist_model; - bool m_masterchan; }; #endif diff --git a/src/mainwindow/maindisplay.cpp b/src/mainwindow/maindisplay.cpp index b3fc0b7..147fc33 100644 --- a/src/mainwindow/maindisplay.cpp +++ b/src/mainwindow/maindisplay.cpp @@ -96,13 +96,21 @@ MainDisplay::MainDisplay (QWidget *parent) : SkinDisplay(parent) m_vslider->setSliderOffset (QPoint (0, 1)); m_vslider->resize (skin->getSize (Skin::SLIDER_VOLUMEBAR_BGS)); m_vslider->move (skin->getPos (Skin::SLIDER_VOLUMEBAR_BGS)); + connect (client.xplayback (), SIGNAL (volumeChanged (int)), + m_vslider, SLOT (setValue (int))); + connect (m_vslider, SIGNAL (sliderMoved (int)), + client.xplayback (), SLOT (setVolume (int))); m_bslider = new PixmapSlider (this); - m_bslider->setMinimum (-20); - m_bslider->setMaximum (20); + m_bslider->setMinimum (-MAX_BALANCE); + m_bslider->setMaximum (MAX_BALANCE); m_bslider->setSliderOffset (QPoint (0, 1)); m_bslider->resize (skin->getSize (Skin::SLIDER_BALANCEBAR_BGS)); m_bslider->move (skin->getPos (Skin::SLIDER_BALANCEBAR_BGS)); + connect (client.xplayback (), SIGNAL (balanceChanged (int)), + m_bslider, SLOT (setValue (int))); + connect (m_bslider, SIGNAL (sliderMoved (int)), + client.xplayback (), SLOT (setBalance (int))); connect (client.cache (), SIGNAL (activeEntryChanged (QVariantHash)), this, SLOT (setMediainfo (const QVariantHash))); @@ -110,9 +118,6 @@ MainDisplay::MainDisplay (QWidget *parent) : SkinDisplay(parent) this, SLOT(setStatus(Xmms::Playback::Status))); connect (client.cache () , SIGNAL (playtime (uint32_t)), this, SLOT (setPlaytime (uint32_t))); - connect (&client, SIGNAL(getVolume(uint)), this, SLOT(updateVolume(uint))); - connect (m_vslider, SIGNAL(sliderMoved(int)), this, SLOT(setVolume(int))); - client.volumeGet(); setupServerConfig (); @@ -131,20 +136,6 @@ MainDisplay::handleDisconnected () qApp->quit (); } -void -MainDisplay::updateVolume (uint volume) -{ - m_vslider->setValue((int)volume); -} - -void -MainDisplay::setVolume (int volume) -{ - XMMSHandler &xmmsh = XMMSHandler::getInstance(); - xmmsh.volumeSet((uint)volume); -} - - void MainDisplay::setPixmaps (Skin *skin) { diff --git a/src/mainwindow/maindisplay.h b/src/mainwindow/maindisplay.h index 77ad1f0..095c5f7 100644 --- a/src/mainwindow/maindisplay.h +++ b/src/mainwindow/maindisplay.h @@ -73,8 +73,6 @@ class MainDisplay : public SkinDisplay void setPlaytime (uint32_t time); // void setMediainfo (const Xmms::PropDict &); void setMediainfo (const QVariantHash); - void updateVolume (uint volume); - void setVolume (int volume); protected slots: void serverConfigChanged (QString key, QString value);