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, unsigned long timecode, int source_channels, int bits_per_sample)
148 {
149  unsigned long len = b_len;
150  short *l = nullptr;
151  short *r = nullptr;
152  bool s32le = false;
153 
154  // 24 bit samples are stored as s32le in the buffer.
155  // 32 bit samples are stored as float. Flag the difference.
156  if (bits_per_sample == 24)
157  {
158  s32le = true;
159  bits_per_sample = 32;
160  }
161 
162  // len is length of buffer in fully converted samples
163  len /= source_channels;
164  len /= (bits_per_sample / 8);
165 
166  if (len > m_samples)
167  len = m_samples;
168 
169  int cnt = len;
170 
171  if (source_channels == 2)
172  {
173  l = new short[len];
174  r = new short[len];
175 
176  if (bits_per_sample == 8)
177  stereo16_from_stereopcm8(l, r, (uchar *) buffer, cnt);
178  else if (bits_per_sample == 16)
179  stereo16_from_stereopcm16(l, r, (short *) buffer, cnt);
180  else if (s32le)
181  stereo16_from_stereopcm32(l, r, (int *) buffer, cnt);
182  else if (bits_per_sample == 32)
183  stereo16_from_stereopcmfloat(l, r, (float *) buffer, cnt);
184  else
185  len = 0;
186  }
187  else if (source_channels == 1)
188  {
189  l = new short[len];
190 
191  if (bits_per_sample == 8)
192  mono16_from_monopcm8(l, (uchar *) buffer, cnt);
193  else if (bits_per_sample == 16)
194  mono16_from_monopcm16(l, (short *) buffer, cnt);
195  else if (s32le)
196  mono16_from_monopcm32(l, (int *) buffer, cnt);
197  else if (bits_per_sample == 32)
198  mono16_from_monopcmfloat(l, (float *) buffer, cnt);
199  else
200  len = 0;
201  }
202  else
203  len = 0;
204 
205  m_nodes.append(new VisualNode(l, r, len, timecode));
206 }
207 
209 {
210  VisualNode *node = nullptr;
211  if (m_playing && gPlayer->getOutput())
212  {
213  QMutexLocker locker(mutex());
214  int64_t timestamp = gPlayer->getOutput()->GetAudiotime();
215  while (m_nodes.size() > 1)
216  {
217  if ((int64_t)m_nodes.first()->m_offset > timestamp)
218  break;
219 
220  if (m_vis)
221  m_vis->processUndisplayed(node);
222 
223  delete m_nodes.first();
224  m_nodes.removeFirst();
225  }
226 
227  if (!m_nodes.isEmpty())
228  node = m_nodes.first();
229  }
230 
231  bool stop = true;
232  if (m_vis)
233  stop = m_vis->process(node);
234 
235  if (m_vis && !stop)
236  {
237  QPainter p(&m_pixmap);
240  }
241 
242  if (m_playing && !stop)
243  m_updateTimer->start();
244 }
245 
246 void MainVisual::resize(const QSize &size)
247 {
248  m_pixmap = QPixmap(size);
250 
251  if (m_vis)
252  m_vis->resize(size);
253 }
254 
255 void MainVisual::customEvent(QEvent *event)
256 {
257  if ((event->type() == OutputEvent::Playing) ||
258  (event->type() == OutputEvent::Info) ||
259  (event->type() == OutputEvent::Buffering) ||
260  (event->type() == OutputEvent::Paused))
261  {
262  m_playing = true;
263  if (!m_updateTimer->isActive())
264  m_updateTimer->start();
265  }
266  else if ((event->type() == OutputEvent::Stopped) ||
267  (event->type() == OutputEvent::Error))
268  {
269  m_playing = false;
270  }
271 }
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:117
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:23
VisualBase::getDesiredSamples
virtual unsigned long getDesiredSamples(void)
Definition: visualize.h:93
OutputEvent::Stopped
static Type Stopped
Definition: output.h:67
arg
arg(title).arg(filename).arg(doDelete))
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MainVisual::customEvent
void customEvent(QEvent *event) override
Definition: mainvisual.cpp:255
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:25
VisFactory
Definition: visualize.h:102
stereo16_from_stereopcm16
static void stereo16_from_stereopcm16(short *l, short *r, const short *s, long cnt)
Definition: videovisualdefs.h:113
AudioOutput::GetAudiotime
virtual int64_t GetAudiotime(void)=0
VisualBase::getDesiredFPS
virtual int getDesiredFPS(void)
Definition: visualize.h:91
MainVisual::timeout
void timeout()
Definition: mainvisual.cpp:208
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:56
MythUIVideo::UpdateFrame
void UpdateFrame(MythImage *image)
Definition: mythuivideo.cpp:52
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:929
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:15
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
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:898
MainVisual::m_updateTimer
QTimer * m_updateTimer
Definition: mainvisual.h:73
MainVisual::add
void add(const void *buffer, unsigned long b_len, unsigned long timecode, int source_channel, int bits_per_sample) override
Definition: mainvisual.cpp:147
MainVisual::m_nodes
QList< VisualNode * > m_nodes
Definition: mainvisual.h:69
VisFactory::next
const VisFactory * next() const
Definition: visualize.h:106
MainVisual::resize
void resize(const QSize &size)
Definition: mainvisual.cpp:246
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