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