Skip to content

Commit

Permalink
libmythtv: Add some visualisation files.
Browse files Browse the repository at this point in the history
These are not yet hooked up.
  • Loading branch information
Mark Kendall committed Mar 22, 2011
1 parent 68578e0 commit cc80dac
Show file tree
Hide file tree
Showing 7 changed files with 798 additions and 0 deletions.
147 changes: 147 additions & 0 deletions mythtv/libs/libmythtv/visualisations/videovisual.cpp
@@ -0,0 +1,147 @@
#include "mythrender_base.h"
#include "mythplayer.h"
#include "videovisual.h"

#ifdef FFTW3_SUPPORT
#include "videovisualspectrum.h"
#include "videovisualcircles.h"
#endif

#ifdef USING_OPENGL
#include "mythrender_opengl2.h"
#endif

bool VideoVisual::CanVisualise(AudioPlayer *audio, MythRender *render)
{
#ifdef FFTW3_SUPPORT
if (render && audio->GetNumChannels() == 2)
return true;
#endif
return false;
}

VideoVisual* VideoVisual::Create(AudioPlayer *audio, MythRender *render)
{
#ifdef FFTW3_SUPPORT
if (render)
{
#ifdef USING_OPENGL
if (dynamic_cast<MythRenderOpenGL2*>(render))
return new VideoVisualCircles(audio, render);
#endif
return new VideoVisualSpectrum(audio, render);
}
#endif
return NULL;
}

VideoVisual::VideoVisual(AudioPlayer *audio, MythRender *render)
: m_audio(audio), m_disabled(false), m_area(QRect()), m_render(render)
{
m_lastUpdate = QDateTime::currentDateTime();
mutex()->lock();
if (m_audio)
m_audio->addVisual(this);
mutex()->unlock();
}

VideoVisual::~VideoVisual()
{
mutex()->lock();
if (m_audio)
m_audio->removeVisual(this);
DeleteNodes();
mutex()->unlock();
}

int64_t VideoVisual::SetLastUpdate(void)
{
QDateTime now = QDateTime::currentDateTime();
int64_t result = m_lastUpdate.msecsTo(now);
m_lastUpdate = now;
return result;
}

// caller holds lock
void VideoVisual::DeleteNodes(void)
{
while (!m_nodes.empty())
{
delete m_nodes.back();
m_nodes.pop_back();
}
}

// caller holds lock
void VideoVisual::prepare()
{
DeleteNodes();
}

// caller holds lock
VisualNode* VideoVisual::GetNode(void)
{
int64_t timestamp = m_audio->GetAudioTime();
while (m_nodes.size() > 1)
{
if (m_nodes.front()->offset > timestamp)
break;
delete m_nodes.front();
m_nodes.pop_front();
}

if (m_nodes.isEmpty())
return NULL;

return m_nodes.first();
}

// caller holds lock
void VideoVisual::add(uchar *b, unsigned long b_len, unsigned long w, int c, int p)
{
if (!m_disabled && m_nodes.size() > 500)
{
VERBOSE(VB_GENERAL, DESC +
QString("Over 500 nodes buffered - disabling visualiser."));
DeleteNodes();
m_disabled = true;
}

if (m_disabled)
return;

long len = b_len, cnt;
short *l = 0, *r = 0;

len /= c;
len /= (p / 8);

if (len > 512)
len = 512;

cnt = len;

if (c == 2)
{
l = new short[len];
r = new short[len];

if (p == 8)
stereo16_from_stereopcm8(l, r, b, cnt);
else if (p == 16)
stereo16_from_stereopcm16(l, r, (short *) b, cnt);
}
else if (c == 1)
{
l = new short[len];

if (p == 8)
mono16_from_monopcm8(l, b, cnt);
else if (p == 16)
mono16_from_monopcm16(l, (short *) b, cnt);
}
else
len = 0;

m_nodes.append(new VisualNode(l, r, len, w));
}
62 changes: 62 additions & 0 deletions mythtv/libs/libmythtv/visualisations/videovisual.h
@@ -0,0 +1,62 @@
#ifndef VIDEOVISUAL_H
#define VIDEOVISUAL_H

