gst-indent
[platform/upstream/gst-plugins-good.git] / gst / goom / goom_core.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include "goom_core.h"
4 #include "goom_tools.h"
5 #include "filters.h"
6 #include "lines.h"
7
8 /*#define VERBOSE */
9
10 #ifdef VERBOSE
11 #include <stdio.h>
12 #endif
13
14 #define STOP_SPEED 128
15
16
17 /**-----------------------------------------------------**
18  **  SHARED DATA                                        **
19  **-----------------------------------------------------**/
20 static guint32 *pixel;
21 static guint32 *back;
22 static guint32 *p1, *p2, *tmp;
23 static guint32 cycle;
24
25 guint32 resolx, resoly, buffsize;
26
27 void
28 goom_init (guint32 resx, guint32 resy)
29 {
30 #ifdef VERBOSE
31   printf ("GOOM: init (%d, %d);\n", resx, resy);
32 #endif
33   resolx = resx;
34   resoly = resy;
35   buffsize = resx * resy;
36
37   pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
38   back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
39   RAND_INIT (GPOINTER_TO_INT (pixel));
40   cycle = 0;
41
42   p1 = (void *) (((unsigned long) pixel + 0x7f) & (~0x7f));
43   p2 = (void *) (((unsigned long) back + 0x7f) & (~0x7f));
44 }
45
46
47 void
48 goom_set_resolution (guint32 resx, guint32 resy)
49 {
50   free (pixel);
51   free (back);
52
53   resolx = resx;
54   resoly = resy;
55   buffsize = resx * resy;
56
57   pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
58   memset (pixel, 0, buffsize * sizeof (guint32) + 128);
59   back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
60   memset (back, 0, buffsize * sizeof (guint32) + 128);
61
62   p1 = (void *) (((unsigned long) pixel + 0x7f) & (~0x7f));
63   p2 = (void *) (((unsigned long) back + 0x7f) & (~0x7f));
64 }
65
66
67 guint32 *
68 goom_update (gint16 data[2][512])
69 {
70   static int lockvar = 0;       /* pour empecher de nouveaux changements */
71   static int goomvar = 0;       /* boucle des gooms */
72   static int totalgoom = 0;     /* nombre de gooms par seconds */
73   static int agoom = 0;         /* un goom a eu lieu..       */
74   static int loopvar = 0;       /* mouvement des points */
75   static int speedvar = 0;      /* vitesse des particules */
76   static int lineMode = 0;      /* l'effet lineaire a dessiner */
77   guint32 *return_val;
78   guint32 pointWidth;
79   guint32 pointHeight;
80   int incvar;                   /* volume du son */
81   int accelvar;                 /* acceleration des particules */
82   int i;
83   float largfactor;             /* elargissement de l'intervalle d'évolution des points */
84   static char goomlimit = 2;    /* sensibilité du goom */
85   static ZoomFilterData zfd = {
86     128, 8, 16,
87     1, 1, 0, WAVE_MODE,
88     0, 0, 0
89   };
90
91   ZoomFilterData *pzfd;
92
93   /* test if the config has changed, update it if so */
94   pointWidth = (resolx * 2) / 5;
95   pointHeight = (resoly * 2) / 5;
96
97   /* ! etude du signal ... */
98   incvar = 0;
99   for (i = 0; i < 512; i++) {
100     if (incvar < data[0][i])
101       incvar = data[0][i];
102   }
103
104   accelvar = incvar / 5000;
105   if (speedvar > 5) {
106     accelvar--;
107     if (speedvar > 20)
108       accelvar--;
109     if (speedvar > 40)
110       speedvar = 40;
111   }
112   accelvar--;
113   speedvar += accelvar;
114
115   if (speedvar < 0)
116     speedvar = 0;
117   if (speedvar > 40)
118     speedvar = 40;
119
120
121   /* ! calcul du deplacement des petits points ... */
122
123   largfactor = ((float) speedvar / 40.0f + (float) incvar / 50000.0f) / 1.5f;
124   if (largfactor > 1.5f)
125     largfactor = 1.5f;
126
127   for (i = 1; i * 15 <= speedvar + 15; i++) {
128     loopvar += speedvar + 1;
129
130     pointFilter (p1,
131         YELLOW,
132         ((pointWidth - 6.0f) * largfactor + 5.0f),
133         ((pointHeight - 6.0f) * largfactor + 5.0f),
134         i * 152.0f, 128.0f, loopvar + i * 2032);
135     pointFilter (p1, ORANGE,
136         ((pointWidth / 2) * largfactor) / i + 10.0f * i,
137         ((pointHeight / 2) * largfactor) / i + 10.0f * i,
138         96.0f, i * 80.0f, loopvar / i);
139     pointFilter (p1, VIOLET,
140         ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
141         ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
142         i + 122.0f, 134.0f, loopvar / i);
143     pointFilter (p1, BLACK,
144         ((pointHeight / 3) * largfactor + 20.0f),
145         ((pointHeight / 3) * largfactor + 20.0f),
146         58.0f, i * 66.0f, loopvar / i);
147     pointFilter (p1, WHITE,
148         (pointHeight * largfactor + 10.0f * i) / i,
149         (pointHeight * largfactor + 10.0f * i) / i,
150         66.0f, 74.0f, loopvar + i * 500);
151   }
152
153   /* par défaut pas de changement de zoom */
154   pzfd = NULL;
155
156   /* diminuer de 1 le temps de lockage */
157   /* note pour ceux qui n'ont pas suivis : le lockvar permet d'empecher un */
158   /* changement d'etat du plugins juste apres un autre changement d'etat. oki ? */
159   if (--lockvar < 0)
160     lockvar = 0;
161
162   /* temps du goom */
163   if (--agoom < 0)
164     agoom = 0;
165
166   /* on verifie qu'il ne se pas un truc interressant avec le son. */
167   if ((accelvar > goomlimit) || (accelvar < -goomlimit)) {
168     /* UN GOOM !!! YAHOO ! */
169     totalgoom++;
170     agoom = 20;                 /* mais pdt 20 cycles, il n'y en aura plus. */
171     lineMode = (lineMode + 1) % 20;     /* Tous les 10 gooms on change de mode lineaire */
172
173     /* changement eventuel de mode */
174     switch (iRAND (10)) {
175       case 0:
176       case 1:
177       case 2:
178         zfd.mode = WAVE_MODE;
179         zfd.vitesse = STOP_SPEED - 1;
180         zfd.reverse = 0;
181         break;
182       case 3:
183       case 4:
184         zfd.mode = CRYSTAL_BALL_MODE;
185         break;
186       case 5:
187         zfd.mode = AMULETTE_MODE;
188         break;
189       case 6:
190         zfd.mode = WATER_MODE;
191         break;
192       case 7:
193         zfd.mode = SCRUNCH_MODE;
194         break;
195       default:
196         zfd.mode = NORMAL_MODE;
197     }
198   }
199
200   /* tout ceci ne sera fait qu'en cas de non-blocage */
201   if (lockvar == 0) {
202     /* reperage de goom (acceleration forte de l'acceleration du volume) */
203     /* -> coup de boost de la vitesse si besoin.. */
204     if ((accelvar > goomlimit) || (accelvar < -goomlimit)) {
205       goomvar++;
206       /*if (goomvar % 1 == 0) */
207       {
208         guint32 vtmp;
209         guint32 newvit;
210
211         newvit = STOP_SPEED - speedvar / 2;
212         /* retablir le zoom avant.. */
213         if ((zfd.reverse) && (!(cycle % 12)) && (rand () % 3 == 0)) {
214           zfd.reverse = 0;
215           zfd.vitesse = STOP_SPEED - 2;
216           lockvar = 50;
217         }
218         if (iRAND (10) == 0) {
219           zfd.reverse = 1;
220           lockvar = 100;
221         }
222
223         /* changement de milieu.. */
224         switch (iRAND (20)) {
225           case 0:
226             zfd.middleY = resoly - 1;
227             zfd.middleX = resolx / 2;
228             break;
229           case 1:
230             zfd.middleX = resolx - 1;
231             break;
232           case 2:
233             zfd.middleX = 1;
234             break;
235           default:
236             zfd.middleY = resoly / 2;
237             zfd.middleX = resolx / 2;
238         }
239
240         if (zfd.mode == WATER_MODE) {
241           zfd.middleX = resolx / 2;
242           zfd.middleY = resoly / 2;
243         }
244
245         switch (vtmp = (iRAND (27))) {
246           case 0:
247             zfd.vPlaneEffect = iRAND (3);
248             zfd.vPlaneEffect -= iRAND (3);
249             zfd.hPlaneEffect = iRAND (3);
250             zfd.hPlaneEffect -= iRAND (3);
251             break;
252           case 3:
253             zfd.vPlaneEffect = 0;
254             zfd.hPlaneEffect = iRAND (8);
255             zfd.hPlaneEffect -= iRAND (8);
256             break;
257           case 4:
258           case 5:
259           case 6:
260           case 7:
261             zfd.vPlaneEffect = iRAND (5);
262             zfd.vPlaneEffect -= iRAND (5);
263             zfd.hPlaneEffect = -zfd.vPlaneEffect;
264             break;
265           case 8:
266             zfd.hPlaneEffect = 5 + iRAND (8);
267             zfd.vPlaneEffect = -zfd.hPlaneEffect;
268             break;
269           case 9:
270             zfd.vPlaneEffect = 5 + iRAND (8);
271             zfd.hPlaneEffect = -zfd.hPlaneEffect;
272             break;
273           case 13:
274             zfd.hPlaneEffect = 0;
275             zfd.vPlaneEffect = iRAND (10);
276             zfd.vPlaneEffect -= iRAND (10);
277             break;
278           default:
279             if (vtmp < 10) {
280               zfd.vPlaneEffect = 0;
281               zfd.hPlaneEffect = 0;
282             }
283         }
284
285         if (iRAND (3) != 0)
286           zfd.noisify = 0;
287         else {
288           zfd.noisify = iRAND (3) + 2;
289           lockvar *= 3;
290         }
291
292         if (zfd.mode == AMULETTE_MODE) {
293           zfd.vPlaneEffect = 0;
294           zfd.hPlaneEffect = 0;
295           zfd.noisify = 0;
296         }
297
298         if ((zfd.middleX == 1) || (zfd.middleX == resolx - 1)) {
299           zfd.vPlaneEffect = 0;
300           zfd.hPlaneEffect = iRAND (2) ? 0 : zfd.hPlaneEffect;
301         }
302
303         if (newvit < zfd.vitesse) {     /* on accelere */
304           pzfd = &zfd;
305           if (((newvit < STOP_SPEED - 7) &&
306                   (zfd.vitesse < STOP_SPEED - 6) &&
307                   (cycle % 3 == 0)) || (iRAND (40) == 0)) {
308             zfd.vitesse = STOP_SPEED - 1;
309             zfd.reverse = !zfd.reverse;
310           } else {
311             zfd.vitesse = (newvit + zfd.vitesse * 4) / 5;
312           }
313           lockvar += 50;
314         }
315       }
316     }
317     /* mode mega-lent */
318     if (iRAND (1000) == 0) {
319       /* 
320          printf ("coup du sort...\n") ;
321        */
322       pzfd = &zfd;
323       zfd.vitesse = STOP_SPEED - 1;
324       zfd.pertedec = 8;
325       zfd.sqrtperte = 16;
326       goomvar = 1;
327       lockvar += 70;
328     }
329   }
330
331   /* gros frein si la musique est calme */
332   if ((speedvar < 1) && (zfd.vitesse < STOP_SPEED - 4) && (cycle % 16 == 0)) {
333     /*
334        printf ("++slow part... %i\n", zfd.vitesse) ;
335      */
336     pzfd = &zfd;
337     zfd.vitesse += 3;
338     zfd.pertedec = 8;
339     zfd.sqrtperte = 16;
340     goomvar = 0;
341     /*
342        printf ("--slow part... %i\n", zfd.vitesse) ;
343      */
344   }
345
346   /* baisser regulierement la vitesse... */
347   if ((cycle % 73 == 0) && (zfd.vitesse < STOP_SPEED - 5)) {
348     /*
349        printf ("slow down...\n") ;
350      */
351     pzfd = &zfd;
352     zfd.vitesse++;
353   }
354
355   /* arreter de decrémenter au bout d'un certain temps */
356   if ((cycle % 101 == 0) && (zfd.pertedec == 7)) {
357     pzfd = &zfd;
358     zfd.pertedec = 8;
359     zfd.sqrtperte = 16;
360   }
361 #ifdef VERBOSE
362   if (pzfd) {
363     printf ("GOOM: pzfd->mode = %d\n", pzfd->mode);
364   }
365 #endif
366
367   /* Zoom here ! */
368   zoomFilterFastRGB (p1, p2, pzfd, resolx, resoly);
369
370   /* si on est dans un goom : afficher les lignes... */
371   if (agoom > 15)
372     goom_lines
373         (data, ((zfd.middleX == resolx / 2) && (zfd.middleY == resoly / 2)
374             && (zfd.mode != WATER_MODE))
375         ? (lineMode / 10) : 0, p2, agoom - 15);
376
377   return_val = p2;
378   tmp = p1;
379   p1 = p2;
380   p2 = tmp;
381
382   /* affichage et swappage des buffers.. */
383   cycle++;
384
385   /* tous les 100 cycles : vérifier si le taux de goom est correct */
386   /* et le modifier sinon.. */
387   if (!(cycle % 100)) {
388     if (totalgoom > 15) {
389       /*  printf ("less gooms\n") ; */
390       goomlimit++;
391     } else {
392       if ((totalgoom == 0) && (goomlimit > 1))
393         goomlimit--;
394     }
395     totalgoom = 0;
396   }
397   return return_val;
398 }
399
400 void
401 goom_close ()
402 {
403   if (pixel != NULL)
404     free (pixel);
405   if (back != NULL)
406     free (back);
407   pixel = back = NULL;
408   RAND_CLOSE ();
409 }