OTHER: make balance slider work

Implemented balance handling and moved volume slider handling to
lib/xplayback.cpp
This commit is contained in:
Thomas Frauendorfer 2008-10-12 22:47:55 +02:00
parent 096ac37121
commit eb96c8b75b
6 changed files with 184 additions and 102 deletions

View file

@ -22,10 +22,17 @@
#include <xmmsclient/xmmsclient++/playback.h>
#include <xmmsclient/xmmsclient++/playlist.h>
#include <QtDebug>
#include <QStyle>
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<QString, QVariant> 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;
}

View file

@ -22,6 +22,7 @@ class XClient;
#include <xmmsclient/xmmsclient++.h>
#include <QObject>
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

View file

@ -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<QString, QString> hash;
levels.each (boost::bind (&XMMSHandler::DictToQHash, this,
_1, _2, boost::ref (hash)));
QList<QString> Values = hash.values();
QListIterator<QString> 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;
}

View file

@ -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<QHash<QString, QString> > &);
*/
void getVolume (uint);
private:
void DictToQHash (const std::string &key,
@ -79,12 +69,8 @@ class XMMSHandler : public XClient {
// const std::string &source,
// QHash<QString, QString> &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

View file

@ -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)
{

View file

@ -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);