summaryrefslogtreecommitdiffstats
path: root/gst/goom/goom_core.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2002-02-01 19:28:30 +0000
committerWim Taymans <wim.taymans@gmail.com>2002-02-01 19:28:30 +0000
commit4d3b1472e78ac7c12460b26914c9a294a3de573a (patch)
tree4d9b1f0a6698385b086e37381b75b2d93bf85e39 /gst/goom/goom_core.c
parente5faa112b67c7681f653949413799180c7382451 (diff)
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
Diffstat (limited to 'gst/goom/goom_core.c')
-rw-r--r--gst/goom/goom_core.c420
1 files changed, 420 insertions, 0 deletions
diff --git a/gst/goom/goom_core.c b/gst/goom/goom_core.c
new file mode 100644
index 00000000..245c280e
--- /dev/null
+++ b/gst/goom/goom_core.c
@@ -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();
+}