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