tdeaddons/noatun-plugins/nexscope/nex.h

357 lines
6.0 KiB

#ifndef NEX_H
#define NEX_H
#include <tqwidget.h>
#include <tqptrlist.h>
#include <stdint.h>
#include <vector>
#include <tqdict.h>
#include <tqdatetime.h>
#include <iostream>
#include <tqdom.h>
#include "SDL.h"
#include "SDL_thread.h"
typedef uint32_t Pixel;
typedef uint8_t Byte;
#define COLOR(r,g,b) ((r<<16) | (g<<8) | (b))
#define COLORSTR(pixel) \
TQString("#%1%2%3").arg(TQString::number((pixel>>16) & 8, 16)) \
.arg(TQString::number((pixel>>8) & 8, 16)).arg(TQString::number(pixel& 8, 16))
#define STRCOLOR(pixel) \
Pixel(((pixel.mid(1,2).toInt(0, 16)) <<16) \
| ((pixel.mid(3,2).toInt(0, 16)) <<8) \
| (pixel.mid(5,2).toInt(0, 16)))
const int samples=512+256;
const int fhtsamples=512;
const int width=320*2;
const int height=240*2;
#define PI 3.141592654
class Mutex
{
public:
Mutex() { mMutex=::SDL_CreateMutex(); }
~Mutex() { ::SDL_DestroyMutex(mMutex); }
inline bool lock() { return !::SDL_mutexP(mMutex); }
inline bool unlock() { return !::SDL_mutexV(mMutex); }
private:
SDL_mutex *mMutex;
};
class Thread
{
public:
Thread();
/**
* kill() the thread
**/
virtual ~Thread();
void start();
void kill();
int wait();
protected:
virtual int run()=0;
private:
static int threadRun(void *);
SDL_Thread *mThread;
};
class Spacer : public TQWidget
{
TQ_OBJECT
public:
Spacer(TQWidget *parent) : TQWidget(parent)
{
setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding,
TQSizePolicy::MinimumExpanding));
}
};
class Bitmap
{
public:
Bitmap() : mData(0)
{ }
~Bitmap() { delete [] mData; }
void resize(int w, int h);
inline void setPixel(int x, int y, Pixel c)
{ mData[y*width+x] = c; }
inline void drawVerticalLine(int x, int yBottom, int yTop, Pixel c)
{
int w=width;
Pixel *d=mData+x+yTop*w;
yBottom-=yTop;
do
{
*d=c;
d+=width;
} while (yBottom--);
}
inline void drawHorizontalLine(int left, int right, int y, Pixel c)
{
Pixel *d=mData+y*width+left;
right-=left;
do
{
*(d++)=c;
} while (right--);
}
void drawCircle(int x, int y, int radius, Pixel color);
void fillCircle(int x, int y, int radius, Pixel color);
void drawLine(int x1, int y1, int x2, int y2, Pixel color);
inline int bytes() const { return width*height*sizeof(Pixel); }
inline Pixel *pixels(int x, int y) { return &(mData[y*width+x]); }
inline Pixel *pixels() const { return mData; }
inline Pixel pixel(int x, int y) { return mData[y*width+x]; }
inline Pixel *lastPixel() { return pixels(width-1, height-1); }
void clear();
private:
Pixel *mData;
};
/**
* maintains a list of bitmaps, so you
* can recycle allocated segments
*
* Thread safe
**/
class BitmapPool
{
public:
BitmapPool();
~BitmapPool();
Bitmap *get(bool clear=false);
void release(Bitmap *bitmap);
private:
struct PoolItem;
TQPtrList<BitmapPool::PoolItem> mBitmaps;
Mutex mMutex;
};
class StereoScope;
struct convolve_state;
class Input
{
public:
Input();
~Input();
/**
* audio is a pair of pointers to the buffers,
* one for each channel
*
* get the amount stated in the const global
* samples
**/
void getAudio(float **audio);
void setConvolve(bool state);
bool convolve() { return state; }
private:
void fht(float *p);
void transform(float *p, long n, long k);
void transform8(float *p);
void connect();
private:
StereoScope *mScope;
float outleft[samples], outright[samples];
float haystack[512];
float temp[samples+256];
convolve_state *state;
volatile bool mConvolve;
float fhtBuf[samples-256];
float fhtTab[(samples-256)*2];
bool ok;
TQObject *notifier;
};
class OutputSDL
{
public:
enum Event
{ None=0, Resize, Exit };
OutputSDL();
~OutputSDL();
int display(Bitmap *source);
private:
// static for speed, since there can be only one anyway because SDL sucks
static SDL_Surface *surface;
};
#include <tqcheckbox.h>
#include <kcolorbutton.h>
class NexCheckBox : public TQCheckBox
{
TQ_OBJECT
public:
NexCheckBox(TQWidget *parent, const TQString &, bool *v);
private slots:
void change(bool b);
private:
bool *value;
};
class NexColorButton : public KColorButton
{
TQ_OBJECT
public:
NexColorButton(TQWidget *parent, Pixel *color);
private slots:
void change(const TQColor &c);
private:
Pixel *c;
};
class Renderer
{
public:
Renderer();
virtual ~Renderer();
virtual Bitmap *render(float *pcm[4], Bitmap *source) = 0;
virtual TQWidget *configure(TQWidget*) { return 0; }
virtual void save(TQDomElement &) {}
virtual void load(const TQDomElement &) {}
};
class TQCheckBox;
class TQMultiLineEdit;
class RendererList;
class RendererListConfigurator : public TQWidget
{
TQ_OBJECT
public:
RendererListConfigurator(RendererList *l, TQWidget *parent);
~RendererListConfigurator();
public slots:
void eraseOn(bool state);
void convolve(bool state);
private:
TQCheckBox *mErase;
TQMultiLineEdit *mComments;
RendererList *mList;
};
class RendererList : public Renderer, public Mutex
{
friend class RendererListConfigurator;
public:
RendererList();
virtual ~RendererList();
virtual Bitmap *render(float *pcm[4], Bitmap *source);
TQPtrList<Renderer> &renderers() { return mRendererList; }
const TQPtrList<Renderer> &renderers() const { return mRendererList; }
bool clearAfter() const { return mClearAfter; }
void setClearAfter(bool b) { mClearAfter=b; }
virtual TQWidget *configure(TQWidget *parent);
virtual void save(TQDomElement &e);
virtual void load(const TQDomElement &e);
private:
TQPtrList<Renderer> mRendererList;
volatile bool mClearAfter;
TQString mComments;
Bitmap *mFrame;
};
typedef Renderer* (CreatorSig)();
class Nex
{
public:
Nex();
~Nex();
void go();
void setupSize(int w, int h);
static Nex *nex() { return sNex; }
BitmapPool *bitmapPool() { return mBitmapPool; }
RendererList *rendererList() { return mRendererList; }
Input *input() { return mInput; }
Renderer *renderer(const TQString &name);
TQStringList renderers() const;
public:
static Nex *sNex;
private:
Input *mInput;
OutputSDL mOutput;
BitmapPool *mBitmapPool;
RendererList *mRendererList;
TQDict<CreatorSig*> mCreators;
};
#define nex Nex::nex()
#endif