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