diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2017-01-09 18:52:47 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2017-01-09 18:52:47 +0000 |
| commit | 271718b9cdc2883ad396e049d4cd04341d9b950e (patch) | |
| tree | bf6a1a29f33ed0548a35010f7a2a12ee32c9272c /src | |
| parent | d6813439f538f29e9fe3dfba7b19e4bfb9a4098d (diff) | |
| download | qmmp-271718b9cdc2883ad396e049d4cd04341d9b950e.tar.gz qmmp-271718b9cdc2883ad396e049d4cd04341d9b950e.tar.bz2 qmmp-271718b9cdc2883ad396e049d4cd04341d9b950e.zip | |
added circular buffer for visualization
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6954 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src')
| -rw-r--r-- | src/plugins/Ui/qsui/qsuianalyzer.cpp | 6 | ||||
| -rw-r--r-- | src/qmmp/outputwriter.cpp | 1 | ||||
| -rw-r--r-- | src/qmmp/qmmp.pro | 6 | ||||
| -rw-r--r-- | src/qmmp/visual.cpp | 20 | ||||
| -rw-r--r-- | src/qmmp/visual.h | 9 | ||||
| -rw-r--r-- | src/qmmp/visualbuffer.cpp | 86 | ||||
| -rw-r--r-- | src/qmmp/visualbuffer.h | 63 |
7 files changed, 185 insertions, 6 deletions
diff --git a/src/plugins/Ui/qsui/qsuianalyzer.cpp b/src/plugins/Ui/qsui/qsuianalyzer.cpp index 440d91400..4b5f6f8d9 100644 --- a/src/plugins/Ui/qsui/qsuianalyzer.cpp +++ b/src/plugins/Ui/qsui/qsuianalyzer.cpp @@ -121,7 +121,7 @@ void QSUiAnalyzer::setCover(const QPixmap &pixmap) void QSUiAnalyzer::timeout() { - mutex()->lock(); + /*mutex()->lock(); if(m_buffer_at < VISUAL_NODE_SIZE) { mutex()->unlock (); @@ -132,7 +132,9 @@ void QSUiAnalyzer::timeout() m_buffer_at -= VISUAL_NODE_SIZE; memmove(m_left_buffer, m_left_buffer + VISUAL_NODE_SIZE, m_buffer_at * sizeof(float)); memmove(m_right_buffer, m_right_buffer + VISUAL_NODE_SIZE, m_buffer_at * sizeof(float)); - mutex()->unlock (); + mutex()->unlock ();*/ + takeData(m_left_buffer, m_right_buffer); + process (m_left_buffer, m_right_buffer); update(); } diff --git a/src/qmmp/outputwriter.cpp b/src/qmmp/outputwriter.cpp index fe156e4e8..523462511 100644 --- a/src/qmmp/outputwriter.cpp +++ b/src/qmmp/outputwriter.cpp @@ -190,6 +190,7 @@ void OutputWriter::dispatchVisual (Buffer *buffer) if(!buffer) return; + Visual::addData(buffer->data, buffer->samples, m_channels, m_totalWritten / m_bytesPerMillisecond, m_output->latency()); foreach (Visual *visual, *Visual::visuals()) { visual->mutex()->lock (); diff --git a/src/qmmp/qmmp.pro b/src/qmmp/qmmp.pro index 7a6baa5c8..d5d483a79 100644 --- a/src/qmmp/qmmp.pro +++ b/src/qmmp/qmmp.pro @@ -40,7 +40,8 @@ HEADERS += \ channelmap.h \ channelconverter_p.h \ audioconverter.h \ - dithering_p.h + dithering_p.h \ + visualbuffer.h SOURCES += recycler.cpp \ decoder.cpp \ output.cpp \ @@ -73,7 +74,8 @@ SOURCES += recycler.cpp \ channelmap.cpp \ channelconverter.cpp \ volume.cpp \ - dithering.cpp + dithering.cpp \ + visualbuffer.cpp FORMS += unix:TARGET = ../../lib/qmmp win32:TARGET = ../../../bin/qmmp diff --git a/src/qmmp/visual.cpp b/src/qmmp/visual.cpp index 05bf99e64..121800a33 100644 --- a/src/qmmp/visual.cpp +++ b/src/qmmp/visual.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008-2016 by Ilya Kotov * + * Copyright (C) 2008-2017 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -29,6 +29,7 @@ #include <QPluginLoader> #include "visualfactory.h" #include "output.h" +#include "visualbuffer.h" #include "visual.h" Visual::Visual(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) @@ -70,6 +71,15 @@ void Visual::closeEvent (QCloseEvent *event) QWidget::closeEvent(event); } +void Visual::takeData(float *left, float *right) +{ + m_buffer.mutex()->lock(); + VisualNode *node = m_buffer.take(); + memcpy(left, node->data[0], 512); + memcpy(right, node->data[1], 512); + m_buffer.mutex()->unlock(); +} + //static members QList<VisualFactory*> *Visual::m_factories = 0; QHash <VisualFactory*, QString> *Visual::m_files = 0; @@ -78,6 +88,7 @@ QHash<VisualFactory*, Visual*> Visual::m_vis_map; QWidget *Visual::m_parentWidget = 0; QObject *Visual::m_receiver = 0; const char *Visual::m_member = 0; +VisualBuffer Visual::m_buffer; QList<VisualFactory *> Visual::factories() { @@ -199,6 +210,13 @@ void Visual::showSettings(VisualFactory *factory, QWidget *parent) dialog->deleteLater(); } +void Visual::addData(float *pcm, int samples, int channels, qint64 ts, qint64 delay) +{ + m_buffer.mutex()->lock(); + m_buffer.add(pcm, samples, channels, ts, delay); + m_buffer.mutex()->unlock(); +} + void Visual::checkFactories() { if (!m_factories) diff --git a/src/qmmp/visual.h b/src/qmmp/visual.h index 26de8d230..9f3b99b07 100644 --- a/src/qmmp/visual.h +++ b/src/qmmp/visual.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008-2014 by Ilya Kotov * + * Copyright (C) 2008-2017 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -30,6 +30,7 @@ class Buffer; class Decoder; class Output; class VisualFactory; +class VisualBuffer; /*! @brief The Visual class provides the base interface class of visualizations. * @author Ilya Kotov <forkotov02@hotmail.ru> @@ -111,6 +112,9 @@ public: */ static void showSettings(VisualFactory *factory, QWidget *parent); + + static void addData(float *pcm, int samples, int channels, qint64 ts, qint64 delay); + signals: /*! * Emitted when visual widget is closed by user. @@ -124,6 +128,8 @@ protected: */ virtual void closeEvent (QCloseEvent *event); + virtual void takeData(float *left, float *right); + private: Decoder *m_decoder; Output *m_output; @@ -137,6 +143,7 @@ private: static QWidget *m_parentWidget; static QObject *m_receiver; static const char *m_member; + static VisualBuffer m_buffer; }; #endif diff --git a/src/qmmp/visualbuffer.cpp b/src/qmmp/visualbuffer.cpp new file mode 100644 index 000000000..2cfac86b1 --- /dev/null +++ b/src/qmmp/visualbuffer.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2017 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include <string.h> +#include "visualbuffer.h" + +static inline void stereo_from_multichannel(float *l, + float *r, + float *s, + long cnt, int chan) +{ + if(chan == 1) + { + memcpy(l, s, cnt * sizeof(float)); + memcpy(r, s, cnt * sizeof(float)); + return; + } + while (cnt > 0) + { + l[0] = s[0]; + r[0] = s[1]; + s += chan; + l++; + r++; + cnt--; + } +} + +VisualBuffer::VisualBuffer() +{ + consumer_pos = 0; + insertion_pos = 0; + m_elapsed = 0; +} + +void VisualBuffer::add(float *pcm, int samples, int channels, qint64 ts, qint64 delay) +{ + insertion_pos++; + if (insertion_pos == VISUAL_BUFFER_SIZE ) + { + insertion_pos = 0; + } + + VisualNode *b = &m_buffer[insertion_pos]; + stereo_from_multichannel(b->data[0], b->data[1], pcm, qMin(512, samples / channels), channels); + b->ts = ts; + m_elapsed = qMax(0LL, ts - delay); + m_time.restart(); +} + +VisualNode *VisualBuffer::take() +{ + int steps = 0; + int t = m_elapsed + m_time.elapsed(); + while(!m_buffer[consumer_pos].ts || ((m_buffer[consumer_pos].ts < t) && (steps++ < VISUAL_BUFFER_SIZE))) + { + consumer_pos++; + if(consumer_pos == VISUAL_BUFFER_SIZE) + { + consumer_pos = 0; + } + } + return &m_buffer[consumer_pos]; +} + +QMutex *VisualBuffer::mutex() +{ + return &m_mutex; +} diff --git a/src/qmmp/visualbuffer.h b/src/qmmp/visualbuffer.h new file mode 100644 index 000000000..8ddc0c556 --- /dev/null +++ b/src/qmmp/visualbuffer.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2017 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef VISUALBUFFER_H +#define VISUALBUFFER_H + +#include <QtGlobal> +#include <QTime> +#include <QMutex> + +#define VISUAL_BUFFER_SIZE 128 //number of nodes + +class VisualNode +{ +public: + float data[2][512]; + bool used; + qint64 ts; + + VisualNode() + { + used = false; + ts = 0; + } +}; + +class VisualBuffer +{ +public: + VisualBuffer(); + + void add(float *pcm, int samples, int channels, qint64 ts, qint64 delay); + VisualNode *take(); + QMutex *mutex(); + +private: + VisualNode m_buffer[VISUAL_BUFFER_SIZE]; + qint64 m_elapsed; + int consumer_pos; + int insertion_pos; + QTime m_time; + QMutex m_mutex; + +}; + +#endif // VISUALBUFFER_H |
