made volume effect use decibels
This commit is contained in:
@@ -51,13 +51,12 @@ MediaPropertiesDialog::MediaPropertiesDialog(QWidget *parent, Media *i) :
|
||||
track_list->addItem(item);
|
||||
}
|
||||
for (int i=0;i<f->audio_tracks.size();i++) {
|
||||
const FootageStream& fs = f->audio_tracks.at(i);
|
||||
const FootageStream& fs = f->audio_tracks.at(i);
|
||||
QListWidgetItem* item = new QListWidgetItem(
|
||||
tr("Audio %1: %2Hz %3 %4").arg(
|
||||
tr("Audio %1: %2Hz %3").arg(
|
||||
QString::number(fs.file_index),
|
||||
QString::number(fs.audio_frequency),
|
||||
QString::number(fs.audio_channels),
|
||||
tr("channel(s)", "", fs.audio_channels)
|
||||
tr("%n channel(s)", "", fs.audio_channels)
|
||||
),
|
||||
track_list
|
||||
);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "project/effect.h"
|
||||
|
||||
class AudioNoiseEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioNoiseEffect(Clip* c, const EffectMeta* em);
|
||||
void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "project/effect.h"
|
||||
|
||||
class FillLeftRightEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FillLeftRightEffect(Clip* c, const EffectMeta* em);
|
||||
void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "project/effect.h"
|
||||
|
||||
class PanEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PanEffect(Clip* c, const EffectMeta* em);
|
||||
void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "project/effect.h"
|
||||
|
||||
class ToneEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ToneEffect(Clip *c, const EffectMeta* em);
|
||||
void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "project/effect.h"
|
||||
|
||||
class VoidEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VoidEffect(Clip* c, const QString& n);
|
||||
|
||||
|
||||
@@ -10,20 +10,20 @@
|
||||
|
||||
VolumeEffect::VolumeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
|
||||
EffectRow* volume_row = add_row(tr("Volume"));
|
||||
volume_val = volume_row->add_field(EFFECT_FIELD_DOUBLE, "volume");
|
||||
volume_val->set_double_minimum_value(0);
|
||||
volume_val = volume_row->add_field(EFFECT_FIELD_DOUBLE, "volume");
|
||||
|
||||
// set defaults
|
||||
volume_val->set_double_default_value(100);
|
||||
volume_val->set_double_default_value(1);
|
||||
static_cast<LabelSlider*>(volume_val->get_ui_element())->set_display_type(LABELSLIDER_DECIBEL);
|
||||
}
|
||||
|
||||
void VolumeEffect::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int) {
|
||||
double interval = (timecode_end-timecode_start)/nb_bytes;
|
||||
for (int i=0;i<nb_bytes;i+=4) {
|
||||
double vol_val = log_volume(volume_val->get_double_value(timecode_start+(interval*i), true)*0.01);
|
||||
double vol_val = log_volume(volume_val->get_double_value(timecode_start+(interval*i), true));
|
||||
|
||||
qint32 right_samp = (qint16) (((samples[i+3] & 0xFF) << 8) | (samples[i+2] & 0xFF));
|
||||
qint32 left_samp = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF));
|
||||
qint32 right_samp = qint16(((samples[i+3] & 0xFF) << 8) | (samples[i+2] & 0xFF));
|
||||
qint32 left_samp = qint16(((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF));
|
||||
|
||||
left_samp *= vol_val;
|
||||
right_samp *= vol_val;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "project/effect.h"
|
||||
|
||||
class VolumeEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VolumeEffect(Clip* c, const EffectMeta* em);
|
||||
void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
|
||||
|
||||
@@ -52,3 +52,11 @@ double cubic_t_from_x(double x_target, double a, double b, double c, double d) {
|
||||
|
||||
return percent;
|
||||
}
|
||||
|
||||
double amplitude_to_db(double amplitude) {
|
||||
return (20.0*(qLn(amplitude)/qLn(10.0)));
|
||||
}
|
||||
|
||||
double db_to_amplitude(double db) {
|
||||
return qPow(M_E, (db*qLn(10.0))/20.0);
|
||||
}
|
||||
|
||||
@@ -10,4 +10,8 @@ double cubic_from_t(double a, double b, double c, double d, double t);
|
||||
double cubic_t_from_x(double x_target, double a, double b, double c, double d);
|
||||
double solveCubicBezier(double p0, double p1, double p2, double p3, double x);
|
||||
|
||||
// decibel conversion functions
|
||||
double amplitude_to_db(double amplitude);
|
||||
double db_to_amplitude(double db);
|
||||
|
||||
#endif // MATH_H
|
||||
|
||||
+2
-2
@@ -15,8 +15,8 @@ struct ProxyInfo {
|
||||
QString path;
|
||||
};
|
||||
|
||||
class ProxyGenerator : public QThread
|
||||
{
|
||||
class ProxyGenerator : public QThread {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProxyGenerator();
|
||||
void run();
|
||||
|
||||
+5
-6
@@ -118,12 +118,11 @@ void Media::update_tooltip(const QString& error) {
|
||||
tooltip += QString::number(f->video_tracks.at(i).video_frame_rate * f->speed);
|
||||
} else {
|
||||
double adjusted_rate = f->video_tracks.at(i).video_frame_rate * f->speed;
|
||||
tooltip += QString("%1 %2 (%3 %4)").arg(
|
||||
QString::number(adjusted_rate * 2),
|
||||
QCoreApplication::translate("Media", "field(s)", "", qCeil(adjusted_rate * 2)),
|
||||
QString::number(adjusted_rate),
|
||||
QCoreApplication::translate("Media", "frame(s)", "", qCeil(adjusted_rate))
|
||||
);
|
||||
|
||||
tooltip += QCoreApplication::translate("Media", "%1 field(s) (%2 frame(s))").arg(
|
||||
QString::number(adjusted_rate*2.0),
|
||||
QString::number(adjusted_rate)
|
||||
);
|
||||
}
|
||||
}
|
||||
tooltip += "\n";
|
||||
|
||||
+77
-12
@@ -3,6 +3,7 @@
|
||||
#include "project/undo.h"
|
||||
#include "panels/viewer.h"
|
||||
#include "io/config.h"
|
||||
#include "io/math.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
@@ -38,7 +39,7 @@ void LabelSlider::set_display_type(int type) {
|
||||
|
||||
void LabelSlider::set_value(double v, bool userSet) {
|
||||
set = true;
|
||||
if (v != internal_value) {
|
||||
if (!qFuzzyCompare(v, internal_value)) {
|
||||
if (min_enabled && v < min_value) {
|
||||
internal_value = min_value;
|
||||
} else if (max_enabled && v > max_value) {
|
||||
@@ -65,8 +66,27 @@ QString LabelSlider::valueToString(double v) {
|
||||
return "---";
|
||||
} else {
|
||||
switch (display_type) {
|
||||
case LABELSLIDER_FRAMENUMBER: return frame_to_timecode(v, config.timecode_view, frame_rate);
|
||||
case LABELSLIDER_PERCENT: return QString::number((v*100), 'f', decimal_places) + "%";
|
||||
case LABELSLIDER_FRAMENUMBER:
|
||||
return frame_to_timecode(long(v), config.timecode_view, frame_rate);
|
||||
case LABELSLIDER_PERCENT:
|
||||
return QString::number((v*100), 'f', decimal_places).append("%");
|
||||
case LABELSLIDER_DECIBEL:
|
||||
{
|
||||
QString db_str;
|
||||
|
||||
// -96 dB is considered -infinity
|
||||
if (amplitude_to_db(v) <= -96) {
|
||||
// hex sequence for -infinity
|
||||
db_str = "-\xE2\x88\x9E";
|
||||
} else {
|
||||
db_str = QString::number(amplitude_to_db(v), 'f', decimal_places);
|
||||
}
|
||||
|
||||
// add "dB" suffix
|
||||
db_str.append(" dB");
|
||||
|
||||
return db_str;
|
||||
}
|
||||
}
|
||||
return QString::number(v, 'f', decimal_places);
|
||||
}
|
||||
@@ -118,7 +138,8 @@ void LabelSlider::mousePressEvent(QMouseEvent *ev) {
|
||||
if (ev->modifiers() & Qt::AltModifier) {
|
||||
|
||||
// if the value is not already default, and there is a default to set
|
||||
if (internal_value != default_value && !qIsNaN(default_value)) {
|
||||
if (!qFuzzyCompare(internal_value, default_value)
|
||||
&& !qIsNaN(default_value)) {
|
||||
|
||||
// cache current value
|
||||
set_previous_value();
|
||||
@@ -166,11 +187,28 @@ void LabelSlider::mouseMoveEvent(QMouseEvent* event) {
|
||||
// ctrl + drag drags in smaller increments
|
||||
if (event->modifiers() & Qt::ControlModifier) diff *= 0.01;
|
||||
|
||||
// we'll also need to drag in smaller increments for a percent value
|
||||
if (display_type == LABELSLIDER_PERCENT) diff *= 0.01;
|
||||
if (display_type == LABELSLIDER_PERCENT) {
|
||||
// we'll also need to drag in smaller increments for a percent value
|
||||
|
||||
// sets the value
|
||||
set_value(internal_value + diff, true);
|
||||
diff *= 0.01;
|
||||
}
|
||||
|
||||
// determine what the new value will be
|
||||
double new_value;
|
||||
|
||||
if (display_type == LABELSLIDER_DECIBEL) {
|
||||
// we move in terms of dB for decibel display
|
||||
|
||||
new_value = db_to_amplitude(amplitude_to_db(internal_value) + diff);
|
||||
|
||||
} else {
|
||||
// for most display types, just add the mouse difference
|
||||
|
||||
new_value = internal_value + diff;
|
||||
}
|
||||
|
||||
// set internal value
|
||||
set_value(new_value, true);
|
||||
|
||||
// keep the cursor in the same location while dragging
|
||||
cursor().setPos(drag_start_x, drag_start_y);
|
||||
@@ -222,23 +260,50 @@ void LabelSlider::mouseReleaseEvent(QMouseEvent*) {
|
||||
// ask the user to enter a normal number value
|
||||
bool ok;
|
||||
|
||||
// value to show
|
||||
double shown_value = internal_value;
|
||||
if (display_type == LABELSLIDER_PERCENT) {
|
||||
shown_value *= 100;
|
||||
} else if (display_type == LABELSLIDER_DECIBEL) {
|
||||
shown_value = amplitude_to_db(shown_value);
|
||||
}
|
||||
|
||||
// set correct minimum value
|
||||
double shown_minimum_value;
|
||||
if (min_enabled) {
|
||||
// if this field has a minimum value set, use it
|
||||
shown_minimum_value = min_value;
|
||||
} else if (display_type == LABELSLIDER_DECIBEL) {
|
||||
// minimum decibel amount is -96db
|
||||
shown_minimum_value = -96;
|
||||
} else {
|
||||
// lowest possible minimum integer
|
||||
shown_minimum_value = INT_MIN;
|
||||
}
|
||||
|
||||
// percentages are stored 0.0 - 1.0 but displayed as 0% - 100%
|
||||
d = QInputDialog::getDouble(
|
||||
this,
|
||||
tr("Set Value"),
|
||||
tr("New value:"),
|
||||
(display_type == LABELSLIDER_PERCENT) ? internal_value * 100 : internal_value,
|
||||
(min_enabled) ? min_value : INT_MIN,
|
||||
shown_value,
|
||||
shown_minimum_value,
|
||||
(max_enabled) ? max_value : INT_MAX,
|
||||
decimal_places,
|
||||
&ok
|
||||
);
|
||||
if (!ok) return;
|
||||
if (display_type == LABELSLIDER_PERCENT) d *= 0.01;
|
||||
|
||||
// convert shown value back to internal value
|
||||
if (display_type == LABELSLIDER_PERCENT) {
|
||||
d *= 0.01;
|
||||
} else if (display_type == LABELSLIDER_DECIBEL) {
|
||||
d = db_to_amplitude(d);
|
||||
}
|
||||
}
|
||||
|
||||
// if the value actually changed, trigger a change event
|
||||
if (d != internal_value) {
|
||||
if (!qFuzzyCompare(d, internal_value)) {
|
||||
set_previous_value();
|
||||
set_value(d, true);
|
||||
}
|
||||
|
||||
+6
-3
@@ -4,9 +4,12 @@
|
||||
#include <QLabel>
|
||||
#include <QUndoCommand>
|
||||
|
||||
#define LABELSLIDER_NORMAL 0
|
||||
#define LABELSLIDER_FRAMENUMBER 1
|
||||
#define LABELSLIDER_PERCENT 2
|
||||
enum LabelSliderDisplayType {
|
||||
LABELSLIDER_NORMAL,
|
||||
LABELSLIDER_FRAMENUMBER,
|
||||
LABELSLIDER_PERCENT,
|
||||
LABELSLIDER_DECIBEL
|
||||
};
|
||||
|
||||
class LabelSlider : public QLabel
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user