MythTV  master
visualize.h
Go to the documentation of this file.
1 /*
2  visualize.h
3 
4  (c) 2003 Thor Sigvaldason and Isaac Richards
5  Closely based on code from mq3 by Brad Hughes
6 
7  Part of the mythTV project
8 
9  music visualizers
10 */
11 
12 #ifndef VISUALIZE_H
13 #define VISUALIZE_H
14 
15 // C++ headers
16 #include <QVector>
17 #include <vector>
18 
19 // Qt headers
20 #include <QCoreApplication>
21 
22 // MythTV headers
23 #include <visual.h>
24 #include <musicmetadata.h>
25 #include <mythbaseexp.h>
26 
27 // MythMusic headers
28 #include "constants.h"
29 #include "config.h"
30 
31 #include <complex>
32 extern "C" {
33 #ifdef FFTW3_SUPPORT
34 #include <fftw3.h>
35 #define myth_fftw_float double /* need to use different plan function to change */
36 #define fftw_real myth_fftw_float
37 #define myth_fftw_complex std::complex<myth_fftw_float>
38 #if (myth_fftw_float == double)
39 #define myth_fftw_complex_cast fftw_complex
40 #elif (myth_fftw_float == float)
41 #define myth_fftw_complex_cast fftwf_complex
42 #endif
43 #endif
44 }
45 
46 #define SAMPLES_DEFAULT_SIZE 512
47 
48 class MainVisual;
49 
50 class VisualNode
51 {
52  public:
53  VisualNode(short *l, short *r, unsigned long n, unsigned long o)
54  : m_left(l), m_right(r), m_length(n), m_offset(o)
55  {
56  // left and right are allocated and then passed to this class
57  // the code that allocated left and right should give up all ownership
58  }
59 
61  {
62  delete [] m_left;
63  delete [] m_right;
64  }
65 
66  short *m_left {nullptr};
67  short *m_right {nullptr};
68  unsigned long m_length;
69  unsigned long m_offset;
70 };
71 
73 {
74  public:
75  explicit VisualBase(bool screensaverenable = false);
76  virtual ~VisualBase(void);
77 
78  // return true if the output should stop
79  virtual bool process( VisualNode *node ) = 0;
80 
81  // this is called on nodes that will not be displayed :: Not needed for most visualizations
82  // (i.e. between the displayed frames, if you need the whole audio stream)
83  virtual bool processUndisplayed( VisualNode */*node*/ )
84  {
85  return true; // By default this does nothing : Ignore the in-between chunks of audio data
86  };
87 
88  virtual bool draw( QPainter *, const QColor & ) = 0;
89  virtual void resize( const QSize &size ) = 0;
90  virtual void handleKeyPress(const QString &action) = 0;
91  virtual int getDesiredFPS(void) { return m_fps; }
92  // Override this if you need the potential of capturing more data than the default
93  virtual unsigned long getDesiredSamples(void) { return SAMPLES_DEFAULT_SIZE; }
94  static void drawWarning(QPainter *p, const QColor &back, const QSize &size, const QString& warning, int fontsize = 28);
95 
96  protected:
97  int m_fps {20};
98  bool m_xscreensaverenable {true};
99 };
100 
102 {
103  public:
105  virtual ~VisFactory() = default;
106  const VisFactory* next() const {return m_pNextVisFactory;}
107  virtual const QString &name(void) const = 0;
108  virtual VisualBase* create(MainVisual *parent, const QString &pluginName) const = 0;
109  virtual uint plugins(QStringList *list) const = 0;
110  static const VisFactory* VisFactories() {return g_pVisFactories;}
111  protected:
114 };
115 
116 #define RUBBERBAND false
117 #define TWOCOLOUR 0
118 
119 class StereoScope : public VisualBase
120 {
121  public:
122  StereoScope();
123  ~StereoScope() override = default;
124 
125  void resize( const QSize &size ) override; // VisualBase
126  bool process( VisualNode *node ) override; // VisualBase
127  bool draw( QPainter *p, const QColor &back ) override; // VisualBase
128  void handleKeyPress(const QString &action) override // VisualBase
129  {(void) action;}
130 
131  protected:
132  QColor m_startColor {Qt::green};
133  QColor m_targetColor {Qt::red};
134  std::vector<double> m_magnitudes {};
135  QSize m_size;
136  bool const m_rubberband {RUBBERBAND};
137  double const m_falloff {1.0};
138 };
139 
140 class MonoScope : public StereoScope
141 {
142  public:
143  MonoScope() = default;
144  ~MonoScope() override = default;
145 
146  bool process( VisualNode *node ) override; // StereoScope
147  bool draw( QPainter *p, const QColor &back ) override; // StereoScope
148 };
149 
150 class LogScale
151 {
152  public:
153  explicit LogScale(int maxscale = 0, int maxrange = 0);
155 
156  int scale() const { return m_s; }
157  int range() const { return m_r; }
158 
159  void setMax(int maxscale, int maxrange);
160 
161  int operator[](int index);
162 
163 
164  private:
165  int *m_indices {nullptr};
166  int m_s {0};
167  int m_r {0};
168 };
169 
170 #ifdef FFTW3_SUPPORT
171 class Spectrum : public VisualBase
172 {
173  // This class draws bars (up and down)
174  // based on the magnitudes at various
175  // frequencies in the audio data.
176 
177  public:
178  Spectrum();
179  ~Spectrum() override;
180 
181  void resize(const QSize &size) override; // VisualBase
182  bool process(VisualNode *node) override; // VisualBase
183  bool draw(QPainter *p, const QColor &back = Qt::black) override; // VisualBase
184  void handleKeyPress(const QString &action) override // VisualBase
185  {(void) action;}
186 
187  protected:
188  static inline double clamp(double cur, double max, double min);
189 
190  QColor m_startColor {Qt::blue};
191  QColor m_targetColor {Qt::red};
192  QVector<QRect> m_rects;
193  QVector<double> m_magnitudes;
194  QSize m_size;
195  LogScale m_scale;
196 
197  // Setup the "magical" audio data transformations
198  // provided by the Fast Fourier Transforms library
199  double m_scaleFactor {2.0};
200  double m_falloff {10.0};
201  int m_analyzerBarWidth {6};
202 
203  fftw_plan m_lplan;
204  fftw_plan m_rplan;
205  myth_fftw_float *m_lin {nullptr};
206  myth_fftw_float *m_rin {nullptr};
207  myth_fftw_complex *m_lout {nullptr};
208  myth_fftw_complex *m_rout {nullptr};
209 };
210 
211 class Squares : public Spectrum
212 {
213  public:
214  Squares();
215  ~Squares() override = default;
216 
217  void resize (const QSize &newsize) override; // Spectrum
218  bool draw(QPainter *p, const QColor &back = Qt::black) override; // Spectrum
219  void handleKeyPress(const QString &action) override // Spectrum
220  {(void) action;}
221 
222  private:
223  void drawRect(QPainter *p, QRect *rect, int i, int c, int w, int h);
224  QSize m_actualSize {0,0};
225  int m_fakeHeight {0};
226  int m_numberOfSquares {16};
227 };
228 
229 #endif // FFTW3_SUPPORT
230 
231 class Piano : public VisualBase
232 {
233  // This class draws bars (up and down)
234  // based on the magnitudes at piano pitch
235  // frequencies in the audio data.
236 
237 #define PIANO_AUDIO_SIZE 4096
238 #define PIANO_N 88
239 
240 #define piano_audio float
241 #define goertzel_data float
242 
243 #define PIANO_RMS_NEGLIGIBLE .001
244 #define PIANO_SPECTRUM_SMOOTHING 0.95
245 #define PIANO_MIN_VOL (-10)
246 #define PIANO_KEYPRESS_TOO_LIGHT .2
247 
251 
252  // This keeps track of the samples processed for each note
253  // Low notes require a lot of samples to be correctly identified
254  // Higher ones are displayed quicker
257 
258  bool is_black_note; // These are painted on top of white notes, and have different colouring
259 };
260 
261  public:
262  Piano();
263  ~Piano() override;
264 
265  void resize(const QSize &size) override; // VisualBase
266 
267  bool process(VisualNode *node) override; // VisualBase
268 
269  // These functions are new, since we need to inspect all the data
270  bool processUndisplayed(VisualNode *node) override; // VisualBase
271  unsigned long getDesiredSamples(void) override; // VisualBase
272 
273  bool draw(QPainter *p, const QColor &back = Qt::black) override; // VisualBase
274  void handleKeyPress(const QString &action) override // VisualBase
275  {(void) action;}
276 
277  protected:
278  static inline double clamp(double cur, double max, double min);
279  bool process_all_types(VisualNode *node, bool this_will_be_displayed);
280  void zero_analysis(void);
281 
282  QColor m_whiteStartColor {245,245,245};
283  QColor m_whiteTargetColor {Qt::red};
284  QColor m_blackStartColor {10,10,10};
285  QColor m_blackTargetColor {Qt::red};
286 
287  std::vector<QRect> m_rects {};
288  QSize m_size;
289 
290  unsigned long m_offsetProcessed {0};
291 
294 
295  std::vector<double> m_magnitude {};
296 };
297 
298 class AlbumArt : public VisualBase
299 {
301 
302  public:
303  AlbumArt(void);
304  ~AlbumArt() override = default;
305 
306  void resize(const QSize &size) override; // VisualBase
307  bool process(VisualNode *node = nullptr) override; // VisualBase
308  bool draw(QPainter *p, const QColor &back = Qt::black) override; // VisualBase
309  void handleKeyPress(const QString &action) override; // VisualBase
310 
311  private:
312  bool needsUpdate(void);
313  void findFrontCover(void);
314  bool cycleImage(void);
315 
316  QSize m_size;
317  QSize m_cursize;
319  QImage m_image;
320 
322  QDateTime m_lastCycle;
323 };
324 
325 class Blank : public VisualBase
326 {
327  // This draws ... well ... nothing
328  public:
329  Blank();
330  ~Blank() override = default;
331 
332  void resize(const QSize &size) override; // VisualBase
333  bool process(VisualNode *node = nullptr) override; // VisualBase
334  bool draw(QPainter *p, const QColor &back = Qt::black) override; // VisualBase
335  void handleKeyPress(const QString &action) override // VisualBase
336  {(void) action;}
337 
338  private:
339  QSize m_size;
340 };
341 
342 #endif // __visualize_h
VisualNode::~VisualNode
~VisualNode()
Definition: visualize.h:60
Piano::piano_key_data::samples_processed
int samples_processed
Definition: visualize.h:255
Blank::Blank
Blank()
Definition: visualize.cpp:1549
Piano::piano_key_data
Definition: visualize.h:248
Piano::m_magnitude
std::vector< double > m_magnitude
Definition: visualize.h:295
Piano::piano_key_data::samples_process_before_display_update
int samples_process_before_display_update
Definition: visualize.h:256
AlbumArt::findFrontCover
void findFrontCover(void)
Definition: visualize.cpp:1363
VisFactory::g_pVisFactories
static VisFactory * g_pVisFactories
Definition: visualize.h:112
Piano
Definition: visualize.h:232
AlbumArt::resize
void resize(const QSize &size) override
Definition: visualize.cpp:1411
VisualNode::m_offset
unsigned long m_offset
Definition: visualize.h:69
Piano::draw
bool draw(QPainter *p, const QColor &back=Qt::black) override
Definition: visualize.cpp:1225
back
static guint32 * back
Definition: goom_core.cpp:30
VisualNode
Definition: videovisual.h:23
Piano::processUndisplayed
bool processUndisplayed(VisualNode *node) override
Definition: visualize.cpp:1073
Piano::zero_analysis
void zero_analysis(void)
Definition: visualize.cpp:967
Piano::getDesiredSamples
unsigned long getDesiredSamples(void) override
Definition: visualize.cpp:1063
StereoScope
Definition: visualize.h:120
AlbumArt::m_image
QImage m_image
Definition: visualize.h:319
VisualBase::getDesiredSamples
virtual unsigned long getDesiredSamples(void)
Definition: visualize.h:93
VisFactory::VisFactory
VisFactory()
Definition: visualize.h:104
RUBBERBAND
#define RUBBERBAND
Definition: visualize.h:116
mythbaseexp.h
AlbumArt::Q_DECLARE_TR_FUNCTIONS
Q_DECLARE_TR_FUNCTIONS(AlbumArt)
LogScale::m_indices
int * m_indices
Definition: videovisualdefs.h:70
Blank::handleKeyPress
void handleKeyPress(const QString &action) override
Definition: visualize.h:335
LogScale::operator[]
int operator[](int index) const
Definition: videovisualdefs.h:63
LogScale::m_r
int m_r
Definition: videovisualdefs.h:72
AlbumArt
Definition: visualize.h:299
VisualBase
Definition: visualize.h:73
Blank::draw
bool draw(QPainter *p, const QColor &back=Qt::black) override
Definition: visualize.cpp:1566
StereoScope::resize
void resize(const QSize &size) override
Definition: visualize.cpp:168
Blank::m_size
QSize m_size
Definition: visualize.h:339
MusicMetadata
Definition: musicmetadata.h:81
StereoScope::process
bool process(VisualNode *node) override
Definition: visualize.cpp:178
LogScale::LogScale
LogScale(int maxscale=0, int maxrange=0)
StereoScope::m_size
QSize m_size
Definition: visualize.h:135
VisualNode::m_offset
long m_offset
Definition: videovisual.h:37
MonoScope
Definition: visualize.h:141
VisualNode::m_left
short * m_left
Definition: videovisual.h:34
VisualBase::VisualBase
VisualBase(bool screensaverenable=false)
Definition: visualize.cpp:45
AlbumArt::m_currImageType
ImageType m_currImageType
Definition: visualize.h:318
VisualBase::drawWarning
static void drawWarning(QPainter *p, const QColor &back, const QSize &size, const QString &warning, int fontsize=28)
Definition: visualize.cpp:64
SAMPLES_DEFAULT_SIZE
#define SAMPLES_DEFAULT_SIZE
Definition: visualize.h:46
MonoScope::process
bool process(VisualNode *node) override
Definition: visualize.cpp:396
Piano::m_whiteStartColor
QColor m_whiteStartColor
Definition: visualize.h:282
MonoScope::~MonoScope
~MonoScope() override=default
VisualBase::resize
virtual void resize(const QSize &size)=0
AlbumArt::draw
bool draw(QPainter *p, const QColor &back=Qt::black) override
Definition: visualize.cpp:1475
Piano::m_blackTargetColor
QColor m_blackTargetColor
Definition: visualize.h:285
StereoScope::draw
bool draw(QPainter *p, const QColor &back) override
Definition: visualize.cpp:296
hardwareprofile.config.p
p
Definition: config.py:33
VisualNode::m_right
short * m_right
Definition: videovisual.h:35
LogScale::range
int range() const
Definition: visualize.h:157
AlbumArt::~AlbumArt
~AlbumArt() override=default
StereoScope::~StereoScope
~StereoScope() override=default
AlbumArt::cycleImage
bool cycleImage(void)
Definition: visualize.cpp:1382
VisFactory
Definition: visualize.h:102
AlbumArt::m_cursize
QSize m_cursize
Definition: visualize.h:317
LogScale::setMax
void setMax(int maxscale, int maxrange)
LogScale::scale
int scale() const
Definition: visualize.h:156
clamp
float clamp(float val, float minimum, float maximum)
Definition: mythmiscutil.h:59
Piano::piano_key_data::q2
goertzel_data q2
Definition: visualize.h:249
AlbumArt::needsUpdate
bool needsUpdate(void)
Definition: visualize.cpp:1455
VisualBase::getDesiredFPS
virtual int getDesiredFPS(void)
Definition: visualize.h:91
AlbumArt::process
bool process(VisualNode *node=nullptr) override
Definition: visualize.cpp:1416
StereoScope::m_targetColor
QColor m_targetColor
Definition: visualize.h:133
VisualBase::~VisualBase
virtual ~VisualBase(void)
Definition: visualize.cpp:52
goertzel_data
#define goertzel_data
Definition: visualize.h:241
VisualBase::draw
virtual bool draw(QPainter *, const QColor &)=0
Piano::resize
void resize(const QSize &size) override
Definition: visualize.cpp:983
StereoScope::m_magnitudes
std::vector< double > m_magnitudes
Definition: visualize.h:134
VisFactory::plugins
virtual uint plugins(QStringList *list) const =0
uint
unsigned int uint
Definition: compat.h:140
VisFactory::VisFactories
static const VisFactory * VisFactories()
Definition: visualize.h:110
AlbumArt::m_currentMetadata
MusicMetadata * m_currentMetadata
Definition: visualize.h:321
LogScale::m_s
int m_s
Definition: videovisualdefs.h:71
LogScale::~LogScale
~LogScale()
StereoScope::m_startColor
QColor m_startColor
Definition: visualize.h:132
Piano::piano_key_data::magnitude
goertzel_data magnitude
Definition: visualize.h:249
VisualBase::process
virtual bool process(VisualNode *node)=0
VisFactory::create
virtual VisualBase * create(MainVisual *parent, const QString &pluginName) const =0
VisualNode::VisualNode
VisualNode(short *l, short *r, unsigned long n, unsigned long o)
Definition: visualize.h:53
StereoScope::m_falloff
double const m_falloff
Definition: visualize.h:137
AlbumArt::m_lastCycle
QDateTime m_lastCycle
Definition: visualize.h:322
MainVisual
Definition: mainvisual.h:33
Piano::m_audioData
piano_audio * m_audioData
Definition: visualize.h:293
VisualBase::processUndisplayed
virtual bool processUndisplayed(VisualNode *)
Definition: visualize.h:83
IT_UNKNOWN
@ IT_UNKNOWN
Definition: musicmetadata.h:30
AlbumArt::handleKeyPress
void handleKeyPress(const QString &action) override
Definition: visualize.cpp:1421
VisFactory::~VisFactory
virtual ~VisFactory()=default
VisualNode::m_length
long m_length
Definition: videovisual.h:36
StereoScope::StereoScope
StereoScope()
Definition: visualize.cpp:163
VisualBase::m_fps
int m_fps
Definition: visualize.h:97
Piano::piano_key_data::coeff
goertzel_data coeff
Definition: visualize.h:249
MonoScope::draw
bool draw(QPainter *p, const QColor &back) override
Definition: visualize.cpp:486
Piano::m_pianoData
piano_key_data * m_pianoData
Definition: visualize.h:292
VisualNode::m_length
unsigned long m_length
Definition: visualize.h:68
Piano::piano_key_data::is_black_note
bool is_black_note
Definition: visualize.h:258
Blank::~Blank
~Blank() override=default
constants.h
Piano::m_size
QSize m_size
Definition: visualize.h:288
AlbumArt::AlbumArt
AlbumArt(void)
Definition: visualize.cpp:1356
VisualBase::m_xscreensaverenable
bool m_xscreensaverenable
Definition: visualize.h:98
MonoScope::MonoScope
MonoScope()=default
VisFactory::name
virtual const QString & name(void) const =0
Blank::resize
void resize(const QSize &size) override
Definition: visualize.cpp:1555
Piano::m_whiteTargetColor
QColor m_whiteTargetColor
Definition: visualize.h:283
VisualBase::handleKeyPress
virtual void handleKeyPress(const QString &action)=0
Piano::process
bool process(VisualNode *node) override
Definition: visualize.cpp:1079
VisFactory::m_pNextVisFactory
VisFactory * m_pNextVisFactory
Definition: visualize.h:113
build_compdb.action
action
Definition: build_compdb.py:9
Blank
Definition: visualize.h:326
Blank::process
bool process(VisualNode *node=nullptr) override
Definition: visualize.cpp:1561
Piano::Piano
Piano()
Definition: visualize.cpp:913
Piano::clamp
static double clamp(double cur, double max, double min)
Definition: visualize.cpp:1216
Piano::~Piano
~Piano() override
Definition: visualize.cpp:959
Piano::piano_key_data::q1
goertzel_data q1
Definition: visualize.h:249
StereoScope::m_rubberband
bool const m_rubberband
Definition: visualize.h:136
Piano::m_blackStartColor
QColor m_blackStartColor
Definition: visualize.h:284
LogScale
Definition: videovisualdefs.h:7
VisFactory::next
const VisFactory * next() const
Definition: visualize.h:106
AlbumArt::m_size
QSize m_size
Definition: visualize.h:316
ImageType
ImageType
Definition: musicmetadata.h:29
Piano::m_rects
std::vector< QRect > m_rects
Definition: visualize.h:287
musicmetadata.h
Piano::process_all_types
bool process_all_types(VisualNode *node, bool this_will_be_displayed)
Definition: visualize.cpp:1087
StereoScope::handleKeyPress
void handleKeyPress(const QString &action) override
Definition: visualize.h:128
Piano::m_offsetProcessed
unsigned long m_offsetProcessed
Definition: visualize.h:290
Piano::piano_key_data::max_magnitude_seen
goertzel_data max_magnitude_seen
Definition: visualize.h:250
piano_audio
#define piano_audio
Definition: visualize.h:240
Piano::handleKeyPress
void handleKeyPress(const QString &action) override
Definition: visualize.h:274
visual.h