kwave  18.07.70
Kwave::NormalizePlugin Class Reference

#include <NormalizePlugin.h>

Inheritance diagram for Kwave::NormalizePlugin:
Inheritance graph
Collaboration diagram for Kwave::NormalizePlugin:
Collaboration graph

Classes

struct  Average
 

Public Member Functions

 NormalizePlugin (QObject *parent, const QVariantList &args)
 
virtual ~NormalizePlugin () Q_DECL_OVERRIDE
 
virtual void run (QStringList params) Q_DECL_OVERRIDE
 
- Public Member Functions inherited from Kwave::Plugin
 Plugin (QObject *parent, const QVariantList &args)
 
virtual ~Plugin () Q_DECL_OVERRIDE
 
virtual QString name () const
 
virtual QString description () const
 
virtual QString progressText ()
 
virtual bool canClose () const
 
bool isRunning () const
 
bool shouldStop () const
 
virtual void load (QStringList &params)
 
virtual void unload ()
 
virtual QStringList * setup (QStringList &previous_params)
 
virtual int start (QStringList &params)
 
virtual int stop ()
 
Kwave::PluginManagermanager () const
 
Kwave::SignalManagersignalManager ()
 
QWidget * parentWidget () const
 
QString signalName ()
 
virtual sample_index_t signalLength ()
 
virtual double signalRate ()
 
virtual const QList< unsigned int > selectedTracks ()
 
virtual sample_index_t selection (QList< unsigned int > *tracks=Q_NULLPTR, sample_index_t *left=Q_NULLPTR, sample_index_t *right=Q_NULLPTR, bool expand_if_empty=false)
 
virtual void selectRange (sample_index_t offset, sample_index_t length)
 
virtual void migrateToActiveContext ()
 
- Public Member Functions inherited from Kwave::Runnable
virtual ~Runnable ()
 

Private Member Functions

double getMaxPower (Kwave::MultiTrackReader &source)
 
void getMaxPowerOfTrack (Kwave::SampleReader *reader, Kwave::NormalizePlugin::Average *average, unsigned int window_size)
 

Additional Inherited Members

- Public Slots inherited from Kwave::Plugin
virtual void setProgressDialogEnabled (bool enable)
 
virtual void updateProgress (qreal progress)
 
virtual void cancel ()
 
virtual void close ()
 
void release ()
 
- Signals inherited from Kwave::Plugin
void sigRunning (Kwave::Plugin *plugin)
 
void sigDone (Kwave::Plugin *plugin)
 
void sigClosed (Kwave::Plugin *p)
 
void sigCommand (const QString &command)
 
void setProgressText (const QString &text)
 
- Protected Member Functions inherited from Kwave::Plugin
int execute (QStringList &params)
 
void emitCommand (const QString &command)
 
void use ()
 
void setPluginManager (Kwave::PluginManager *new_plugin_manager)
 
virtual void run_wrapper (const QVariant &params) Q_DECL_OVERRIDE
 

Detailed Description

This is a two-pass plugin that determines the average volume level of a signal and then calls the volume plugin to adjust the volume.

Definition at line 43 of file NormalizePlugin.h.

Constructor & Destructor Documentation

◆ NormalizePlugin()

Kwave::NormalizePlugin::NormalizePlugin ( QObject *  parent,
const QVariantList &  args 
)

Constructor

Parameters
parentreference to our plugin manager
argsargument list [unused]

Definition at line 56 of file NormalizePlugin.cpp.

58  :Kwave::Plugin(parent, args)
59 {
60 }

◆ ~NormalizePlugin()

Kwave::NormalizePlugin::~NormalizePlugin ( )
virtual

Destructor

Definition at line 63 of file NormalizePlugin.cpp.

64 {
65 }

Member Function Documentation

◆ getMaxPower()

double Kwave::NormalizePlugin::getMaxPower ( Kwave::MultiTrackReader source)
private

get the maximum power level of the input

Definition at line 142 of file NormalizePlugin.cpp.

References Kwave::SampleReader::eof(), Kwave::MultiTrackReader::eof(), getMaxPowerOfTrack(), Kwave::NormalizePlugin::Average::n, Kwave::FileInfo::rate(), Kwave::Plugin::shouldStop(), Kwave::Plugin::signalManager(), SMOOTHLEN, Kwave::NormalizePlugin::Average::sum, Kwave::toUint(), and Kwave::MultiTrackSource< SOURCE, INITIALIZE >::tracks().

Referenced by run().

