aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Visual
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2010-10-08 18:06:38 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2010-10-08 18:06:38 +0000
commitc4749f20a5ad31ed8c68c11547120a0d1da45a8f (patch)
tree805248511deeea91f7da2d2881f9afefe9f21b1a /src/plugins/Visual
parent767150cfe9403eb432ea82377664abda214d6e04 (diff)
downloadqmmp-c4749f20a5ad31ed8c68c11547120a0d1da45a8f.tar.gz
qmmp-c4749f20a5ad31ed8c68c11547120a0d1da45a8f.tar.bz2
qmmp-c4749f20a5ad31ed8c68c11547120a0d1da45a8f.zip
dynamic buffer size
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@1928 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/plugins/Visual')
-rw-r--r--src/plugins/Visual/analyzer/analyzer.cpp125
-rw-r--r--src/plugins/Visual/analyzer/analyzer.h32
-rw-r--r--src/plugins/Visual/analyzer/inlines.h93
3 files changed, 66 insertions, 184 deletions
diff --git a/src/plugins/Visual/analyzer/analyzer.cpp b/src/plugins/Visual/analyzer/analyzer.cpp
index c071b12f2..22941892f 100644
--- a/src/plugins/Visual/analyzer/analyzer.cpp
+++ b/src/plugins/Visual/analyzer/analyzer.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2007 by Ilya Kotov *
+ * Copyright (C) 2007-2010 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -32,6 +32,8 @@
#include "inlines.h"
#include "analyzer.h"
+#define VISUAL_NODE_SIZE 512 //samples
+#define VISUAL_BUFFER_SIZE (5*VISUAL_NODE_SIZE)
Analyzer::Analyzer (QWidget *parent)
: Visual (parent), m_fps (20)
@@ -42,8 +44,9 @@ Analyzer::Analyzer (QWidget *parent)
m_pixmap = QPixmap (75,20);
m_timer = new QTimer (this);
connect(m_timer, SIGNAL (timeout()), this, SLOT (timeout()));
- m_nodes.clear();
-
+ m_left_buffer = new short[VISUAL_BUFFER_SIZE];
+ m_right_buffer = new short[VISUAL_BUFFER_SIZE];
+ m_buffer_at = 0;
clear();
setWindowTitle (tr("Qmmp Analyzer"));
@@ -66,14 +69,13 @@ Analyzer::Analyzer (QWidget *parent)
Analyzer::~Analyzer()
{
- while (!m_nodes.isEmpty())
- m_nodes.removeFirst();
+ delete [] m_left_buffer;
+ delete [] m_right_buffer;
}
void Analyzer::clear()
{
- while (!m_nodes.isEmpty())
- m_nodes.removeFirst();
+ m_buffer_at = 0;
for (int i = 0; i< 75; ++i)
{
m_intern_vis_data[i] = 0;
@@ -87,50 +89,44 @@ void Analyzer::add (unsigned char *data, qint64 size, int chan)
if (!m_timer->isActive ())
return;
- short *l = 0, *r = 0;
- qint64 samples = size/chan >> 1;
- int frames = samples/512;
- for (int i = 0; i < frames; ++i)
+ if(VISUAL_BUFFER_SIZE == m_buffer_at)
{
- l = new short[512];
- r = 0;
- if (chan == 2)
- {
- r = new short[512];
- stereo16_from_stereopcm16 (l, r, (short *) (data + i*4*512), 512);
- }
- else if (chan == 1)
- mono16_from_monopcm16 (l, (short *) (data + i*2*512), 512);
- else
- {
- r = new short[512];
- stereo16_from_multichannel(l, r, (short *) (data + i*2*chan*512), 512, chan);
- }
- m_nodes.append (new VisualNode (l, r, 512));
+ m_buffer_at -= VISUAL_NODE_SIZE;
+ memmove(m_left_buffer, m_left_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1);
+ memmove(m_right_buffer, m_right_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1);
+ return;
}
-}
-void Analyzer::timeout()
-{
- VisualNode *node = 0;
- mutex()->lock ();
+ int frames = qMin((int)size/chan >> 1, VISUAL_BUFFER_SIZE - m_buffer_at);
- while(m_nodes.size() > 5)
+ if (chan >= 2)
{
- delete m_nodes.takeFirst();
+ stereo16_from_multichannel(m_left_buffer + m_buffer_at,
+ m_right_buffer + m_buffer_at,(short *) data, frames, chan);
+ }
+ else
+ {
+ memcpy(m_left_buffer + m_buffer_at, (short *) data, frames << 1);
+ memcpy(m_right_buffer + m_buffer_at, (short *) data, frames << 1);
}
- if(!m_nodes.isEmpty())
- node = m_nodes.takeFirst();
-
- mutex()->unlock();
+ m_buffer_at += frames;
+}
- if (node)
+void Analyzer::timeout()
+{
+ mutex()->lock ();
+ if(m_buffer_at < VISUAL_NODE_SIZE)
{
- process (node);
- delete node;
- update();
+ mutex()->unlock ();
+ return;
}
+
+ process (m_left_buffer, m_right_buffer);
+ m_buffer_at -= VISUAL_NODE_SIZE;
+ memmove(m_left_buffer, m_left_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1);
+ memmove(m_right_buffer, m_right_buffer + VISUAL_NODE_SIZE, m_buffer_at << 1);
+ mutex()->unlock ();
update();
}
@@ -159,7 +155,7 @@ void Analyzer::closeEvent (QCloseEvent *event)
Visual::closeEvent(event); //removes visualization before class deleting
}
-bool Analyzer::process (VisualNode *node)
+void Analyzer::process (short *left, short *right)
{
static fft_state *state = 0;
if (!state)
@@ -174,15 +170,9 @@ bool Analyzer::process (VisualNode *node)
36, 47, 62, 82, 107, 141, 184, 255
};
- if (node)
- {
- //i = node->length;
- calc_freq (dest_l, node->left);
- if (node->right)
- calc_freq (dest_r, node->right);
- }
- else
- return false;
+ calc_freq (dest_l, left);
+ calc_freq (dest_r, right);
+
const double y_scale = 3.60673760222; /* 20.0 / log(256) */
int yl,yr, j;
@@ -194,16 +184,14 @@ bool Analyzer::process (VisualNode *node)
{
if (dest_l[j] > yl)
yl = dest_l[j];
- if (dest_r[j] > yr && node->right)
+ if (dest_r[j] > yr)
yr = dest_r[j];
}
yl >>= 7;
+ yr >>= 7;
int magnitude_l = 0;
int magnitude_r = 0;
- if (node->right)
- {
- yr >>= 7;
- }
+
if (yl)
{
magnitude_l = int(log (yl) * y_scale);
@@ -212,7 +200,7 @@ bool Analyzer::process (VisualNode *node)
if (magnitude_l < 0)
magnitude_l = 0;
}
- if (yr && node->right)
+ if (yr)
{
magnitude_r = int(log (yr) * y_scale);
if (magnitude_r > 15)
@@ -224,27 +212,20 @@ bool Analyzer::process (VisualNode *node)
m_intern_vis_data[i] -= m_analyzer_falloff;
m_intern_vis_data[i] = magnitude_l > m_intern_vis_data[i]
? magnitude_l : m_intern_vis_data[i];
- if (node->right)
- {
- m_intern_vis_data[37-i] -= m_analyzer_falloff;
- m_intern_vis_data[37-i] = magnitude_r > m_intern_vis_data[37-i]
- ? magnitude_r : m_intern_vis_data[37-i];
- }
+
+ m_intern_vis_data[37-i] -= m_analyzer_falloff;
+ m_intern_vis_data[37-i] = magnitude_r > m_intern_vis_data[37-i]
+ ? magnitude_r : m_intern_vis_data[37-i];
if (m_show_peaks)
{
m_peaks[i] -= m_peaks_falloff;
- m_peaks[i] = magnitude_l > m_peaks[i]
- ? magnitude_l : m_peaks[i];
- if (node->right)
- {
- m_peaks[37-i] -= m_peaks_falloff;
- m_peaks[37-i] = magnitude_r > m_peaks[37-i]
- ? magnitude_r : m_peaks[37-i];
- }
+ m_peaks[i] = magnitude_l > m_peaks[i] ? magnitude_l : m_peaks[i];
+
+ m_peaks[37-i] -= m_peaks_falloff;
+ m_peaks[37-i] = magnitude_r > m_peaks[37-i] ? magnitude_r : m_peaks[37-i];
}
}
- return true;
}
void Analyzer::draw (QPainter *p)
diff --git a/src/plugins/Visual/analyzer/analyzer.h b/src/plugins/Visual/analyzer/analyzer.h
index 1c0e8974e..d2ff0469a 100644
--- a/src/plugins/Visual/analyzer/analyzer.h
+++ b/src/plugins/Visual/analyzer/analyzer.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2007 by Ilya Kotov *
+ * Copyright (C) 2007-2010 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -23,35 +23,11 @@
#include <QWidget>
#include <QResizeEvent>
#include <qmmp/visual.h>
-#include <QDir>
-class QSettings;
class QTimer;
class QMenu;
class QActionGroup;
-class Buffer;
-
-
-class VisualNode
-{
-public:
- VisualNode(short *l, short *r, unsigned long n)
- : left(l), right(r), length(n)
- {
- // left and right are allocated and then passed to this class
- // the code that allocated left and right should give up all ownership
- }
-
- ~VisualNode()
- {
- delete [] left;
- delete [] right;
- }
-
- short *left, *right;
- long length;
-};
class Analyzer : public Visual
{
@@ -74,11 +50,10 @@ public slots:
void timeout();
private:
- bool process(VisualNode *node);
+ void process(short *l, short *r);
void draw(QPainter *p);
QPixmap m_pixmap;
QPixmap m_bg;
- QList <VisualNode*> m_nodes;
QTimer *m_timer;
int m_fps;
double m_intern_vis_data[75];
@@ -86,6 +61,9 @@ private:
double m_peaks_falloff;
double m_analyzer_falloff;
bool m_show_peaks;
+ short *m_left_buffer;
+ short *m_right_buffer;
+ int m_buffer_at;
//colors
QColor m_color1;
QColor m_color2;
diff --git a/src/plugins/Visual/analyzer/inlines.h b/src/plugins/Visual/analyzer/inlines.h
index e2c48d019..39b81bd57 100644
--- a/src/plugins/Visual/analyzer/inlines.h
+++ b/src/plugins/Visual/analyzer/inlines.h
@@ -10,8 +10,7 @@
#include "fft.h"
// *fast* convenience functions
-static inline void
-calc_freq(short* dest, short *src)
+static inline void calc_freq(short* dest, short *src)
{
static fft_state *state = NULL;
float tmp_out[257];
@@ -26,27 +25,6 @@ calc_freq(short* dest, short *src)
dest[i] = ((int) sqrt(tmp_out[i + 1])) >> 8;
}
-static inline void
-calc_mono_freq(short dest[2][256], short src[2][512], int nch)
-{
- int i;
- short *d, *sl, *sr, tmp[512];
-
- if (nch == 1)
- calc_freq(dest[0], src[0]);
- else
- {
- d = tmp;
- sl = src[0];
- sr = src[1];
- for (i = 0; i < 512; i++)
- {
- *(d++) = (*(sl++) + *(sr++)) >> 1;
- }
- calc_freq(dest[0], tmp);
- }
-}
-
static inline void stereo16_from_multichannel(register short *l,
register short *r,
register short *s,
@@ -63,71 +41,16 @@ static inline void stereo16_from_multichannel(register short *l,
}
}
-
-static inline void stereo16_from_stereopcm16(register short *l,
- register short *r,
- register short *s,
- long cnt)
-{
- while (cnt >= 4l)
- {
- l[0] = s[0];
- r[0] = s[1];
- l[1] = s[2];
- r[1] = s[3];
- l[2] = s[4];
- r[2] = s[5];
- l[3] = s[6];
- r[3] = s[7];
- l += 4;
- r += 4;
- s += 8;
- cnt -= 4l;
- }
-
- if (cnt > 0l)
- {
- l[0] = s[0];
- r[0] = s[1];
- if (cnt > 1l)
- {
- l[1] = s[2];
- r[1] = s[3];
- if (cnt > 2l)
- {
- l[2] = s[4];
- r[2] = s[5];
- }
- }
- }
-}
-
-static inline void mono16_from_monopcm16(register short *l,
- register short *s,
- long cnt)
+static inline void mono16_from_multichannel(register short *l,
+ register short *s,
+ long cnt, int chan)
{
- while (cnt >= 4l)
- {
- l[0] = s[0];
- l[1] = s[1];
- l[2] = s[2];
- l[3] = s[3];
- l += 4;
- s += 4;
- cnt -= 4l;
- }
-
- if (cnt > 0l)
+ while (cnt > 0)
{
l[0] = s[0];
- if (cnt > 1l)
- {
- l[1] = s[1];
- if (cnt > 2l)
- {
- l[2] = s[2];
- }
- }
+ s += chan;
+ l++;
+ cnt--;
}
}