aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Ui/qsui
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Ui/qsui')
-rw-r--r--src/plugins/Ui/qsui/fft.c15
-rw-r--r--src/plugins/Ui/qsui/fft.h9
-rw-r--r--src/plugins/Ui/qsui/inlines.h31
-rw-r--r--src/plugins/Ui/qsui/logo.cpp25
-rw-r--r--src/plugins/Ui/qsui/logo.h6
-rw-r--r--src/plugins/Ui/qsui/qsuianalyzer.cpp44
-rw-r--r--src/plugins/Ui/qsui/qsuianalyzer.h10
7 files changed, 82 insertions, 58 deletions
diff --git a/src/plugins/Ui/qsui/fft.c b/src/plugins/Ui/qsui/fft.c
index 0ea89eae6..2865e878e 100644
--- a/src/plugins/Ui/qsui/fft.c
+++ b/src/plugins/Ui/qsui/fft.c
@@ -25,6 +25,11 @@
* More optimisations.
*/
+/*
+ modifications compared to original code:
+ using float format for input data
+*/
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
@@ -56,7 +61,7 @@ struct _struct_fft_state {
/* # Local function prototypes # */
/* ############################# */
-static void fft_prepare(const sound_sample * input, float *re, float *im);
+static void fft_prepare(const float *input, float *re, float *im);
static void fft_calculate(float *re, float *im);
static void fft_output(const float *re, const float *im, float *output);
static int reverseBits(unsigned int initial);
@@ -126,7 +131,7 @@ fft_init(void)
* state is a (non-NULL) pointer returned by fft_init.
*/
void
-fft_perform(const sound_sample * input, float *output, fft_state * state)
+fft_perform(const float *input, float *output, fft_state * state)
{
/* Convert data from sound format to be ready for FFT */
fft_prepare(input, state->real, state->imag);
@@ -156,7 +161,7 @@ fft_close(fft_state * state)
* Prepare data to perform an FFT on
*/
static void
-fft_prepare(const sound_sample * input, float *re, float *im)
+fft_prepare(const float *input, float *re, float *im)
{
unsigned int i;
float *realptr = re;
@@ -164,7 +169,7 @@ fft_prepare(const sound_sample * input, float *re, float *im)
/* Get input, in reverse bit order */
for (i = 0; i < FFT_BUFFER_SIZE; i++) {
- *realptr++ = input[bitReverse[i]];
+ *realptr++ = input[bitReverse[i]] * 32767.0;
*imagptr++ = 0;
}
}
@@ -174,7 +179,7 @@ fft_prepare(const sound_sample * input, float *re, float *im)
* Note: only produces half as many data points as the input had.
* This is roughly a consequence of the Nyquist sampling theorm thingy.
* (FIXME - make this comment better, and helpful.)
- *
+ *
* The two divisions by 4 are also a consequence of this: the contributions
* returned for each frequency are split into two parts, one at i in the
* table, and the other at FFT_BUFFER_SIZE - i, except for i = 0 and
diff --git a/src/plugins/Ui/qsui/fft.h b/src/plugins/Ui/qsui/fft.h
index 915bccaf6..c24e2e584 100644
--- a/src/plugins/Ui/qsui/fft.h
+++ b/src/plugins/Ui/qsui/fft.h
@@ -23,8 +23,11 @@
#define FFT_BUFFER_SIZE (1 << FFT_BUFFER_SIZE_LOG)
-/* sound sample - should be an signed 16 bit value */
-typedef short int sound_sample;
+/*
+ modifications compared to original code:
+ using float format for input data
+*/
+
#ifdef __cplusplus
extern "C" {
@@ -33,7 +36,7 @@ extern "C" {
/* FFT library */
typedef struct _struct_fft_state fft_state;
fft_state *fft_init(void);
- void fft_perform(const sound_sample * input, float *output,
+ void fft_perform(const float *input, float *output,
fft_state * state);
void fft_close(fft_state * state);
diff --git a/src/plugins/Ui/qsui/inlines.h b/src/plugins/Ui/qsui/inlines.h
index 39b81bd57..8203de336 100644
--- a/src/plugins/Ui/qsui/inlines.h
+++ b/src/plugins/Ui/qsui/inlines.h
@@ -4,13 +4,20 @@
// warranty, or liability of any kind.
//
+/*
+ modifications compared to original code:
+ using float format
+*/
+
#ifndef INLINES_H
#define INLINES_H
#include "fft.h"
+#include <math.h>
+#include <string.h>
// *fast* convenience functions
-static inline void calc_freq(short* dest, short *src)
+static inline void calc_freq(short* dest, float *src)
{
static fft_state *state = NULL;
float tmp_out[257];
@@ -25,11 +32,17 @@ static inline void calc_freq(short* dest, short *src)
dest[i] = ((int) sqrt(tmp_out[i + 1])) >> 8;
}
-static inline void stereo16_from_multichannel(register short *l,
- register short *r,
- register short *s,
+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];
@@ -41,10 +54,16 @@ static inline void stereo16_from_multichannel(register short *l,
}
}
-static inline void mono16_from_multichannel(register short *l,
- register short *s,
+static inline void mono_from_multichannel(float *l,
+ float *s,
long cnt, int chan)
{
+ if(chan == 1)
+ {
+ memcpy(l, s, cnt * sizeof(float));
+ return;
+ }
+
while (cnt > 0)
{
l[0] = s[0];
diff --git a/src/plugins/Ui/qsui/logo.cpp b/src/plugins/Ui/qsui/logo.cpp
index 49ec2f275..1de6c663a 100644
--- a/src/plugins/Ui/qsui/logo.cpp
+++ b/src/plugins/Ui/qsui/logo.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2011-2014 by Ilya Kotov *
+ * Copyright (C) 2011-2015 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -23,6 +23,7 @@
#include <QTimer>
#include <stdlib.h>
#include <qmmp/qmmp.h>
+#include "inlines.h"
#include "logo.h"
#define VISUAL_NODE_SIZE 128 //samples
@@ -73,7 +74,7 @@ Logo::Logo(QWidget *parent) : Visual(parent)
m_buffer_at = 0;
m_value = 0;
m_elapsed = 0;
- m_buffer = new short[VISUAL_BUFFER_SIZE];
+ m_buffer = new float[VISUAL_BUFFER_SIZE];
updateLetters();
Visual::add(this);
@@ -82,20 +83,22 @@ Logo::Logo(QWidget *parent) : Visual(parent)
Logo::~Logo()
{
Visual::remove(this);
+ delete[] m_buffer;
}
-void Logo::add(unsigned char *data, qint64 size, int chan)
+void Logo::add(float *data, size_t samples, int chan)
{
Q_UNUSED(chan);
if(VISUAL_BUFFER_SIZE == m_buffer_at)
{
m_buffer_at -= VISUAL_NODE_SIZE;
- memmove(m_buffer, (short*) (m_buffer + VISUAL_NODE_SIZE), m_buffer_at * 2);
+ memmove(m_buffer, (m_buffer + VISUAL_NODE_SIZE), m_buffer_at * sizeof(float));
return;
}
- int size_2 = qMin((int)size/2, VISUAL_BUFFER_SIZE - m_buffer_at);
- memcpy((ushort*)(m_buffer + m_buffer_at), (short*) data, size_2 * 2);
- m_buffer_at += size_2;
+ int frames = qMin(int(samples/chan), VISUAL_BUFFER_SIZE - m_buffer_at);
+
+ mono_from_multichannel(m_buffer + m_buffer_at, data, frames, chan);
+ m_buffer_at += frames;
}
void Logo::clear()
@@ -239,11 +242,11 @@ void Logo::processPreset4()
for(int j = 0; j < VISUAL_NODE_SIZE; j+=8)
{
if(m_buffer[j] > max)
- max = m_buffer[j];
+ max = abs(m_buffer[j] * 65536.0);
}
m_buffer_at -= VISUAL_NODE_SIZE;
- memmove(m_buffer, m_buffer + VISUAL_NODE_SIZE, m_buffer_at * 2);
+ memmove(m_buffer, m_buffer + VISUAL_NODE_SIZE, m_buffer_at * sizeof(float));
m_value -= 512;
m_value = qMax(m_value, max);
}
@@ -258,7 +261,7 @@ void Logo::processPreset4()
while(k < m_value * count / 2048 / 16 / 2)
{
- int value = abs(m_buffer[qMin(at++, m_buffer_at)] / 2048);
+ int value = abs(m_buffer[qMin(at++, m_buffer_at)] * 16);
line.replace(line.indexOf("X"), 1, QString("%1").arg(value, 0, 16).toUpper());
k++;
}
@@ -267,7 +270,7 @@ void Logo::processPreset4()
while(k < m_value * count / 2048 / 16 / 2)
{
- int value = abs(m_buffer[qMin(at++, m_buffer_at)] / 2048);
+ int value = abs(m_buffer[qMin(at++, m_buffer_at)] * 16);
line.replace(line.lastIndexOf("X"), 1, QString("%1").arg(value, 0, 16).toUpper());
k++;
}
diff --git a/src/plugins/Ui/qsui/logo.h b/src/plugins/Ui/qsui/logo.h
index 9b2c6284b..15b50b539 100644
--- a/src/plugins/Ui/qsui/logo.h
+++ b/src/plugins/Ui/qsui/logo.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2011-2014 by Ilya Kotov *
+ * Copyright (C) 2011-2015 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -39,7 +39,7 @@ public:
explicit Logo(QWidget *parent = 0);
virtual ~Logo();
- void add(unsigned char *data, qint64 size, int chan);
+ void add(float *data, size_t samples, int chan);
void clear();
private slots:
@@ -55,7 +55,7 @@ private:
QHash <QChar, QPixmap> m_letters;
QStringList m_lines;
QStringList m_source_lines;
- short *m_buffer;
+ float *m_buffer;
int m_buffer_at;
int m_value;
qint64 m_elapsed;
diff --git a/src/plugins/Ui/qsui/qsuianalyzer.cpp b/src/plugins/Ui/qsui/qsuianalyzer.cpp
index 04c867ce7..df3e733d6 100644
--- a/src/plugins/Ui/qsui/qsuianalyzer.cpp
+++ b/src/plugins/Ui/qsui/qsuianalyzer.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2012-2014 by Ilya Kotov *
+ * Copyright (C) 2012-2015 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -51,8 +51,8 @@ QSUiAnalyzer::QSUiAnalyzer (QWidget *parent) : Visual (parent)
m_timer = new QTimer (this);
connect(m_timer, SIGNAL (timeout()), this, SLOT (timeout()));
- m_left_buffer = new short[VISUAL_BUFFER_SIZE];
- m_right_buffer = new short[VISUAL_BUFFER_SIZE];
+ m_left_buffer = new float[VISUAL_BUFFER_SIZE];
+ m_right_buffer = new float[VISUAL_BUFFER_SIZE];
readSettings();
clear();
@@ -91,7 +91,7 @@ QSize QSUiAnalyzer::sizeHint() const
return QSize(200, 100);
}
-void QSUiAnalyzer::add (unsigned char *data, qint64 size, int chan)
+void QSUiAnalyzer::add (float *data, size_t samples, int chan)
{
if (!m_timer->isActive ())
return;
@@ -99,23 +99,16 @@ void QSUiAnalyzer::add (unsigned char *data, qint64 size, int chan)
if(VISUAL_BUFFER_SIZE == m_buffer_at)
{
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);
+ 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));
return;
}
- int frames = qMin((int)size/chan >> 1, VISUAL_BUFFER_SIZE - m_buffer_at);
+ int frames = qMin(int(samples/chan), VISUAL_BUFFER_SIZE - m_buffer_at);
+
+ stereo_from_multichannel(m_left_buffer + m_buffer_at,
+ m_right_buffer + m_buffer_at, data, frames, chan);
- if (chan >= 2)
- {
- 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);
- }
m_buffer_at += frames;
}
@@ -157,8 +150,8 @@ void QSUiAnalyzer::hideEvent (QHideEvent *)
void QSUiAnalyzer::showEvent (QShowEvent *)
{
- if(m_running)
- m_timer->start();
+ if(m_running)
+ m_timer->start();
}
void QSUiAnalyzer::resizeEvent(QResizeEvent *)
@@ -166,7 +159,7 @@ void QSUiAnalyzer::resizeEvent(QResizeEvent *)
updateCover();
}
-void QSUiAnalyzer::process (short *left, short *right)
+void QSUiAnalyzer::process (float *left, float *right)
{
int rows = qMax((height() - 2) / m_cell_size.height(),2);
int cols = qMax((width() - m_offset - 2) / m_cell_size.width(),1);
@@ -196,11 +189,12 @@ void QSUiAnalyzer::process (short *left, short *right)
short dest[256];
short y;
int k, magnitude;
- short data[512];
+ float data[512];
for(int i = 0; i < VISUAL_NODE_SIZE; ++i)
{
- data[i] = (left[i] >> 1) + (right[i] >> 1);
+ data[i] = left[i] / 2 + right[i] / 2;
+ data[i] = qBound(-1.0f, data[i], 1.0f);
}
calc_freq (dest, data);
@@ -407,13 +401,13 @@ void QSUiAnalyzer::writeSettings()
void QSUiAnalyzer::start()
{
- m_running = true;
+ m_running = true;
if(isVisible())
m_timer->start();
}
void QSUiAnalyzer::stop()
{
- m_running = false;
- m_timer->stop();
+ m_running = false;
+ m_timer->stop();
}
diff --git a/src/plugins/Ui/qsui/qsuianalyzer.h b/src/plugins/Ui/qsui/qsuianalyzer.h
index 1c68e84f9..9dae2f9f1 100644
--- a/src/plugins/Ui/qsui/qsuianalyzer.h
+++ b/src/plugins/Ui/qsui/qsuianalyzer.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2012-2013 by Ilya Kotov *
+ * Copyright (C) 2012-2015 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -37,7 +37,7 @@ public:
QSUiAnalyzer( QWidget *parent = 0);
virtual ~QSUiAnalyzer();
- void add(unsigned char *data, qint64 size, int chan);
+ void add(float *data, size_t samples, int chan);
void setCover(const QPixmap &pixmap);
void clear();
void clearCover();
@@ -58,7 +58,7 @@ private:
void hideEvent(QHideEvent *);
void showEvent(QShowEvent *);
void resizeEvent(QResizeEvent *);
- void process(short *l, short *r);
+ void process(float *l, float *r);
void draw(QPainter *p);
void createMenu();
void updateCover();
@@ -73,8 +73,8 @@ private:
double m_analyzer_falloff;
bool m_show_peaks;
bool m_show_cover;
- short *m_left_buffer;
- short *m_right_buffer;
+ float *m_left_buffer;
+ float *m_right_buffer;
int m_buffer_at;
int m_cols, m_rows;
int m_offset;