]> git.sesse.net Git - vlc/blob - modules/visualization/visual/effects.c
A bit of headers cleanup
[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 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <vlc/vlc.h>
29 #include <vlc_vout.h>
30 #include <vlc_aout.h>
31
32 #include "visual.h"
33 #include <math.h>
34
35 #include "fft.h"
36
37 #define PEAK_SPEED 1
38
39 /*****************************************************************************
40  * dummy_Run
41  *****************************************************************************/
42 int dummy_Run( visual_effect_t * p_effect, aout_instance_t *p_aout,
43                aout_buffer_t * p_buffer , picture_t * p_picture)
44 {
45     return 0;
46 }
47
48 /*****************************************************************************
49  * spectrum_Run: spectrum analyser
50  *****************************************************************************/
51 int spectrum_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
52                  aout_buffer_t * p_buffer , picture_t * p_picture)
53 {
54     float p_output[FFT_BUFFER_SIZE];  /* Raw FFT Result  */
55     int *height;                      /* Bar heights */
56     int *peaks;                       /* Peaks */
57     int i_nb_bands;                   /* number of bands */
58     int i_band_width;                 /* width of bands */
59     int i_separ;                      /* Should we let blanks ? */
60     int i_amp;                        /* Vertical amplification */
61     int i_peak;                       /* Should we draw peaks ? */
62     char *psz_parse = NULL;           /* Args line */
63
64     /* Horizontal scale for 20-band equalizer */
65     const int xscale1[]={0,1,2,3,4,5,6,7,8,11,15,20,27,
66                         36,47,62,82,107,141,184,255};
67
68     /* Horizontal scale for 80-band equalizer */
69     const int xscale2[] =
70     {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
71      19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
72      35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
73      52,53,54,55,56,57,58,59,61,63,67,72,77,82,87,93,99,105,
74      110,115,121,130,141,152,163,174,185,200,255};
75     const int *xscale;
76     const double y_scale =  3.60673760222;  /* (log 256) */
77
78     fft_state *p_state;                 /* internal FFT data */
79
80     int i , j , y , k;
81     int i_line;
82     int16_t p_dest[FFT_BUFFER_SIZE];      /* Adapted FFT result */
83     int16_t p_buffer1[FFT_BUFFER_SIZE];   /* Buffer on which we perform
84                                              the FFT (first channel) */
85
86     float *p_buffl =                     /* Original buffer */
87             (float*)p_buffer->p_buffer;
88
89     int16_t  *p_buffs;                    /* int16_t converted buffer */
90     int16_t  *p_s16_buff = NULL;                /* int16_t converted buffer */
91
92     p_s16_buff = (int16_t*)malloc(
93               p_buffer->i_nb_samples * p_effect->i_nb_chans * sizeof(int16_t));
94
95     if( !p_s16_buff )
96     {
97         msg_Err(p_aout,"out of memory");
98         return -1;
99     }
100
101     p_buffs = p_s16_buff;
102     i_nb_bands = config_GetInt ( p_aout, "visual-nbbands" );
103     i_separ    = config_GetInt( p_aout, "visual-separ" );
104     i_amp     = config_GetInt ( p_aout, "visual-amp" );
105     i_peak     = config_GetInt ( p_aout, "visual-peaks" );
106
107     if( i_nb_bands == 20)
108     {
109         xscale = xscale1;
110     }
111     else
112     {
113         i_nb_bands = 80;
114         xscale = xscale2;
115     }
116
117     if( !p_effect->p_data )
118     {
119         p_effect->p_data=(void *)malloc(i_nb_bands * sizeof(int) );
120         if( !p_effect->p_data)
121         {
122             msg_Err(p_aout,"out of memory");
123             return -1;
124         }
125         peaks = (int *)p_effect->p_data;
126         for( i = 0 ; i < i_nb_bands ; i++)
127         {
128            peaks[i] = 0;
129         }
130
131     }
132     else
133     {
134         peaks =(int *)p_effect->p_data;
135     }
136
137
138     height = (int *)malloc( i_nb_bands * sizeof(int) );
139     if( !height)
140     {
141         msg_Err(p_aout,"out of memory");
142         return -1;
143     }
144     /* Convert the buffer to int16_t  */
145     /* Pasted from float32tos16.c */
146     for (i = p_buffer->i_nb_samples * p_effect->i_nb_chans; i--; )
147     {
148         union { float f; int32_t i; } u;
149         u.f = *p_buffl + 384.0;
150         if(u.i >  0x43c07fff ) * p_buffs = 32767;
151         else if ( u.i < 0x43bf8000 ) *p_buffs = -32768;
152         else *p_buffs = u.i - 0x43c00000;
153
154         p_buffl++ ; p_buffs++ ;
155     }
156     p_state  = visual_fft_init();
157     if( !p_state)
158     {
159         msg_Err(p_aout,"unable to initialize FFT transform");
160         return -1;
161     }
162     p_buffs = p_s16_buff;
163     for ( i = 0 ; i < FFT_BUFFER_SIZE ; i++)
164     {
165         p_output[i]    = 0;
166         p_buffer1[i] = *p_buffs;
167         p_buffs      = p_buffs + p_effect->i_nb_chans;
168     }
169     fft_perform( p_buffer1, p_output, p_state);
170     for(i= 0; i< FFT_BUFFER_SIZE ; i++ )
171         p_dest[i] = ( (int) sqrt( p_output [ i + 1 ] ) ) >> 8;
172
173     for ( i = 0 ; i< i_nb_bands ;i++)
174     {
175         /* We search the maximum on one scale */
176         for( j = xscale[i] , y=0 ; j< xscale[ i + 1 ] ; j++ )
177         {
178             if ( p_dest[j] > y )
179                  y = p_dest[j];
180         }
181         /* Calculate the height of the bar */
182         y >>=7;/* remove some noise */
183         if( y != 0)
184         {
185             height[i] = (int)log(y)* y_scale;
186                if(height[i] > 150)
187                   height[i] = 150;
188         }
189         else
190         {
191             height[i] = 0 ;
192         }
193
194         /* Draw the bar now */
195         i_band_width = floor( p_effect->i_width / i_nb_bands) ;
196
197         if( i_amp * height[i] > peaks[i])
198         {
199             peaks[i] = i_amp * height[i];
200         }
201         else if (peaks[i] > 0 )
202         {
203             peaks[i] -= PEAK_SPEED;
204             if( peaks[i] < i_amp * height[i] )
205             {
206                 peaks[i] = i_amp * height[i];
207             }
208             if( peaks[i] < 0 )
209             {
210                 peaks[i] = 0;
211             }
212         }
213
214         if( peaks[i] > 0 && i_peak )
215         {
216             if( peaks[i] >= p_effect->i_height )
217                 peaks[i] = p_effect->i_height - 2;
218             i_line = peaks[i];
219
220             for( j = 0 ; j< i_band_width - i_separ; j++)
221             {
222                for( k = 0 ; k< 3 ; k ++)
223                {
224                    /* Draw the peak */
225                      *(p_picture->p[0].p_pixels +
226                     (p_picture->p[0].i_lines - i_line -1 -k ) *
227                      p_picture->p[0].i_pitch + (i_band_width*i +j) )
228                                     = 0xff;
229
230                     *(p_picture->p[1].p_pixels +
231                      (p_picture->p[1].i_lines - i_line /2 -1 -k/2 ) *
232                      p_picture->p[1].i_pitch +
233                     ( ( i_band_width * i + j ) /2  ) )
234                                     = 0x00;
235
236                    if( 0x04 * (i_line + k ) - 0x0f > 0 )
237                    {
238                        if ( 0x04 * (i_line + k ) -0x0f < 0xff)
239                            *(p_picture->p[2].p_pixels  +
240                             (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
241                              p_picture->p[2].i_pitch +
242                              ( ( i_band_width * i + j ) /2  ) )
243                                     = ( 0x04 * ( i_line + k ) ) -0x0f ;
244                        else
245                            *(p_picture->p[2].p_pixels  +
246                             (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
247                              p_picture->p[2].i_pitch +
248                              ( ( i_band_width * i + j ) /2  ) )
249                                     = 0xff;
250                    }
251                    else
252                    {
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                                = 0x10 ;
258                    }
259                }
260             }
261         }
262
263         if(height[i] * i_amp > p_effect->i_height)
264             height[i] = floor(p_effect->i_height / i_amp );
265
266         for(i_line = 0 ; i_line < i_amp * height[i]; i_line ++ )
267         {
268             for( j = 0 ; j< i_band_width - i_separ ; j++)
269             {
270                *(p_picture->p[0].p_pixels +
271                  (p_picture->p[0].i_lines - i_line -1) *
272                   p_picture->p[0].i_pitch + (i_band_width*i +j) ) = 0xff;
273
274                 *(p_picture->p[1].p_pixels +
275                  (p_picture->p[1].i_lines - i_line /2 -1) *
276                  p_picture->p[1].i_pitch +
277                  ( ( i_band_width * i + j ) /2  ) ) = 0x00;
278
279                if( 0x04 * i_line - 0x0f > 0 )
280                {
281                     if( 0x04 * i_line - 0x0f < 0xff )
282                          *(p_picture->p[2].p_pixels  +
283                           (p_picture->p[2].i_lines - i_line /2 - 1) *
284                            p_picture->p[2].i_pitch +
285                            ( ( i_band_width * i + j ) /2  ) ) =
286                                ( 0x04 * i_line) -0x0f ;
287                     else
288                          *(p_picture->p[2].p_pixels  +
289                           (p_picture->p[2].i_lines - i_line /2 - 1) *
290                            p_picture->p[2].i_pitch +
291                            ( ( i_band_width * i + j ) /2  ) ) =
292                                        0xff;
293                }
294                else
295                {
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                             0x10 ;
301                }
302             }
303         }
304     }
305
306     fft_close( p_state );
307
308     if( p_s16_buff != NULL )
309     {
310         free( p_s16_buff );
311         p_s16_buff = NULL;
312     }
313
314     if(height) free(height);
315
316     if(psz_parse) free(psz_parse);
317
318     return 0;
319 }
320
321
322 /*****************************************************************************
323  * spectrometer_Run: derivative spectrum analysis
324  *****************************************************************************/
325 int spectrometer_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
326                  aout_buffer_t * p_buffer , picture_t * p_picture)
327 {
328 #define Y(R,G,B) ((uint8_t)( (R * .299) + (G * .587) + (B * .114) ))
329 #define U(R,G,B) ((uint8_t)( (R * -.169) + (G * -.332) + (B * .500) + 128 ))
330 #define V(R,G,B) ((uint8_t)( (R * .500) + (G * -.419) + (B * -.0813) + 128 ))
331     float p_output[FFT_BUFFER_SIZE];  /* Raw FFT Result  */
332     int *height;                      /* Bar heights */
333     int *peaks;                       /* Peaks */
334     int i_nb_bands;                   /* number of bands */
335     int i_band_width;                 /* width of bands */
336     int i_separ;                      /* Should we let blanks ? */
337     int i_amp;                        /* Vertical amplification */
338     int i_peak;                       /* Should we draw peaks ? */
339
340     int i_original;          /* original spectrum graphic routine */
341     int i_rad;               /* radius of circle of base of bands */
342     int i_sections;          /* sections of spectranalysis */
343     int i_extra_width;       /* extra width on peak */
344     int i_peak_height;       /* height of peak */
345     int c;                   /* sentinel container of total spectral sections */
346     double band_sep_angle;   /* angled separation between beginning of each band */
347     double section_sep_angle;/* "   "    '     "    '    "     "    spectrum section */
348     int max_band_length;     /* try not to go out of screen */
349     int i_show_base;         /* Should we draw base of circle ? */
350     int i_show_bands;        /* Should we draw bands ? */
351     //int i_invert_bands;      /* do the bands point inward ? */
352     double a;                /* for various misc angle situations in radians */
353     int x,y,xx,yy;           /* various misc x/y */
354     char color1;             /* V slide on a YUV color cube */
355     //char color2;             /* U slide.. ?  color2 fade color ? */
356
357     char *psz_parse = NULL;           /* Args line */
358
359     /* Horizontal scale for 20-band equalizer */
360     const int xscale1[]={0,1,2,3,4,5,6,7,8,11,15,20,27,
361                         36,47,62,82,107,141,184,255};
362
363     /* Horizontal scale for 80-band equalizer */
364     const int xscale2[] =
365     {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
366      19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
367      35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
368      52,53,54,55,56,57,58,59,61,63,67,72,77,82,87,93,99,105,
369      110,115,121,130,141,152,163,174,185,200,255};
370     const int *xscale;
371     const double y_scale =  3.60673760222;  /* (log 256) */
372
373     fft_state *p_state;                 /* internal FFT data */
374
375     int i , j , k;
376     int i_line;
377     int16_t p_dest[FFT_BUFFER_SIZE];      /* Adapted FFT result */
378     int16_t p_buffer1[FFT_BUFFER_SIZE];   /* Buffer on which we perform
379                                              the FFT (first channel) */
380     float *p_buffl =                     /* Original buffer */
381             (float*)p_buffer->p_buffer;
382
383     int16_t  *p_buffs;                    /* int16_t converted buffer */
384     int16_t  *p_s16_buff = NULL;                /* int16_t converted buffer */
385
386     i_line = 0;
387
388     p_s16_buff = (int16_t*)malloc(
389               p_buffer->i_nb_samples * p_effect->i_nb_chans * sizeof(int16_t));
390
391     if( !p_s16_buff )
392     {
393         msg_Err(p_aout,"out of memory");
394         return -1;
395     }
396
397     p_buffs = p_s16_buff;
398     i_original     = config_GetInt ( p_aout, "spect-show-original" );
399     i_nb_bands     = config_GetInt ( p_aout, "spect-nbbands" );
400     i_separ        = config_GetInt ( p_aout, "spect-separ" );
401     i_amp          = config_GetInt ( p_aout, "spect-amp" );
402     i_peak         = config_GetInt ( p_aout, "spect-show-peaks" );
403     i_show_base    = config_GetInt ( p_aout, "spect-show-base" );
404     i_show_bands   = config_GetInt ( p_aout, "spect-show-bands" );
405     i_rad          = config_GetInt ( p_aout, "spect-radius" );
406     i_sections     = config_GetInt ( p_aout, "spect-sections" );
407     i_extra_width  = config_GetInt ( p_aout, "spect-peak-width" );
408     i_peak_height  = config_GetInt ( p_aout, "spect-peak-height" );
409     color1         = config_GetInt ( p_aout, "spect-color" );
410
411     if( i_nb_bands == 20)
412     {
413         xscale = xscale1;
414     }
415     else
416     {
417         if( i_nb_bands > 80 )
418             i_nb_bands = 80;
419         xscale = xscale2;
420     }
421
422     if( !p_effect->p_data )
423     {
424         p_effect->p_data=(void *)malloc(i_nb_bands * sizeof(int) );
425         if( !p_effect->p_data)
426         {
427             msg_Err(p_aout,"out of memory");
428             return -1;
429         }
430         peaks = (int *)p_effect->p_data;
431         for( i = 0 ; i < i_nb_bands ; i++)
432         {
433            peaks[i] = 0;
434         }
435     }
436     else
437     {
438         peaks =(int *)p_effect->p_data;
439     }
440
441     height = (int *)malloc( i_nb_bands * sizeof(int) );
442     if( !height)
443     {
444         msg_Err(p_aout,"out of memory");
445         return -1;
446     }
447
448     /* Convert the buffer to int16_t  */
449     /* Pasted from float32tos16.c */
450     for (i = p_buffer->i_nb_samples * p_effect->i_nb_chans; i--; )
451     {
452         union { float f; int32_t i; } u;
453         u.f = *p_buffl + 384.0;
454         if(u.i >  0x43c07fff ) * p_buffs = 32767;
455         else if ( u.i < 0x43bf8000 ) *p_buffs = -32768;
456         else *p_buffs = u.i - 0x43c00000;
457
458         p_buffl++ ; p_buffs++ ;
459     }
460     p_state  = visual_fft_init();
461     if( !p_state)
462     {
463         msg_Err(p_aout,"unable to initialize FFT transform");
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 + 1 ] ) ) >> 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     if( p_s16_buff != NULL )
767     {
768         free( p_s16_buff );
769         p_s16_buff = NULL;
770     }
771
772     if(height) free(height);
773
774     if(psz_parse) free(psz_parse);
775
776     return 0;
777 }
778
779
780 /*****************************************************************************
781  * scope_Run: scope effect
782  *****************************************************************************/
783 int scope_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
784               aout_buffer_t * p_buffer , picture_t * p_picture)
785 {
786     int i_index;
787     float *p_sample ;
788     uint8_t *ppp_area[2][3];
789
790
791         for( i_index = 0 ; i_index < 2 ; i_index++ )
792         {
793             int j;
794             for( j = 0 ; j < 3 ; j++ )
795             {
796                 ppp_area[i_index][j] =
797                     p_picture->p[j].p_pixels + i_index * p_picture->p[j].i_lines
798                                 / 2 * p_picture->p[j].i_pitch;
799             }
800         }
801
802         for( i_index = 0, p_sample = (float *)p_buffer->p_buffer;
803              i_index < p_effect->i_width;
804              i_index++ )
805         {
806             uint8_t i_value;
807
808             /* Left channel */
809             i_value =  (*p_sample++ +1) * 127;
810             *(ppp_area[0][0]
811                + p_picture->p[0].i_pitch * i_index / p_effect->i_width
812                + p_picture->p[0].i_lines * i_value / 512
813                    * p_picture->p[0].i_pitch) = 0xbf;
814             *(ppp_area[0][1]
815                 + p_picture->p[1].i_pitch * i_index / p_effect->i_width
816                 + p_picture->p[1].i_lines * i_value / 512
817                    * p_picture->p[1].i_pitch) = 0xff;
818
819
820            /* Right channel */
821            i_value = ( *p_sample++ +1 ) * 127;
822            *(ppp_area[1][0]
823               + p_picture->p[0].i_pitch * i_index / p_effect->i_width
824               + p_picture->p[0].i_lines * i_value / 512
825                  * p_picture->p[0].i_pitch) = 0x9f;
826            *(ppp_area[1][2]
827               + p_picture->p[2].i_pitch * i_index / p_effect->i_width
828               + p_picture->p[2].i_lines * i_value / 512
829                 * p_picture->p[2].i_pitch) = 0xdd;
830         }
831         return 0;
832 }