Added a goom plugin (goom.sourceforge.net) to test: ./gst-launch filesrc location=/opt/data/south.mp3 ! mad ! tee sil...

Original commit message from CVS:
Added a goom plugin (goom.sourceforge.net)

to test:
./gst-launch filesrc location=/opt/data/south.mp3 ! mad ! tee silent=true src%d! goom ! colorspace ! xvideosink  tee0.src%d! osssink
This commit is contained in:
Wim Taymans 2002-02-01 19:28:30 +00:00
parent e5faa112b6
commit 4d3b1472e7
12 changed files with 1691 additions and 0 deletions

13
gst/goom/Makefile.am Normal file
View file

@ -0,0 +1,13 @@
plugindir = $(libdir)/gst
plugin_LTLIBRARIES = libgstgoom.la
libgstgoom_la_SOURCES = gstgoom.c goom_core.c filters.c filters_mmx.s graphic.c lines.c
noinst_HEADERS = filters.h goom_core.h goom_tools.h graphic.h lines.h
#CFLAGS += -Wall -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math -DNDEBUG
libgstgoom_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS) -DMMX
libgstgoom_la_LIBADD = $(GST_LIBS)
libgstgoom_la_LDFLAGS = @GST_PLUGIN_LDFLAGS@

528
gst/goom/filters.c Normal file
View file

