demux: libmp4: add and parse 3DDS uuid
[vlc.git] / modules / visualization / visual / effects.c
blob56d493247ecc6a8aac88cc0ad11c2ddd0b9d5f3b
1 /*****************************************************************************
2 * effects.c : Effects for the visualization system
3 *****************************************************************************
4 * Copyright (C) 2002-2009 VLC authors and VideoLAN
5 * $Id$
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 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
33 #include <vlc_picture.h>
34 #include <vlc_block.h>
36 #include "visual.h"
37 #include <math.h>
39 #include "fft.h"
40 #include "window.h"
42 #define PEAK_SPEED 1
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 /*****************************************************************************
50 * dummy_Run
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);
57 return 0;
60 static void dummy_Free( void *data )
62 VLC_UNUSED(data);
66 /*****************************************************************************
67 * spectrum_Run: spectrum analyser
68 *****************************************************************************/
69 typedef struct spectrum_data
71 int *peaks;
72 int *prev_heights;
74 unsigned i_prev_nb_samples;
75 int16_t *p_prev_s16_buff;
77 window_param wind_param;
78 } spectrum_data;
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 */
99 const int xscale2[] =
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};
105 const int *xscale;
107 fft_state *p_state; /* internal FFT data */
108 DEFINE_WIND_CONTEXT( wind_ctx ); /* internal window data */
110 int i , j , y , k;
111 int i_line;
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");
124 return -1;
127 /* Create p_data if needed */
128 if( !p_data )
130 p_effect->p_data = p_data = malloc( sizeof( spectrum_data ) );
131 if( !p_data )
132 return -1;
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 *
151 sizeof(int16_t));
152 p_data->i_prev_nb_samples = p_buffer->i_nb_samples;
153 if( !p_data->p_prev_s16_buff )
154 return -1;
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" );
161 if( i_80_bands != 0)
163 xscale = xscale2;
164 i_nb_bands = 80;
166 else
168 xscale = xscale1;
169 i_nb_bands = 20;
172 height = malloc( i_nb_bands * sizeof(int) );
173 if( !height )
175 return -1;
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();
190 if( !p_state)
192 free( height );
193 msg_Err(p_aout,"unable to initialize FFT transform");
194 return -1;
196 if( !window_init( FFT_BUFFER_SIZE, &p_data->wind_param, &wind_ctx ) )
198 fft_close( p_state );
199 free( height );
200 msg_Err(p_aout,"unable to initialize FFT window");
201 return -1;
203 p_buffs = p_s16_buff;
204 for ( i = 0 ; i < FFT_BUFFER_SIZE ; i++)
206 p_output[i] = 0;
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++ )
228 if ( p_dest[j] > y )
229 y = p_dest[j];
231 /* Calculate the height of the bar */
232 if( y != 0 )
234 height[i] = log( y ) * 30;
235 if( height[i] > 380 )
236 height[i] = 380;
238 else
239 height[ i ] = 0;
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];
254 if( peaks[i] < 0 )
256 peaks[i] = 0;
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;
272 i_line = peaks[i];
274 for( j = 0; j < i_band_width - 1; j++ )
276 for( k = 0; k < 3; k ++ )
278 /* Draw the peak */
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 ) )
283 = 0xff;
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 ) )
289 = 0x00;
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;
299 else
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 ) )
304 = 0xff;
306 else
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 ) )
312 = 0x10 ;
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 ) ) =
342 i_line - 0x0f;
343 else
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 ) ) =
348 0xff;
350 else
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 ) ) =
356 0x10;
362 window_close( &wind_ctx );
364 fft_close( p_state );
366 free( height );
368 return 0;
371 static void spectrum_Free( void *data )
373 spectrum_data *p_data = data;
375 if( p_data != NULL )
377 free( p_data->peaks );
378 free( p_data->prev_heights );
379 free( p_data->p_prev_s16_buff );
380 free( p_data );
385 /*****************************************************************************
386 * spectrometer_Run: derivative spectrum analysis
387 *****************************************************************************/
388 typedef struct
390 int *peaks;
392 unsigned i_prev_nb_samples;
393 int16_t *p_prev_s16_buff;
395 window_param wind_param;
396 } spectrometer_data;
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};
442 const int *xscale;
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 */
448 int i , j , k;
449 int i_line = 0;
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");
461 return -1;
464 /* Create the data struct if needed */
465 spectrometer_data *p_data = p_effect->p_data;
466 if( !p_data )
468 p_data = malloc( sizeof(spectrometer_data) );
469 if( !p_data )
470 return -1;
471 p_data->peaks = calloc( 80, sizeof(int) );
472 if( !p_data->peaks )
474 free( p_data );
475 return -1;
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 *
490 sizeof(int16_t));
491 p_data->i_prev_nb_samples = p_buffer->i_nb_samples;
492 if( !p_data->p_prev_s16_buff )
493 return -1;
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" );
510 if( i_80_bands != 0)
512 xscale = xscale2;
513 i_nb_bands = 80;
515 else
517 xscale = xscale1;
518 i_nb_bands = 20;
521 height = malloc( i_nb_bands * sizeof(int) );
522 if( !height)
523 return -1;
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();
538 if( !p_state)
540 msg_Err(p_aout,"unable to initialize FFT transform");
541 free( height );
542 return -1;
544 if( !window_init( FFT_BUFFER_SIZE, &p_data->wind_param, &wind_ctx ) )
546 fft_close( p_state );
547 free( height );
548 msg_Err(p_aout,"unable to initialize FFT window");
549 return -1;
551 p_buffs = p_s16_buff;
552 for ( i = 0 ; i < FFT_BUFFER_SIZE; i++)
554 p_output[i] = 0;
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++ )
576 if ( p_dest[j] > y )
577 y = p_dest[j];
579 /* Calculate the height of the bar */
580 y >>=7;/* remove some noise */
581 if( y != 0)
583 int logy = log(y);
584 height[i] = logy * y_scale;
585 if(height[i] > 150)
586 height[i] = 150;
588 else
590 height[i] = 0 ;
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];
607 if( peaks[i] < 0 )
609 peaks[i] = 0;
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;
619 i_line = peaks[i];
621 for( j = 0 ; j< i_band_width - i_separ; j++)
623 for( k = 0 ; k< 3 ; k ++)
625 //* Draw the peak
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) )
629 = 0xff;
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 ) )
635 = 0x00;
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 ;
645 else
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 ) )
650 = 0xff;
652 else
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 ) )
658 = 0x10 ;
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 ;
687 else
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 ) ) =
692 0xff;
694 else
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 ) ) =
700 0x10 ;
707 band_sep_angle = 360.0 / i_nb_bands;
708 section_sep_angle = 360.0 / i_sections;
709 if( i_peak_height < 1 )
710 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 )
715 i_band_width = 1;
717 for( c = 0 ; c < i_sections ; c++ )
718 for( i = 0 ; i < (i_nb_bands / i_sections) ; i++ )
720 /* DO A PEAK */
721 if( peaks[i] > 0 && i_peak )
723 if( peaks[i] >= p_effect->i_height )
724 peaks[i] = p_effect->i_height - 2;
725 i_line = peaks[i];
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;
733 xx = x;
734 yy = y;
735 for( k = 0 ; k < (i_band_width + i_extra_width) ; k++ )
737 x = xx;
738 y = yy;
739 a = ( (i+1) * band_sep_angle + section_sep_angle * (c+1) + k )
740 * 3.141592 / 180.0;
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); */
747 x /= 2;
748 y /= 2;
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); */
758 else
759 *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
760 ) = 255;/* V(R,G,B); */
762 else
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) )
782 * 3.141592 / 180.0;
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); */
789 x /= 2;
790 y /= 2;
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); */
800 else
801 *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
802 ) = 255;/* V(R,G,B); */
804 else
806 *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
807 ) = color1;/* V(R,G,B); */
811 /* DO A BAND */
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;
817 xx = x;
818 yy = y;
819 a = ( (i+1) * band_sep_angle + section_sep_angle * (c+1) + j )
820 * 3.141592/180.0;
822 for( k = (i_rad+1) ; k < max_band_length ; k++ )
824 if( (k-i_rad) > height[i] )
825 break;/* uhh.. */
827 x = xx;
828 y = yy;
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
833 ) = 255;
835 x /= 2;
836 y /= 2;
838 *(p_picture->p[1].p_pixels + x + y * p_picture->p[1].i_pitch
839 ) = 0;
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);
846 else
847 *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
848 ) = 255;
850 else
852 *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch
853 ) = color1;
859 window_close( &wind_ctx );
861 fft_close( p_state );
863 free( height );
865 return 0;
868 static void spectrometer_Free( void *data )
870 spectrometer_data *p_data = data;
872 if( p_data != NULL )
874 free( p_data->peaks );
875 free( p_data->p_prev_s16_buff );
876 free( p_data );
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)
887 VLC_UNUSED(p_aout);
889 int i_index;
890 float *p_sample ;
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 );
905 i_index++ )
907 int8_t i_value;
909 /* Left channel */
910 i_value = p_sample[p_effect->i_idx_left] * 127;
911 *(ppp_area[0][0]
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;
915 *(ppp_area[0][1]
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;
921 /* Right channel */
922 i_value = p_sample[p_effect->i_idx_right] * 127;
923 *(ppp_area[1][0]
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;
927 *(ppp_area[1][2]
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;
934 return 0;
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)
944 VLC_UNUSED(p_aout);
945 float i_value_l = 0;
946 float i_value_r = 0;
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;
952 float ch;
954 ch = p_sample[p_effect->i_idx_left] * 256;
955 if (ch > i_value_l)
956 i_value_l = ch;
958 ch = p_sample[p_effect->i_idx_right] * 256;
959 if (ch > i_value_r)
960 i_value_r = ch;
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;
974 float *i_value;
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;
984 else
986 /* Make the hands go down slowly if the current values are slower
987 than the previous */
988 i_value = p_effect->p_data;
990 if ( i_value_l > i_value[0] - 6 )
991 i_value[0] = i_value_l;
992 else
993 i_value[0] = i_value[0] - 6;
995 if ( i_value_r > i_value[1] - 6 )
996 i_value[1] = i_value_r;
997 else
998 i_value[1] = i_value[1] - 6;
1001 int x, y;
1002 float teta;
1003 float teta_grad;
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 */
1010 int k = 0;
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;
1022 k = k + 5;
1024 *(p_picture->p[0].p_pixels +
1025 (p_picture->p[0].i_lines - y - 1 ) * p_picture->p[0].i_pitch
1026 + x ) = 0x45;
1027 *(p_picture->p[1].p_pixels +
1028 (p_picture->p[1].i_lines - y / 2 - 1 ) * p_picture->p[1].i_pitch
1029 + x / 2 ) = 0x0;
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
1044 + x ) = 0xAD;
1045 *(p_picture->p[1].p_pixels +
1046 (p_picture->p[1].i_lines - y / 2 - 1 ) * p_picture->p[1].i_pitch
1047 + x / 2 ) = 0xFC;
1048 *(p_picture->p[2].p_pixels +
1049 (p_picture->p[2].i_lines - y / 2 - 1 ) * p_picture->p[2].i_pitch
1050 + x / 2 ) = 0xAC;
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
1062 + x ) = 0xFF;
1063 *(p_picture->p[1].p_pixels +
1064 (p_picture->p[1].i_lines - y / 2 - 1 ) * p_picture->p[1].i_pitch
1065 + x / 2 ) = 0x80;
1066 *(p_picture->p[2].p_pixels +
1067 (p_picture->p[2].i_lines - y / 2 - 1 ) * p_picture->p[2].i_pitch
1068 + x / 2 ) = 0x80;
1074 return 0;
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]);