]> git.sesse.net Git - vlc/blob - modules/visualization/visual/effects.c
Clone video filter : fix potential memleak.
[vlc] / modules / visualization / visual / effects.c
1 /*****************************************************************************
2  * effects.c : Effects for the visualization system
3  *****************************************************************************
4  * Copyright (C) 2002 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@via.ecp.fr>
8  *          Adrien Maglo <magsoft@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33 #include <vlc_vout.h>
34 #include <vlc_aout.h>
35
36 #include "visual.h"
37 #include <math.h>
38
39 #include "fft.h"
40
41 #define PEAK_SPEED 1
42
43 #define GRAD_ANGLE_MIN 0.2
44 #define GRAD_ANGLE_MAX 0.5
45 #define GRAD_INCR 0.01
46
47 /*****************************************************************************
48  * dummy_Run
49  *****************************************************************************/
50 int dummy_Run( visual_effect_t * p_effect, aout_instance_t *p_aout,
51                aout_buffer_t * p_buffer , picture_t * p_picture)
52 {
53     VLC_UNUSED(p_effect); VLC_UNUSED(p_aout); VLC_UNUSED(p_buffer);
54     VLC_UNUSED(p_picture);
55     return 0;
56 }
57
58 /*****************************************************************************
59  * spectrum_Run: spectrum analyser
60  *****************************************************************************/
61 int spectrum_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
62                  aout_buffer_t * p_buffer , picture_t * p_picture)
63 {
64     float p_output[FFT_BUFFER_SIZE];  /* Raw FFT Result  */
65     int *height;                      /* Bar heights */
66     int *peaks;                       /* Peaks */
67     int i_nb_bands;                   /* number of bands */
68     int i_band_width;                 /* width of bands */
69     int i_separ;                      /* Should we let blanks ? */
70     int i_amp;                        /* Vertical amplification */
71     int i_peak;                       /* Should we draw peaks ? */
72
73     /* Horizontal scale for 20-band equalizer */
74     const int xscale1[]={0,1,2,3,4,5,6,7,8,11,15,20,27,
75                         36,47,62,82,107,141,184,255};
76
77     /* Horizontal scale for 80-band equalizer */
78     const int xscale2[] =
79     {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
80      19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
81      35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
82      52,53,54,55,56,57,58,59,61,63,67,72,77,82,87,93,99,105,
83      110,115,121,130,141,152,163,174,185,200,255};
84     const int *xscale;
85     const double y_scale =  3.60673760222;  /* (log 256) */
86
87     fft_state *p_state;                 /* internal FFT data */
88
89     int i , j , y , k;
90     int i_line;
91     int16_t p_dest[FFT_BUFFER_SIZE];      /* Adapted FFT result */
92     int16_t p_buffer1[FFT_BUFFER_SIZE];   /* Buffer on which we perform
93                                              the FFT (first channel) */
94
95     float *p_buffl =                     /* Original buffer */
96             (float*)p_buffer->p_buffer;
97
98     int16_t  *p_buffs;                    /* int16_t converted buffer */
99     int16_t  *p_s16_buff = NULL;                /* int16_t converted buffer */
100
101     p_s16_buff = (int16_t*)malloc(
102               p_buffer->i_nb_samples * p_effect->i_nb_chans * sizeof(int16_t));
103
104     if( !p_s16_buff )
105     {
106         msg_Err(p_aout,"out of memory");
107         return -1;
108     }
109
110     p_buffs = p_s16_buff;
111     i_nb_bands = config_GetInt ( p_aout, "visual-nbbands" );
112     i_separ    = config_GetInt( p_aout, "visual-separ" );
113     i_amp     = config_GetInt ( p_aout, "visual-amp" );
114     i_peak     = config_GetInt ( p_aout, "visual-peaks" );
115
116     if( i_nb_bands == 20)
117     {
118         xscale = xscale1;
119     }
120     else
121     {
122         i_nb_bands = 80;
123         xscale = xscale2;
124     }
125
126     if( !p_effect->p_data )
127     {
128         p_effect->p_data=(void *)malloc(i_nb_bands * sizeof(int) );
129         if( !p_effect->p_data)
130         {
131             msg_Err(p_aout,"out of memory");
132             return -1;
133         }
134         peaks = (int *)p_effect->p_data;
135         for( i = 0 ; i < i_nb_bands ; i++)
136         {
137            peaks[i] = 0;
138         }
139
140     }
141     else
142     {
143         peaks =(int *)p_effect->p_data;
144     }
145
146
147     height = (int *)malloc( i_nb_bands * sizeof(int) );
148     if( !height)
149     {
150         msg_Err(p_aout,"out of memory");
151         return -1;
152     }
153     /* Convert the buffer to int16_t  */
154     /* Pasted from float32tos16.c */
155     for (i = p_buffer->i_nb_samples * p_effect->i_nb_chans; i--; )
156     {
157         union { float f; int32_t i; } u;
158         u.f = *p_buffl + 384.0;
159         if(u.i >  0x43c07fff ) * p_buffs = 32767;
160         else if ( u.i < 0x43bf8000 ) *p_buffs = -32768;
161         else *p_buffs = u.i - 0x43c00000;
162
163         p_buffl++ ; p_buffs++ ;
164     }
165     p_state  = visual_fft_init();
166     if( !p_state)
167     {
168         msg_Err(p_aout,"unable to initialize FFT transform");
169         return -1;
170     }
171     p_buffs = p_s16_buff;
172     for ( i = 0 ; i < FFT_BUFFER_SIZE ; i++)
173     {
174         p_output[i]    = 0;
175         p_buffer1[i] = *p_buffs;
176         p_buffs      = p_buffs + p_effect->i_nb_chans;
177     }
178     fft_perform( p_buffer1, p_output, p_state);
179     for(i= 0; i< FFT_BUFFER_SIZE ; i++ )
180         p_dest[i] = ( (int) sqrt( p_output [ i ] ) ) >> 8;
181
182     for ( i = 0 ; i< i_nb_bands ;i++)
183     {
184         /* We search the maximum on one scale */
185         for( j = xscale[i] , y=0 ; j< xscale[ i + 1 ] ; j++ )
186         {
187             if ( p_dest[j] > y )
188                  y = p_dest[j];
189         }
190         /* Calculate the height of the bar */
191         y >>=7;/* remove some noise */
192         if( y != 0)
193         {
194             height[i] = (int)log(y)* y_scale;
195                if(height[i] > 150)
196                   height[i] = 150;
197         }
198         else
199         {
200             height[i] = 0 ;
201         }
202
203         /* Draw the bar now */
204         i_band_width = floor( p_effect->i_width / i_nb_bands) ;
205
206         if( i_amp * height[i] > peaks[i])
207         {
208             peaks[i] = i_amp * height[i];
209         }
210         else if (peaks[i] > 0 )
211         {
212             peaks[i] -= PEAK_SPEED;
213             if( peaks[i] < i_amp * height[i] )
214             {
215                 peaks[i] = i_amp * height[i];
216             }
217             if( peaks[i] < 0 )
218             {
219                 peaks[i] = 0;
220             }
221         }
222
223         if( peaks[i] > 0 && i_peak )
224         {
225             if( peaks[i] >= p_effect->i_height )
226                 peaks[i] = p_effect->i_height - 2;
227             i_line = peaks[i];
228
229             for( j = 0 ; j< i_band_width - i_separ; j++)
230             {
231                for( k = 0 ; k< 3 ; k ++)
232                {
233                    /* Draw the peak */
234                      *(p_picture->p[0].p_pixels +
235                     (p_picture->p[0].i_lines - i_line -1 -k ) *
236                      p_picture->p[0].i_pitch + (i_band_width*i +j) )
237                                     = 0xff;
238
239                     *(p_picture->p[1].p_pixels +
240                      (p_picture->p[1].i_lines - i_line /2 -1 -k/2 ) *
241                      p_picture->p[1].i_pitch +
242                     ( ( i_band_width * i + j ) /2  ) )
243                                     = 0x00;
244
245                    if( 0x04 * (i_line + k ) - 0x0f > 0 )
246                    {
247                        if ( 0x04 * (i_line + k ) -0x0f < 0xff)
248                            *(p_picture->p[2].p_pixels  +
249                             (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
250                              p_picture->p[2].i_pitch +
251                              ( ( i_band_width * i + j ) /2  ) )
252                                     = ( 0x04 * ( i_line + k ) ) -0x0f ;
253                        else
254                            *(p_picture->p[2].p_pixels  +
255                             (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
256                              p_picture->p[2].i_pitch +
257                              ( ( i_band_width * i + j ) /2  ) )
258                                     = 0xff;
259                    }
260                    else
261                    {
262                         *(p_picture->p[2].p_pixels  +
263                          (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
264                          p_picture->p[2].i_pitch +
265                          ( ( i_band_width * i + j ) /2  ) )
266                                = 0x10 ;
267                    }
268                }
269             }
270         }
271
272         if(height[i] * i_amp > p_effect->i_height)
273             height[i] = floor(p_effect->i_height / i_amp );
274
275         for(i_line = 0 ; i_line < i_amp * height[i]; i_line ++ )
276         {
277             for( j = 0 ; j< i_band_width - i_separ ; j++)
278             {
279                *(p_picture->p[0].p_pixels +
280                  (p_picture->p[0].i_lines - i_line -1) *
281                   p_picture->p[0].i_pitch + (i_band_width*i +j) ) = 0xff;
282
283                 *(p_picture->p[1].p_pixels +
284                  (p_picture->p[1].i_lines - i_line /2 -1) *
285                  p_picture->p[1].i_pitch +
286                  ( ( i_band_width * i + j ) /2  ) ) = 0x00;
287
288                if( 0x04 * i_line - 0x0f > 0 )
289                {
290                     if( 0x04 * i_line - 0x0f < 0xff )
291                          *(p_picture->p[2].p_pixels  +
292                           (p_picture->p[2].i_lines - i_line /2 - 1) *
293                            p_picture->p[2].i_pitch +
294                            ( ( i_band_width * i + j ) /2  ) ) =
295                                ( 0x04 * i_line) -0x0f ;
296                     else
297                          *(p_picture->p[2].p_pixels  +
298                           (p_picture->p[2].i_lines - i_line /2 - 1) *
299                            p_picture->p[2].i_pitch +
300                            ( ( i_band_width * i + j ) /2  ) ) =
301                                        0xff;
302                }
303                else
304                {
305                     *(p_picture->p[2].p_pixels  +
306                      (p_picture->p[2].i_lines - i_line /2 - 1) *
307                      p_picture->p[2].i_pitch +
308                      ( ( i_band_width * i + j ) /2  ) ) =
309                             0x10 ;
310                }
311             }
312         }
313     }
314
315     fft_close( p_state );
316
317     free( p_s16_buff );
318     p_s16_buff = NULL;
319
320     free( height );
321
322     return 0;
323 }
324
325
326 /*****************************************************************************
327  * spectrometer_Run: derivative spectrum analysis
328  *****************************************************************************/
329 int spectrometer_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
330                  aout_buffer_t * p_buffer , picture_t * p_picture)
331 {
332 #define Y(R,G,B) ((uint8_t)( (R * .299) + (G * .587) + (B * .114) ))
333 #define U(R,G,B) ((uint8_t)( (R * -.169) + (G * -.332) + (B * .500) + 128 ))
334 #define V(R,G,B) ((uint8_t)( (R * .500) + (G * -.419) + (B * -.0813) + 128 ))
335     float p_output[FFT_BUFFER_SIZE];  /* Raw FFT Result  */
336     int *height;                      /* Bar heights */
337     int *peaks;                       /* Peaks */
338     int i_nb_bands;                   /* number of bands */
339     int i_band_width;                 /* width of bands */
340     int i_separ;                      /* Should we let blanks ? */
341     int i_amp;                        /* Vertical amplification */
342     int i_peak;                       /* Should we draw peaks ? */
343
344     int i_original;          /* original spectrum graphic routine */
345     int i_rad;               /* radius of circle of base of bands */
346     int i_sections;          /* sections of spectranalysis */
347     int i_extra_width;       /* extra width on peak */
348     int i_peak_height;       /* height of peak */
349     int c;                   /* sentinel container of total spectral sections */
350     double band_sep_angle;   /* angled separation between beginning of each band */
351     double section_sep_angle;/* "   "    '     "    '    "     "    spectrum section */
352     int max_band_length;     /* try not to go out of screen */
353     int i_show_base;         /* Should we draw base of circle ? */
354     int i_show_bands;        /* Should we draw bands ? */
355     //int i_invert_bands;      /* do the bands point inward ? */
356     double a;                /* for various misc angle situations in radians */
357     int x,y,xx,yy;           /* various misc x/y */
358     char color1;             /* V slide on a YUV color cube */
359     //char color2;             /* U slide.. ?  color2 fade color ? */
360
361     /* Horizontal scale for 20-band equalizer */
362     const int xscale1[]={0,1,2,3,4,5,6,7,8,11,15,20,27,
363                         36,47,62,82,107,141,184,255};
364
365     /* Horizontal scale for 80-band equalizer */
366     const int xscale2[] =
367     {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
368      19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
369      35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
370      52,53,54,55,56,57,58,59,61,63,67,72,77,82,87,93,99,105,
371      110,115,121,130,141,152,163,174,185,200,255};
372     const int *xscale;
373     const double y_scale =  3.60673760222;  /* (log 256) */
374
375     fft_state *p_state;                 /* internal FFT data */
376
377     int i , j , k;
378     int i_line;
379     int16_t p_dest[FFT_BUFFER_SIZE];      /* Adapted FFT result */
380     int16_t p_buffer1[FFT_BUFFER_SIZE];   /* Buffer on which we perform
381                                              the FFT (first channel) */
382     float *p_buffl =                     /* Original buffer */
383             (float*)p_buffer->p_buffer;
384
385     int16_t  *p_buffs;                    /* int16_t converted buffer */
386     int16_t  *p_s16_buff = NULL;                /* int16_t converted buffer */
387
388     i_line = 0;
389
390     p_s16_buff = (int16_t*)malloc(
391               p_buffer->i_nb_samples * p_effect->i_nb_chans * sizeof(int16_t));
392
393     if( !p_s16_buff )
394     {
395         msg_Err(p_aout,"out of memory");
396         return -1;
397     }
398
399     p_buffs = p_s16_buff;
400     i_original     = config_GetInt ( p_aout, "spect-show-original" );
401     i_nb_bands     = config_GetInt ( p_aout, "spect-nbbands" );
402     i_separ        = config_GetInt ( p_aout, "spect-separ" );
403     i_amp          = config_GetInt ( p_aout, "spect-amp" );
404     i_peak         = config_GetInt ( p_aout, "spect-show-peaks" );
405     i_show_base    = config_GetInt ( p_aout, "spect-show-base" );
406     i_show_bands   = config_GetInt ( p_aout, "spect-show-bands" );
407     i_rad          = config_GetInt ( p_aout, "spect-radius" );
408     i_sections     = config_GetInt ( p_aout, "spect-sections" );
409     i_extra_width  = config_GetInt ( p_aout, "spect-peak-width" );
410     i_peak_height  = config_GetInt ( p_aout, "spect-peak-height" );
411     color1         = config_GetInt ( p_aout, "spect-color" );
412
413     if( i_nb_bands == 20)
414     {
415         xscale = xscale1;
416     }
417     else
418     {
419         if( i_nb_bands > 80 )
420             i_nb_bands = 80;
421         xscale = xscale2;
422     }
423
424     if( !p_effect->p_data )
425     {
426         p_effect->p_data=(void *)malloc(i_nb_bands * sizeof(int) );
427         if( !p_effect->p_data)
428         {
429             msg_Err(p_aout,"out of memory");
430             return -1;
431         }
432         peaks = (int *)p_effect->p_data;
433         for( i = 0 ; i < i_nb_bands ; i++)
434         {
435            peaks[i] = 0;
436         }
437     }
438     else
439     {
440         peaks =(int *)p_effect->p_data;
441     }
442
443     height = (int *)malloc( i_nb_bands * sizeof(int) );
444     if( !height)
445     {
446         msg_Err(p_aout,"out of memory");
447         return -1;
448     }
449
450     /* Convert the buffer to int16_t  */
451     /* Pasted from float32tos16.c */
452     for (i = p_buffer->i_nb_samples * p_effect->i_nb_chans; i--; )
453     {
454         union { float f; int32_t i; } u;
455         u.f = *p_buffl + 384.0;
456         if(u.i >  0x43c07fff ) * p_buffs = 32767;
457         else if ( u.i < 0x43bf8000 ) *p_buffs = -32768;
458         else *p_buffs = u.i - 0x43c00000;
459
460         p_buffl++ ; p_buffs++ ;
461     }
462     p_state  = visual_fft_init();
463     if( !p_state)
464     {
465         msg_Err(p_aout,"unable to initialize FFT transform");
466         return -1;
467     }
468     p_buffs = p_s16_buff;
469     for ( i = 0 ; i < FFT_BUFFER_SIZE ; i++)
470     {
471         p_output[i]    = 0;
472         p_buffer1[i] = *p_buffs;
473         p_buffs      = p_buffs + p_effect->i_nb_chans;
474     }
475     fft_perform( p_buffer1, p_output, p_state);
476     for(i= 0; i< FFT_BUFFER_SIZE ; i++ )
477         p_dest[i] = ( (int) sqrt( p_output [ i ] ) ) >> 8;
478
479     i_nb_bands *= i_sections;
480
481     for ( i = 0 ; i< i_nb_bands/i_sections ;i++)
482     {
483         /* We search the maximum on one scale */
484         for( j = xscale[i] , y=0 ; j< xscale[ i + 1 ] ; j++ )
485         {
486             if ( p_dest[j] > y )
487                  y = p_dest[j];
488         }
489         /* Calculate the height of the bar */
490         y >>=7;/* remove some noise */
491         if( y != 0)
492         {
493             height[i] = (int)log(y)* y_scale;
494                if(height[i] > 150)
495                   height[i] = 150;
496         }
497         else
498         {
499             height[i] = 0 ;
500         }
501
502         /* Draw the bar now */
503         i_band_width = floor( p_effect->i_width / (i_nb_bands/i_sections)) ;
504
505         if( i_amp * height[i] > peaks[i])
506         {
507             peaks[i] = i_amp * height[i];
508         }
509         else if (peaks[i] > 0 )
510         {
511             peaks[i] -= PEAK_SPEED;
512             if( peaks[i] < i_amp * height[i] )
513             {
514                 peaks[i] = i_amp * height[i];
515             }
516             if( peaks[i] < 0 )
517             {
518                 peaks[i] = 0;
519             }
520         }
521
522         if( i_original != 0 )
523         {
524         if( peaks[i] > 0 && i_peak )
525         {
526             if( peaks[i] >= p_effect->i_height )
527                 peaks[i] = p_effect->i_height - 2;
528             i_line = peaks[i];
529
530             for( j = 0 ; j< i_band_width - i_separ; j++)
531             {
532                for( k = 0 ; k< 3 ; k ++)
533                {
534                    //* Draw the peak
535                      *(p_picture->p[0].p_pixels +
536                     (p_picture->p[0].i_lines - i_line -1 -k ) *
537                      p_picture->p[0].i_pitch + (i_band_width*i +j) )
538                                     = 0xff;
539
540                     *(p_picture->p[1].p_pixels +
541                      (p_picture->p[1].i_lines - i_line /2 -1 -k/2 ) *
542                      p_picture->p[1].i_pitch +
543                     ( ( i_band_width * i + j ) /2  ) )
544                                     = 0x00;
545
546                    if( 0x04 * (i_line + k ) - 0x0f > 0 )
547                    {
548                        if ( 0x04 * (i_line + k ) -0x0f < 0xff)
549                            *(p_picture->p[2].p_pixels  +
550                             (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
551                              p_picture->p[2].i_pitch +
552                              ( ( i_band_width * i + j ) /2  ) )
553                                     = ( 0x04 * ( i_line + k ) ) -0x0f ;
554                        else
555                            *(p_picture->p[2].p_pixels  +
556                             (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
557                              p_picture->p[2].i_pitch +
558                              ( ( i_band_width * i + j ) /2  ) )
559                                     = 0xff;
560                    }
561                    else
562                    {
563                         *(p_picture->p[2].p_pixels  +
564                          (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
565                          p_picture->p[2].i_pitch +
566                          ( ( i_band_width * i + j ) /2  ) )
567                                = 0x10 ;
568                    }
569                }
570             }
571         }
572         if(height[i] * i_amp > p_effect->i_height)
573             height[i] = floor(p_effect->i_height / i_amp );
574
575         for(i_line = 0 ; i_line < i_amp * height[i]; i_line ++ )
576         {
577             for( j = 0 ; j< i_band_width - i_separ ; j++)
578             {
579                *(p_picture->p[0].p_pixels +
580                  (p_picture->p[0].i_lines - i_line -1) *
581                   p_picture->p[0].i_pitch + (i_band_width*i +j) ) = 0xff;
582
583                 *(p_picture->p[1].p_pixels +
584                  (p_picture->p[1].i_lines - i_line /2 -1) *
585                  p_picture->p[1].i_pitch +
586                  ( ( i_band_width * i + j ) /2  ) ) = 0x00;
587
588                if( 0x04 * i_line - 0x0f > 0 )
589                {
590                     if( 0x04 * i_line - 0x0f < 0xff )
591                          *(p_picture->p[2].p_pixels  +
592                           (p_picture->p[2].i_lines - i_line /2 - 1) *
593                            p_picture->p[2].i_pitch +
594                            ( ( i_band_width * i + j ) /2  ) ) =
595                                ( 0x04 * i_line) -0x0f ;
596                     else
597                          *(p_picture->p[2].p_pixels  +
598                           (p_picture->p[2].i_lines - i_line /2 - 1) *
599                            p_picture->p[2].i_pitch +
600                            ( ( i_band_width * i + j ) /2  ) ) =
601                                        0xff;
602                }
603                else
604                {
605                     *(p_picture->p[2].p_pixels  +
606                      (p_picture->p[2].i_lines - i_line /2 - 1) *
607                      p_picture->p[2].i_pitch +
608                      ( ( i_band_width * i + j ) /2  ) ) =
609                             0x10 ;
610                }
611             }
612         }
613         }
614     }
615
616     band_sep_angle = 360.0 / i_nb_bands;
617     section_sep_angle = 360.0 / i_sections;
618     if( i_peak_height < 1 )
619         i_peak_height = 1;
620     max_band_length = p_picture->p[0].i_lines / 2 - ( i_rad + i_peak_height + 1 );
621
622     i_band_width = floor( 360 / i_nb_bands - i_separ );
623     if( i_band_width < 1 )
624         i_band_width = 1;
625
626     for( c = 0 ; c < i_sections ; c++ )
627     for( i = 0 ; i < (i_nb_bands / i_sections) ; i++ )
628     {
629         /* DO A PEAK */
630         if( peaks[i] > 0 && i_peak )
631         {
632             if( peaks[i] >= p_effect->i_height )
633                 peaks[i] = p_effect->i_height - 2;
634             i_line = peaks[i];
635
636             /* circular line pattern(so color blend is more visible) */
637             for( j = 0 ; j < i_peak_height ; j++ )
638             {
639                 x = p_picture->p[0].i_pitch / 2;
640                 y = p_picture->p[0].i_lines / 2;
641                 xx = x;
642                 yy = y;
643                 for( k = 0 ; k < (i_band_width + i_extra_width) ; k++ )
644                 {
645                     x = xx;
646                     y = yy;
647                     a = ( (i+1) * band_sep_angle + section_sep_angle * (c+1) + k )
648                         * 3.141592 / 180.0;
649                     x += (double)( cos(a) * (double)( i_line + j + i_rad ) );
650                     y += (double)( -sin(a) * (double)( i_line + j + i_rad ) );
651
652                     *(p_picture->p[0].p_pixels + x + y * p_picture->p[0].i_pitch
653                     ) = 255;/* Y(R,G,B); */
654
655                     x /= 2;
656                     y /= 2;
657
658                     *(p_picture->p[1].p_pixels + x + y * p_picture->p[1].i_pitch
659                     ) = 0;/* U(R,G,B); */
660
661                     if( 0x04 * (i_line + k ) - 0x0f > 0 )
662                     {
663                         if ( 0x04 * (i_line + k ) -0x0f < 0xff)
664                             *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
665                             ) = ( 0x04 * ( i_line + k ) ) -(color1-1);/* -V(R,G,B); */
666                         else
667                             *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
668                             ) = 255;/* V(R,G,B); */
669                     }
670                     else
671                     {
672                         *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
673                         ) = color1;/* V(R,G,B); */
674                     }
675                 }
676             }
677         }
678
679         if( (height[i] * i_amp) > p_effect->i_height )
680             height[i] = floor( p_effect->i_height / i_amp );
681
682         /* DO BASE OF BAND (mostly makes a circle) */
683         if( i_show_base != 0 )
684         {
685             x = p_picture->p[0].i_pitch / 2;
686             y = p_picture->p[0].i_lines / 2;
687
688             a =  ( (i+1) * band_sep_angle + section_sep_angle * (c+1) )
689                 * 3.141592 / 180.0;
690             x += (double)( cos(a) * (double)i_rad );/* newb-forceful casting */
691             y += (double)( -sin(a) * (double)i_rad );
692
693             *(p_picture->p[0].p_pixels + x + y * p_picture->p[0].i_pitch
694             ) = 255;/* Y(R,G,B); */
695
696             x /= 2;
697             y /= 2;
698
699             *(p_picture->p[1].p_pixels + x + y * p_picture->p[1].i_pitch
700             ) = 0;/* U(R,G,B); */
701
702             if( 0x04 * i_line - 0x0f > 0 )
703             {
704                 if( 0x04 * i_line -0x0f < 0xff)
705                     *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
706                     ) = ( 0x04 * i_line) -(color1-1);/* -V(R,G,B); */
707                 else
708                     *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
709                     ) = 255;/* V(R,G,B); */
710             }
711             else
712             {
713                 *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
714                 ) = color1;/* V(R,G,B); */
715             }
716         }
717
718         /* DO A BAND */
719         if( i_show_bands != 0 )
720         for( j = 0 ; j < i_band_width ; j++ )
721         {
722             x = p_picture->p[0].i_pitch / 2;
723             y = p_picture->p[0].i_lines / 2;
724             xx = x;
725             yy = y;
726             a = ( (i+1) * band_sep_angle + section_sep_angle * (c+1) + j )
727                 * 3.141592/180.0;
728
729             for( k = (i_rad+1) ; k < max_band_length ; k++ )
730             {
731                 if( (k-i_rad) > height[i] )
732                     break;/* uhh.. */
733
734                 x = xx;
735                 y = yy;
736                 x += (double)( cos(a) * (double)k );/* newbed! */
737                 y += (double)( -sin(a) * (double)k );
738
739                 *(p_picture->p[0].p_pixels + x + y * p_picture->p[0].i_pitch
740                 ) = 255;
741
742                 x /= 2;
743                 y /= 2;
744
745                 *(p_picture->p[1].p_pixels + x + y * p_picture->p[1].i_pitch
746                 ) = 0;
747
748                 if( 0x04 * i_line - 0x0f > 0 )
749                 {
750                     if ( 0x04 * i_line -0x0f < 0xff)
751                         *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
752                         ) = ( 0x04 * i_line) -(color1-1);
753                     else
754                         *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
755                         ) = 255;
756                 }
757                 else
758                 {
759                     *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
760                     ) = color1;
761                 }
762             }
763         }
764     }
765
766     fft_close( p_state );
767
768     free( p_s16_buff );
769     p_s16_buff = NULL;
770
771     free( height );
772
773     return 0;
774 }
775
776
777 /*****************************************************************************
778  * scope_Run: scope effect
779  *****************************************************************************/
780 int scope_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
781               aout_buffer_t * p_buffer , picture_t * p_picture)
782 {
783     VLC_UNUSED(p_aout);
784     int i_index;
785     float *p_sample ;
786     uint8_t *ppp_area[2][3];
787
788
789         for( i_index = 0 ; i_index < 2 ; i_index++ )
790         {
791             int j;
792             for( j = 0 ; j < 3 ; j++ )
793             {
794                 ppp_area[i_index][j] =
795                     p_picture->p[j].p_pixels + i_index * p_picture->p[j].i_lines
796                                 / 2 * p_picture->p[j].i_pitch;
797             }
798         }
799
800         for( i_index = 0, p_sample = (float *)p_buffer->p_buffer;
801              i_index < p_effect->i_width;
802              i_index++ )
803         {
804             uint8_t i_value;
805
806             /* Left channel */
807             i_value =  (*p_sample++ +1) * 127;
808             *(ppp_area[0][0]
809                + p_picture->p[0].i_pitch * i_index / p_effect->i_width
810                + p_picture->p[0].i_lines * i_value / 512
811                    * p_picture->p[0].i_pitch) = 0xbf;
812             *(ppp_area[0][1]
813                 + p_picture->p[1].i_pitch * i_index / p_effect->i_width
814                 + p_picture->p[1].i_lines * i_value / 512
815                    * p_picture->p[1].i_pitch) = 0xff;
816
817
818            /* Right channel */
819            i_value = ( *p_sample++ +1 ) * 127;
820            *(ppp_area[1][0]
821               + p_picture->p[0].i_pitch * i_index / p_effect->i_width
822               + p_picture->p[0].i_lines * i_value / 512
823                  * p_picture->p[0].i_pitch) = 0x9f;
824            *(ppp_area[1][2]
825               + p_picture->p[2].i_pitch * i_index / p_effect->i_width
826               + p_picture->p[2].i_lines * i_value / 512
827                 * p_picture->p[2].i_pitch) = 0xdd;
828         }
829         return 0;
830 }
831
832
833 /*****************************************************************************
834  * vuMeter_Run: vu meter effect
835  *****************************************************************************/
836 int vuMeter_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
837               aout_buffer_t * p_buffer , picture_t * p_picture)
838 {
839         VLC_UNUSED(p_aout);
840         int i, j;
841         float *p_sample = (float *)p_buffer->p_buffer;
842         float i_value_l = 0;
843         float i_value_r = 0;
844         float ch;
845
846         /* Compute the peack values */
847         for ( i = 0 ; i < 1024; i++ )
848         {
849                 ch = (*p_sample++) * 256;
850                 if (ch > i_value_l)
851                         i_value_l = ch;
852
853                 ch = (*p_sample++) * 256;
854                 if (ch > i_value_r)
855                         i_value_r = ch;
856         }
857
858         i_value_l = abs(i_value_l);
859         i_value_r = abs(i_value_r);
860
861         /* Stay under maximum value admited */
862         if ( i_value_l > 200 * M_PI_2 )
863                 i_value_l = 200 * M_PI_2;
864         if ( i_value_r > 200 * M_PI_2 )
865                 i_value_r = 200 * M_PI_2;
866
867         float *i_value;
868
869         if( !p_effect->p_data )
870         {
871                 /* Allocate memory to save hand positions */
872                 p_effect->p_data = (void *)malloc( 2 * sizeof(float) );
873                 i_value = p_effect->p_data;
874                 i_value[0] = i_value_l;
875                 i_value[1] = i_value_r;
876         }
877         else
878         {
879                 /* Make the hands go down slowly if the current values are slower
880                 than the previous */
881                 i_value = p_effect->p_data;
882
883                 if ( i_value_l > i_value[0] - 6 )
884                         i_value[0] = i_value_l;
885                 else
886                         i_value[0] = i_value[0] - 6;
887
888                 if ( i_value_r > i_value[1] - 6 )
889                         i_value[1] = i_value_r;
890                 else
891                         i_value[1] = i_value[1] - 6;
892         }
893
894         int x, y, k;
895         float teta;
896         float teta_grad;
897
898         for ( j = 0; j < 2; j++ )
899         {
900                 /* Draw the two scales */
901                 k = 0;
902                 teta_grad = GRAD_ANGLE_MIN;
903                 for ( teta = -M_PI_4; teta <= M_PI_4; teta = teta + 0.003 )
904                 {
905                         for ( i = 140; i <= 150; i++ )
906                         {
907                                 y = i * cos(teta) + 20;
908                                 x = i * sin(teta) + 150 + 240 * j;
909                                 /* Compute the last color for the gradation */
910                                 if (teta >= teta_grad + GRAD_INCR && teta_grad <= GRAD_ANGLE_MAX)
911                                 {
912                                         teta_grad = teta_grad + GRAD_INCR;
913                                         k = k + 5;
914                                 }
915                                 *(p_picture->p[0].p_pixels +
916                                  (p_picture->p[0].i_lines - y - 1 ) * p_picture->p[0].i_pitch
917                                  + x ) = 0x45;
918                                 *(p_picture->p[1].p_pixels +
919                                  (p_picture->p[1].i_lines - y / 2 - 1 ) * p_picture->p[1].i_pitch
920                                  + x / 2 ) = 0x0;
921                                 *(p_picture->p[2].p_pixels +
922                                  (p_picture->p[2].i_lines - y / 2 - 1 ) * p_picture->p[2].i_pitch
923                                  + x / 2 ) = 0x4D + k;
924                         }
925                 }
926
927                 /* Draw the two hands */
928                 teta = (float)i_value[j] / 200 - M_PI_4;
929                 for ( i = 0; i <= 150; i++ )
930                 {
931                         y = i * cos(teta) + 20;
932                         x = i * sin(teta) + 150 + 240 * j;
933                         *(p_picture->p[0].p_pixels +
934                          (p_picture->p[0].i_lines - y - 1 ) * p_picture->p[0].i_pitch
935                          + x ) = 0xAD;
936                         *(p_picture->p[1].p_pixels +
937                          (p_picture->p[1].i_lines - y / 2 - 1 ) * p_picture->p[1].i_pitch
938                          + x / 2 ) = 0xFC;
939                         *(p_picture->p[2].p_pixels +
940                          (p_picture->p[2].i_lines - y / 2 - 1 ) * p_picture->p[2].i_pitch
941                          + x / 2 ) = 0xAC;
942                 }
943
944                 /* Draw the hand bases */
945                 for ( teta = -M_PI_2; teta <= M_PI_2 + 0.01; teta = teta + 0.003 )
946                 {
947                         for ( i = 0; i < 10; i++ )
948                         {
949                                 y = i * cos(teta) + 20;
950                                 x = i * sin(teta) + 150 + 240 * j;
951                                 *(p_picture->p[0].p_pixels +
952                                  (p_picture->p[0].i_lines - y - 1 ) * p_picture->p[0].i_pitch
953                                  + x ) = 0xFF;
954                                 *(p_picture->p[1].p_pixels +
955                                  (p_picture->p[1].i_lines - y / 2 - 1 ) * p_picture->p[1].i_pitch
956                                  + x / 2 ) = 0x80;
957                                 *(p_picture->p[2].p_pixels +
958                                  (p_picture->p[2].i_lines - y / 2 - 1 ) * p_picture->p[2].i_pitch
959                                  + x / 2 ) = 0x80;
960                         }
961                 }
962
963         }
964
965         return 0;
966 }