@ -0,0 +1,528 @@
/* filter.c version 0.7
* contient les filtres applicable a un buffer
* creation : 01/10/2000
* -ajout de sinFilter()
* -ajout de zoomFilter()
* -copie de zoomFilter() en zoomFilterRGB(), gérant les 3 couleurs
* -optimisation de sinFilter (utilisant une table de sin)
* -asm
* -optimisation de la procedure de génération du buffer de transformation
* la vitesse est maintenant comprise dans [0..128] au lieu de [0..100]
*/
//#define _DEBUG_PIXEL;
#include "filters.h"
#include "graphic.h"
#include "goom_tools.h"
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#ifdef MMX
#define USE_ASM
#endif
#ifdef POWERPC
#define USE_ASM
#endif
#ifdef USE_ASM
#define EFFECT_DISTORS 4
#else
#define EFFECT_DISTORS 10
#endif
extern volatile guint32 resolx;
extern volatile guint32 resoly;
#ifdef USE_ASM
#ifdef MMX
int mmx_zoom () ;
guint32 mmx_zoom_size;
#endif /* MMX */
#ifdef POWERPC
extern unsigned int useAltivec;
extern void ppc_zoom(void);
extern void ppc_zoom_altivec(void);
unsigned int ppcsize4;
#endif /* PowerPC */
unsigned int *coeffs = 0, *freecoeffs = 0;
guint32 *expix1 = 0; // pointeur exporte vers p1
guint32 *expix2 = 0; // pointeur exporte vers p2
guint32 zoom_width;
#endif /* ASM */
static int sintable [0xffff] ;
static int vitesse = 127;
static char theMode = AMULETTE_MODE ;
static int vPlaneEffect = 0;
static int hPlaneEffect = 0;
static char noisify = 2;
static int middleX , middleY ;
static unsigned char sqrtperte = 16 ;
static int * firedec = 0 ;
// retourne x>>s , en testant le signe de x
inline int ShiftRight (int x, const unsigned char s)
{
if (x<0)
return -(-x >> s) ;
else
return x >> s ;
}
/*
calculer px et py en fonction de x,y,middleX,middleY et theMode
px et py indique la nouvelle position (en sqrtperte ieme de pixel)
(valeur * 16)
*/
inline void calculatePXandPY (int x, int y, int *px, int *py)
{
if (theMode == WATER_MODE)
{
static int wave = 0 ;
static int wavesp = 0 ;
int yy ;
yy = y + RAND () % 4 - RAND () % 4 + wave / 10 ;
if (yy < 0) yy = 0 ;
if (yy >= resoly) yy = resoly - 1 ;
*px = (x<<4) + firedec [yy] + (wave / 10) ;
*py = (y<<4) + 132 - ((vitesse < 132) ? vitesse : 131) ;
wavesp += RAND () % 3 - RAND () % 3 ;
if (wave < -10) wavesp += 2 ;
if (wave > 10) wavesp -= 2 ;
wave += (wavesp / 10) + RAND () % 3 - RAND () % 3 ;
if (wavesp > 100) wavesp = (wavesp * 9) / 10 ;
}
else
{
int dist ;
register int vx,vy ;
int fvitesse = vitesse << 4 ;
if (noisify)
{
x += RAND() % noisify - RAND() % noisify ;
y += RAND() % noisify - RAND() % noisify ;
}
if (hPlaneEffect) vx = ((x - middleX) << 9) + hPlaneEffect * (y - middleY);
else vx = (x - middleX) << 9 ;
if (vPlaneEffect) vy = ((y - middleY) << 9) + vPlaneEffect * (x - middleX);
else vy = (y - middleY) << 9 ;
switch (theMode)
{
case WAVE_MODE:
dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
fvitesse *= 1024 + ShiftRight (
sintable [(unsigned short)(0xffff*dist*EFFECT_DISTORS)],6);
fvitesse /= 1024 ;
break ;
case CRYSTAL_BALL_MODE:
dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
fvitesse += (dist * EFFECT_DISTORS >> 10);
break;
case AMULETTE_MODE:
dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
fvitesse -= (dist * EFFECT_DISTORS >> 4);
break;
case SCRUNCH_MODE:
dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
fvitesse -= (dist * EFFECT_DISTORS >> 9);
break;
}
if (vx<0) *px = (middleX << 4) - (-(vx * fvitesse) >> 16) ;
else *px = (middleX << 4) + ((vx * fvitesse) >> 16) ;
if (vy<0) *py = (middleY << 4) - (-(vy * fvitesse) >> 16) ;
else *py = (middleY << 4) + ((vy * fvitesse) >> 16) ;
}
}
//#define _DEBUG
inline void setPixelRGB(Uint *buffer, Uint x, Uint y, Color c)
{
// buffer[ y*WIDTH + x ] = (c.r<<16)|(c.v<<8)|c.b
#ifdef _DEBUG_PIXEL
if ( x+y*resolx >= resolx * resoly)
{
fprintf (stderr,"setPixel ERROR : hors du tableau... %i, %i\n", x,y) ;
//exit (1) ;
}
#endif
#ifdef USE_DGA
buffer[ y*resolx + x ] = (c.b<<16)|(c.v<<8)|c.r ;
#else
buffer[ y*resolx + x ] = (c.r<<16)|(c.v<<8)|c.b ;
#endif
}
inline void setPixelRGB_ (Uint *buffer, Uint x, Color c)
{
#ifdef _DEBUG
if ( x >= resolx*resoly )
{
printf ("setPixel ERROR : hors du tableau... %i, %i\n", x,y) ;
exit (1) ;
}
#endif
#ifdef USE_DGA
buffer[ x ] = (c.b<<16)|(c.v<<8)|c.r ;
#else
buffer[ x ] = (c.r<<16)|(c.v<<8)|c.b ;
#endif
}
inline void getPixelRGB (Uint *buffer, Uint x, Uint y, Color *c)
{
register unsigned char *tmp8;
#ifdef _DEBUG
if (x + y * resolx >= resolx*resoly)
{
printf ("getPixel ERROR : hors du tableau... %i, %i\n", x,y) ;
exit (1) ;
}
#endif
#ifdef __BIG_ENDIAN__
c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + (x + y*resolx)));
c->r = *(unsigned char *)(++tmp8);
c->v = *(unsigned char *)(++tmp8);
c->b = *(unsigned char *)(++tmp8);
#else
/* ATTENTION AU PETIT INDIEN */
c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + (x + y*resolx)));
c->v = *(unsigned char *)(++tmp8);
c->r = *(unsigned char *)(++tmp8);
// *c = (Color) buffer[x+y*WIDTH] ;
#endif
}
inline void getPixelRGB_ (Uint *buffer, Uint x, Color *c)
{
register unsigned char *tmp8;
#ifdef _DEBUG
if ( x >= resolx*resoly )
{
printf ("getPixel ERROR : hors du tableau... %i\n", x) ;
exit (1) ;
}
#endif
#ifdef __BIG_ENDIAN__
c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + x));
c->r = *(unsigned char *)(++tmp8);
c->v = *(unsigned char *)(++tmp8);
c->b = *(unsigned char *)(++tmp8);
#else
/* ATTENTION AU PETIT INDIEN */
c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + x));
c->v = *(unsigned char *)(++tmp8);
c->r = *(unsigned char *)(++tmp8);
// *c = (Color) buffer[x+y*WIDTH] ;
#endif
}
/*===============================================================*/
void zoomFilterFastRGB (Uint *pix1,
Uint *pix2,
ZoomFilterData *zf,
Uint resx, Uint resy)
{
static guint32 prevX = 0, prevY = 0;
static char reverse = 0 ; //vitesse inversé..(zoom out)
// static int perte = 100; // 100 = normal
static unsigned char pertedec = 8 ;
static char firstTime = 1;
Uint x, y;
// static unsigned int prevX = 0, prevY = 0;
#ifdef USE_ASM
expix1 = pix1 ;
expix2 = pix2 ;
#else
Color couleur;
Color col1,col2,col3,col4;
Uint position ;
static unsigned int *pos10 = 0;
static unsigned int *c1 = 0,
*c2 = 0,
*c3 = 0,
*c4 = 0;
#endif
if ((prevX != resx) || (prevY != resy))
{
prevX = resx;
prevY = resy;
#ifndef USE_ASM
if (c1) free (c1) ;
if (c2) free (c2) ;
if (c3) free (c3) ;
if (c4) free (c4) ;
if (pos10) free (pos10) ;
c1=c2=c3=c4=pos10=0;
#else
if (coeffs) free (freecoeffs) ;
coeffs = 0;
#endif
middleX = resx / 2 ;
middleY = resy - 1;
firstTime = 1 ;
if (firedec) free (firedec);
firedec=0;
}
if (zf)
{
reverse = zf->reverse ;
vitesse = zf->vitesse ;
if (reverse)
vitesse = 256 - vitesse ;
#ifndef USE_ASM
sqrtperte = zf->sqrtperte ;
#endif
pertedec = zf->pertedec ;
middleX = zf->middleX ;
middleY = zf->middleY ;
theMode = zf->mode ;
hPlaneEffect = zf->hPlaneEffect;
vPlaneEffect = zf->vPlaneEffect;
noisify = zf->noisify;
}
if (firstTime || zf)
{
// generation d'une table de sinus
if (firstTime)
{
unsigned short us ;
firstTime = 0;
#ifdef USE_ASM
freecoeffs = (unsigned int *)
malloc (resx*resy*2*sizeof(unsigned int)+128);
coeffs = (guint32 *)((1+((unsigned int)(freecoeffs))/128)*128);
#else
pos10 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
c1 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
c2 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
c3 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
c4 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
#endif
for (us=0; us<0xffff; us++)
{
sintable [us] = (int)(1024.0f * sin (us*2*3.31415f/0xffff)) ;
}
{
int loopv ;
firedec = (int *) malloc (prevY * sizeof(int)) ;
for (loopv = prevY ; loopv != 0 ;)
{
static int decc = 0 ;
static int spdc = 0 ;
static int accel = 0 ;
loopv -- ;
firedec [loopv] = decc ;
decc += spdc / 10 ;
spdc = spdc + RAND () % 3 - RAND () % 3 ;
if (decc > 4)
spdc -= 1 ;
if (decc < -4)
spdc += 1 ;
if (spdc > 30)
spdc = spdc - RAND () % 3 + accel / 10 ;
if (spdc < -30)
spdc = spdc + RAND () % 3 + accel / 10 ;
if (decc > 8 && spdc > 1 )
spdc -= RAND () % 3 - 2 ;
if (decc < -8 && spdc < -1 )
spdc += RAND () % 3 + 2 ;
if (decc > 8 || decc < -8)
decc = decc * 8 / 9 ;
accel += RAND () % 2 - RAND () % 2 ;
if (accel > 20)
accel -= 2 ;
if (accel < -20)
accel += 2 ;
}
}
}
// generation du buffer
for (y = 0 ; y < prevY ; y++)
for (x = 0; x < prevX ; x++)
{
int px,py;
unsigned char coefv,coefh;
// calculer px et py en fonction de
// x,y,middleX,middleY et theMode
calculatePXandPY (x,y,&px, &py) ;
if ((px == x << 4) && (py == y << 4))
py += 8 ;
if ( (py<0) || (px<0) ||
(py>=(prevY-1)*sqrtperte) ||
(px>=(prevX-1)*sqrtperte))
{
#ifdef USE_ASM
coeffs[(y*prevX+x)*2]=0 ;
coeffs[(y*prevX+x)*2+1]=0;
#else
pos10[y*prevX+x]=0 ;
c1[y*prevX+x] = 0 ;
c2[y*prevX+x] = 0 ;
c3[y*prevX+x] = 0 ;
c4[y*prevX+x] = 0 ;
#endif
}
else
{
int npx10 ;
int npy10 ;
int pos = (y*prevX+x)*2;
npx10 = (px/sqrtperte) ;
npy10 = (py/sqrtperte) ;
/* if (npx10 >= prevX) fprintf(stderr,"error npx:%d",npx10);
if (npy10 >= prevY) fprintf(stderr,"error npy:%d",npy10);
*/
coefh = px % sqrtperte ;
coefv = py % sqrtperte ;
#ifdef USE_ASM
coeffs[pos] = (npx10 + prevX * npy10) * 4;
if (!(coefh || coefv))
coeffs[pos+1] = (sqrtperte*sqrtperte-1) ;
else
coeffs[pos+1] = (
(sqrtperte-coefh) *
(sqrtperte-coefv) );
coeffs[pos+1] |= (coefh * (sqrtperte-coefv)) << 8 ;
coeffs[pos+1] |= ((sqrtperte-coefh) * coefv) << 16 ;
coeffs[pos+1] |= (coefh * coefv)<<24 ;
#else
pos10[y*prevX+x]= npx10 + prevX * npy10 ;
if (!(coefh || coefv))
c1[y*prevX+x] = sqrtperte*sqrtperte-1 ;
else
c1[y*prevX+x] = (sqrtperte-coefh) * (sqrtperte-coefv);
c2[y*prevX+x] = coefh * (sqrtperte-coefv) ;
c3[y*prevX+x] = (sqrtperte-coefh) * coefv ;
c4[y*prevX+x] = coefh * coefv ;
#endif
}
}
}
#ifdef USE_ASM
#ifdef MMX
zoom_width = prevX ;
mmx_zoom_size = prevX * prevY ;
mmx_zoom () ;
#endif
#ifdef POWERPC
zoom_width = prevX;
if (useAltivec)
{
ppcsize4 = ((unsigned int)(prevX*prevY))/4;
ppc_zoom_altivec();
}
else
{
ppcsize4 = ((unsigned int)(prevX*prevY));
ppc_zoom();
}
#endif
#else
for (position=0; position<prevX*prevY; position++)
{
getPixelRGB_(pix1,pos10[position],&col1);
getPixelRGB_(pix1,pos10[position]+1,&col2);
getPixelRGB_(pix1,pos10[position]+prevX,&col3);
getPixelRGB_(pix1,pos10[position]+prevX+1,&col4);
couleur.r = col1.r * c1[position]
+ col2.r * c2[position]
+ col3.r * c3[position]
+ col4.r * c4[position];
couleur.r >>= pertedec ;
couleur.v = col1.v * c1[position]
+ col2.v * c2[position]
+ col3.v * c3[position]
+ col4.v * c4[position];
couleur.v >>= pertedec ;
couleur.b = col1.b * c1[position]
+ col2.b * c2[position]
+ col3.b * c3[position]
+ col4.b * c4[position];
couleur.b >>= pertedec ;
setPixelRGB_(pix2,position,couleur);
}
#endif
}
void pointFilter(Uint *pix1, Color c,
float t1, float t2, float t3, float t4,
Uint cycle)
{
Uint x = (Uint)((int)middleX + (int)(t1*cos((float)cycle/t3)));
Uint y = (Uint)((int)middleY + (int)(t2*sin((float)cycle/t4)));
if ((x>1) && (y>1) && (x<resolx-2) && (y<resoly-2))
{
setPixelRGB(pix1, x+1, y, c);
setPixelRGB(pix1, x, y+1, c);
setPixelRGB(pix1, x+1, y+1, WHITE);
setPixelRGB(pix1, x+2, y+1, c);
setPixelRGB(pix1, x+1, y+2, c);
}
}

