aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2015-12-27 14:12:14 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2015-12-27 14:12:14 +0000
commitb47a13e6d614fca27f5dfcdb6574282180e31ecb (patch)
tree471115145cbf72f3784d6c8693a21f1c3a67d7db
parent73109017fa5b8c75166d513ef10a7972fb021896 (diff)
downloadqmmp-b47a13e6d614fca27f5dfcdb6574282180e31ecb.tar.gz
qmmp-b47a13e6d614fca27f5dfcdb6574282180e31ecb.tar.bz2
qmmp-b47a13e6d614fca27f5dfcdb6574282180e31ecb.zip
enabled replay gain support
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5907 90c681e8-e032-0410-971d-27865f9a5e38
-rw-r--r--src/qmmp/qmmpaudioengine.cpp46
-rw-r--r--src/qmmp/replaygain.cpp112
-rw-r--r--src/qmmp/replaygain_p.h15
3 files changed, 42 insertions, 131 deletions
diff --git a/src/qmmp/qmmpaudioengine.cpp b/src/qmmp/qmmpaudioengine.cpp
index 7da96a5c2..d55372266 100644
--- a/src/qmmp/qmmpaudioengine.cpp
+++ b/src/qmmp/qmmpaudioengine.cpp
@@ -47,12 +47,11 @@ QmmpAudioEngine::QmmpAudioEngine(QObject *parent)
m_decoder = 0;
m_output = 0;
m_muted = false;
- m_replayGain = new ReplayGain;
+ m_replayGain = 0;
m_converter = new AudioConverter;
m_settings = QmmpSettings::instance();
connect(m_settings,SIGNAL(replayGainSettingsChanged()), SLOT(updateReplayGainSettings()));
connect(m_settings, SIGNAL(eqSettingsChanged()), SLOT(updateEqSettings()));
- updateReplayGainSettings();
reset();
m_instance = this;
}
@@ -66,7 +65,6 @@ QmmpAudioEngine::~QmmpAudioEngine()
m_output_buf = 0;
qDeleteAll(m_effects);
m_instance = 0;
- delete m_replayGain;
delete m_converter;
}
@@ -301,13 +299,8 @@ qint64 QmmpAudioEngine::produceSound(unsigned char *data, qint64 size, quint32 b
size_t sz = size < m_bks ? size : m_bks;
size_t samples = sz / m_sample_size;
- //size_t samples = qMin(m_bks / sizeof(float), (uint)size / m_ap.sampleSize());
- //size_t in_size = samples * m_ap.sampleSize();
-
m_converter->toFloat(data, b->data, samples);
- //m_replayGain->applyReplayGain(data, sz);
- //memcpy(b->data, data, sz);
b->samples = samples;
b->rate = brate;
foreach(Effect* effect, m_effects)
@@ -332,12 +325,15 @@ void QmmpAudioEngine::finish()
void QmmpAudioEngine::updateReplayGainSettings()
{
- mutex()->lock();
- m_replayGain->updateSettings(m_settings->replayGainMode(),
- m_settings->replayGainPreamp(),
- m_settings->replayGainDefaultGain(),
- m_settings->replayGainPreventClipping());
- mutex()->unlock();
+ if(m_replayGain)
+ {
+ mutex()->lock();
+ m_replayGain->updateSettings(m_settings->replayGainMode(),
+ m_settings->replayGainPreamp(),
+ m_settings->replayGainDefaultGain(),
+ m_settings->replayGainPreventClipping());
+ mutex()->unlock();
+ }
}
void QmmpAudioEngine::updateEqSettings()
@@ -361,7 +357,7 @@ void QmmpAudioEngine::run()
}
m_decoder = m_decoders.dequeue();
addOffset(); //offset
- m_replayGain->setReplayGainInfo(m_decoder->replayGainInfo(), false);
+ m_replayGain->setReplayGainInfo(m_decoder->replayGainInfo());
mutex()->unlock();
m_output->start();
StateHandler::instance()->dispatch(Qmmp::Buffering);
@@ -432,7 +428,7 @@ void QmmpAudioEngine::run()
StateHandler::instance()->dispatch(Qmmp::Buffering);
m_decoder->next();
StateHandler::instance()->dispatch(m_decoder->totalTime());
- m_replayGain->setReplayGainInfo(m_decoder->replayGainInfo(), false);
+ m_replayGain->setReplayGainInfo(m_decoder->replayGainInfo());
m_output->mutex()->lock();
m_output->seek(0); //reset counter
m_output->mutex()->unlock();
@@ -448,7 +444,7 @@ void QmmpAudioEngine::run()
m_decoder = m_decoders.dequeue();
//m_seekTime = m_inputs.value(m_decoder)->offset();
flush(true);
- m_replayGain->setReplayGainInfo(m_decoder->replayGainInfo(), false);
+ m_replayGain->setReplayGainInfo(m_decoder->replayGainInfo());
//use current output if possible
prepareEffects(m_decoder);
if(m_ap == m_output->audioParameters())
@@ -613,11 +609,9 @@ void QmmpAudioEngine::prepareEffects(Decoder *d)
m_output_size = m_bks * 4;
m_sample_size = m_ap.sampleSize();
m_output_buf = new unsigned char[m_output_size];
- //converter
+ //audio converter
m_converter->configure(m_ap.format());
m_ap = AudioParameters(m_ap.sampleRate(), m_ap.channelMap(), Qmmp::PCM_FLOAT);
- //replay gain
- m_replayGain->configure(m_ap);
//remove disabled and external effects
foreach(Effect *e, m_effects)
{
@@ -625,12 +619,22 @@ void QmmpAudioEngine::prepareEffects(Decoder *d)
{
m_effects.removeAll(e);
m_blockedEffects.removeAll(e);
- delete e;
+ if(m_replayGain != e)
+ delete e;
}
}
+ m_replayGain = 0;
QList <Effect *> tmp_effects = m_effects;
m_effects.clear();
+ //replay gain
+ {
+ m_replayGain = new ReplayGain();
+ m_replayGain->configure(m_ap.sampleRate(), m_ap.channelMap());
+ m_effects << m_replayGain;
+ updateReplayGainSettings();
+ }
+ //channel order converter
if(m_ap.channelMap() != m_ap.channelMap().remaped())
{
m_effects << new ChannelConverter(m_ap.channelMap().remaped());
diff --git a/src/qmmp/replaygain.cpp b/src/qmmp/replaygain.cpp
index e0a85b941..e246d5f0f 100644
--- a/src/qmmp/replaygain.cpp
+++ b/src/qmmp/replaygain.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2009-2013 by Ilya Kotov *
+ * Copyright (C) 2009-2015 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -26,35 +26,19 @@ ReplayGain::ReplayGain()
{
m_scale = 1.0;
m_mode = QmmpSettings::REPLAYGAIN_DISABLED;
- m_format = Qmmp::PCM_UNKNOWM;
m_preamp = 0.0;
m_default_gain = 0.0;
- m_prebuf = 0;
m_prevent_clipping = false;
m_disabled = true;
- m_headroom = false;
- m_sample_size = 2;
}
ReplayGain::~ReplayGain()
-{
- if(m_prebuf)
- delete [] m_prebuf;
-}
+{}
-void ReplayGain::configure(const AudioParameters &p)
-{
- m_format = p.format();
- if(m_prebuf)
- delete [] m_prebuf;
- m_prebuf = new float[QMMP_BLOCK_FRAMES * p.channels() * 4];
- m_sample_size = AudioParameters::sampleSize(m_format);
-}
-
-void ReplayGain::setReplayGainInfo(const QMap<Qmmp::ReplayGainKey, double> &info, bool headroom)
+void ReplayGain::setReplayGainInfo(const QMap<Qmmp::ReplayGainKey, double> &info)
{
m_info = info;
- m_headroom = headroom;
+ updateScale();
if(m_mode != QmmpSettings::REPLAYGAIN_DISABLED)
{
qDebug("ReplayGain: track: gain=%f dB, peak=%f; album: gain=%f dB, peak=%f",
@@ -63,95 +47,23 @@ void ReplayGain::setReplayGainInfo(const QMap<Qmmp::ReplayGainKey, double> &info
m_info[Qmmp::REPLAYGAIN_ALBUM_GAIN],
m_info[Qmmp::REPLAYGAIN_ALBUM_PEAK]);
qDebug("ReplayGain: scale=%f", m_scale);
- qDebug("ReplayGain: headroom=%d", m_headroom);
}
- updateScale();
}
-qint64 ReplayGain::read(Decoder *decoder, unsigned char *data, qint64 size)
+void ReplayGain::applyEffect(Buffer *b)
{
if(m_disabled)
- return decoder->read(data, size);
-
- if(m_headroom) //with peak overflow support
{
- qint64 samples = decoder->read(m_prebuf, size >> (m_sample_size >> 1)); //size / m_sample_size;
-
- if(samples <= 0)
- return samples;
-
- for(qint64 i = 0; i < samples; ++i)
+ for(size_t i = 0; i < b->samples; ++i)
{
- m_prebuf[i] *= m_scale;
- m_prebuf[i] = qBound((float)-1.0, m_prebuf[i], (float)1.0);
-
- switch (m_format)
- {
- case Qmmp::PCM_S8:
- ((char*)data)[i] = m_prebuf[i] * (128.0 - 0.5);
- break;
- case Qmmp::PCM_S16LE:
- ((short*)data)[i] = m_prebuf[i] * (32768.0 - 0.5);
- break;
- case Qmmp::PCM_S24LE:
- ((qint32*)data)[i] = m_prebuf[i] * ((double)(1U << 23) - 0.5);
- break;
- case Qmmp::PCM_S32LE:
- ((qint32*)data)[i] = m_prebuf[i] * ((double)(1U << 31) - 0.5);
- break;
- default:
- return -1;
- }
+ b->data[i] = qBound(-1.0f, b->data[i], 1.0f);
}
- return samples << (m_sample_size >> 1); //samples * m_sample_size;
+ return;
}
- else //without peak overflow support
- {
- size = decoder->read(data, size);
- if(size <= 0)
- return size;
-
- qint64 samples = size >> (m_sample_size >> 1); //size / m_sample_size;
-
- switch (m_format)
- {
- case Qmmp::PCM_S8:
- {
- for (qint64 i = 0; i < samples; i++)
- ((char*)data)[i] = qBound(-128.0, ((char*)data)[i] * m_scale, 127.0);
- break;
- }
- case Qmmp::PCM_S16LE:
- {
- for (qint64 i = 0; i < samples; i++)
- ((short*)data)[i] = qBound(-32768.0, ((short*)data)[i] * m_scale, 32767.0);
- break;
- }
- case Qmmp::PCM_S24LE:
- {
- for (qint64 i = 0; i < samples; i++)
- {
- ((qint32*)data)[i] = qBound(-(double)(1U << 23),
- ((qint32*)data)[i] * m_scale,
- (double)((1U << 23) - 1));
- }
- break;
- }
- case Qmmp::PCM_S32LE:
- {
- for (qint64 i = 0; i < samples; i++)
- {
- ((qint32*)data)[i] = qBound(-(double)(1U << 31),
- ((qint32*)data)[i] * m_scale,
- (double)((1U << 31) - 1));
- }
- break;
- }
- default:
- return -1;
- }
- return size;
+ for(size_t i = 0; i < b->samples; ++i)
+ {
+ b->data[i] = qBound(-1.0f, float(b->data[i] * m_scale), 1.0f);
}
}
@@ -162,7 +74,7 @@ void ReplayGain::updateSettings(QmmpSettings::ReplayGainMode mode, double preamp
m_preamp = preamp;
m_default_gain = default_gain;
m_prevent_clipping = clip;
- setReplayGainInfo(m_info, m_headroom);
+ setReplayGainInfo(m_info);
}
void ReplayGain::updateScale()
diff --git a/src/qmmp/replaygain_p.h b/src/qmmp/replaygain_p.h
index 36f2294ac..d9f03c796 100644
--- a/src/qmmp/replaygain_p.h
+++ b/src/qmmp/replaygain_p.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2009-2013 by Ilya Kotov *
+ * Copyright (C) 2009-2015 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -23,24 +23,23 @@
#include <QtGlobal>
#include <QMap>
-#include "decoder.h"
+#include "effect.h"
#include "qmmpsettings.h"
#include "qmmp.h"
/*! @internal
* @author Ilya Kotov <forkotov02@hotmail.ru>
*/
-class ReplayGain
+class ReplayGain : public Effect
{
public:
ReplayGain();
~ReplayGain();
- void configure(const AudioParameters &p);
void updateSettings(QmmpSettings::ReplayGainMode mode, double preamp,
double default_gain, bool clip);
- void setReplayGainInfo(const QMap<Qmmp::ReplayGainKey, double> &info, bool headroom);
- qint64 read(Decoder *decoder, unsigned char *data, qint64 size);
+ void setReplayGainInfo(const QMap<Qmmp::ReplayGainKey, double> &info);
+ void applyEffect(Buffer *b);
private:
void updateScale();
@@ -49,12 +48,8 @@ private:
double m_scale;
double m_preamp;
double m_default_gain;
- float *m_prebuf;
bool m_prevent_clipping;
- Qmmp::AudioFormat m_format;
bool m_disabled;
- bool m_headroom;
- int m_sample_size;
};
#endif // REPLAYGAIN_H