aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2017-01-09 18:52:47 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2017-01-09 18:52:47 +0000
commit271718b9cdc2883ad396e049d4cd04341d9b950e (patch)
treebf6a1a29f33ed0548a35010f7a2a12ee32c9272c /src
parentd6813439f538f29e9fe3dfba7b19e4bfb9a4098d (diff)
downloadqmmp-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.cpp6
-rw-r--r--src/qmmp/outputwriter.cpp1
-rw-r--r--src/qmmp/qmmp.pro6
-rw-r--r--src/qmmp/visual.cpp20
-rw-r--r--src/qmmp/visual.h9
-rw-r--r--src/qmmp/visualbuffer.cpp86
-rw-r--r--src/qmmp/visualbuffer.h63
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