71
gst/goom/filters.h Normal file
View file

@ -0,0 +1,71 @@
#ifndef FILTERS_H
#define FILTERS_H
#include <glib.h>
#include "graphic.h"
typedef struct
{
int vitesse ;
unsigned char pertedec ;
unsigned char sqrtperte ;
int middleX,middleY ;
char reverse ;
char mode ;
/** @since June 2001 */
int hPlaneEffect ;
int vPlaneEffect ;
char noisify ;
} ZoomFilterData ;
#define NORMAL_MODE 0
#define WAVE_MODE 1
#define CRYSTAL_BALL_MODE 2
#define SCRUNCH_MODE 3
#define AMULETTE_MODE 4
#define WATER_MODE 5
void pointFilter(guint32 *pix1, Color c,
float t1, float t2, float t3, float t4,
guint32 cycle);
/* filtre de zoom :
le contenu de pix1 est copie dans pix2, avec l'effet appliqué
midx et midy represente le centre du zoom
void zoomFilter(Uint *pix1, Uint *pix2, Uint middleX, Uint middleY);
void zoomFilterRGB(Uint *pix1,
Uint *pix2,
Uint middleX,
Uint middleY);
*/
void zoomFilterFastRGB (guint32 *pix1,
guint32 *pix2,
ZoomFilterData *zf,
guint32 resx, guint32 resy);
/* filtre sin :
le contenu de pix1 est copie dans pix2, avec l'effet appliqué
cycle est la variable de temps.
mode vaut SIN_MUL ou SIN_ADD
rate est le pourcentage de l'effet appliqué
lenght : la longueur d'onde (1..10) [5]
speed : la vitesse (1..100) [10]
*/
/*
void sinFilter(Uint *pix1,Uint *pix2,
Uint cycle,
Uint mode,
Uint rate,
char lenght,
Uint speed);
*/
#define SIN_MUL 1
#define SIN_ADD 2
#endif

