aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qmmp/output.cpp21
-rw-r--r--src/qmmp/output.h1
-rw-r--r--src/qmmp/volumecontrol.cpp58
-rw-r--r--src/qmmp/volumecontrol.h9
4 files changed, 69 insertions, 20 deletions
diff --git a/src/qmmp/output.cpp b/src/qmmp/output.cpp
index e3300fbb4..feff9e11f 100644
--- a/src/qmmp/output.cpp
+++ b/src/qmmp/output.cpp
@@ -187,7 +187,8 @@ void Output::run()
if (b)
{
dispatchVisual(b, m_totalWritten, m_channels, m_precision);
- changeVolume(b->data, b->nbytes, m_channels);
+ if (SoftwareVolume::instance())
+ SoftwareVolume::instance()->changeVolume(b->data, b->nbytes, m_channels, m_precision);
l = 0;
m = 0;
while (l < b->nbytes)
@@ -238,24 +239,6 @@ void Output::status()
}
}
-void Output::changeVolume(uchar *data, qint64 size, int chan)
-{
- if (!SoftwareVolume::instance())
- return;
- if (chan > 1)
- for (qint64 i = 0; i < size/2; i+=2)
- {
- ((short*)data)[i]*= SoftwareVolume::instance()->left()/100.0;
- ((short*)data)[i+1]*= SoftwareVolume::instance()->right()/100.0;
- }
- else
- {
- int l = qMax(SoftwareVolume::instance()->left(), SoftwareVolume::instance()->right());
- for (qint64 i = 0; i < size/2; i++)
- ((short*)data)[i]*= l/100.0;
- }
-}
-
// static methods
QList<OutputFactory*> *Output::m_factories = 0;
diff --git a/src/qmmp/output.h b/src/qmmp/output.h
index 45fb1ad50..853ec1b8f 100644
--- a/src/qmmp/output.h
+++ b/src/qmmp/output.h
@@ -143,7 +143,6 @@ protected:
private:
void run(); //thread run function
void status();
- void changeVolume(uchar *data, qint64 size, int chan);
void dispatch(qint64 elapsed,
int bitrate,
int frequency,
diff --git a/src/qmmp/volumecontrol.cpp b/src/qmmp/volumecontrol.cpp
index 70d0b7a70..d2d768f58 100644
--- a/src/qmmp/volumecontrol.cpp
+++ b/src/qmmp/volumecontrol.cpp
@@ -95,6 +95,8 @@ SoftwareVolume::SoftwareVolume(QObject *parent)
checkVolume();
blockSignals(FALSE);
QTimer::singleShot(125, this, SLOT(checkVolume()));
+ m_scaleLeft = (double)m_left/100.0;
+ m_scaleRight = (double)m_right/100.0;
m_instance = this;
}
@@ -111,6 +113,8 @@ void SoftwareVolume::setVolume(int left, int right)
m_left = left;
m_right = right;
checkVolume();
+ m_scaleLeft = (double)m_left/100.0;
+ m_scaleRight = (double)m_right/100.0;
}
void SoftwareVolume::volume(int *left, int *right)
@@ -118,6 +122,60 @@ void SoftwareVolume::volume(int *left, int *right)
*left = m_left;
*right = m_right;
}
+
+void SoftwareVolume::changeVolume(uchar *data, qint64 size, int chan, int bits)
+{
+ size = size*8/bits;
+ if(bits == 16)
+ {
+ if (chan > 1)
+ {
+ for (qint64 i = 0; i < size; i+=2)
+ {
+ ((short*)data)[i]*= m_scaleLeft;
+ ((short*)data)[i+1]*= m_scaleRight;
+ }
+ }
+ else
+ {
+ for (qint64 i = 0; i < size; i++)
+ ((short*)data)[i]*= qMax(m_scaleRight, m_scaleLeft);
+ }
+ }
+ else if(bits == 8)
+ {
+ if (chan > 1)
+ {
+ for (qint64 i = 0; i < size; i++)
+ {
+ ((char*)data)[i]*= m_scaleLeft;
+ ((char*)data)[i+1]*= m_scaleRight;
+ }
+ }
+ else
+ {
+ for (qint64 i = 0; i < size; i++)
+ ((char*)data)[i]*= qMax(m_scaleRight, m_scaleLeft);
+ }
+ }
+ else if(bits == 32)
+ {
+ if (chan > 1)
+ {
+ for (qint64 i = 0; i < size; i+=2)
+ {
+ ((qint32*)data)[i]*= m_scaleLeft;
+ ((qint32*)data)[i+1]*= m_scaleRight;
+ }
+ }
+ else
+ {
+ for (qint64 i = 0; i < size/4; i++)
+ ((qint32*)data)[i]*= qMax(m_scaleRight, m_scaleLeft);
+ }
+ }
+}
+
//static
SoftwareVolume *SoftwareVolume::instance()
{
diff --git a/src/qmmp/volumecontrol.h b/src/qmmp/volumecontrol.h
index c08833e4e..575bdf4f3 100644
--- a/src/qmmp/volumecontrol.h
+++ b/src/qmmp/volumecontrol.h
@@ -110,6 +110,14 @@ public:
*/
void setVolume(int left, int right);
/*!
+ * Changes volume of buffer.
+ * @param data Pointer to the buffer.
+ * @param size Buffer size in bytes.
+ * @param chan Number of channels.
+ * @param bits Sample size in bits.
+ */
+ void changeVolume(uchar *data, qint64 size, int chan, int bits);
+ /*!
* Returns software volume object instance.
*/
static SoftwareVolume *instance();
@@ -129,6 +137,7 @@ protected:
private:
int m_left, m_right;
+ double m_scaleLeft, m_scaleRight;
static SoftwareVolume *m_instance;
};