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