143 {
144  double maxpow = 0.0;
145  const unsigned int tracks = source.tracks();
146  const double rate = Kwave::FileInfo(signalManager().metaData()).rate();
147  const unsigned int window_size = Kwave::toUint(rate / 100);
148  if (!window_size) return 0;
149 
150  // set up smoothing window buffer
151  QVector<Kwave::NormalizePlugin::Average> average(tracks);
152  for (unsigned int t = 0; t < tracks; t++) {
153  average[t].fifo = QVector<double>(SMOOTHLEN, double(0.0));
154  average[t].wp = 0;
155  average[t].n = 0;
156  average[t].sum = 0.0;
157  average[t].max = 0.0;
158  }
159 
160  while (!shouldStop() && !source.eof()) {
161  QFutureSynchronizer<void> synchronizer;
162 
163  for (unsigned int t = 0; t < tracks; t++) {
164  Kwave::SampleReader *reader = source[t];
165  if (!reader) continue;
166  if (reader->eof()) continue;
167 
168  synchronizer.addFuture(QtConcurrent::run(
169  this,
171  reader, &(average[t]), window_size
172  ));
173  }
174  synchronizer.waitForFinished();
175  }
176 
177  if (average[0].n < SMOOTHLEN) {
178  // if file was too short, calculate power out of what we have
179  for (unsigned int t = 0; t < tracks; t++) {
180  Kwave::NormalizePlugin::Average &avg = average[t];
181  double pow = avg.sum / static_cast<double>(avg.n);
182  if (pow > maxpow) maxpow = pow;
183  }
184  } else {
185  // get maximum among all tracks
186  for (unsigned int t = 0; t < tracks; t++) {
187  double p = average[t].max;
188  if (p > maxpow) maxpow = p;
189  }
190  }
191 
192  double level = sqrt(maxpow);
193  return level;
194 }
double rate() const
Definition: FileInfo.cpp:415
virtual unsigned int tracks() const Q_DECL_OVERRIDE
Kwave::SignalManager & signalManager()
Definition: Plugin.cpp:444
void getMaxPowerOfTrack(Kwave::SampleReader *reader, Kwave::NormalizePlugin::Average *average, unsigned int window_size)
bool eof() const
Definition: SampleReader.h:66
virtual bool eof() const
#define SMOOTHLEN
unsigned int toUint(T x)
Definition: Utils.h:109
bool shouldStop() const
Definition: Plugin.h:120
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getMaxPowerOfTrack()

void Kwave::NormalizePlugin::getMaxPowerOfTrack ( Kwave::SampleReader reader,
Kwave::NormalizePlugin::Average average,
unsigned int  window_size 
)
private

calculate the maximum power of one track

Parameters
readerreference to a SampleReader to read from
averagereference to smoothing information
window_sizelength of the sliding window for volume detection

Definition at line 197 of file NormalizePlugin.cpp.

References Kwave::StreamObject::blockSize(), Kwave::SampleReader::eof(), Kwave::NormalizePlugin::Average::fifo, Kwave::NormalizePlugin::Average::max, Kwave::NormalizePlugin::Average::n, Kwave::SampleReader::read(), sample2double(), SMOOTHLEN, Kwave::NormalizePlugin::Average::sum, and Kwave::NormalizePlugin::Average::wp.

Referenced by getMaxPower().

201 {
202  Kwave::NormalizePlugin::Average &average = *p_average;
203  Kwave::SampleArray data(window_size);
204  unsigned int round = 0;
205  unsigned int loops = 5 * reader->blockSize() / window_size;
206  loops++;
207 
208  while ((round++ < loops) && !reader->eof()) {
209  unsigned int len = reader->read(data, 0, window_size);
210 
211  // calculate power of one block
212  double sum = 0;
213  const Kwave::SampleArray &in = data;
214  for (unsigned int i = 0; i < len; i++) {
215  sample_t s = in[i];
216  double d = sample2double(s);
217  sum += (d * d);
218  }
219  double pow = sum / static_cast<double>(len);
220 
221  // collect all power values in a FIFO
222  unsigned int wp = average.wp;
223  average.sum -= average.fifo[wp];
224  average.sum += pow;
225  average.fifo[wp] = pow;
226  if (++wp >= SMOOTHLEN) wp = 0;
227  average.wp = wp;
228  if (average.n == SMOOTHLEN) {
229  // detect power peak
230  double p = average.sum / static_cast<double>(SMOOTHLEN);
231  if (p > average.max) average.max = p;
232  } else {
233  average.n++;
234  }
235  }
236 // qDebug("%p -> pos=%llu, max=%g", this, reader->pos(), average.max);
237 }
bool eof() const
Definition: SampleReader.h:66
#define SMOOTHLEN
static double sample2double(const sample_t s)
Definition: Sample.h:73
virtual unsigned int blockSize() const
unsigned int read(Kwave::SampleArray &buffer, unsigned int dstoff, unsigned int length)
qint32 sample_t
Definition: Sample.h:37
Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

