This commit is contained in:
itsmattkc
2020-03-18 15:03:20 +11:00
26 changed files with 292 additions and 199 deletions
-10
View File
@@ -258,13 +258,3 @@ int64_t Timecode::time_to_timestamp(const double &time, const rational &timebase
{
return qRound64(time * timebase.flipped().toDouble());
}
Timecode::Display Timecode::CurrentDisplay()
{
return static_cast<Timecode::Display>(Config::Current()["TimecodeDisplay"].toInt());
}
void Timecode::SetCurrentDisplay(Timecode::Display d)
{
Config::Current()["TimecodeDisplay"] = d;
}
-3
View File
@@ -45,9 +45,6 @@ public:
kMilliseconds
};
static Display CurrentDisplay();
static void SetCurrentDisplay(Display d);
/**
* @brief Convert a timestamp (according to a rational timebase) to a user-friendly string representation
*/
+1
View File
@@ -77,6 +77,7 @@ void Config::SetDefaults()
config_map_["DefaultViewerDivider"] = 2;
config_map_["AutoSelectDivider"] = false;
config_map_["SetNameWithMarker"] = false;
config_map_["RectifiedWaveforms"] = false;
config_map_["DropWithoutSequenceBehavior"] = TimelineWidget::kDWSAsk;
config_map_["DiskCachePath"] = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
+12
View File
@@ -482,6 +482,18 @@ Folder *Core::GetSelectedFolderInActiveProject()
}
}
Timecode::Display Core::GetTimecodeDisplay() const
{
return static_cast<Timecode::Display>(Config::Current()["TimecodeDisplay"].toInt());
}
void Core::SetTimecodeDisplay(Timecode::Display d)
{
Config::Current()["TimecodeDisplay"] = d;
emit TimecodeDisplayChanged(d);
}
void Core::SetProjectModified(bool e)
{
main_window()->setWindowModified(e);
+16
View File
@@ -26,6 +26,7 @@
#include <QTimer>
#include "common/rational.h"
#include "common/timecodefunctions.h"
#include "project/item/footage/footage.h"
#include "project/item/sequence/sequence.h"
#include "project/project.h"
@@ -125,6 +126,16 @@ public:
ProjectViewModel* GetActiveProjectModel();
Folder* GetSelectedFolderInActiveProject();
/**
* @brief Gets current timecode display mode
*/
Timecode::Display GetTimecodeDisplay() const;
/**
* @brief Sets current timecode display mode
*/
void SetTimecodeDisplay(Timecode::Display d);
/**
* @brief Sets state to "modified" so that the GUI will prompt the user to save before closing
*
@@ -269,6 +280,11 @@ signals:
*/
void SnappingChanged(const bool& b);
/**
* @brief Signal emitted when the default timecode display mode changed
*/
void TimecodeDisplayChanged(Timecode::Display d);
private:
/**
* @brief Get the file filter than can be used with QFileDialog to open and save compatible projects
@@ -2,8 +2,6 @@
#include <QGridLayout>
#include <QLabel>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include "common/autoscroll.h"
@@ -74,6 +72,14 @@ PreferencesGeneralTab::PreferencesGeneralTab()
row++;
general_layout->addWidget(new QLabel(tr("Rectified Waveforms:")), row, 0);
rectified_waveforms_ = new QCheckBox();
rectified_waveforms_->setChecked(Config::Current()["RectifiedWaveforms"].toBool());
general_layout->addWidget(rectified_waveforms_, row, 1);
row++;
general_layout->addWidget(new QLabel(tr("Default Still Image Length:")), row, 0);
default_still_length_ = new FloatSlider();
@@ -101,6 +107,8 @@ void PreferencesGeneralTab::Accept()
Config::Current()["DefaultSequenceAudioFrequency"] = default_sequence_.audio_params().sample_rate();
Config::Current()["DefaultSequenceAudioLayout"] = QVariant::fromValue(default_sequence_.audio_params().channel_layout());
Config::Current()["RectifiedWaveforms"] = rectified_waveforms_->isChecked();
Config::Current()["Autoscroll"] = autoscroll_method_->currentData();
Config::Current()["DefaultStillLength"] = QVariant::fromValue(rational::fromDouble(default_still_length_->GetValue()));
@@ -1,6 +1,7 @@
#ifndef PREFERENCESGENERALTAB_H
#define PREFERENCESGENERALTAB_H
#include <QCheckBox>
#include <QComboBox>
#include <QSpinBox>
@@ -27,6 +28,8 @@ private:
QComboBox* autoscroll_method_;
QCheckBox* rectified_waveforms_;
FloatSlider* default_still_length_;
/**
+3 -5
View File
@@ -23,9 +23,9 @@
#include <QCoreApplication>
#include "codec/decoder.h"
#include "common/timecodefunctions.h"
#include "common/xmlutils.h"
#include "config/config.h"
#include "core.h"
#include "ui/icons/icons.h"
Footage::Footage()
@@ -40,8 +40,6 @@ Footage::~Footage()
void Footage::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr>& footage_ptrs, QList<NodeParam::FootageConnection>&, const QAtomicInt* cancelled)
{
qDebug() << "Hello?";
QXmlStreamAttributes attributes = reader->attributes();
foreach (const QXmlStreamAttribute& attr, attributes) {
@@ -234,12 +232,12 @@ QString Footage::duration()
return Timecode::timestamp_to_timecode(duration,
frame_rate_timebase,
Timecode::CurrentDisplay());
Core::instance()->GetTimecodeDisplay());
} else if (streams_.first()->type() == Stream::kAudio) {
AudioStreamPtr audio_stream = std::static_pointer_cast<AudioStream>(streams_.first());
// If we're showing in a timecode, we prefer showing audio in seconds instead
Timecode::Display display = Timecode::CurrentDisplay();
Timecode::Display display = Core::instance()->GetTimecodeDisplay();
if (display == Timecode::kTimecodeDropFrame
|| display == Timecode::kTimecodeNonDropFrame) {
display = Timecode::kTimecodeSeconds;
+1 -1
View File
@@ -199,7 +199,7 @@ QString Sequence::duration()
int64_t timestamp = Timecode::time_to_timestamp(timeline_length, video_params().time_base());
return Timecode::timestamp_to_timecode(timestamp, video_params().time_base(), Timecode::CurrentDisplay());
return Timecode::timestamp_to_timecode(timestamp, video_params().time_base(), Core::instance()->GetTimecodeDisplay());
}
QString Sequence::rate()
@@ -24,7 +24,7 @@
#include <QEvent>
#include <QHBoxLayout>
#include "common/timecodefunctions.h"
#include "core.h"
#include "config/config.h"
#include "ui/icons/icons.h"
@@ -120,6 +120,8 @@ PlaybackControls::PlaybackControls(QWidget *parent) :
UpdateIcons();
SetTimebase(0);
connect(Core::instance(), &Core::TimecodeDisplayChanged, this, &PlaybackControls::TimecodeChanged);
}
void PlaybackControls::SetTimecodeEnabled(bool enabled)
@@ -147,9 +149,11 @@ void PlaybackControls::SetEndTime(const int64_t &r)
return;
}
end_tc_lbl_->setText(Timecode::timestamp_to_timecode(r,
end_time_ = r;
end_tc_lbl_->setText(Timecode::timestamp_to_timecode(end_time_,
time_base_,
Timecode::CurrentDisplay()));
Core::instance()->GetTimecodeDisplay()));
}
void PlaybackControls::ShowPauseButton()
@@ -181,3 +185,9 @@ void PlaybackControls::UpdateIcons()
next_frame_btn_->setIcon(icon::NextFrame);
go_to_end_btn_->setIcon(icon::GoToEnd);
}
void PlaybackControls::TimecodeChanged()
{
// Update end time
SetEndTime(end_time_);
}
@@ -101,6 +101,8 @@ private:
TimeSlider* cur_tc_lbl_;
QLabel* end_tc_lbl_;
int64_t end_time_;
rational time_base_;
QPushButton* go_to_start_btn_;
@@ -113,7 +115,7 @@ private:
QStackedWidget* playpause_stack_;
private slots:
void TimecodeChanged();
};
+10 -2
View File
@@ -1,11 +1,14 @@
#include "timeslider.h"
#include "common/timecodefunctions.h"
#include "core.h"
TimeSlider::TimeSlider(QWidget *parent) :
IntegerSlider(parent)
{
SetMinimum(0);
connect(Core::instance(), &Core::TimecodeDisplayChanged, this, &TimeSlider::TimecodeDisplayChanged);
}
void TimeSlider::SetTimebase(const rational &timebase)
@@ -25,10 +28,15 @@ QString TimeSlider::ValueToString(const QVariant &v)
return Timecode::timestamp_to_timecode(v.toLongLong(),
timebase_,
Timecode::CurrentDisplay());
Core::instance()->GetTimecodeDisplay());
}
QVariant TimeSlider::StringToValue(const QString &s, bool *ok)
{
return QVariant::fromValue(Timecode::timecode_to_timestamp(s, timebase_, Timecode::CurrentDisplay(), ok));
return QVariant::fromValue(Timecode::timecode_to_timestamp(s, timebase_, Core::instance()->GetTimecodeDisplay(), ok));
}
void TimeSlider::TimecodeDisplayChanged()
{
UpdateLabel(Value());
}
+4
View File
@@ -6,6 +6,7 @@
class TimeSlider : public IntegerSlider
{
Q_OBJECT
public:
TimeSlider(QWidget* parent = nullptr);
@@ -19,6 +20,9 @@ protected:
private:
rational timebase_;
private slots:
void TimecodeDisplayChanged();
};
#endif // TIMESLIDER_H
+1 -1
View File
@@ -143,7 +143,7 @@ void TimelineWidget::ImportTool::DragMove(TimelineViewMouseEvent *event)
int64_t earliest_timestamp = Timecode::time_to_timestamp(earliest_ghost, parent()->timebase());
QString tooltip_text = Timecode::timestamp_to_timecode(earliest_timestamp,
parent()->timebase(),
Timecode::CurrentDisplay());
Core::instance()->GetTimecodeDisplay());
// Force tooltip to update (otherwise the tooltip won't move as written in the documentation, and could get in the way
// of the cursor)
+1 -1
View File
@@ -404,7 +404,7 @@ void TimelineWidget::PointerTool::ProcessDrag(const TimelineCoordinate &mouse_po
int64_t earliest_timestamp = Timecode::time_to_timestamp(time_movement, parent()->timebase());
QString tooltip_text = Timecode::timestamp_to_timecode(earliest_timestamp,
parent()->timebase(),
Timecode::CurrentDisplay(),
Core::instance()->GetTimecodeDisplay(),
true);
// Force tooltip to update (otherwise the tooltip won't move as written in the documentation, and could get in the way
+1 -1
View File
@@ -54,7 +54,7 @@ void TimelineWidget::SlipTool::ProcessDrag(const TimelineCoordinate &mouse_pos)
int64_t earliest_timestamp = Timecode::time_to_timestamp(time_movement, parent()->timebase());
QString tooltip_text = Timecode::timestamp_to_timecode(earliest_timestamp,
parent()->timebase(),
Timecode::CurrentDisplay(),
Core::instance()->GetTimecodeDisplay(),
true);
// Force tooltip to update (otherwise the tooltip won't move as written in the documentation, and could get in the way
// of the cursor)
@@ -32,7 +32,7 @@
#include "common/qtutils.h"
#include "config/config.h"
#include "node/block/transition/transition.h"
#include "widget/viewer/waveformview.h"
#include "widget/viewer/audiowaveformview.h"
TimelineViewBlockItem::TimelineViewBlockItem(Block *block, QGraphicsItem* parent) :
TimelineViewRect(parent),
@@ -93,7 +93,7 @@ void TimelineViewBlockItem::paint(QPainter *painter, const QStyleOptionGraphicsI
QByteArray w = wave_file.readAll();
// FIXME: Hardcoded channel count
WaveformView::DrawWaveform(painter,
AudioWaveformView::DrawWaveform(painter,
rect().toRect(),
this->GetScale(),
reinterpret_cast<const SampleSummer::Sum*>(w.constData()),
+4 -1
View File
@@ -47,6 +47,9 @@ TimeRuler::TimeRuler(bool text_visible, bool cache_status_visible, QWidget* pare
// Text visibility affects height, so we set that here
UpdateHeight();
// Force update if the default timecode display mode changes
connect(Core::instance(), &Core::TimecodeDisplayChanged, this, static_cast<void (TimeRuler::*)()>(&TimeRuler::update));
}
void TimeRuler::SetCacheStatusLength(const rational &length)
@@ -203,7 +206,7 @@ void TimeRuler::paintEvent(QPaintEvent *)
if (text_visible_) {
QRect text_rect;
Qt::Alignment text_align;
QString timecode_str = Timecode::timestamp_to_timecode(ScreenToUnit(i), timebase(), Timecode::CurrentDisplay());
QString timecode_str = Timecode::timestamp_to_timecode(ScreenToUnit(i), timebase(), Core::instance()->GetTimecodeDisplay());
int timecode_width = QFontMetricsWidth(fm, timecode_str);
int timecode_left;
+2 -2
View File
@@ -16,6 +16,8 @@
set(OLIVE_SOURCES
${OLIVE_SOURCES}
widget/viewer/audiowaveformview.h
widget/viewer/audiowaveformview.cpp
widget/viewer/footageviewer.h
widget/viewer/footageviewer.cpp
widget/viewer/viewer.h
@@ -24,7 +26,5 @@ set(OLIVE_SOURCES
widget/viewer/viewerglwidget.cpp
widget/viewer/viewersizer.h
widget/viewer/viewersizer.cpp
widget/viewer/waveformview.h
widget/viewer/waveformview.cpp
PARENT_SCOPE
)
+189
View File
@@ -0,0 +1,189 @@
#include "audiowaveformview.h"
#include <QFile>
#include <QPainter>
#include <QtMath>
#include "common/clamp.h"
#include "config/config.h"
AudioWaveformView::AudioWaveformView(QWidget *parent) :
SeekableWidget(parent),
backend_(nullptr)
{
setAutoFillBackground(true);
setBackgroundRole(QPalette::Base);
}
void AudioWaveformView::SetBackend(AudioRenderBackend *backend)
{
if (backend_) {
disconnect(backend_, &AudioRenderBackend::QueueComplete, this, static_cast<void (AudioWaveformView::*)()>(&AudioWaveformView::update));
disconnect(backend_, &AudioRenderBackend::ParamsChanged, this, &AudioWaveformView::BackendParamsChanged);
SetTimebase(0);
}
backend_ = backend;
if (backend_) {
connect(backend_, &AudioRenderBackend::QueueComplete, this, static_cast<void (AudioWaveformView::*)()>(&AudioWaveformView::update));
connect(backend_, &AudioRenderBackend::ParamsChanged, this, &AudioWaveformView::BackendParamsChanged);
SetTimebase(backend_->params().time_base());
}
update();
}
void AudioWaveformView::DrawWaveform(QPainter *painter, const QRect& rect, const double& scale, const SampleSummer::Sum* samples, int nb_samples, int channels)
{
int sample_index, next_sample_index = 0;
QVector<SampleSummer::Sum> summary;
int summary_index = -1;
int channel_height = rect.height() / channels;
int channel_half_height = channel_height / 2;
for (int i=0;i<rect.width();i++) {
sample_index = next_sample_index;
if (sample_index == nb_samples) {
break;
}
next_sample_index = qMin(nb_samples,
qFloor(static_cast<double>(SampleSummer::kSumSampleRate) * static_cast<double>(i+1) / scale) * channels);
if (summary_index != sample_index) {
summary = SampleSummer::ReSumSamples(&samples[sample_index],
qMax(channels, next_sample_index - sample_index),
channels);
summary_index = sample_index;
}
int line_x = i + rect.x();
for (int j=0;j<summary.size();j++) {
if (Config::Current()[QStringLiteral("RectifiedWaveforms")].toBool()) {
int channel_bottom = rect.y() + channel_height * (j + 1);
int diff = qRound((summary.at(j).max - summary.at(j).min) * channel_half_height);
painter->drawLine(line_x,
channel_bottom - diff,
line_x,
channel_bottom);
} else{
int channel_mid = rect.y() + channel_height * j + channel_half_height;
painter->drawLine(line_x,
channel_mid + clamp(qRound(summary.at(j).min * channel_half_height), -channel_half_height, channel_half_height),
line_x,
channel_mid + clamp(qRound(summary.at(j).max * channel_half_height), -channel_half_height, channel_half_height));
}
}
}
}
void AudioWaveformView::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
if (!backend_ || backend_->CachePathName().isEmpty() || !backend_->params().is_valid()) {
return;
}
const AudioRenderingParams& params = backend_->params();
if (cached_size_ != size()
|| cached_scale_ != GetScale()
|| cached_scroll_ != GetScroll()) {
cached_waveform_ = QPixmap(size());
cached_waveform_.fill(Qt::transparent);
QFile fs(backend_->CachePathName());
if (fs.open(QFile::ReadOnly)) {
QPainter wave_painter(&cached_waveform_);
// FIXME: Hardcoded color
wave_painter.setPen(Qt::green);
int channel_height = height() / params.channel_count();
int channel_half_height = channel_height / 2;
int drew = 0;
fs.seek(params.samples_to_bytes(ScreenToUnitRounded(0)));
for (int x=0; x<width() && !fs.atEnd(); x++) {
int samples_len = ScreenToUnitRounded(x+1) - ScreenToUnitRounded(x);
int max_read_size = params.samples_to_bytes(samples_len);
QByteArray read_buffer = fs.read(max_read_size);
// Detect whether we've reached EOF and recalculate sample count if so
if (read_buffer.size() < max_read_size) {
samples_len = params.bytes_to_samples(read_buffer.size());
}
QVector<SampleSummer::Sum> samples = SampleSummer::SumSamples(reinterpret_cast<const float*>(read_buffer.constData()),
samples_len,
params.channel_count());
for (int i=0;i<params.channel_count();i++) {
if (Config::Current()[QStringLiteral("RectifiedWaveforms")].toBool()) {
int channel_bottom = channel_height * (i + 1);
int diff = qRound((samples.at(i).max - samples.at(i).min) * channel_half_height);
wave_painter.drawLine(x,
channel_bottom - diff,
x,
channel_bottom);
} else {
int channel_mid = channel_height * i + channel_half_height;
wave_painter.drawLine(x,
channel_mid + samples.at(i).min * static_cast<float>(channel_half_height),
x,
channel_mid + samples.at(i).max * static_cast<float>(channel_half_height));
}
drew++;
}
}
cached_size_ = size();
cached_scale_ = GetScale();
cached_scroll_ = GetScroll();
fs.close();
}
}
QPainter p(this);
// Draw in/out points
DrawTimelinePoints(&p);
// Draw cached waveform pixmap
p.drawPixmap(0, 0, cached_waveform_);
// Draw playhead
p.setPen(GetPlayheadColor());
int playhead_x = UnitToScreen(GetTime());
p.drawLine(playhead_x, 0, playhead_x, height());
}
void AudioWaveformView::BackendParamsChanged()
{
SetTimebase(backend_->params().time_base());
}
@@ -8,11 +8,11 @@
#include "render/backend/audiorenderbackend.h"
#include "widget/timeruler/seekablewidget.h"
class WaveformView : public SeekableWidget
class AudioWaveformView : public SeekableWidget
{
Q_OBJECT
public:
WaveformView(QWidget* parent = nullptr);
AudioWaveformView(QWidget* parent = nullptr);
//void SetData(const QString& file, const AudioRenderingParams& params);
@@ -26,6 +26,11 @@ protected:
private:
AudioRenderBackend* backend_;
QPixmap cached_waveform_;
QSize cached_size_;
double cached_scale_;
int cached_scroll_;
private slots:
void BackendParamsChanged();
+5 -5
View File
@@ -61,7 +61,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
sizer_->SetWidget(gl_widget_);
// Create waveform view when audio is connected and video isn't
waveform_view_ = new WaveformView();
waveform_view_ = new AudioWaveformView();
stack_->addWidget(waveform_view_);
// Create time ruler
@@ -70,7 +70,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
// Create scrollbar
layout->addWidget(scrollbar());
connect(scrollbar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll);
connect(scrollbar(), &QScrollBar::valueChanged, waveform_view_, &WaveformView::SetScroll);
connect(scrollbar(), &QScrollBar::valueChanged, waveform_view_, &AudioWaveformView::SetScroll);
// Create lower controls
controls_ = new PlaybackControls();
@@ -96,7 +96,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
audio_renderer_ = new AudioBackend(this);
waveform_view_->SetBackend(audio_renderer_);
connect(waveform_view_, &WaveformView::TimeChanged, this, &ViewerWidget::SetTimeAndSignal);
connect(waveform_view_, &AudioWaveformView::TimeChanged, this, &ViewerWidget::SetTimeAndSignal);
connect(PixelFormat::instance(), &PixelFormat::FormatChanged, this, &ViewerWidget::UpdateRendererParameters);
@@ -306,8 +306,8 @@ void ViewerWidget::PushScrubbedAudio()
QIODevice* audio_src = audio_renderer_->GetAudioPullDevice();
if (audio_src && audio_src->open(QFile::ReadOnly)) {
// Try to get one "frame" of audio
int size_of_sample = audio_renderer_->params().time_to_bytes(timebase());
// FIXME: Hardcoded scrubbing interval (20ms)
int size_of_sample = audio_renderer_->params().time_to_bytes(rational(20, 1000));
// Push audio
audio_src->seek(audio_renderer_->params().time_to_bytes(GetTime()));
+2 -2
View File
@@ -28,6 +28,7 @@
#include <QTimer>
#include <QWidget>
#include "audiowaveformview.h"
#include "common/rational.h"
#include "node/output/viewer/viewer.h"
#include "render/backend/opengl/openglbackend.h"
@@ -35,7 +36,6 @@
#include "render/backend/audio/audiobackend.h"
#include "viewerglwidget.h"
#include "viewersizer.h"
#include "waveformview.h"
#include "widget/playbackcontrols/playbackcontrols.h"
#include "widget/timebased/timebased.h"
@@ -159,7 +159,7 @@ private:
bool time_changed_from_timer_;
WaveformView* waveform_view_;
AudioWaveformView* waveform_view_;
private slots:
void PlaybackTimerUpdate();
-148
View File
@@ -1,148 +0,0 @@
#include "waveformview.h"
#include <QFile>
#include <QPainter>
#include <QtMath>
#include "common/clamp.h"
WaveformView::WaveformView(QWidget *parent) :
SeekableWidget(parent),
backend_(nullptr)
{
setAutoFillBackground(true);
setBackgroundRole(QPalette::Base);
}
void WaveformView::SetBackend(AudioRenderBackend *backend)
{
if (backend_) {
disconnect(backend_, &AudioRenderBackend::QueueComplete, this, static_cast<void (WaveformView::*)()>(&WaveformView::update));
disconnect(backend_, &AudioRenderBackend::ParamsChanged, this, &WaveformView::BackendParamsChanged);
SetTimebase(0);
}
backend_ = backend;
if (backend_) {
connect(backend_, &AudioRenderBackend::QueueComplete, this, static_cast<void (WaveformView::*)()>(&WaveformView::update));
connect(backend_, &AudioRenderBackend::ParamsChanged, this, &WaveformView::BackendParamsChanged);
SetTimebase(backend_->params().time_base());
}
update();
}
void WaveformView::DrawWaveform(QPainter *painter, const QRect& rect, const double& scale, const SampleSummer::Sum* samples, int nb_samples, int channels)
{
int sample_index, next_sample_index = 0;
QVector<SampleSummer::Sum> summary;
int summary_index = -1;
int channel_height = rect.height() / channels;
int channel_half_height = channel_height / 2;
for (int i=0;i<rect.width();i++) {
sample_index = next_sample_index;
if (sample_index == nb_samples) {
break;
}
next_sample_index = qMin(nb_samples,
qFloor(static_cast<double>(SampleSummer::kSumSampleRate) * static_cast<double>(i+1) / scale) * channels);
if (summary_index != sample_index) {
summary = SampleSummer::ReSumSamples(&samples[sample_index],
qMax(channels, next_sample_index - sample_index),
channels);
summary_index = sample_index;
}
int line_x = i + rect.x();
for (int j=0;j<summary.size();j++) {
int channel_mid = rect.y() + channel_height * j + channel_half_height;
painter->drawLine(line_x,
channel_mid + clamp(qRound(summary.at(j).min * channel_half_height), -channel_half_height, channel_half_height),
line_x,
channel_mid + clamp(qRound(summary.at(j).max * channel_half_height), -channel_half_height, channel_half_height));
}
}
}
void WaveformView::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
if (!backend_ || backend_->CachePathName().isEmpty() || !backend_->params().is_valid()) {
return;
}
const AudioRenderingParams& params = backend_->params();
QFile fs(backend_->CachePathName());
if (fs.open(QFile::ReadOnly)) {
QPainter p(this);
DrawTimelinePoints(&p);
// FIXME: Hardcoded color
p.setPen(Qt::green);
int channel_height = height() / params.channel_count();
int channel_half_height = channel_height / 2;
int drew = 0;
fs.seek(params.samples_to_bytes(ScreenToUnitRounded(0)));
for (int x=0; x<width() && !fs.atEnd(); x++) {
int samples_len = ScreenToUnitRounded(x+1) - ScreenToUnitRounded(x);
int max_read_size = params.samples_to_bytes(samples_len);
QByteArray read_buffer = fs.read(max_read_size);
// Detect whether we've reached EOF and recalculate sample count if so
if (read_buffer.size() < max_read_size) {
samples_len = params.bytes_to_samples(read_buffer.size());
}
QVector<SampleSummer::Sum> samples = SampleSummer::SumSamples(reinterpret_cast<const float*>(read_buffer.constData()),
samples_len,
params.channel_count());
for (int i=0;i<params.channel_count();i++) {
int channel_mid = channel_height * i + channel_half_height;
p.drawLine(x,
channel_mid + samples.at(i).min * static_cast<float>(channel_half_height),
x,
channel_mid + samples.at(i).max * static_cast<float>(channel_half_height));
drew++;
}
}
fs.close();
// Draw playhead
p.setPen(GetPlayheadColor());
int playhead_x = UnitToScreen(GetTime());
p.drawLine(playhead_x, 0, playhead_x, height());
}
}
void WaveformView::BackendParamsChanged()
{
SetTimebase(rational(1, backend_->params().sample_rate()));
}
+2 -6
View File
@@ -100,9 +100,6 @@ MainMenu::MainMenu(QMainWindow *parent) :
view_show_all_item_ = view_menu_->AddItem("showall", nullptr, nullptr, "\\");
view_show_all_item_->setCheckable(true);
view_menu_->addSeparator();
view_rectified_waveforms_item_ = view_menu_->AddItem("rectifiedwaveforms", nullptr, nullptr);
view_rectified_waveforms_item_->setCheckable(true);
view_menu_->addSeparator();
frame_view_mode_group_ = new QActionGroup(this);
@@ -327,7 +324,7 @@ void MainMenu::TimecodeDisplayTriggered()
Timecode::Display display = static_cast<Timecode::Display>(action->data().toInt());
// Set the current display mode
Timecode::SetCurrentDisplay(display);
Core::instance()->SetTimecodeDisplay(display);
}
void MainMenu::FileMenuAboutToShow()
@@ -343,7 +340,7 @@ void MainMenu::ViewMenuAboutToShow()
// Ensure checked timecode display mode is correct
QList<QAction*> timecode_display_actions = frame_view_mode_group_->actions();
foreach (QAction* a, timecode_display_actions) {
if (a->data() == Timecode::CurrentDisplay()) {
if (a->data() == Core::instance()->GetTimecodeDisplay()) {
a->setChecked(true);
break;
}
@@ -553,7 +550,6 @@ void MainMenu::Retranslate()
view_increase_track_height_item_->setText(tr("Increase Track Height"));
view_decrease_track_height_item_->setText(tr("Decrease Track Height"));
view_show_all_item_->setText(tr("Toggle Show All"));
view_rectified_waveforms_item_->setText(tr("Rectified Waveforms"));
view_timecode_view_frames_item_->setText(tr("Frames"));
view_timecode_view_dropframe_item_->setText(tr("Drop Frame"));
view_timecode_view_nondropframe_item_->setText(tr("Non-Drop Frame"));
-1
View File
@@ -181,7 +181,6 @@ private:
QAction* view_increase_track_height_item_;
QAction* view_decrease_track_height_item_;
QAction* view_show_all_item_;
QAction* view_rectified_waveforms_item_;
QActionGroup* frame_view_mode_group_;
QAction* view_timecode_view_dropframe_item_;
QAction* view_timecode_view_nondropframe_item_;