From e7f05ff64be02f8344b20ee4f7bc98666dd32dc7 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 22 Jan 2019 12:57:00 +1100 Subject: [PATCH] fixed audio monitor regression --- playback/audio.cpp | 62 ++++++++++++--------------- playback/audio.h | 4 +- project/effect.cpp | 7 +-- ui/audiomonitor.cpp | 101 +++++++++++++++++--------------------------- ui/audiomonitor.h | 16 +++---- 5 files changed, 77 insertions(+), 113 deletions(-) diff --git a/playback/audio.cpp b/playback/audio.cpp index 87be6a646..bfbe73067 100644 --- a/playback/audio.cpp +++ b/playback/audio.cpp @@ -164,47 +164,36 @@ void AudioSenderThread::run() { lock.unlock(); } -int AudioSenderThread::send_audio_to_output(int offset, int max) { +int AudioSenderThread::send_audio_to_output(unsigned long offset, int max) { // send audio to device unsigned long actual_write = audio_io_device->write((const char*) audio_ibuffer+offset, max); unsigned long audio_ibuffer_limit = audio_ibuffer_read + actual_write; - // send samples to audio monitor cache - // TODO make this work for the footage viewer - currently, enabling it causes crash due to an ASSERT - Sequence* s = nullptr; - /*if (panel_footage_viewer->playing) { - s = panel_footage_viewer->seq; - }*/ - if (panel_sequence_viewer->playing) { - s = panel_sequence_viewer->seq; - } - if (s != nullptr) { - if (panel_timeline->audio_monitor->sample_cache_offset == -1) { - panel_timeline->audio_monitor->sample_cache_offset = s->playhead; - } - int channel_count = av_get_channel_layout_nb_channels(s->audio_layout); - long sample_cache_playhead = panel_timeline->audio_monitor->sample_cache_offset + (panel_timeline->audio_monitor->sample_cache.size()/channel_count); - unsigned long next_buffer_offset, buffer_offset_adjusted; - int i; - unsigned long buffer_offset = get_buffer_offset_from_frame(s->frame_rate, sample_cache_playhead); - if (samples.size() != channel_count) samples.resize(channel_count); - samples.fill(0); + if (actual_write > 0) { + // average values and send to audio monitor + int channels = audio_output->format().channelCount(); + unsigned long lim = offset + actual_write; + QVector averages; + averages.resize(channels); + averages.fill(0); - // TODO: I don't like this, but i'm not sure if there's a smarter way to do it - while (static_cast(buffer_offset) < audio_ibuffer_limit) { - sample_cache_playhead++; - next_buffer_offset = qMin(get_buffer_offset_from_frame(s->frame_rate, sample_cache_playhead), static_cast(audio_ibuffer_limit)); - while (buffer_offset < next_buffer_offset) { - for (i=0;iaudio_monitor->sample_cache.append(samples); - buffer_offset = next_buffer_offset; + for (int i=0;iaudio_monitor->set_value(averages); } memset(audio_ibuffer+offset, 0, actual_write); @@ -214,6 +203,11 @@ int AudioSenderThread::send_audio_to_output(int offset, int max) { return actual_write; } +double log_volume(double linear) { + // expects a value between 0 and 1 (or more if amplifying) + return (qExp(linear)-1)/(M_E-1); +} + void int32_to_char_array(qint32 i, char* array) { memcpy(array, &i, 4); } diff --git a/playback/audio.h b/playback/audio.h index 980641854..7ea138425 100644 --- a/playback/audio.h +++ b/playback/audio.h @@ -27,9 +27,11 @@ public slots: void notifyReceiver(); private: QVector samples; - int send_audio_to_output(int offset, int max); + int send_audio_to_output(unsigned long offset, int max); }; +double log_volume(double linear); + extern QAudioOutput* audio_output; extern QIODevice* audio_io_device; extern AudioSenderThread* audio_thread; diff --git a/project/effect.cpp b/project/effect.cpp index ddf2748ad..f8a597231 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -693,7 +693,7 @@ void Effect::startEffect() { void Effect::endEffect() { if (bound) glslProgram->release(); - bound = false; + bound = false; } void Effect::process_image(double, uint8_t *, uint8_t *, int){} @@ -912,8 +912,3 @@ qint16 mix_audio_sample(qint16 a, qint16 b) { mixed_sample = qMax(qMin(mixed_sample, static_cast(INT16_MAX)), static_cast(INT16_MIN)); return static_cast(mixed_sample); } - -double log_volume(double linear) { - // expects a value between 0 and 1 (or more if amplifying) - return (qExp(linear)-1)/(M_E-1); -} diff --git a/ui/audiomonitor.cpp b/ui/audiomonitor.cpp index 12738aa4b..52003f72f 100644 --- a/ui/audiomonitor.cpp +++ b/ui/audiomonitor.cpp @@ -9,6 +9,8 @@ #include #include +#include + #define AUDIO_MONITOR_PEAK_HEIGHT 15 #define AUDIO_MONITOR_GAP 3 @@ -16,79 +18,52 @@ extern "C" { #include "libavformat/avformat.h" } -AudioMonitor::AudioMonitor(QWidget *parent) : QWidget(parent) { - reset(); +AudioMonitor::AudioMonitor(QWidget *parent) : + QWidget(parent) +{ + values.resize(2); + values.fill(1.0); } -void AudioMonitor::reset() { - sample_cache_offset = -1; - sample_cache.clear(); - update(); +void AudioMonitor::set_value(const QVector &ivalues) { + values = ivalues; + update(); } void AudioMonitor::resizeEvent(QResizeEvent *e) { - gradient = QLinearGradient(QPoint(0, rect().top()), QPoint(0, rect().bottom())); - gradient.setColorAt(0, Qt::red); - gradient.setColorAt(0.25, Qt::yellow); - gradient.setColorAt(1, Qt::green); - QWidget::resizeEvent(e); + gradient = QLinearGradient(QPoint(0, rect().top()), QPoint(0, rect().bottom())); + gradient.setColorAt(0, Qt::red); + gradient.setColorAt(0.25, Qt::yellow); + gradient.setColorAt(1, Qt::green); + QWidget::resizeEvent(e); } void AudioMonitor::paintEvent(QPaintEvent *) { - if (sequence != nullptr) { - QPainter p(this); - int channel_x = AUDIO_MONITOR_GAP; - int channel_count = av_get_channel_layout_nb_channels(sequence->audio_layout); - /*if (peaks.size() != channel_count) { - peaks.resize(channel_count); - peaks.fill(false); - }*/ - int channel_width = (width()/channel_count) - AUDIO_MONITOR_GAP; - long playhead_offset = -1; - int i; - for (i=0;iaudio_layout); + int channel_count = values.size(); + int channel_width = (width()/channel_count) - AUDIO_MONITOR_GAP; + int i; + for (i=0;i 0) { - playhead_offset = (sequence->playhead - sample_cache_offset) * channel_count; - if (playhead_offset >= 0 && playhead_offset < sample_cache.size()) { - double multiplier = 1 - qAbs((double) sample_cache.at(playhead_offset+i) / 32768.0); // 16-bit int divided to float - /*if (multiplier == (double) 0) { - peaks[i] = true; - }*/ - r.setHeight(r.height()*multiplier); - } else { - reset(); - } - } + bool peak = false; - /*QRect peak_rect(channel_x, 0, channel_width, AUDIO_MONITOR_PEAK_HEIGHT); - if (peaks.at(i)) { - p.fillRect(peak_rect, QColor(255, 0, 0)); - } else { - p.fillRect(peak_rect, QColor(64, 0, 0)); - }*/ + r.setHeight(qRound(r.height()*(values.at(i)))); - p.fillRect(r, QColor(0, 0, 0, 160)); + QRect peak_rect(channel_x, 0, channel_width, AUDIO_MONITOR_PEAK_HEIGHT); + if (peak) { + p.fillRect(peak_rect, QColor(255, 0, 0)); + } else { + p.fillRect(peak_rect, QColor(64, 0, 0)); + } - channel_x += channel_width + AUDIO_MONITOR_GAP; - } - if (playhead_offset > -1) { - // clean up used samples - bool error = false; - while (sample_cache_offset < sequence->playhead && !error) { - sample_cache_offset++; - for (i=0;i sample_cache; - long sample_cache_offset; - void reset(); + explicit AudioMonitor(QWidget *parent = 0); + void set_value(const QVector& values); protected: - void paintEvent(QPaintEvent *); - void resizeEvent(QResizeEvent *); + void paintEvent(QPaintEvent *); + void resizeEvent(QResizeEvent *); signals: public slots: private: - QLinearGradient gradient; -// QVector peaks; + QLinearGradient gradient; + QVector values; }; #endif // AUDIOMONITOR_H