130
gst/goom/filters_mmx.s Normal file
View file

@ -0,0 +1,130 @@
;// file : mmx_zoom.s
;// author : JC Hoelt <jeko@free.fr>
;//
;// history
;// 07/01/2001 : Changing FEMMS to EMMS : slower... but run on intel machines
;// 03/01/2001 : WIDTH and HEIGHT are now variable
;// 28/12/2000 : adding comments to the code, suppress some useless lines
;// 27/12/2000 : reducing memory access... improving performance by 20%
;// coefficients are now on 1 byte
;// 22/12/2000 : Changing data structure
;// 16/12/2000 : AT&T version
;// 14/12/2000 : unrolling loop
;// 12/12/2000 : 64 bits memory access
.data
thezero:
.long 0x00000000
.long 0x00000000
.text
.globl mmx_zoom ;// name of the function to call by C program
.extern coeffs ;// the transformation buffer
.extern expix1,expix2 ;// the source and destination buffer
.extern mmx_zoom_size, zoom_width ;// size of the buffers
.align 16
mmx_zoom:
push %ebp
push %esp
;// initialisation du mm7 à zero
movq (thezero), %mm7
movl zoom_width, %eax
movl $4, %ebx
mull %ebx
movl %eax, %ebp
movl (coeffs), %eax
movl (expix1), %edx
movl (expix2), %ebx
movl $10, %edi
movl mmx_zoom_size, %ecx
.while:
;// esi <- nouvelle position
movl (%eax), %esi
leal (%edx, %esi), %esi
;// recuperation des deux premiers pixels dans mm0 et mm1
movq (%esi), %mm0 /* b1-v1-r1-a1-b2-v2-r2-a2 */
movq %mm0, %mm1 /* b1-v1-r1-a1-b2-v2-r2-a2 */
;// recuperation des 4 coefficients
movd 4(%eax), %mm6 /* ??-??-??-??-c4-c3-c2-c1 */
;// depackage du premier pixel
punpcklbw %mm7, %mm0 /* 00-b2-00-v2-00-r2-00-a2 */
movq %mm6, %mm5 /* ??-??-??-??-c4-c3-c2-c1 */
;// depackage du 2ieme pixel
punpckhbw %mm7, %mm1 /* 00-b1-00-v1-00-r1-00-a1 */
;// extraction des coefficients...
punpcklbw %mm5, %mm6 /* c4-c4-c3-c3-c2-c2-c1-c1 */
movq %mm6, %mm4 /* c4-c4-c3-c3-c2-c2-c1-c1 */
movq %mm6, %mm5 /* c4-c4-c3-c3-c2-c2-c1-c1 */
punpcklbw %mm5, %mm6 /* c2-c2-c2-c2-c1-c1-c1-c1 */
punpckhbw %mm5, %mm4 /* c4-c4-c4-c4-c3-c3-c3-c3 */
movq %mm6, %mm3 /* c2-c2-c2-c2-c1-c1-c1-c1 */
punpcklbw %mm7, %mm6 /* 00-c1-00-c1-00-c1-00-c1 */
punpckhbw %mm7, %mm3 /* 00-c2-00-c2-00-c2-00-c2 */
;// multiplication des pixels par les coefficients
pmullw %mm6, %mm0 /* c1*b2-c1*v2-c1*r2-c1*a2 */
pmullw %mm3, %mm1 /* c2*b1-c2*v1-c2*r1-c2*a1 */
paddw %mm1, %mm0
;// ...extraction des 2 derniers coefficients
movq %mm4, %mm5 /* c4-c4-c4-c4-c3-c3-c3-c3 */
punpcklbw %mm7, %mm4 /* 00-c3-00-c3-00-c3-00-c3 */
punpckhbw %mm7, %mm5 /* 00-c4-00-c4-00-c4-00-c4 */
;// recuperation des 2 derniers pixels
movq (%esi,%ebp), %mm1
movq %mm1, %mm2
;// depackage des pixels
punpcklbw %mm7, %mm1
punpckhbw %mm7, %mm2
;// multiplication pas les coeffs
pmullw %mm4, %mm1
pmullw %mm5, %mm2
;// ajout des valeurs obtenues à la valeur finale
paddw %mm1, %mm0
paddw %mm2, %mm0
;// division par 256 = 16+16+16+16, puis repackage du pixel final
psrlw $8, %mm0
packuswb %mm7, %mm0
;// passage au suivant
leal 8(%eax), %eax
decl %ecx
;// enregistrement du resultat
movd %mm0, (%ebx)
leal 4(%ebx), %ebx
;// test de fin du tantque
cmpl $0, %ecx ;// 400x300
jz .fin_while
jmp .while
.fin_while:
emms
pop %esp
pop %ebp
ret ;//The End

420
gst/goom/goom_core.c Normal file
View file

