MythTV  master
mainvisual.cpp
Go to the documentation of this file.
1 // Copyright (c) 2000-2001 Brad Hughes <bhughes@trolltech.com>
2 //
3 // Use, modification and distribution is allowed without limitation,
4 // warranty, or liability of any kind.
5 //
6 
7 // C
8 #include <cmath>
9 #include <cstdio>
10 
11 // C++
12 #include <algorithm>
13 #include <iostream>
14 
15 // Qt
16 #include <QPainter>
17 
18 // mythtv
19 #include <mythuivideo.h>
20 
21 // mythmusic
22 #include "visualize.h"
23 #include "mainvisual.h"
24 #include "constants.h"
25 #include "musicplayer.h"
26 
27 // fast inlines
28 #include "inlines.h"
29 
30 
32 // MainVisual
33 
35  : QObject(nullptr), m_visualizerVideo(visualizer)
36 {
37  setObjectName("MainVisual");
38 
39  for (const VisFactory* pVisFactory = VisFactory::VisFactories();
40  pVisFactory; pVisFactory = pVisFactory->next())
41  {
42  pVisFactory->plugins(&m_visualizers);
43  }
44  m_visualizers.sort();
45 
46  m_currentVisualizer = gCoreContext->GetNumSetting("MusicLastVisualizer", 0);
47 
48  resize(m_visualizerVideo->GetArea().size());
49 
50  m_updateTimer = new QTimer(this);
51  m_updateTimer->setInterval(1000 / m_fps);
52  m_updateTimer->setSingleShot(true);
54 }
55 
57 {
58  m_updateTimer->stop();
59  delete m_updateTimer;
60 
61  delete m_vis;
62 
63  while (!m_nodes.empty())
64  delete m_nodes.takeLast();
65 
66  gCoreContext->SaveSetting("MusicLastVisualizer", m_currentVisualizer);
67 }
68 
69 void MainVisual::stop(void)
70 {
71  m_updateTimer->stop();
72 
73  if (m_vis)
74  {
75  delete m_vis;
76  m_vis = nullptr;
77  }
78 }
79 
80 void MainVisual::setVisual(const QString &name)
81 {
82  m_updateTimer->stop();
83 
84  int index = m_visualizers.indexOf(name);
85 
86  if (index == -1)
87  {
88  LOG(VB_GENERAL, LOG_ERR, QString("MainVisual: visualizer %1 not found!").arg(name));
89  return;
90  }
91 
92  m_currentVisualizer = index;
93 
95 
96  QString visName;
97  QString pluginName;
98 
99  if (name.contains("-"))
100  {
101  visName = name.section('-', 0, 0);
102  pluginName = name.section('-', 1, 1);
103  }
104  else
105  {
106  visName = name;
107  pluginName.clear();
108  }
109 
110  if (m_vis)
111  {
112  delete m_vis;
113  m_vis = nullptr;
114  }
115 
116  for (const VisFactory* pVisFactory = VisFactory::VisFactories();
117  pVisFactory; pVisFactory = pVisFactory->next())
118  {
119  if (pVisFactory->name() == visName)
120  {
121  m_vis = pVisFactory->create(this, pluginName);
125 
126  QMutexLocker locker(mutex());
127  prepare();
128 
129  break;
130  }
131  }
132 
133  // force an update
134  m_updateTimer->start(1000 / m_fps);
135 }
136 
137 // Caller holds mutex() lock
139 {
140  while (!m_nodes.empty())
141  delete m_nodes.takeLast();
142 }
143 
144 // This is called via : mythtv/libs/libmyth/output.cpp :: OutputListeners::dispatchVisual
145 // from : mythtv/libs/libmyth/audio/audiooutputbase.cpp :: AudioOutputBase::AddData
146 // Caller holds mutex() lock
147 void MainVisual::add(const void *buffer, unsigned long b_len,
148  std::chrono::milliseconds timecode,
149  int source_channels, int bits_per_sample)
150 {
151  unsigned long len = b_len;
152  short *l = nullptr;
153  short *r = nullptr;
154  bool s32le = false;
155 
156  // 24 bit samples are stored as s32le in the buffer.
157  // 32 bit samples are stored as float. Flag the difference.
158  if (bits_per_sample == 24)
159  {
160  s32le = true;
161  bits_per_sample = 32;
162  }
163 
164  // len is length of buffer in fully converted samples
165  len /= source_channels;
166  len /= (bits_per_sample / 8);
167 
168  if (len > m_samples)
169  len = m_samples;
170 
171  int cnt = len;
172 
173  if (source_channels == 2)
174  {
175  l = new short[len];
176  r = new short[len];
177 
178  if (bits_per_sample == 8)
179  stereo16_from_stereopcm8(l, r, (uchar *) buffer, cnt);
180  else if (bits_per_sample == 16)
181  stereo16_from_stereopcm16(l, r, (short *) buffer, cnt);
182  else if (s32le)
183  stereo16_from_stereopcm32(l, r, (int *) buffer, cnt);
184  else if (bits_per_sample == 32)
185  stereo16_from_stereopcmfloat(l, r, (float *) buffer, cnt);
186  else
187  len = 0;
188  }
189  else if (source_channels == 1)
190  {
191  l = new short[len];
192 
193  if (bits_per_sample == 8)
194  mono16_from_monopcm8(l, (uchar *) buffer, cnt);
195  else if (bits_per_sample == 16)
196  mono16_from_monopcm16(l, (short *) buffer, cnt);
197  else if (s32le)
198  mono16_from_monopcm32(l, (int *) buffer, cnt);
199  else if (bits_per_sample == 32)
200  mono16_from_monopcmfloat(l, (float *) buffer, cnt);
201  else
202  len = 0;
203  }
204  else
205  len = 0;
206 
207  m_nodes.append(new VisualNode(l, r, len, timecode));
208 }
209 
211 {
212  VisualNode *node = nullptr;
213  if (m_playing && gPlayer->getOutput())
214  {
215  QMutexLocker locker(mutex());
216  std::chrono::milliseconds timestamp = gPlayer->getOutput()->GetAudiotime();
217  while (m_nodes.size() > 1)
218  {
219  if (m_nodes.first()->m_offset > timestamp)
220  break;
221 
222  if (m_vis)
223  m_vis->processUndisplayed(node);
224 
225  delete m_nodes.first();
226  m_nodes.removeFirst();
227  }
228 
229  if (!m_nodes.isEmpty())
230  node = m_nodes.first();
231  }
232 
233  bool stop = true;
234  if (m_vis)
235  stop = m_vis->process(node);
236 
237  if (m_vis && !stop)
238  {
239  QPainter p(&m_pixmap);
242  }
243 
244  if (m_playing && !stop)
245  m_updateTimer->start();
246 }
247 
248 void MainVisual::resize(const QSize size)
249 {
250  m_pixmap = QPixmap(size);
252 
253  if (m_vis)
254  m_vis->resize(size);
255 }
256 
257 void MainVisual::customEvent(QEvent *event)
258 {
259  if ((event->type() == OutputEvent::Playing) ||
260  (event->type() == OutputEvent::Info) ||
261  (event->type() == OutputEvent::Buffering) ||
262  (event->type() == OutputEvent::Paused))
263  {
264  m_playing = true;
265  if (!m_updateTimer->isActive())
266  m_updateTimer->start();
267  }
268  else if ((event->type() == OutputEvent::Stopped) ||
269  (event->type() == OutputEvent::Error))
270  {
271  m_playing = false;
272  }
273 }
mono16_from_monopcm8
static void mono16_from_monopcm8(short *l, const uchar *c, long cnt)
Definition: videovisualdefs.h:151
MusicPlayer::getOutput
AudioOutput * getOutput(void)
Definition: musicplayer.h:125
MainVisual::~MainVisual
~MainVisual() override
Definition: mainvisual.cpp:56
gPlayer
MusicPlayer * gPlayer
Definition: musicplayer.cpp:35
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
mono16_from_monopcmfloat
static void mono16_from_monopcmfloat(short *l, float *s, long cnt)
Definition: inlines.h:169
OutputEvent::Buffering
static Type Buffering
Definition: output.h:64
mythuivideo.h
VisualNode
Definition: videovisual.h:24
VisualBase::getDesiredSamples
virtual unsigned long getDesiredSamples(void)
Definition: visualize.h:93
OutputEvent::Stopped
static Type Stopped
Definition: output.h:67
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MainVisual::customEvent
void customEvent(QEvent *event) override
Definition: mainvisual.cpp:257
MainVisual::m_fps
int m_fps
Definition: mainvisual.h:71
MainVisual::prepare
void prepare(void) override
Definition: mainvisual.cpp:138
MainVisual::setVisual
void setVisual(const QString &name)
Definition: mainvisual.cpp:80
MythUIType::GetArea
virtual MythRect GetArea(void) const
If the object has a minimum area defined, return it, other wise return the default area.
Definition: mythuitype.cpp:870
MainVisual::m_samples
unsigned long m_samples
Definition: mainvisual.h:72
OutputEvent::Error
static Type Error
Definition: output.h:68
MainVisual::m_playing
bool m_playing
Definition: mainvisual.h:70
VisualBase::resize
virtual void resize(const QSize &size)=0
OutputEvent::Playing
static Type Playing
Definition: output.h:63
mono16_from_monopcm16
static void mono16_from_monopcm16(short *l, const short *s, long cnt)
Definition: videovisualdefs.h:180
hardwareprofile.config.p
p
Definition: config.py:33
stereo16_from_stereopcmfloat
static void stereo16_from_stereopcmfloat(short *l, short *r, float *s, long cnt)
Definition: inlines.h:96
MythTV::Visual::mutex
QMutex * mutex()
Definition: visual.h:26
VisFactory
Definition: visualize.h:101
stereo16_from_stereopcm16
static void stereo16_from_stereopcm16(short *l, short *r, const short *s, long cnt)
Definition: videovisualdefs.h:113
MainVisual::resize
void resize(QSize size)
Definition: mainvisual.cpp:248
VisualBase::getDesiredFPS
virtual int getDesiredFPS(void)
Definition: visualize.h:91
MainVisual::timeout
void timeout()
Definition: mainvisual.cpp:210
VisualBase::draw
virtual bool draw(QPainter *, const QColor &)=0
inlines.h
visualize.h
VisFactory::VisFactories
static const VisFactory * VisFactories()
Definition: visualize.h:110
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
MythUIVideo::UpdateFrame
void UpdateFrame(MythImage *image)
Definition: mythuivideo.cpp:52
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:937
AudioOutput::GetAudiotime
virtual std::chrono::milliseconds GetAudiotime(void)=0
VisualBase::process
virtual bool process(VisualNode *node)=0
MainVisual::m_visualizerVideo
MythUIVideo * m_visualizerVideo
Definition: mainvisual.h:64
MainVisual::stop
void stop(void)
Definition: mainvisual.cpp:69
OutputEvent::Paused
static Type Paused
Definition: output.h:66
VisualBase::processUndisplayed
virtual bool processUndisplayed(VisualNode *)
Definition: visualize.h:83
stereo16_from_stereopcm8
static void stereo16_from_stereopcm8(short *l, short *r, const uchar *c, long cnt)
Definition: videovisualdefs.h:75
MainVisual::m_currentVisualizer
int m_currentVisualizer
Definition: mainvisual.h:66
mono16_from_monopcm32
static void mono16_from_monopcm32(short *l, int *s, long cnt)
Definition: inlines.h:160
MythUIVideo
Video widget, displays raw image data.
Definition: mythuivideo.h:14
constants.h
OutputEvent::Info
static Type Info
Definition: output.h:65
mainvisual.h
stereo16_from_stereopcm32
static void stereo16_from_stereopcm32(short *l, short *r, int *s, long cnt)
Definition: inlines.h:84
MythUIVideo::GetBackgroundColor
QColor GetBackgroundColor(void)
Definition: mythuivideo.h:23
MainVisual::add
void add(const void *buffer, unsigned long b_len, std::chrono::milliseconds timecode, int source_channel, int bits_per_sample) override
Definition: mainvisual.cpp:147
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:906
MainVisual::m_updateTimer
QTimer * m_updateTimer
Definition: mainvisual.h:73
MainVisual::m_nodes
QList< VisualNode * > m_nodes
Definition: mainvisual.h:69
VisFactory::next
const VisFactory * next() const
Definition: visualize.h:106
MainVisual::m_visualizers
QStringList m_visualizers
Definition: mainvisual.h:65
MainVisual::m_vis
VisualBase * m_vis
Definition: mainvisual.h:67
MainVisual::m_pixmap
QPixmap m_pixmap
Definition: mainvisual.h:68
MainVisual::MainVisual
MainVisual(MythUIVideo *visualizer)
Definition: mainvisual.cpp:34
musicplayer.h