--- /dev/null
+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@
+
--- /dev/null
+/* 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);
+ }
+}
--- /dev/null
+#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
--- /dev/null
+;// 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
--- /dev/null
+#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();
+}
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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 ;
--- /dev/null
+#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*/
--- /dev/null
+/* 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
+};
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
+
--- /dev/null
+/*
+ * 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]);
+