summaryrefslogtreecommitdiffstats
path: root/noatun/modules/kjofol-skin/kjvis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'noatun/modules/kjofol-skin/kjvis.cpp')
-rw-r--r--noatun/modules/kjofol-skin/kjvis.cpp538
1 files changed, 538 insertions, 0 deletions
diff --git a/noatun/modules/kjofol-skin/kjvis.cpp b/noatun/modules/kjofol-skin/kjvis.cpp
new file mode 100644
index 00000000..71246089
--- /dev/null
+++ b/noatun/modules/kjofol-skin/kjvis.cpp
@@ -0,0 +1,538 @@
+/***************************************************************************
+ kjvis.cpp - Visualizations used in the KJöfol-GUI
+ --------------------------------------
+ Maintainer: Stefan Gehn <metz AT gehn.net>
+
+ ***************************************************************************/
+
+// local includes
+#include "kjvis.h"
+#include "kjprefs.h"
+
+// system includes
+#include <math.h>
+
+//qt includes
+#include <qpainter.h>
+#include <qsize.h>
+
+//kde includes
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kconfig.h>
+#include <kpixmapeffect.h>
+#include <kpixmap.h>
+
+// noatun includes
+#include <noatun/player.h>
+
+#define _KJ_GRADIENT_DIFF 130
+
+/*******************************************
+ * KJFFTScope
+ *******************************************/
+
+void KJVisScope::swapScope(Visuals newOne)
+{
+ //kdDebug(66666) << k_funcinfo << endl;
+ QStringList line = parent()->item("analyzerwindow");
+ KJLoader *p=parent();
+ p->removeChild(this);
+ delete this;
+
+ KJLoader::kjofol->prefs()->setVisType ( newOne );
+
+ KJWidget *w = 0;
+ switch (newOne)
+ {
+ case Null:
+ w = new KJNullScope(line, p);
+ break;
+ case FFT:
+ w = new KJFFT(line, p);
+ break;
+ case StereoFFT:
+ w = new KJStereoFFT(line, p);
+ break;
+ case Mono:
+ w = new KJScope(line, p);
+ break;
+ };
+
+ p->addChild(w);
+}
+
+/*******************************************
+ * KJNullScope
+ *******************************************/
+
+KJNullScope::KJNullScope(const QStringList &l, KJLoader *parent)
+ : KJVisScope(parent)
+{
+ int x = l[1].toInt();
+ int y = l[2].toInt();
+ int xs = l[3].toInt() - x;
+ int ys = l[4].toInt() - y;
+
+ // background under vis
+ QPixmap tmp = parent->pixmap(parent->item("backgroundimage")[1]);
+ mBack = new KPixmap ( QSize(xs,ys) );
+ bitBlt( mBack, 0, 0, &tmp, x, y, xs, ys, Qt::CopyROP );
+ setRect ( x, y, xs, ys );
+ repaint();
+}
+
+void KJNullScope::paint(QPainter *p, const QRect &)
+{
+ // just redraw the background
+ bitBlt ( p->device(), rect().topLeft(), mBack, QRect(0,0,-1,-1), Qt::CopyROP );
+}
+
+bool KJNullScope::mousePress(const QPoint &)
+{
+ return true;
+}
+
+void KJNullScope::mouseRelease(const QPoint &, bool in)
+{
+ if (!in) // only do something if users is still inside the button
+ return;
+
+ parent()->repaint(rect(), false);
+ swapScope(FFT);
+}
+
+void KJNullScope::readConfig()
+{
+// kdDebug(66666) << "[KJNullScope] readConfig()" << endl;
+ Visuals v = (Visuals) KJLoader::kjofol->prefs()->visType();
+ if ( v != Null )
+ {
+ parent()->repaint(rect(), false);
+ swapScope ( v );
+ }
+}
+
+
+/*************************************************
+ * KJFFT - Analyzer like visualization, mono
+ *************************************************/
+
+KJFFT::KJFFT(const QStringList &l, KJLoader *parent)
+ : KJVisScope(parent), MonoFFTScope(50), mGradient(0)
+{
+ int x = l[1].toInt();
+ int y = l[2].toInt();
+ int xs = l[3].toInt()-x;
+ int ys = l[4].toInt()-y;
+
+ // each bar will be 1px wide
+ mMultiples=1;
+
+ if ( parent->exist("analyzercolor") )
+ {
+ QStringList &col = parser()["analyzercolor"];
+ mColor.setRgb ( col[1].toInt(), col[2].toInt(), col[3].toInt() );
+ }
+ else // TODO: what should be default colors for Vis?
+ {
+ mColor.setRgb ( 255, 255, 255 ); // white is default
+ }
+
+ // background under vis
+ QPixmap tmp = parent->pixmap(parent->item("backgroundimage")[1]);
+ mBack = new KPixmap ( QSize(xs,ys) );
+ bitBlt( mBack, 0, 0, &tmp, x, y, xs, ys, Qt::CopyROP );
+
+ mAnalyzer = new KPixmap ( QSize(xs,ys) );
+ bitBlt( mAnalyzer, 0, 0, &tmp, x, y, xs, ys, Qt::CopyROP );
+
+ // create a gradient for the bars going from 30% lighter to 30% darker than mColor
+ mGradient = new KPixmap ( QSize(xs,ys) );
+ KPixmapEffect::gradient ( *mGradient, mColor.light(_KJ_GRADIENT_DIFF),
+ mColor.dark(_KJ_GRADIENT_DIFF), KPixmapEffect::VerticalGradient );
+
+ setRect (x,y,xs,ys);
+ setBands(magic(xs/mMultiples));
+ readConfig(); // read our config settings
+ start();
+}
+
+void KJFFT::scopeEvent(float *d, int size)
+{
+ if ( !napp->player()->isPlaying() ) // don't draw if we aren't playing (either paused or stopped)
+ {
+ if ( napp->player()->isStopped() ) // clear vis-window if playing has been stopped
+ parent()->repaint(rect(), false);
+ return;
+ }
+
+ int x = 0;
+ int h = rect().height();
+
+ QBitmap mGradientMask ( rect().width(), h, true );
+ QPainter mask( &mGradientMask );
+
+ float *start = d ;
+ float *end = d + size /*- 1*/;
+
+ // loop creating the mask for vis-gradient
+ for ( ; start < end; ++start )
+ {
+ // 5 has been 8 before and I have no idea how this scaling works :/
+ // FIXME: somebody please make it scale to 100% of height,
+ // I guess that would be nicer to look at
+// float n = log((*start)+1) * (float)h * 5;
+ float n = log((*start)+1) * (float)h * 5;
+ int amp=(int)n;
+
+ // range check
+ if ( amp < 0 ) amp = 0;
+ else if ( amp > h ) amp = h;
+
+ // make a part of the analyzer-gradient visible
+ mask.fillRect ( x, (h-amp), mMultiples, amp, Qt::color1 );
+ x += mMultiples;
+ }
+ // done creating our mask
+
+ // draw background of vis into it
+ bitBlt ( mAnalyzer, 0, 0, mBack, 0, 0, -1, -1, Qt::CopyROP );
+
+ // draw the analyzer
+ mGradient->setMask(mGradientMask);
+ bitBlt ( mAnalyzer, 0, 0, mGradient, 0, 0, -1, -1, Qt::CopyROP );
+
+ repaint();
+}
+
+void KJFFT::paint(QPainter *p, const QRect &)
+{
+ // put that thing on screen
+ if ( !napp->player()->isStopped() )
+ bitBlt ( p->device(), rect().topLeft(), mAnalyzer, QRect(0,0,-1,-1), Qt::CopyROP );
+}
+
+
+bool KJFFT::mousePress(const QPoint &)
+{
+ return true;
+}
+
+void KJFFT::mouseRelease(const QPoint &, bool in)
+{
+ if (!in) // only do something if users is still inside the button
+ return;
+
+ stop();
+ parent()->repaint(rect(), false);
+ swapScope(Mono);
+}
+
+void KJFFT::readConfig()
+{
+// kdDebug(66666) << "[KJFFT] readConfig()" << endl;
+ Visuals v = (Visuals) KJLoader::kjofol->prefs()->visType();
+ if ( v != FFT )
+ {
+ stop();
+ parent()->repaint(rect(), false);
+ swapScope ( v );
+ return;
+ }
+
+ mTimerValue = KJLoader::kjofol->prefs()->visTimerValue();
+ setInterval( mTimerValue );
+}
+
+
+/*************************************************
+ * KJStereoFFT - Analyzer like visualization, stereo
+ *************************************************/
+
+KJStereoFFT::KJStereoFFT(const QStringList &l, KJLoader *parent)
+ : KJVisScope(parent), StereoFFTScope(50), mGradient(0)
+{
+ //kdDebug(66666) << k_funcinfo << endl;
+
+ int x = l[1].toInt();
+ int y = l[2].toInt();
+ int xs = l[3].toInt()-x;
+ int ys = l[4].toInt()-y;
+
+ // each bar will be 1px wide
+ mMultiples=1;
+
+ if ( parent->exist("analyzercolor") )
+ {
+ QStringList &col = parser()["analyzercolor"];
+ mColor.setRgb ( col[1].toInt(), col[2].toInt(), col[3].toInt() );
+ }
+ else // TODO: what should be default colors for Vis?
+ {
+ mColor.setRgb ( 255, 255, 255 ); // white is default
+ }
+
+ // background under vis
+ QPixmap tmp = parent->pixmap(parent->item("backgroundimage")[1]);
+ mBack = new KPixmap ( QSize(xs,ys) );
+ bitBlt( mBack, 0, 0, &tmp, x, y, xs, ys, Qt::CopyROP );
+
+ mAnalyzer = new KPixmap ( QSize(xs,ys) );
+ bitBlt( mAnalyzer, 0, 0, &tmp, x, y, xs, ys, Qt::CopyROP );
+
+ // create a gradient for the bars going from 30% lighter to 30% darker than mColor
+ mGradient = new KPixmap ( QSize(xs,ys) );
+ KPixmapEffect::gradient ( *mGradient, mColor.light(_KJ_GRADIENT_DIFF),
+ mColor.dark(_KJ_GRADIENT_DIFF), KPixmapEffect::VerticalGradient );
+
+ setRect (x,y,xs,ys);
+ setBands(magic(xs/mMultiples));
+ readConfig(); // read our config settings
+ start();
+}
+
+void KJStereoFFT::scopeEvent(float *left, float *right, int len)
+{
+ if ( !napp->player()->isPlaying() ) // don't draw if we aren't playing (either paused or stopped)
+ {
+ if ( napp->player()->isStopped() ) // clear vis-window if playing has been stopped
+ parent()->repaint(rect(), false);
+ return;
+ }
+
+ unsigned int h = rect().height();
+ int hh = (int)(rect().height()/2);
+
+ QBitmap mGradientMask ( rect().width(), h, true );
+ QPainter mask( &mGradientMask );
+
+ float *start = left;
+ float *end = left + len;
+ float n = 0.0;
+ int amp = 0;
+ int x = 0;
+
+ // loop creating the mask for vis-gradient
+ for ( ; start < end; ++start )
+ {
+ n = log((*start)+1) * (float)hh * 5;
+ amp = (int)n;
+
+ // range check
+ if ( amp < 0 ) amp = 0;
+ else if ( amp > hh ) amp = hh;
+
+ // make a part of the analyzer-gradient visible
+ mask.fillRect ( x, (h-amp), mMultiples, amp, Qt::color1 );
+ x += mMultiples;
+ }
+ // done creating our mask
+
+
+ start = right;
+ end = right + len;
+ x = 0;
+ // loop creating the mask for vis-gradient
+ for ( ; start < end; ++start )
+ {
+ n = log((*start)+1) * (float)hh * 5;
+ amp = (int)n;
+
+ // range check
+ if ( amp < 0 ) amp = 0;
+ else if ( amp > hh ) amp = hh;
+
+ // make a part of the analyzer-gradient visible
+ mask.fillRect ( x, 0, mMultiples, amp, Qt::color1 );
+ x += mMultiples;
+ }
+
+
+ // draw background of vis into it
+ bitBlt ( mAnalyzer, 0, 0, mBack, 0, 0, -1, -1, Qt::CopyROP );
+
+ // draw the analyzer
+ mGradient->setMask(mGradientMask);
+ bitBlt ( mAnalyzer, 0, 0, mGradient, 0, 0, -1, -1, Qt::CopyROP );
+
+ repaint();
+}
+
+void KJStereoFFT::paint(QPainter *p, const QRect &)
+{
+ // put that thing on screen
+ if ( !napp->player()->isStopped() )
+ bitBlt ( p->device(), rect().topLeft(), mAnalyzer, QRect(0,0,-1,-1), Qt::CopyROP );
+}
+
+bool KJStereoFFT::mousePress(const QPoint &)
+{
+ return true;
+}
+
+void KJStereoFFT::mouseRelease(const QPoint &, bool in)
+{
+ if (!in) // only do something if users is still inside the button
+ return;
+ stop();
+ parent()->repaint(rect(), false);
+ swapScope(Null);
+}
+
+void KJStereoFFT::readConfig()
+{
+ //kdDebug(66666) << k_funcinfo << endl;
+ Visuals v = (Visuals) KJLoader::kjofol->prefs()->visType();
+ if ( v != StereoFFT )
+ {
+ stop();
+ parent()->repaint(rect(), false);
+ swapScope ( v );
+ return;
+ }
+ setInterval(KJLoader::kjofol->prefs()->visTimerValue());
+}
+
+
+/*************************************************
+ * KJScope - oscilloscope like visualization
+ *************************************************/
+
+KJScope::KJScope(const QStringList &l, KJLoader *parent)
+ : KJVisScope(parent), MonoScope(50)/*, blurnum(0), mOsci(0)*/
+{
+ int x=l[1].toInt();
+ int y=l[2].toInt();
+ int xs = mWidth = l[3].toInt()-x;
+ int ys = mHeight = l[4].toInt()-y;
+
+ blurnum = 0;
+
+// kdDebug(66666) << "Analyzer Window " << x << "," << y << " " << mWidth << "," << mHeight << endl;
+
+ if ( parent->exist("analyzercolor") )
+ {
+ QStringList &col = parser()["analyzercolor"];
+ mColor.setRgb ( col[1].toInt(), col[2].toInt(), col[3].toInt() );
+ }
+ else // FIXME: what should be default colors for Vis?
+ mColor.setRgb ( 255, 255, 255 );
+
+ // background under vis
+ QPixmap tmp = parent->pixmap(parent->item("backgroundimage")[1]);
+ mBack = new KPixmap ( QSize(xs,ys) );
+ bitBlt( mBack, 0, 0, &tmp, x, y, xs, ys, Qt::CopyROP );
+
+ mOsci = new KPixmap ( QSize(xs,ys) );
+ bitBlt( mOsci, 0, 0, &tmp, x, y, xs, ys, Qt::CopyROP );
+
+ // create a gradient
+ mGradient = new KPixmap ( QSize(xs,ys) );
+ KPixmapEffect::gradient ( *mGradient, mColor.light(_KJ_GRADIENT_DIFF),
+ mColor.dark(_KJ_GRADIENT_DIFF), KPixmapEffect::VerticalGradient );
+
+ setRect ( x, y, xs, ys );
+
+ // set the samplewidth to the largest integer divisible by mWidth
+ setSamples ( xs );
+
+ readConfig();
+ start();
+}
+
+void KJScope::scopeEvent(float *d, int size)
+{
+ if ( !napp->player()->isPlaying() )
+ {
+ if ( napp->player()->isStopped() )
+ {
+ bitBlt ( mOsci, 0, 0, mBack, 0, 0, -1, -1, Qt::CopyROP );
+ repaint();
+ }
+ return;
+ }
+
+ float *start = d;
+ float *end = d + size;
+
+ int heightHalf = rect().height()/2 /* -1 */;
+ int x = 0;
+
+ QPainter tempP( mOsci );
+
+ if ( blurnum == 3 )
+ { // clear whole Vis
+ bitBlt ( mOsci, 0, 0, mBack, 0, 0, -1, -1, Qt::CopyROP );
+ tempP.setPen( mColor.light(110) ); // 10% lighter than mColor
+ blurnum=0;
+ }
+ else
+ {
+ blurnum++;
+ // reduce color for blur-effect
+ tempP.setPen( mColor.dark(90+(10*blurnum)) ); // darken color
+ }
+
+ for ( ; start < end; ++start )
+ {
+ float n = (*start) * (float)heightHalf;
+ int amp = (int)n;
+
+ // range check
+ if ( amp > heightHalf ) amp = heightHalf;
+ else if ( amp < -heightHalf) amp = -heightHalf;
+
+ // draw
+// tempP.drawLine(x, heightHalf, x, heightHalf+amp);
+ if ( amp > 0 )
+ {
+ bitBlt ( tempP.device(), QPoint(x,heightHalf), mGradient, QRect(x,heightHalf,1,amp), Qt::CopyROP );
+ }
+ else
+ {
+ amp = -amp;
+ bitBlt ( tempP.device(), QPoint(x,heightHalf-amp), mGradient, QRect(x,(heightHalf-amp),1,amp), Qt::CopyROP );
+ }
+ x++;
+ }
+
+ repaint();
+}
+
+void KJScope::paint(QPainter *p, const QRect &)
+{
+ // put that thing on screen
+ bitBlt ( p->device(), rect().topLeft(), mOsci, QRect(0,0,-1,-1), Qt::CopyROP );
+}
+
+bool KJScope::mousePress(const QPoint &)
+{
+ return true;
+}
+
+void KJScope::mouseRelease(const QPoint &, bool in)
+{
+ if (!in) // only do something if users is still inside the button
+ return;
+
+ stop();
+ parent()->repaint(rect(), false);
+ swapScope(/*Null*/ StereoFFT);
+}
+
+void KJScope::readConfig()
+{
+// kdDebug(66666) << "[KJScope] readConfig()" << endl;
+ Visuals v = (Visuals) KJLoader::kjofol->prefs()->visType();
+ if ( v != Mono )
+ {
+ stop();
+ parent()->repaint(rect(), false);
+ swapScope ( v );
+ return;
+ }
+
+ mTimerValue = KJLoader::kjofol->prefs()->visTimerValue();
+ setInterval( mTimerValue );
+}