@ -0,0 +1,420 @@
#include <stdlib.h>
#include <string.h>
#include "goom_core.h"
#include "goom_tools.h"
#include "filters.h"
#include "lines.h"
//#define VERBOSE
#ifdef VERBOSE
#include <stdio.h>
#endif
#define STOP_SPEED 128
/**-----------------------------------------------------**
** SHARED DATA **
**-----------------------------------------------------**/
static guint32 *pixel ;
static guint32 *back ;
static guint32 *p1,*p2,*tmp;
static guint32 cycle;
guint32 resolx, resoly, buffsize;
void goom_init (guint32 resx, guint32 resy)
{
#ifdef VERBOSE
printf ("GOOM: init (%d, %d);\n", resx,resy);
#endif
resolx = resx;
resoly = resy;
buffsize = resx * resy;
pixel = (guint32 *) malloc (buffsize * sizeof(guint32) + 128);
back = (guint32 *) malloc (buffsize * sizeof(guint32) + 128);
RAND_INIT ((guint32)pixel) ;
cycle = 0 ;
p1 = (guint32 *)((1+((unsigned int)(pixel))/128)*128);
p2 = (guint32 *)((1+((unsigned int)(back))/128)*128);
}
void goom_set_resolution (guint32 resx, guint32 resy)
{
free (pixel);
free (back);
resolx = resx;
resoly = resy;
buffsize = resx * resy;
pixel = (guint32 *) malloc (buffsize * sizeof(guint32) + 128);
bzero(pixel,buffsize * sizeof(guint32) + 128);
back = (guint32 *) malloc (buffsize * sizeof(guint32) + 128);
bzero(back,buffsize * sizeof(guint32) + 128);
p1 = (guint32 *)((1+((unsigned int)(pixel))/128)*128);
p2 = (guint32 *)((1+((unsigned int)(back))/128)*128);
}
guint32 * goom_update (gint16 data [2][512])
{
static int lockvar = 0 ; // pour empecher de nouveaux changements
static int goomvar = 0 ; // boucle des gooms
static int totalgoom = 0 ; // nombre de gooms par seconds
static int agoom = 0 ; // un goom a eu lieu..
static int loopvar = 0 ; // mouvement des points
static int speedvar = 0 ; // vitesse des particules
static int lineMode = 0 ; // l'effet lineaire a dessiner
guint32 * return_val;
guint32 pointWidth;
guint32 pointHeight;
int incvar ; // volume du son
int accelvar ; // acceleration des particules
int i ;
float largfactor ; // elargissement de l'intervalle d'évolution des points
static char goomlimit = 2 ; // sensibilité du goom
static ZoomFilterData zfd =
{
128, 8, 16,
1, 1, 0, WAVE_MODE,
0, 0, 0};
ZoomFilterData *pzfd;
/* test if the config has changed, update it if so */
pointWidth = (resolx * 2) / 5;
pointHeight = (resoly * 2) / 5;
/* ! etude du signal ... */
incvar = 0 ;
for (i=0;i<512;i++)
{
if (incvar < data[0][i]) incvar = data[0][i] ;
}
accelvar = incvar / 5000 ;
if (speedvar>5)
{
accelvar-- ;
if (speedvar>20) accelvar -- ;
if (speedvar>40) speedvar = 40 ;
}
accelvar -- ;
speedvar += accelvar ;
if (speedvar<0) speedvar=0;
if (speedvar>40) speedvar = 40 ;
/* ! calcul du deplacement des petits points ... */
largfactor = ((float)speedvar / 40.0f + (float)incvar / 50000.0f) / 1.5f ;
if (largfactor>1.5f) largfactor = 1.5f ;
for (i = 1 ; i*15 <= speedvar + 15; i ++) {
loopvar += speedvar + 1 ;
pointFilter(p1,
YELLOW,
((pointWidth - 6.0f) * largfactor + 5.0f),
((pointHeight - 6.0f) * largfactor + 5.0f),
i * 152.0f, 128.0f,
loopvar + i*2032);
pointFilter(p1, ORANGE,
((pointWidth / 2) * largfactor) / i + 10.0f * i,
((pointHeight / 2) * largfactor) / i + 10.0f * i,
96.0f, i * 80.0f, loopvar / i);
pointFilter(p1, VIOLET,
((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
i + 122.0f, 134.0f, loopvar / i);
pointFilter(p1, BLACK,
((pointHeight / 3) * largfactor + 20.0f),
((pointHeight / 3) * largfactor + 20.0f),
58.0f, i * 66.0f, loopvar / i);
pointFilter(p1, WHITE,
(pointHeight * largfactor + 10.0f * i) / i,
(pointHeight * largfactor + 10.0f * i) / i,
66.0f, 74.0f, loopvar + i * 500);
}
// par défaut pas de changement de zoom
pzfd = NULL ;
// diminuer de 1 le temps de lockage
// note pour ceux qui n'ont pas suivis : le lockvar permet d'empecher un
// changement d'etat du plugins juste apres un autre changement d'etat. oki ?
if (--lockvar < 0) lockvar = 0 ;
// temps du goom
if (--agoom < 0) agoom = 0 ;
// on verifie qu'il ne se pas un truc interressant avec le son.
if ((accelvar>goomlimit) || (accelvar<-goomlimit))
{
// UN GOOM !!! YAHOO !
totalgoom ++ ;
agoom = 20 ; // mais pdt 20 cycles, il n'y en aura plus.
lineMode = (lineMode + 1)%20; // Tous les 10 gooms on change de mode lineaire
// changement eventuel de mode
switch (iRAND(10))
{
case 0:
case 1:
case 2:
zfd.mode=WAVE_MODE;
zfd.vitesse=STOP_SPEED-1;
zfd.reverse=0;
break;
case 3:
case 4:
zfd.mode=CRYSTAL_BALL_MODE;
break;
case 5:
zfd.mode=AMULETTE_MODE;
break;
case 6:
zfd.mode = WATER_MODE ;
break;
case 7:
zfd.mode=SCRUNCH_MODE;
break;
default:
zfd.mode=NORMAL_MODE;
}
}
// tout ceci ne sera fait qu'en cas de non-blocage
if (lockvar == 0)
{
// reperage de goom (acceleration forte de l'acceleration du volume)
// -> coup de boost de la vitesse si besoin..
if ( (accelvar>goomlimit) || (accelvar<-goomlimit) )
{
goomvar ++ ;
//if (goomvar % 1 == 0)
{
guint32 vtmp ;
guint32 newvit ;
newvit = STOP_SPEED - speedvar / 2 ;
// retablir le zoom avant..
if ((zfd.reverse) &&
(!(cycle%12)) &&
(rand ()%3==0))
{
zfd.reverse = 0 ;
zfd.vitesse = STOP_SPEED - 2 ;
lockvar = 50 ;
}
if (iRAND (10) == 0)
{
zfd.reverse = 1;
lockvar = 100;
}
// changement de milieu..
switch (iRAND(20))
{
case 0:
zfd.middleY = resoly - 1 ;
zfd.middleX = resolx / 2 ;
break ;
case 1:
zfd.middleX = resolx - 1 ;
break ;
case 2:
zfd.middleX = 1 ;
break ;
default:
zfd.middleY = resoly / 2 ;
zfd.middleX = resolx / 2 ;
}
if (zfd.mode == WATER_MODE)
{
zfd.middleX = resolx / 2;
zfd.middleY = resoly / 2;
}
switch (vtmp = (iRAND (27)))
{
case 0:
zfd.vPlaneEffect = iRAND(3) - iRAND(3);
zfd.hPlaneEffect = iRAND(3) - iRAND(3);
break;
case 3:
zfd.vPlaneEffect = 0 ;
zfd.hPlaneEffect = iRAND(8) - iRAND(8);
break;
case 4:
case 5:
case 6:
case 7:
zfd.vPlaneEffect = iRAND(5) - iRAND (5);
zfd.hPlaneEffect = - zfd.vPlaneEffect;
break;
case 8:
zfd.hPlaneEffect = 5 + iRAND (8);
zfd.vPlaneEffect = - zfd.hPlaneEffect ;
break;
case 9:
zfd.vPlaneEffect = 5 + iRAND (8);
zfd.hPlaneEffect = - zfd.hPlaneEffect ;
break;
case 13:
zfd.hPlaneEffect = 0;
zfd.vPlaneEffect = iRAND(10) - iRAND(10);
break;
default:
if (vtmp < 10)
{
zfd.vPlaneEffect = 0;
zfd.hPlaneEffect = 0;
}
}
if (iRAND (3) != 0) zfd.noisify = 0 ;
else
{
zfd.noisify = iRAND (3) + 2 ;
lockvar *= 3;
}
if (zfd.mode == AMULETTE_MODE)
{
zfd.vPlaneEffect = 0;
zfd.hPlaneEffect = 0;
zfd.noisify = 0;
}
if ((zfd.middleX == 1) || (zfd.middleX == resolx - 1))
{
zfd.vPlaneEffect = 0 ;
zfd.hPlaneEffect = iRAND (2) ? 0 : zfd.hPlaneEffect;
}
if (newvit < zfd.vitesse) // on accelere
{
pzfd = &zfd;
if ( ( (newvit < STOP_SPEED - 7) &&
(zfd.vitesse < STOP_SPEED - 6) &&
(cycle % 3 == 0)) ||
(iRAND (40) == 0))
{
zfd.vitesse = STOP_SPEED - 1 ;
zfd.reverse = ! zfd.reverse ;
}
else
{
zfd.vitesse = (newvit + zfd.vitesse * 4) / 5 ;
}
lockvar += 50 ;
}
}
}
// mode mega-lent
if (iRAND(1000) == 0)
{
/*
printf ("coup du sort...\n") ;
*/
pzfd = &zfd ;
zfd.vitesse = STOP_SPEED - 1 ;
zfd.pertedec = 8 ;
zfd.sqrtperte = 16 ;
goomvar = 1 ;
lockvar += 70 ;
}
}
// gros frein si la musique est calme
if ((speedvar < 1) && (zfd.vitesse < STOP_SPEED - 4) && (cycle % 16 == 0))
{
/*
printf ("++slow part... %i\n", zfd.vitesse) ;
*/
pzfd = &zfd ;
zfd.vitesse += 3 ;
zfd.pertedec = 8 ;
zfd.sqrtperte = 16 ;
goomvar = 0 ;
/*
printf ("--slow part... %i\n", zfd.vitesse) ;
*/
}
// baisser regulierement la vitesse...
if ( (cycle % 73 == 0) && (zfd.vitesse < STOP_SPEED - 5))
{
/*
printf ("slow down...\n") ;
*/
pzfd = &zfd ;
zfd.vitesse ++ ;
}
// arreter de decrémenter au bout d'un certain temps
if ((cycle % 101 == 0) && (zfd.pertedec == 7))
{
pzfd = &zfd ;
zfd.pertedec=8 ;
zfd.sqrtperte=16 ;
}
#ifdef VERBOSE
if (pzfd)
{
printf ("GOOM: pzfd->mode = %d\n", pzfd->mode);
}
#endif
// Zoom here !
zoomFilterFastRGB (p1, p2, pzfd, resolx, resoly) ;
// si on est dans un goom : afficher les lignes...
if (agoom > 15) goom_lines
(data,
((zfd.middleX==resolx/2) && (zfd.middleY==resoly/2) && (zfd.mode!=WATER_MODE))
? (lineMode/10) : 0,
p2,agoom-15);
return_val = p2 ;
tmp=p1;
p1=p2;
p2=tmp;
// affichage et swappage des buffers..
cycle++;
// tous les 100 cycles : vérifier si le taux de goom est correct
// et le modifier sinon..
if (!(cycle%100))
{
if (totalgoom>15)
{
// printf ("less gooms\n") ;
goomlimit ++ ;
}
else
{
if ((totalgoom==0) && (goomlimit>1))
goomlimit -- ;
}
totalgoom = 0 ;
}
return return_val;
}
void goom_close ()
{
if (pixel!=NULL) free (pixel) ;
if (back!=NULL) free (back) ;
pixel = back = NULL;
RAND_CLOSE();
}

13
gst/goom/goom_core.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef _GOOMCORE_H
#define _GOOMCORE_H
#include <glib.h>
void goom_init (guint32 resx, guint32 resy);
void goom_set_resolution (guint32 resx, guint32 resy);
guint32 * goom_update (gint16 data [2][512]);
void goom_close ();
#endif

29
gst/goom/goom_tools.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef _GOOMTOOLS_H
#define _GOOMTOOLS_H
#define NB_RAND 0x10000
/* in graphic.c */
extern int * rand_tab ;
extern unsigned short rand_pos ;
#define RAND_INIT(i) \
srand (i) ;\
if (!rand_tab)\
rand_tab = (int *) malloc (NB_RAND * sizeof(int)) ;\
rand_pos = 1 ;\
while (rand_pos != 0)\
rand_tab [rand_pos++] = rand () ;
#define RAND()\
(rand_tab[rand_pos = rand_pos + 1])
#define RAND_CLOSE()\
free (rand_tab);\
rand_tab = 0;
//#define iRAND(i) ((guint32)((float)i * RAND()/RAND_MAX))
#define iRAND(i) (RAND()%i)
#endif

17
gst/goom/graphic.c Normal file
View file

@ -0,0 +1,17 @@
#include "graphic.h"
const Color BLACK = {0,0,0} ;
const Color WHITE = {0xff,0xff,0xff} ;
const Color RED = {0xff,0,0} ;
const Color GREEN = {0,0xff,0} ;
const Color BLUE = {0,0,0xff} ;
const Color YELLOW = {0xff, 0xff, 0x33} ;
const Color ORANGE = {0xff, 0xcc, 0x00} ;
const Color VIOLET = {0x55, 0x00, 0xff} ;
unsigned int SIZE ;
unsigned int HEIGHT ;
unsigned int WIDTH ;
int * rand_tab = 0 ;
unsigned short int rand_pos = 0 ;

24
gst/goom/graphic.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef GRAPHIC_H
#define GRAPHIC_H
typedef unsigned int Uint;
typedef struct
{
unsigned short r,v,b;
}
Color;
extern const Color BLACK;
extern const Color WHITE;
extern const Color RED;
extern const Color BLUE;
extern const Color GREEN;
extern const Color YELLOW;
extern const Color ORANGE;
extern const Color VIOLET;
inline void setPixelRGB (Uint *buffer, Uint x, Uint y, Color c) ;
inline void getPixelRGB (Uint *buffer, Uint x, Uint y, Color *c) ;
#endif /*GRAPHIC_H*/

341
gst/goom/gstgoom.c Normal file
View file

@ -0,0 +1,341 @@
/* gstgoom.c: implementation of goom drawing element
* Copyright (C) <2001> Richard Boulton <richard@tartarus.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <gst/gst.h>
#include "goom_core.h"
#define GST_TYPE_GOOM (gst_goom_get_type())
#define GST_GOOM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GOOM,GstGOOM))
#define GST_GOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GOOM,GstGOOM))
#define GST_IS_GOOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GOOM))
#define GST_IS_GOOM_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GOOM))
typedef struct _GstGOOM GstGOOM;
typedef struct _GstGOOMClass GstGOOMClass;
struct _GstGOOM {
GstElement element;
/* pads */
GstPad *sinkpad,*srcpad;
GstBufferPool *peerpool;
// the timestamp of the next frame
guint64 next_time;
// video state
gint bpp;
gint depth;
gint width;
gint height;
gboolean first_buffer;
gint samplerate;
gint framerate; // desired frame rate
gint samples_between_frames; // number of samples between start of successive frames
gint samples_since_last_frame; // number of samples between start of successive frames
};
struct _GstGOOMClass {
GstElementClass parent_class;
};
GType gst_goom_get_type(void);
/* elementfactory information */
static GstElementDetails gst_goom_details = {
"GOOM: what a GOOM!",
"Filter/Visualization",
"Takes frames of data and outputs video frames using the GOOM filter",
VERSION,
"Wim Taymans <wim.taymans@chello.be>",
"(C) 2002",
};
/* signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
/* FILL ME */
};
GST_PADTEMPLATE_FACTORY (src_template,
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_CAPS_NEW (
"goomsrc",
"video/raw",
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")),
"bpp", GST_PROPS_INT (32),
"depth", GST_PROPS_INT (32),
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"red_mask", GST_PROPS_INT (0xff0000),
"green_mask", GST_PROPS_INT (0xff00),
"blue_mask", GST_PROPS_INT (0xff),
"width", GST_PROPS_INT_RANGE (16, 4096),
"height", GST_PROPS_INT_RANGE (16, 4096)
)
)
GST_PADTEMPLATE_FACTORY (sink_template,
"sink", /* the name of the pads */
GST_PAD_SINK, /* type of the pad */
GST_PAD_ALWAYS, /* ALWAYS/SOMETIMES */
GST_CAPS_NEW (
"goomsink", /* the name of the caps */
"audio/raw", /* the mime type of the caps */
/* Properties follow: */
"format", GST_PROPS_STRING ("int"),
"law", GST_PROPS_INT (0),
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"signed", GST_PROPS_BOOLEAN (TRUE),
"width", GST_PROPS_INT (16),
"depth", GST_PROPS_INT (16),
"rate", GST_PROPS_INT_RANGE (8000, 96000),
"channels", GST_PROPS_INT (1)
)
)
static void gst_goom_class_init (GstGOOMClass *klass);
static void gst_goom_init (GstGOOM *goom);
static void gst_goom_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_goom_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_goom_chain (GstPad *pad, GstBuffer *buf);
static GstPadConnectReturn
gst_goom_sinkconnect (GstPad *pad, GstCaps *caps);
static GstElementClass *parent_class = NULL;
GType
gst_goom_get_type (void)
{
static GType type = 0;
if (!type) {
static const GTypeInfo info = {
sizeof (GstGOOMClass),
NULL,
NULL,
(GClassInitFunc) gst_goom_class_init,
NULL,
NULL,
sizeof (GstGOOM),
0,
(GInstanceInitFunc) gst_goom_init,
};
type = g_type_register_static (GST_TYPE_ELEMENT, "GstGOOM", &info, 0);
}
return type;
}
static void
gst_goom_class_init(GstGOOMClass *klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*) klass;
gstelement_class = (GstElementClass*) klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
gobject_class->set_property = gst_goom_set_property;
gobject_class->get_property = gst_goom_get_property;
}
static void
gst_goom_init (GstGOOM *goom)
{
/* create the sink and src pads */
goom->sinkpad = gst_pad_new_from_template (
GST_PADTEMPLATE_GET (sink_template ), "sink");
goom->srcpad = gst_pad_new_from_template (
GST_PADTEMPLATE_GET (src_template ), "src");
gst_element_add_pad (GST_ELEMENT (goom), goom->sinkpad);
gst_element_add_pad (GST_ELEMENT (goom), goom->srcpad);
gst_pad_set_chain_function (goom->sinkpad, gst_goom_chain);
gst_pad_set_connect_function (goom->sinkpad, gst_goom_sinkconnect);
goom->next_time = 0;
goom->peerpool = NULL;
// reset the initial video state
goom->bpp = 32;
goom->depth = 32;
goom->first_buffer = TRUE;
goom->width = 320;
goom->height = 200;
goom->samplerate = -1;
goom->framerate = 25; // desired frame rate
goom->samples_between_frames = 0; // number of samples between start of successive frames
goom->samples_since_last_frame = 0;
goom_init (goom->width, goom->height);
}
static GstPadConnectReturn
gst_goom_sinkconnect (GstPad *pad, GstCaps *caps)
{
GstGOOM *goom;
goom = GST_GOOM (gst_pad_get_parent (pad));
if (!GST_CAPS_IS_FIXED (caps)) {
return GST_PAD_CONNECT_DELAYED;
}
goom->samplerate = gst_caps_get_int (caps, "rate");
goom->samples_between_frames = goom->samplerate / goom->framerate;
GST_DEBUG (0, "GOOM: new sink caps: rate %d\n",
goom->samplerate);
return GST_PAD_CONNECT_OK;
}
static void
gst_goom_chain (GstPad *pad, GstBuffer *bufin)
{
GstGOOM *goom;
GstBuffer *bufout;
guint32 samples_in;
gint16 datain[2][512];
goom = GST_GOOM (gst_pad_get_parent (pad));
GST_DEBUG (0, "GOOM: chainfunc called\n");
samples_in = GST_BUFFER_SIZE (bufin) / sizeof (gint16);
GST_DEBUG (0, "input buffer has %d samples\n", samples_in);
if (goom->next_time <= GST_BUFFER_TIMESTAMP (bufin)) {
goom->next_time = GST_BUFFER_TIMESTAMP (bufin);
GST_DEBUG (0, "in: %lld\n", GST_BUFFER_TIMESTAMP (bufin));
}
if (goom->first_buffer) {
GstCaps *caps;
GST_DEBUG (0, "making new pad\n");
caps = GST_CAPS_NEW (
"goomsrc",
"video/raw",
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")),
"bpp", GST_PROPS_INT (goom->bpp),
"depth", GST_PROPS_INT (goom->depth),
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"red_mask", GST_PROPS_INT (0xff0000),
"green_mask", GST_PROPS_INT (0x00ff00),
"blue_mask", GST_PROPS_INT (0x0000ff),
"width", GST_PROPS_INT (goom->width),
"height", GST_PROPS_INT (goom->height)
);
if (!gst_pad_try_set_caps (goom->srcpad, caps)) {
gst_element_error (GST_ELEMENT (goom), "could not set caps");
return;
}
goom->first_buffer = FALSE;
}
memcpy (&datain[0][0], GST_BUFFER_DATA (bufin), 512);
memcpy (&datain[1][0], GST_BUFFER_DATA (bufin), 512);
bufout = gst_buffer_new ();
GST_BUFFER_DATA (bufout) = (guchar *) goom_update (datain);
GST_BUFFER_SIZE (bufout) = goom->width * goom->height * 4;
GST_BUFFER_FLAG_SET (bufout, GST_BUFFER_DONTFREE);
gst_pad_push (goom->srcpad, bufout);
gst_buffer_unref (bufin);
GST_DEBUG (0, "GOOM: exiting chainfunc\n");
}
static void
gst_goom_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
GstGOOM *goom;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_GOOM (object));
goom = GST_GOOM (object);
switch (prop_id) {
default:
break;
}
}
static void
gst_goom_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
GstGOOM *goom;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_GOOM (object));
goom = GST_GOOM (object);
switch (prop_id) {
default:
break;
}
}
static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
GstElementFactory *factory;
/* create an elementfactory for the goom element */
factory = gst_elementfactory_new("goom",GST_TYPE_GOOM,
&gst_goom_details);
g_return_val_if_fail(factory != NULL, FALSE);
gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_template));
gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_template));
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
return TRUE;
}
GstPluginDesc plugin_desc = {
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"goom",
plugin_init
};