#include <QRect>
#include <QList>
#include "stdint.h"

#include "mythverbose.h"
#include "visual.h"
#include "mythpainter.h"
#include "videovisualdefs.h"

#define DESC QString("Visualiser: ")

class MythRender;
class AudioPlayer;

class VisualNode
{
public:
VisualNode(short *l, short *r, unsigned long n, unsigned long o)
: left(l), right(r), length(n), offset(o) { }

~VisualNode()
{
delete [] left;
delete [] right;
}

short *left, *right;
long length, offset;
};

class VideoVisual : public MythTV::Visual
{
public:
static bool CanVisualise(AudioPlayer *audio, MythRender *render);
static VideoVisual* Create(AudioPlayer *audio, MythRender *render);

VideoVisual(AudioPlayer *audio, MythRender *render);
~VideoVisual();

virtual void Draw(const QRect &area, MythPainter *painter,
QPaintDevice* device) = 0;

virtual void add(uchar *b, unsigned long b_len, unsigned long w, int c, int p);
virtual void prepare();

protected:
VisualNode* GetNode(void);
void DeleteNodes(void);
int64_t SetLastUpdate(void);

AudioPlayer *m_audio;
bool m_disabled;
QRect m_area;
MythRender *m_render;
QList<VisualNode*> m_nodes;
QDateTime m_lastUpdate;
};

#endif // VIDEOVISUAL_H
47 changes: 47 additions & 0 deletions mythtv/libs/libmythtv/visualisations/videovisualcircles.cpp
@@ -0,0 +1,47 @@
#include <QPen>
#include "videovisualcircles.h"

VideoVisualCircles::VideoVisualCircles(AudioPlayer *audio, MythRender *render)
: VideoVisualSpectrum(audio, render)
{
m_numSamples = 32;
}

void VideoVisualCircles::DrawPriv(MythPainter *painter, QPaintDevice* device)
{
if (!painter)
return;

static const QBrush nobrush(Qt::NoBrush);
int red = 0, green = 200;
QPen pen(QColor(red, green, 0, 255));
int count = m_scale.range();
int incr = 200 / count;
int rad = m_range;
QRect circ(m_area.x() + m_area.width() / 2, m_area.y() + m_area.height() / 2,
rad, rad);
painter->Begin(device);
for (int i = 0; i < count; i++, rad += m_range, red += incr, green -= incr)
{
double mag = abs((m_magnitudes[i] + m_magnitudes[i + count]) / 2.0);
if (mag > 1.0)
{
pen.setWidth((int)mag);
painter->DrawRoundRect(circ, rad, nobrush, pen, 200);
}
circ.adjust(-m_range, -m_range, m_range, m_range);
pen.setColor(QColor(red, green, 0, 255));
}
painter->End();
}

bool VideoVisualCircles::InitialisePriv(void)
{
m_range = (m_area.height() / 2) / (m_scale.range() -10);
m_scaleFactor = 10.0;
m_falloff = 1.0;

VERBOSE(VB_GENERAL, DESC + QString("Initialised Circles with %1 circles.")
.arg(m_scale.range()));
return true;
}
16 changes: 16 additions & 0 deletions mythtv/libs/libmythtv/visualisations/videovisualcircles.h
@@ -0,0 +1,16 @@
#ifndef VIDEOVISUALCIRCLES_H
#define VIDEOVISUALCIRCLES_H

#include "videovisualspectrum.h"

class VideoVisualCircles : public VideoVisualSpectrum
{
public:
VideoVisualCircles(AudioPlayer *audio, MythRender *render);

protected:
virtual bool InitialisePriv(void);
virtual void DrawPriv(MythPainter *painter, QPaintDevice* device);
};

#endif // VIDEOVISUALCIRCLES_H

0 comments on commit cc80dac

Please sign in to comment.