void Kwave::NormalizePlugin::run ( QStringList  params)
virtual

normalizes the volume

Parameters
paramslist of strings with parameters

Reimplemented from Kwave::Plugin.

Definition at line 68 of file NormalizePlugin.cpp.

References Kwave::connect(), Kwave::MultiTrackReader::eof(), Kwave::MultiWriter::flush(), getMaxPower(), Kwave::MultiTrackSource< SOURCE, INITIALIZE >::goOn(), Kwave::Overwrite, Kwave::Plugin::selection(), Kwave::Plugin::setProgressText(), Kwave::Plugin::shouldStop(), Kwave::Plugin::signalManager(), Kwave::SinglePassForward, TARGET_LEVEL, Kwave::MultiTrackSink< SINK, INITIALIZE >::tracks(), and Kwave::Plugin::updateProgress().

69 {
70  Q_UNUSED(params);
71  Kwave::UndoTransactionGuard undo_guard(*this, i18n("Normalize"));
72 
73  // get the current selection
74  QList<unsigned int> tracks;
75  sample_index_t first = 0;
76  sample_index_t last = 0;
77  sample_index_t length = selection(&tracks, &first, &last, true);
78  if (!length || tracks.isEmpty()) return;
79 
80  // get the current volume level
81  double level = 0.0;
82  {
84  signalManager(), tracks, first, last);
85 
86  // connect the progress dialog
87  connect(&src, SIGNAL(progress(qreal)),
88  this, SLOT(updateProgress(qreal)),
89  Qt::BlockingQueuedConnection);
90 
91  // detect the peak value
92  emit setProgressText(i18n("Analyzing volume level..."));
93 // qDebug("NormalizePlugin: getting peak...");
94  level = getMaxPower(src);
95 // qDebug("NormalizePlugin: level is %g", level);
96  }
97 
99  signalManager(), tracks, first, last);
101  first, last);
103  tracks.count(), this);
104 
105  // break if aborted
106  if (!sink.tracks()) return;
107 
108  // connect the progress dialog
109  connect(&source, SIGNAL(progress(qreal)),
110  this, SLOT(updateProgress(qreal)),
111  Qt::BlockingQueuedConnection);
112 
113  // connect them
114  bool ok = true;
115  if (ok) ok = Kwave::connect(
116  source, SIGNAL(output(Kwave::SampleArray)),
117  normalizer, SLOT(input(Kwave::SampleArray)));
118  if (ok) ok = Kwave::connect(
119  normalizer, SIGNAL(output(Kwave::SampleArray)),
120  sink, SLOT(input(Kwave::SampleArray)));
121  if (!ok) {
122  return;
123  }
124 
125  double target = pow(10.0, (TARGET_LEVEL / 20.0));
126  double gain = target / level;
127  qDebug("NormalizePlugin: gain=%g", gain);
128 
129  QString db;
130  emit setProgressText(i18n("Normalizing (%1 dB) ...",
131  db.sprintf("%+0.1f", 20 * log10(gain))));
132 
133  normalizer.setAttribute(SLOT(setGain(QVariant)), QVariant(gain));
134  while (!shouldStop() && !source.eof()) {
135  source.goOn();
136  }
137 
138  sink.flush();
139 }
Kwave::SignalManager & signalManager()
Definition: Plugin.cpp:444
quint64 sample_index_t
Definition: Sample.h:28
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
#define TARGET_LEVEL
double getMaxPower(Kwave::MultiTrackReader &source)
virtual void updateProgress(qreal progress)
Definition: Plugin.cpp:260
void setProgressText(const QString &text)
bool shouldStop() const
Definition: Plugin.h:120
virtual sample_index_t selection(QList< unsigned int > *tracks=Q_NULLPTR, sample_index_t *left=Q_NULLPTR, sample_index_t *right=Q_NULLPTR, bool expand_if_empty=false)
Definition: Plugin.cpp:480
Here is the call graph for this function:

The documentation for this class was generated from the following files: