From 358d1ba16a44eb6ef8becedcf48ea2997052eb1c Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 11 Apr 2019 10:23:38 +1000 Subject: [PATCH] audio monitor functional with float system --- rendering/audio.cpp | 26 ++++++++--------------- ui/audiomonitor.cpp | 52 ++++++++++++++++++++++++++++++++------------- ui/audiomonitor.h | 22 ++++++++++++++----- 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/rendering/audio.cpp b/rendering/audio.cpp index 1faaf4bf1..105524ab9 100644 --- a/rendering/audio.cpp +++ b/rendering/audio.cpp @@ -209,33 +209,25 @@ int AudioSenderThread::send_audio_to_output(qint64 offset, int max) { // send audio to device audio_write_lock.lock(); - qint64 actual_write = audio_io_device->write(reinterpret_cast(audio_ibuffer+offset), max); + qint64 actual_write = audio_io_device->write(reinterpret_cast(&audio_ibuffer[offset]), max); - /* if (actual_write > 0) { // average values and send to audio monitor int channels = audio_output->format().channelCount(); - qint64 lim = offset + actual_write; - QVector averages; + qint64 lim = offset + (actual_write/sizeof(float)); + QVector averages; averages.resize(channels); - averages.fill(0); + averages.fill(0.0); - int counter = 0; - qint16 sample; - for (qint64 i=offset;iaudio_monitor->set_value(averages); } - */ - memset(audio_ibuffer+offset, 0, actual_write); + memset(&audio_ibuffer[offset], 0, actual_write); audio_ibuffer_read += (actual_write / sizeof(float)); @@ -246,7 +238,7 @@ int AudioSenderThread::send_audio_to_output(qint64 offset, int max) { double log_volume(double linear) { // expects a value between 0 and 1 (or more if amplifying) - return (qExp(linear)-1)/(M_E-1); + return (qExp(linear)-1.0f)/(M_E-1.0f); } void int32_to_char_array(qint32 i, char* array) { diff --git a/ui/audiomonitor.cpp b/ui/audiomonitor.cpp index b3628ad74..61e1f07ee 100644 --- a/ui/audiomonitor.cpp +++ b/ui/audiomonitor.cpp @@ -37,25 +37,33 @@ extern "C" { } AudioMonitor::AudioMonitor(QWidget *parent) : - QWidget(parent) + QWidget(parent), + peaked_(false) { clear_timer.setInterval(500); connect(&clear_timer, SIGNAL(timeout()), this, SLOT(clear())); } -void AudioMonitor::set_value(const QVector &ivalues) { - value_lock.lock(); - values = ivalues; - value_lock.unlock(); +void AudioMonitor::set_value(const QVector &ivalues) { + if (value_lock.tryLock()) { + values = ivalues; - QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection); - QMetaObject::invokeMethod(&clear_timer, "start", Qt::QueuedConnection); + if (peaked_.size() != values.size()) { + peaked_.resize(values.size()); + peaked_.fill(false); + } + + value_lock.unlock(); + + QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection); + QMetaObject::invokeMethod(&clear_timer, "start", Qt::QueuedConnection); + } } void AudioMonitor::clear() { clear_timer.stop(); - - values.fill(1); + peaked_.fill(false); + values.fill(0.0); update(); } @@ -67,6 +75,12 @@ void AudioMonitor::resizeEvent(QResizeEvent *e) { QWidget::resizeEvent(e); } +void AudioMonitor::mousePressEvent(QMouseEvent *) +{ + peaked_.fill(false); + update(); +} + void AudioMonitor::paintEvent(QPaintEvent *) { value_lock.lock(); if (values.size() > 0) { @@ -74,18 +88,26 @@ void AudioMonitor::paintEvent(QPaintEvent *) { int channel_x = AUDIO_MONITOR_GAP; int channel_count = values.size(); int channel_width = (width()/channel_count) - AUDIO_MONITOR_GAP; - int i; - for (i=0;i 1.0f) { + peaked_[i] = true; + } - r.setHeight(qRound(r.height()*(values.at(i)))); - peak = (r.height() == 0); + // We draw an inverted dark shadow over the gradient to represent to are not lit up + // TODO change to decibel representation + float val = 1.0f - qMin(1.0f, values.at(i)); + r.setHeight(qRound(r.height()*val)); QRect peak_rect(channel_x, 0, channel_width, AUDIO_MONITOR_PEAK_HEIGHT); - if (peak) { + if (peaked_[i]) { + // We're peaked on this channel, so we light up the peak light p.fillRect(peak_rect, QColor(255, 0, 0)); } else { p.fillRect(peak_rect, QColor(64, 0, 0)); diff --git a/ui/audiomonitor.h b/ui/audiomonitor.h index 70898ce60..f6a4505c2 100644 --- a/ui/audiomonitor.h +++ b/ui/audiomonitor.h @@ -53,22 +53,29 @@ public: * An array of doubles between 0.0 and 1.0 to display the amplitude. 0.0 is no audio, 1.0 is full volume. Each array * entry is a channel and the audio monitor will automatically adjust to the channel count in the array. */ - void set_value(const QVector& values); + void set_value(const QVector &values); protected: /** * @brief Internal paint event * - * Paints the + * Paints the audio monitor */ - void paintEvent(QPaintEvent *); + virtual void paintEvent(QPaintEvent *) override; /** * @brief Internal resize event handler * * Triggers a repaint when the widget is resized. */ - void resizeEvent(QResizeEvent *); + virtual void resizeEvent(QResizeEvent *) override; + + /** + * @brief Internal mouse press handler + * + * @param event + */ + virtual void mousePressEvent(QMouseEvent *event) override; signals: @@ -83,7 +90,7 @@ private: /** * @brief Internal value storage */ - QVector values; + QVector values; /** * @brief Value mutex @@ -100,6 +107,11 @@ private: */ QTimer clear_timer; + /** + * @brief Internal variable for whether audio played as peaked or not + */ + QVector peaked_; + private slots: /** * @brief Slot to clear the audio monitor