diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2015-12-27 14:12:14 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2015-12-27 14:12:14 +0000 |
| commit | b47a13e6d614fca27f5dfcdb6574282180e31ecb (patch) | |
| tree | 471115145cbf72f3784d6c8693a21f1c3a67d7db | |
| parent | 73109017fa5b8c75166d513ef10a7972fb021896 (diff) | |
| download | qmmp-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.cpp | 46 | ||||
| -rw-r--r-- | src/qmmp/replaygain.cpp | 112 | ||||
| -rw-r--r-- | src/qmmp/replaygain_p.h | 15 |
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 |
