1 /*****************************************************************************
2 * effects.c : Effects for the visualization system
3 *****************************************************************************
4 * Copyright (C) 2002-2009 VLC authors and VideoLAN
7 * Authors: Clément Stenac <zorglub@via.ecp.fr>
8 * Adrien Maglo <magsoft@videolan.org>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
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 Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_picture.h>
34 #include <vlc_block.h>
43 #define BAR_DECREASE_SPEED 5
45 #define GRAD_ANGLE_MIN 0.2
46 #define GRAD_ANGLE_MAX 0.5
47 #define GRAD_INCR 0.01
49 /*****************************************************************************
51 *****************************************************************************/
52 static int dummy_Run( visual_effect_t
* p_effect
, vlc_object_t
*p_aout
,
53 const block_t
* p_buffer
, picture_t
* p_picture
)
55 VLC_UNUSED(p_effect
); VLC_UNUSED(p_aout
); VLC_UNUSED(p_buffer
);
56 VLC_UNUSED(p_picture
);
60 static void dummy_Free( void *data
)
66 /*****************************************************************************
67 * spectrum_Run: spectrum analyser
68 *****************************************************************************/
69 typedef struct spectrum_data
74 unsigned i_prev_nb_samples
;
75 int16_t *p_prev_s16_buff
;
77 window_param wind_param
;
80 static int spectrum_Run(visual_effect_t
* p_effect
, vlc_object_t
*p_aout
,
81 const block_t
* p_buffer
, picture_t
* p_picture
)
83 spectrum_data
*p_data
= p_effect
->p_data
;
84 float p_output
[FFT_BUFFER_SIZE
]; /* Raw FFT Result */
85 int *height
; /* Bar heights */
86 int *peaks
; /* Peaks */
87 int *prev_heights
; /* Previous bar heights */
88 int i_80_bands
; /* number of bands : 80 if true else 20 */
89 int i_nb_bands
; /* number of bands : 80 or 20 */
90 int i_band_width
; /* width of bands */
91 int i_start
; /* first band horizontal position */
92 int i_peak
; /* Should we draw peaks ? */
94 /* Horizontal scale for 20-band equalizer */
95 const int xscale1
[]={0,1,2,3,4,5,6,7,8,11,15,20,27,
96 36,47,62,82,107,141,184,255};
98 /* Horizontal scale for 80-band equalizer */
100 {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
101 19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
102 35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
103 52,53,54,55,56,57,58,59,61,63,67,72,77,82,87,93,99,105,
104 110,115,121,130,141,152,163,174,185,200,255};
107 fft_state
*p_state
; /* internal FFT data */
108 DEFINE_WIND_CONTEXT( wind_ctx
); /* internal window data */
112 int16_t p_dest
[FFT_BUFFER_SIZE
]; /* Adapted FFT result */
113 int16_t p_buffer1
[FFT_BUFFER_SIZE
]; /* Buffer on which we perform
114 the FFT (first channel) */
116 float *p_buffl
= /* Original buffer */
117 (float*)p_buffer
->p_buffer
;
119 int16_t *p_buffs
; /* int16_t converted buffer */
120 int16_t *p_s16_buff
; /* int16_t converted buffer */
122 if (!p_buffer
->i_nb_samples
) {
123 msg_Err(p_aout
, "no samples yet");
127 /* Create p_data if needed */
130 p_effect
->p_data
= p_data
= malloc( sizeof( spectrum_data
) );
134 p_data
->peaks
= calloc( 80, sizeof(int) );
135 p_data
->prev_heights
= calloc( 80, sizeof(int) );
137 p_data
->i_prev_nb_samples
= 0;
138 p_data
->p_prev_s16_buff
= NULL
;
140 window_get_param( p_aout
, &p_data
->wind_param
);
142 peaks
= (int *)p_data
->peaks
;
143 prev_heights
= (int *)p_data
->prev_heights
;
145 /* Allocate the buffer only if the number of samples change */
146 if( p_buffer
->i_nb_samples
!= p_data
->i_prev_nb_samples
)
148 free( p_data
->p_prev_s16_buff
);
149 p_data
->p_prev_s16_buff
= malloc( p_buffer
->i_nb_samples
*
150 p_effect
->i_nb_chans
*
152 p_data
->i_prev_nb_samples
= p_buffer
->i_nb_samples
;
153 if( !p_data
->p_prev_s16_buff
)
156 p_buffs
= p_s16_buff
= p_data
->p_prev_s16_buff
;
158 i_80_bands
= var_InheritInteger( p_aout
, "visual-80-bands" );
159 i_peak
= var_InheritInteger( p_aout
, "visual-peaks" );
172 height
= malloc( i_nb_bands
* sizeof(int) );
177 /* Convert the buffer to int16_t */
178 /* Pasted from float32tos16.c */
179 for (i
= p_buffer
->i_nb_samples
* p_effect
->i_nb_chans
; i
--; )
181 union { float f
; int32_t i
; } u
;
182 u
.f
= *p_buffl
+ 384.0;
183 if(u
.i
> 0x43c07fff ) * p_buffs
= 32767;
184 else if ( u
.i
< 0x43bf8000 ) *p_buffs
= -32768;
185 else *p_buffs
= u
.i
- 0x43c00000;
187 p_buffl
++ ; p_buffs
++ ;
189 p_state
= visual_fft_init();
193 msg_Err(p_aout
,"unable to initialize FFT transform");
196 if( !window_init( FFT_BUFFER_SIZE
, &p_data
->wind_param
, &wind_ctx
) )
198 fft_close( p_state
);
200 msg_Err(p_aout
,"unable to initialize FFT window");
203 p_buffs
= p_s16_buff
;
204 for ( i
= 0 ; i
< FFT_BUFFER_SIZE
; i
++)
207 p_buffer1
[i
] = *p_buffs
;
209 p_buffs
+= p_effect
->i_nb_chans
;
210 if( p_buffs
>= &p_s16_buff
[p_buffer
->i_nb_samples
* p_effect
->i_nb_chans
] )
211 p_buffs
= p_s16_buff
;
214 window_scale_in_place( p_buffer1
, &wind_ctx
);
215 fft_perform( p_buffer1
, p_output
, p_state
);
216 for( i
= 0; i
< FFT_BUFFER_SIZE
; i
++ )
217 p_dest
[i
] = p_output
[i
] * ( 2 ^ 16 ) / ( ( FFT_BUFFER_SIZE
/ 2 * 32768 ) ^ 2 );
219 /* Compute the horizontal position of the first band */
220 i_band_width
= floor( p_effect
->i_width
/ i_nb_bands
);
221 i_start
= ( p_effect
->i_width
- i_band_width
* i_nb_bands
) / 2;
223 for ( i
= 0 ; i
< i_nb_bands
;i
++)
225 /* We search the maximum on one scale */
226 for( j
= xscale
[i
], y
= 0; j
< xscale
[ i
+ 1 ]; j
++ )
231 /* Calculate the height of the bar */
234 height
[i
] = log( y
) * 30;
235 if( height
[i
] > 380 )
241 /* Draw the bar now */
243 if( height
[i
] > peaks
[i
] )
245 peaks
[i
] = height
[i
];
247 else if( peaks
[i
] > 0 )
249 peaks
[i
] -= PEAK_SPEED
;
250 if( peaks
[i
] < height
[i
] )
252 peaks
[i
] = height
[i
];
260 /* Decrease the bars if needed */
261 if( height
[i
] <= prev_heights
[i
] - BAR_DECREASE_SPEED
)
263 height
[i
] = prev_heights
[i
];
264 height
[i
] -= BAR_DECREASE_SPEED
;
266 prev_heights
[i
] = height
[i
];
268 if( peaks
[i
] > 0 && i_peak
)
270 if( peaks
[i
] >= p_effect
->i_height
)
271 peaks
[i
] = p_effect
->i_height
- 2;
274 for( j
= 0; j
< i_band_width
- 1; j
++ )
276 for( k
= 0; k
< 3; k
++ )
279 *(p_picture
->p
[0].p_pixels
+
280 ( p_effect
->i_height
- i_line
-1 -k
) *
281 p_picture
->p
[0].i_pitch
+
282 ( i_start
+ i_band_width
*i
+ j
) )
285 *(p_picture
->p
[1].p_pixels
+
286 ( ( p_effect
->i_height
- i_line
) / 2 - 1 -k
/2 ) *
287 p_picture
->p
[1].i_pitch
+
288 ( ( i_start
+ i_band_width
* i
+ j
) /2 ) )
291 if( i_line
+ k
- 0x0f > 0 )
293 if ( i_line
+ k
- 0x0f < 0xff )
294 *(p_picture
->p
[2].p_pixels
+
295 ( ( p_effect
->i_height
- i_line
) / 2 - 1 -k
/2 ) *
296 p_picture
->p
[2].i_pitch
+
297 ( ( i_start
+ i_band_width
* i
+ j
) /2 ) )
298 = ( i_line
+ k
) - 0x0f;
300 *(p_picture
->p
[2].p_pixels
+
301 ( ( p_effect
->i_height
- i_line
) / 2 - 1 -k
/2 ) *
302 p_picture
->p
[2].i_pitch
+
303 ( ( i_start
+ i_band_width
* i
+ j
) /2 ) )
308 *(p_picture
->p
[2].p_pixels
+
309 ( ( p_effect
->i_height
- i_line
) / 2 - 1 -k
/2 ) *
310 p_picture
->p
[2].i_pitch
+
311 ( ( i_start
+ i_band_width
* i
+ j
) /2 ) )
318 if(height
[i
] > p_effect
->i_height
)
319 height
[i
] = floor(p_effect
->i_height
);
321 for( i_line
= 0; i_line
< height
[i
]; i_line
++ )
323 for( j
= 0 ; j
< i_band_width
- 1; j
++)
325 *(p_picture
->p
[0].p_pixels
+
326 (p_effect
->i_height
- i_line
- 1) *
327 p_picture
->p
[0].i_pitch
+
328 ( i_start
+ i_band_width
*i
+ j
) ) = 0xff;
330 *(p_picture
->p
[1].p_pixels
+
331 ( ( p_effect
->i_height
- i_line
) / 2 - 1) *
332 p_picture
->p
[1].i_pitch
+
333 ( ( i_start
+ i_band_width
* i
+ j
) /2 ) ) = 0x00;
335 if( i_line
- 0x0f > 0 )
337 if( i_line
- 0x0f < 0xff )
338 *(p_picture
->p
[2].p_pixels
+
339 ( ( p_effect
->i_height
- i_line
) / 2 - 1) *
340 p_picture
->p
[2].i_pitch
+
341 ( ( i_start
+ i_band_width
* i
+ j
) /2 ) ) =
344 *(p_picture
->p
[2].p_pixels
+
345 ( ( p_effect
->i_height
- i_line
) / 2 - 1) *
346 p_picture
->p
[2].i_pitch
+
347 ( ( i_start
+ i_band_width
* i
+ j
) /2 ) ) =
352 *(p_picture
->p
[2].p_pixels
+
353 ( ( p_effect
->i_height
- i_line
) / 2 - 1) *
354 p_picture
->p
[2].i_pitch
+
355 ( ( i_start
+ i_band_width
* i
+ j
) /2 ) ) =
362 window_close( &wind_ctx
);
364 fft_close( p_state
);
371 static void spectrum_Free( void *data
)
373 spectrum_data
*p_data
= data
;
377 free( p_data
->peaks
);
378 free( p_data
->prev_heights
);
379 free( p_data
->p_prev_s16_buff
);
385 /*****************************************************************************
386 * spectrometer_Run: derivative spectrum analysis
387 *****************************************************************************/
392 unsigned i_prev_nb_samples
;
393 int16_t *p_prev_s16_buff
;
395 window_param wind_param
;
398 static int spectrometer_Run(visual_effect_t
* p_effect
, vlc_object_t
*p_aout
,
399 const block_t
* p_buffer
, picture_t
* p_picture
)
401 #define Y(R,G,B) ((uint8_t)( (R * .299) + (G * .587) + (B * .114) ))
402 #define U(R,G,B) ((uint8_t)( (R * -.169) + (G * -.332) + (B * .500) + 128 ))
403 #define V(R,G,B) ((uint8_t)( (R * .500) + (G * -.419) + (B * -.0813) + 128 ))
404 float p_output
[FFT_BUFFER_SIZE
]; /* Raw FFT Result */
405 int *height
; /* Bar heights */
406 int *peaks
; /* Peaks */
407 int i_80_bands
; /* number of bands : 80 if true else 20 */
408 int i_nb_bands
; /* number of bands : 80 or 20 */
409 int i_band_width
; /* width of bands */
410 int i_separ
; /* Should we let blanks ? */
411 int i_amp
; /* Vertical amplification */
412 int i_peak
; /* Should we draw peaks ? */
414 int i_original
; /* original spectrum graphic routine */
415 int i_rad
; /* radius of circle of base of bands */
416 int i_sections
; /* sections of spectranalysis */
417 int i_extra_width
; /* extra width on peak */
418 int i_peak_height
; /* height of peak */
419 int c
; /* sentinel container of total spectral sections */
420 double band_sep_angle
; /* angled separation between beginning of each band */
421 double section_sep_angle
;/* " " ' " ' " " spectrum section */
422 int max_band_length
; /* try not to go out of screen */
423 int i_show_base
; /* Should we draw base of circle ? */
424 int i_show_bands
; /* Should we draw bands ? */
425 //int i_invert_bands; /* do the bands point inward ? */
426 double a
; /* for various misc angle situations in radians */
427 int x
,y
,xx
,yy
; /* various misc x/y */
428 char color1
; /* V slide on a YUV color cube */
429 //char color2; /* U slide.. ? color2 fade color ? */
431 /* Horizontal scale for 20-band equalizer */
432 const int xscale1
[]={0,1,2,3,4,5,6,7,8,11,15,20,27,
433 36,47,62,82,107,141,184,255};
435 /* Horizontal scale for 80-band equalizer */
436 const int xscale2
[] =
437 {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
438 19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
439 35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
440 52,53,54,55,56,57,58,59,61,63,67,72,77,82,87,93,99,105,
441 110,115,121,130,141,152,163,174,185,200,255};
443 const double y_scale
= 3.60673760222; /* (log 256) */
445 fft_state
*p_state
; /* internal FFT data */
446 DEFINE_WIND_CONTEXT( wind_ctx
); /* internal window data */
450 int16_t p_dest
[FFT_BUFFER_SIZE
]; /* Adapted FFT result */
451 int16_t p_buffer1
[FFT_BUFFER_SIZE
]; /* Buffer on which we perform
452 the FFT (first channel) */
453 float *p_buffl
= /* Original buffer */
454 (float*)p_buffer
->p_buffer
;
456 int16_t *p_buffs
; /* int16_t converted buffer */
457 int16_t *p_s16_buff
; /* int16_t converted buffer */
459 if (!p_buffer
->i_nb_samples
) {
460 msg_Err(p_aout
, "no samples yet");
464 /* Create the data struct if needed */
465 spectrometer_data
*p_data
= p_effect
->p_data
;
468 p_data
= malloc( sizeof(spectrometer_data
) );
471 p_data
->peaks
= calloc( 80, sizeof(int) );
477 p_data
->i_prev_nb_samples
= 0;
478 p_data
->p_prev_s16_buff
= NULL
;
479 window_get_param( p_aout
, &p_data
->wind_param
);
480 p_effect
->p_data
= (void*)p_data
;
482 peaks
= p_data
->peaks
;
484 /* Allocate the buffer only if the number of samples change */
485 if( p_buffer
->i_nb_samples
!= p_data
->i_prev_nb_samples
)
487 free( p_data
->p_prev_s16_buff
);
488 p_data
->p_prev_s16_buff
= malloc( p_buffer
->i_nb_samples
*
489 p_effect
->i_nb_chans
*
491 p_data
->i_prev_nb_samples
= p_buffer
->i_nb_samples
;
492 if( !p_data
->p_prev_s16_buff
)
495 p_buffs
= p_s16_buff
= p_data
->p_prev_s16_buff
;
497 i_original
= var_InheritInteger( p_aout
, "spect-show-original" );
498 i_80_bands
= var_InheritInteger( p_aout
, "spect-80-bands" );
499 i_separ
= var_InheritInteger( p_aout
, "spect-separ" );
500 i_amp
= var_InheritInteger( p_aout
, "spect-amp" );
501 i_peak
= var_InheritInteger( p_aout
, "spect-show-peaks" );
502 i_show_base
= var_InheritInteger( p_aout
, "spect-show-base" );
503 i_show_bands
= var_InheritInteger( p_aout
, "spect-show-bands" );
504 i_rad
= var_InheritInteger( p_aout
, "spect-radius" );
505 i_sections
= var_InheritInteger( p_aout
, "spect-sections" );
506 i_extra_width
= var_InheritInteger( p_aout
, "spect-peak-width" );
507 i_peak_height
= var_InheritInteger( p_aout
, "spect-peak-height" );
508 color1
= var_InheritInteger( p_aout
, "spect-color" );
521 height
= malloc( i_nb_bands
* sizeof(int) );
525 /* Convert the buffer to int16_t */
526 /* Pasted from float32tos16.c */
527 for (i
= p_buffer
->i_nb_samples
* p_effect
->i_nb_chans
; i
--; )
529 union { float f
; int32_t i
; } u
;
530 u
.f
= *p_buffl
+ 384.0;
531 if(u
.i
> 0x43c07fff ) * p_buffs
= 32767;
532 else if ( u
.i
< 0x43bf8000 ) *p_buffs
= -32768;
533 else *p_buffs
= u
.i
- 0x43c00000;
535 p_buffl
++ ; p_buffs
++ ;
537 p_state
= visual_fft_init();
540 msg_Err(p_aout
,"unable to initialize FFT transform");
544 if( !window_init( FFT_BUFFER_SIZE
, &p_data
->wind_param
, &wind_ctx
) )
546 fft_close( p_state
);
548 msg_Err(p_aout
,"unable to initialize FFT window");
551 p_buffs
= p_s16_buff
;
552 for ( i
= 0 ; i
< FFT_BUFFER_SIZE
; i
++)
555 p_buffer1
[i
] = *p_buffs
;
557 p_buffs
+= p_effect
->i_nb_chans
;
558 if( p_buffs
>= &p_s16_buff
[p_buffer
->i_nb_samples
* p_effect
->i_nb_chans
] )
559 p_buffs
= p_s16_buff
;
561 window_scale_in_place( p_buffer1
, &wind_ctx
);
562 fft_perform( p_buffer1
, p_output
, p_state
);
563 for(i
= 0; i
< FFT_BUFFER_SIZE
; i
++)
565 int sqrti
= sqrt(p_output
[i
]);
566 p_dest
[i
] = sqrti
>> 8;
569 i_nb_bands
*= i_sections
;
571 for ( i
= 0 ; i
< i_nb_bands
/i_sections
;i
++)
573 /* We search the maximum on one scale */
574 for( j
= xscale
[i
] , y
=0 ; j
< xscale
[ i
+ 1 ] ; j
++ )
579 /* Calculate the height of the bar */
580 y
>>=7;/* remove some noise */
584 height
[i
] = logy
* y_scale
;
593 /* Draw the bar now */
594 i_band_width
= floor( p_effect
->i_width
/ (i_nb_bands
/i_sections
)) ;
596 if( i_amp
* height
[i
] > peaks
[i
])
598 peaks
[i
] = i_amp
* height
[i
];
600 else if (peaks
[i
] > 0 )
602 peaks
[i
] -= PEAK_SPEED
;
603 if( peaks
[i
] < i_amp
* height
[i
] )
605 peaks
[i
] = i_amp
* height
[i
];
613 if( i_original
!= 0 )
615 if( peaks
[i
] > 0 && i_peak
)
617 if( peaks
[i
] >= p_effect
->i_height
)
618 peaks
[i
] = p_effect
->i_height
- 2;
621 for( j
= 0 ; j
< i_band_width
- i_separ
; j
++)
623 for( k
= 0 ; k
< 3 ; k
++)
626 *(p_picture
->p
[0].p_pixels
+
627 (p_effect
->i_height
- i_line
-1 -k
) *
628 p_picture
->p
[0].i_pitch
+ (i_band_width
*i
+j
) )
631 *(p_picture
->p
[1].p_pixels
+
632 ( ( p_effect
->i_height
- i_line
) / 2 -1 -k
/2 ) *
633 p_picture
->p
[1].i_pitch
+
634 ( ( i_band_width
* i
+ j
) /2 ) )
637 if( 0x04 * (i_line
+ k
) - 0x0f > 0 )
639 if ( 0x04 * (i_line
+ k
) -0x0f < 0xff)
640 *(p_picture
->p
[2].p_pixels
+
641 ( ( p_effect
->i_height
- i_line
) / 2 - 1 -k
/2 ) *
642 p_picture
->p
[2].i_pitch
+
643 ( ( i_band_width
* i
+ j
) /2 ) )
644 = ( 0x04 * ( i_line
+ k
) ) -0x0f ;
646 *(p_picture
->p
[2].p_pixels
+
647 ( ( p_effect
->i_height
- i_line
) / 2 - 1 -k
/2 ) *
648 p_picture
->p
[2].i_pitch
+
649 ( ( i_band_width
* i
+ j
) /2 ) )
654 *(p_picture
->p
[2].p_pixels
+
655 ( ( p_effect
->i_height
- i_line
) / 2 - 1 -k
/2 ) *
656 p_picture
->p
[2].i_pitch
+
657 ( ( i_band_width
* i
+ j
) /2 ) )
663 if(height
[i
] * i_amp
> p_effect
->i_height
)
664 height
[i
] = floor(p_effect
->i_height
/ i_amp
);
666 for(i_line
= 0 ; i_line
< i_amp
* height
[i
]; i_line
++ )
668 for( j
= 0 ; j
< i_band_width
- i_separ
; j
++)
670 *(p_picture
->p
[0].p_pixels
+
671 (p_effect
->i_height
- i_line
-1) *
672 p_picture
->p
[0].i_pitch
+ (i_band_width
*i
+j
) ) = 0xff;
674 *(p_picture
->p
[1].p_pixels
+
675 ( ( p_effect
->i_height
- i_line
) / 2 -1) *
676 p_picture
->p
[1].i_pitch
+
677 ( ( i_band_width
* i
+ j
) /2 ) ) = 0x00;
679 if( 0x04 * i_line
- 0x0f > 0 )
681 if( 0x04 * i_line
- 0x0f < 0xff )
682 *(p_picture
->p
[2].p_pixels
+
683 ( ( p_effect
->i_height
- i_line
) / 2 - 1) *
684 p_picture
->p
[2].i_pitch
+
685 ( ( i_band_width
* i
+ j
) /2 ) ) =
686 ( 0x04 * i_line
) -0x0f ;
688 *(p_picture
->p
[2].p_pixels
+
689 ( ( p_effect
->i_height
- i_line
) / 2 - 1) *
690 p_picture
->p
[2].i_pitch
+
691 ( ( i_band_width
* i
+ j
) /2 ) ) =
696 *(p_picture
->p
[2].p_pixels
+
697 ( ( p_effect
->i_height
- i_line
) / 2 - 1) *
698 p_picture
->p
[2].i_pitch
+
699 ( ( i_band_width
* i
+ j
) /2 ) ) =
707 band_sep_angle
= 360.0 / i_nb_bands
;
708 section_sep_angle
= 360.0 / i_sections
;
709 if( i_peak_height
< 1 )
711 max_band_length
= p_effect
->i_height
/ 2 - ( i_rad
+ i_peak_height
+ 1 );
713 i_band_width
= floor( 360 / i_nb_bands
- i_separ
);
714 if( i_band_width
< 1 )
717 for( c
= 0 ; c
< i_sections
; c
++ )
718 for( i
= 0 ; i
< (i_nb_bands
/ i_sections
) ; i
++ )
721 if( peaks
[i
] > 0 && i_peak
)
723 if( peaks
[i
] >= p_effect
->i_height
)
724 peaks
[i
] = p_effect
->i_height
- 2;
727 /* circular line pattern(so color blend is more visible) */
728 for( j
= 0 ; j
< i_peak_height
; j
++ )
730 //x = p_picture->p[0].i_pitch / 2;
731 x
= p_effect
->i_width
/ 2;
732 y
= p_effect
->i_height
/ 2;
735 for( k
= 0 ; k
< (i_band_width
+ i_extra_width
) ; k
++ )
739 a
= ( (i
+1) * band_sep_angle
+ section_sep_angle
* (c
+1) + k
)
741 x
+= (double)( cos(a
) * (double)( i_line
+ j
+ i_rad
) );
742 y
+= (double)( -sin(a
) * (double)( i_line
+ j
+ i_rad
) );
744 *(p_picture
->p
[0].p_pixels
+ x
+ y
* p_picture
->p
[0].i_pitch
745 ) = 255;/* Y(R,G,B); */
750 *(p_picture
->p
[1].p_pixels
+ x
+ y
* p_picture
->p
[1].i_pitch
751 ) = 0;/* U(R,G,B); */
753 if( 0x04 * (i_line
+ k
) - 0x0f > 0 )
755 if ( 0x04 * (i_line
+ k
) -0x0f < 0xff)
756 *(p_picture
->p
[2].p_pixels
+ x
+ y
* p_picture
->p
[2].i_pitch
757 ) = ( 0x04 * ( i_line
+ k
) ) -(color1
-1);/* -V(R,G,B); */
759 *(p_picture
->p
[2].p_pixels
+ x
+ y
* p_picture
->p
[2].i_pitch
760 ) = 255;/* V(R,G,B); */
764 *(p_picture
->p
[2].p_pixels
+ x
+ y
* p_picture
->p
[2].i_pitch
765 ) = color1
;/* V(R,G,B); */
771 if( (height
[i
] * i_amp
) > p_effect
->i_height
)
772 height
[i
] = floor( p_effect
->i_height
/ i_amp
);
774 /* DO BASE OF BAND (mostly makes a circle) */
775 if( i_show_base
!= 0 )
777 //x = p_picture->p[0].i_pitch / 2;
778 x
= p_effect
->i_width
/ 2;
779 y
= p_effect
->i_height
/ 2;
781 a
= ( (i
+1) * band_sep_angle
+ section_sep_angle
* (c
+1) )
783 x
+= (double)( cos(a
) * (double)i_rad
);/* newb-forceful casting */
784 y
+= (double)( -sin(a
) * (double)i_rad
);
786 *(p_picture
->p
[0].p_pixels
+ x
+ y
* p_picture
->p
[0].i_pitch
787 ) = 255;/* Y(R,G,B); */
792 *(p_picture
->p
[1].p_pixels
+ x
+ y
* p_picture
->p
[1].i_pitch
793 ) = 0;/* U(R,G,B); */
795 if( 0x04 * i_line
- 0x0f > 0 )
797 if( 0x04 * i_line
-0x0f < 0xff)
798 *(p_picture
->p
[2].p_pixels
+ x
+ y
* p_picture
->p
[2].i_pitch
799 ) = ( 0x04 * i_line
) -(color1
-1);/* -V(R,G,B); */
801 *(p_picture
->p
[2].p_pixels
+ x
+ y
* p_picture
->p
[2].i_pitch
802 ) = 255;/* V(R,G,B); */
806 *(p_picture
->p
[2].p_pixels
+ x
+ y
* p_picture
->p
[2].i_pitch
807 ) = color1
;/* V(R,G,B); */
812 if( i_show_bands
!= 0 )
813 for( j
= 0 ; j
< i_band_width
; j
++ )
815 x
= p_effect
->i_width
/ 2;
816 y
= p_effect
->i_height
/ 2;
819 a
= ( (i
+1) * band_sep_angle
+ section_sep_angle
* (c
+1) + j
)
822 for( k
= (i_rad
+1) ; k
< max_band_length
; k
++ )
824 if( (k
-i_rad
) > height
[i
] )
829 x
+= (double)( cos(a
) * (double)k
);/* newbed! */
830 y
+= (double)( -sin(a
) * (double)k
);
832 *(p_picture
->p
[0].p_pixels
+ x
+ y
* p_picture
->p
[0].i_pitch
838 *(p_picture
->p
[1].p_pixels
+ x
+ y
* p_picture
->p
[1].i_pitch
841 if( 0x04 * i_line
- 0x0f > 0 )
843 if ( 0x04 * i_line
-0x0f < 0xff)
844 *(p_picture
->p
[2].p_pixels
+ x
+ y
* p_picture
->p
[2].i_pitch
845 ) = ( 0x04 * i_line
) -(color1
-1);
847 *(p_picture
->p
[2].p_pixels
+ x
+ y
* p_picture
->p
[2].i_pitch
852 *(p_picture
->p
[2].p_pixels
+ x
+ y
* p_picture
->p
[2].i_pitch
859 window_close( &wind_ctx
);
861 fft_close( p_state
);
868 static void spectrometer_Free( void *data
)
870 spectrometer_data
*p_data
= data
;
874 free( p_data
->peaks
);
875 free( p_data
->p_prev_s16_buff
);
881 /*****************************************************************************
882 * scope_Run: scope effect
883 *****************************************************************************/
884 static int scope_Run(visual_effect_t
* p_effect
, vlc_object_t
*p_aout
,
885 const block_t
* p_buffer
, picture_t
* p_picture
)
891 uint8_t *ppp_area
[2][3];
893 for( i_index
= 0 ; i_index
< 2 ; i_index
++ )
895 for( int j
= 0 ; j
< 3 ; j
++ )
897 ppp_area
[i_index
][j
] =
898 p_picture
->p
[j
].p_pixels
+ (i_index
* 2 + 1) * p_picture
->p
[j
].i_lines
899 / 4 * p_picture
->p
[j
].i_pitch
;
903 for( i_index
= 0, p_sample
= (float *)p_buffer
->p_buffer
;
904 i_index
< __MIN( p_effect
->i_width
, (int)p_buffer
->i_nb_samples
);
910 i_value
= p_sample
[p_effect
->i_idx_left
] * 127;
912 + p_picture
->p
[0].i_pitch
* i_index
/ p_effect
->i_width
913 + p_picture
->p
[0].i_lines
* i_value
/ 512
914 * p_picture
->p
[0].i_pitch
) = 0xbf;
916 + p_picture
->p
[1].i_pitch
* i_index
/ p_effect
->i_width
917 + p_picture
->p
[1].i_lines
* i_value
/ 512
918 * p_picture
->p
[1].i_pitch
) = 0xff;
922 i_value
= p_sample
[p_effect
->i_idx_right
] * 127;
924 + p_picture
->p
[0].i_pitch
* i_index
/ p_effect
->i_width
925 + p_picture
->p
[0].i_lines
* i_value
/ 512
926 * p_picture
->p
[0].i_pitch
) = 0x9f;
928 + p_picture
->p
[2].i_pitch
* i_index
/ p_effect
->i_width
929 + p_picture
->p
[2].i_lines
* i_value
/ 512
930 * p_picture
->p
[2].i_pitch
) = 0xdd;
932 p_sample
+= p_effect
->i_nb_chans
;
938 /*****************************************************************************
939 * vuMeter_Run: vu meter effect
940 *****************************************************************************/
941 static int vuMeter_Run(visual_effect_t
* p_effect
, vlc_object_t
*p_aout
,
942 const block_t
* p_buffer
, picture_t
* p_picture
)
948 /* Compute the peak values */
949 for ( unsigned i
= 0 ; i
< p_buffer
->i_nb_samples
; i
++ )
951 const float *p_sample
= (float *)p_buffer
->p_buffer
;
954 ch
= p_sample
[p_effect
->i_idx_left
] * 256;
958 ch
= p_sample
[p_effect
->i_idx_right
] * 256;
962 p_sample
+= p_effect
->i_nb_chans
;
965 i_value_l
= fabsf(i_value_l
);
966 i_value_r
= fabsf(i_value_r
);
968 /* Stay under maximum value admited */
969 if ( i_value_l
> 200 * M_PI_2
)
970 i_value_l
= 200 * M_PI_2
;
971 if ( i_value_r
> 200 * M_PI_2
)
972 i_value_r
= 200 * M_PI_2
;
976 if( !p_effect
->p_data
)
978 /* Allocate memory to save hand positions */
979 p_effect
->p_data
= malloc( 2 * sizeof(float) );
980 i_value
= p_effect
->p_data
;
981 i_value
[0] = i_value_l
;
982 i_value
[1] = i_value_r
;
986 /* Make the hands go down slowly if the current values are slower
988 i_value
= p_effect
->p_data
;
990 if ( i_value_l
> i_value
[0] - 6 )
991 i_value
[0] = i_value_l
;
993 i_value
[0] = i_value
[0] - 6;
995 if ( i_value_r
> i_value
[1] - 6 )
996 i_value
[1] = i_value_r
;
998 i_value
[1] = i_value
[1] - 6;
1005 int start_x
= p_effect
->i_width
/ 2 - 120; /* i_width.min = 532 (visual.c) */
1007 for ( int j
= 0; j
< 2; j
++ )
1009 /* Draw the two scales */
1011 teta_grad
= GRAD_ANGLE_MIN
;
1012 for ( teta
= -M_PI_4
; teta
<= M_PI_4
; teta
= teta
+ 0.003 )
1014 for ( unsigned i
= 140; i
<= 150; i
++ )
1016 y
= i
* cos(teta
) + 20;
1017 x
= i
* sin(teta
) + start_x
+ 240 * j
;
1018 /* Compute the last color for the gradation */
1019 if (teta
>= teta_grad
+ GRAD_INCR
&& teta_grad
<= GRAD_ANGLE_MAX
)
1021 teta_grad
= teta_grad
+ GRAD_INCR
;
1024 *(p_picture
->p
[0].p_pixels
+
1025 (p_picture
->p
[0].i_lines
- y
- 1 ) * p_picture
->p
[0].i_pitch
1027 *(p_picture
->p
[1].p_pixels
+
1028 (p_picture
->p
[1].i_lines
- y
/ 2 - 1 ) * p_picture
->p
[1].i_pitch
1030 *(p_picture
->p
[2].p_pixels
+
1031 (p_picture
->p
[2].i_lines
- y
/ 2 - 1 ) * p_picture
->p
[2].i_pitch
1032 + x
/ 2 ) = 0x4D + k
;
1036 /* Draw the two hands */
1037 teta
= (float)i_value
[j
] / 200 - M_PI_4
;
1038 for ( int i
= 0; i
<= 150; i
++ )
1040 y
= i
* cos(teta
) + 20;
1041 x
= i
* sin(teta
) + start_x
+ 240 * j
;
1042 *(p_picture
->p
[0].p_pixels
+
1043 (p_picture
->p
[0].i_lines
- y
- 1 ) * p_picture
->p
[0].i_pitch
1045 *(p_picture
->p
[1].p_pixels
+
1046 (p_picture
->p
[1].i_lines
- y
/ 2 - 1 ) * p_picture
->p
[1].i_pitch
1048 *(p_picture
->p
[2].p_pixels
+
1049 (p_picture
->p
[2].i_lines
- y
/ 2 - 1 ) * p_picture
->p
[2].i_pitch
1053 /* Draw the hand bases */
1054 for ( teta
= -M_PI_2
; teta
<= M_PI_2
+ 0.01; teta
= teta
+ 0.003 )
1056 for ( int i
= 0; i
< 10; i
++ )
1058 y
= i
* cos(teta
) + 20;
1059 x
= i
* sin(teta
) + start_x
+ 240 * j
;
1060 *(p_picture
->p
[0].p_pixels
+
1061 (p_picture
->p
[0].i_lines
- y
- 1 ) * p_picture
->p
[0].i_pitch
1063 *(p_picture
->p
[1].p_pixels
+
1064 (p_picture
->p
[1].i_lines
- y
/ 2 - 1 ) * p_picture
->p
[1].i_pitch
1066 *(p_picture
->p
[2].p_pixels
+
1067 (p_picture
->p
[2].i_lines
- y
/ 2 - 1 ) * p_picture
->p
[2].i_pitch
1077 /* Table of effects */
1078 const struct visual_cb_t effectv
[] = {
1079 { "scope", scope_Run
, dummy_Free
},
1080 { "vuMeter", vuMeter_Run
, dummy_Free
},
1081 { "spectrum", spectrum_Run
, spectrum_Free
},
1082 { "spectrometer", spectrometer_Run
, spectrometer_Free
},
1083 { "dummy", dummy_Run
, dummy_Free
},
1085 const unsigned effectc
= sizeof (effectv
) / sizeof (effectv
[0]);