90
gst/goom/lines.c Normal file
View file

@ -0,0 +1,90 @@
/*
* lines.c
* iTunesXPlugIn
*
* Created by guillaum on Tue Aug 14 2001.
* Copyright (c) 2001 __CompanyName__. All rights reserved.
*
*/
#include "lines.h"
#include <math.h>
extern unsigned int resolx,resoly;
inline unsigned char lighten(unsigned char value,unsigned char power)
{
unsigned char i;
for (i=0;i < power; i++) value += (255-value)/5;
return value;
}
void goom_lines(gint16 data [2][512], unsigned int ID,unsigned int* p, guint32 power)
{
guint32 color1;
guint32 color2;
unsigned char * color = 1 + (unsigned char *) &color1;
switch (ID)
{
case 0: // Horizontal stereo lines
{
color1 = 0x0000AA00;
color2 = 0x00AA0000;
break;
}
case 1: // Stereo circles
{
color1 = 0x00AA33DD;
color2 = 0x00AA33DD;
break;
}
}
*color = lighten(*color,power);
color++;
* color = lighten(*color,power);
color++;
* color = lighten(*color,power);
color = 1 + (unsigned char *) &color2;
* color = lighten(*color,power);
color++;
* color = lighten(*color,power);
color++;
* color = lighten(*color,power);
switch (ID)
{
case 0: // Horizontal stereo lines
{
unsigned int i;
for (i=0;i<512;i++)
{
guint32 plot ;
plot = i * resolx / 512 + (resoly / 4 + data[0][i] / 1600) * resolx;
p[plot] = color1;
p[plot+1] = color1;
plot = i * resolx / 512 + (resoly * 3 / 4 - data[1][i] / 1600) * resolx;
p[plot] = color2;
p[plot+1] = color2;
}
break;
}
case 1: // Stereo circles
{
float z;
unsigned int monX = resolx/2;
float monY = resoly/4;
float monY2 = resoly/2;
for (z=0;z<6.2832f; z+=1.0f/monY)
{
// float offset1 = 128+data[1][(unsigned int)(z*81.33f)])/200000;
p[ monX + (unsigned int)( (monY + ((float)resoly) * (128+data[1][(unsigned int)(z*81.33f)])/200000) * cos (z) + resolx * (unsigned int)( monY2 + (monY + ((float)resoly)*(128+data[1][(unsigned int)(z*81.33f)])/400000) * sin (z)))] = color1;
p[ monX + (unsigned int)((monY - ((float)resoly) * (128+data[0][(unsigned int)(z*81.33f)])/200000) * cos (z) + resolx * (unsigned int)( monY2 + (monY - ((float)resoly)*(128+data[0][(unsigned int)(z*81.33f)])/400000) * sin (z)))] = color2;
}
break;
}
}
}

15
gst/goom/lines.h Normal file
View file

@ -0,0 +1,15 @@
/*
* lines.h
* iGoom
*
* Created by guillaum on Tue Aug 14 2001.
* Copyright (c) 2001 ios. All rights reserved.
*
*/
#include <glib.h>
#include "graphic.h"
void goom_lines(gint16 data [2][512], unsigned int ID,unsigned int* p, guint32 power);
void goom_lines_conf(gint16 config [25]);