Remove legacy parameter from add_string()
[vlc/asuraparaju-public.git] / modules / video_filter / audiobargraph_v.c
blob70754e0e3201e84ec82987e9d8fafb26208714c3
1 /*****************************************************************************
2 * audiobargraph_v.c : audiobargraph video plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2003-2006 the VideoLAN team
6 * Authors: Clement CHESNIN <clement.chesnin@gmail.com>
7 * Philippe COENT <philippe.coent@tdf.fr>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31 #include <string.h>
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_filter.h>
37 #include <vlc_image.h>
39 #ifdef LoadImage
40 # undef LoadImage
41 #endif
43 /*****************************************************************************
44 * Module descriptor
45 *****************************************************************************/
47 #define I_VALUES_TEXT N_("Value of the audio channels levels")
48 #define I_VALUES_LONGTEXT N_("Value of the audio level of each channels between 0 and 1" \
49 "Each level should be separated with ':'.")
50 #define POSX_TEXT N_("X coordinate")
51 #define POSX_LONGTEXT N_("X coordinate of the bargraph." )
52 #define POSY_TEXT N_("Y coordinate")
53 #define POSY_LONGTEXT N_("Y coordinate of the bargraph." )
54 #define TRANS_TEXT N_("Transparency of the bargraph")
55 #define TRANS_LONGTEXT N_("Bargraph transparency value " \
56 "(from 0 for full transparency to 255 for full opacity)." )
57 #define POS_TEXT N_("Bargraph position")
58 #define POS_LONGTEXT N_( \
59 "Enforce the bargraph position on the video " \
60 "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
61 "also use combinations of these values, eg 6 = top-right).")
62 #define ALARM_TEXT N_("Alarm")
63 #define ALARM_LONGTEXT N_("Signals a silence and displays and alert " \
64 "(0=no alarm, 1=alarm).")
65 #define BARWIDTH_TEXT N_("Bar width in pixel (default : 10)")
66 #define BARWIDTH_LONGTEXT N_("Width in pixel of each bar in the BarGraph to be displayed " \
67 "(default : 10).")
69 #define CFG_PREFIX "audiobargraph_v-"
71 static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
72 static const char *const ppsz_pos_descriptions[] =
73 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
74 N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
76 static int OpenSub ( vlc_object_t * );
77 static int OpenVideo( vlc_object_t * );
78 static void Close ( vlc_object_t * );
80 vlc_module_begin ()
82 set_category( CAT_VIDEO )
83 set_subcategory( SUBCAT_VIDEO_SUBPIC )
85 set_capability( "sub filter", 0 )
86 set_callbacks( OpenSub, Close )
87 set_description( N_("Audio Bar Graph Video sub filter") )
88 set_shortname( N_("Audio Bar Graph Video") )
89 add_shortcut( "audiobargraph_v" )
91 add_string( CFG_PREFIX "i_values", NULL, I_VALUES_TEXT, I_VALUES_LONGTEXT, false )
92 add_integer( CFG_PREFIX "x", 0, NULL, POSX_TEXT, POSX_LONGTEXT, true )
93 add_integer( CFG_PREFIX "y", 0, NULL, POSY_TEXT, POSY_LONGTEXT, true )
94 add_integer_with_range( CFG_PREFIX "transparency", 255, 0, 255, NULL,
95 TRANS_TEXT, TRANS_LONGTEXT, false )
96 add_integer( CFG_PREFIX "position", -1, NULL, POS_TEXT, POS_LONGTEXT, false )
97 change_integer_list( pi_pos_values, ppsz_pos_descriptions )
98 add_integer( CFG_PREFIX "alarm", 0, NULL, ALARM_TEXT, ALARM_LONGTEXT, true )
99 add_integer( CFG_PREFIX "barWidth", 10, NULL, BARWIDTH_TEXT, BARWIDTH_LONGTEXT, true )
101 /* video output filter submodule */
102 add_submodule ()
103 set_capability( "video filter2", 0 )
104 set_callbacks( OpenVideo, Close )
105 set_description( N_("Audio Bar Graph Video sub filter") )
106 add_shortcut( "audiobargraph_v" )
107 vlc_module_end ()
110 /*****************************************************************************
111 * Local prototypes
112 *****************************************************************************/
114 /*****************************************************************************
115 * Structure to hold the Bar Graph properties
116 ****************************************************************************/
117 typedef struct
119 int i_alpha; /* -1 means use default alpha */
120 int nbChannels;
121 int *i_values;
122 picture_t *p_pic;
123 mtime_t date;
124 int scale;
125 int alarm;
126 int barWidth;
128 } BarGraph_t;
131 * Private data holder
133 struct filter_sys_t
135 filter_t *p_blend;
137 vlc_mutex_t lock;
139 BarGraph_t p_BarGraph;
141 int i_pos;
142 int i_pos_x;
143 int i_pos_y;
144 bool b_absolute;
146 /* On the fly control variable */
147 bool b_spu_update;
150 static const char *const ppsz_filter_options[] = {
151 "i_values", "x", "y", "transparency", "position", "alarm", "barWidth", NULL
154 static const char *const ppsz_filter_callbacks[] = {
155 "audiobargraph_v-i_values",
156 "audiobargraph_v-x",
157 "audiobargraph_v-y",
158 "audiobargraph_v-transparency",
159 "audiobargraph_v-position",
160 "audiobargraph_v-alarm",
161 "audiobargraph_v-barWidth",
162 NULL
165 static int OpenCommon( vlc_object_t *, bool b_sub );
167 static subpicture_t *FilterSub( filter_t *, mtime_t );
168 static picture_t *FilterVideo( filter_t *, picture_t * );
170 static int BarGraphCallback( vlc_object_t *, char const *,
171 vlc_value_t, vlc_value_t, void * );
173 static void LoadBarGraph( vlc_object_t *, BarGraph_t *);
174 void parse_i_values( BarGraph_t *p_BarGraph, char *i_values);
177 * Open the sub filter
179 static int OpenSub( vlc_object_t *p_this )
181 return OpenCommon( p_this, true );
185 * Open the video filter
187 static int OpenVideo( vlc_object_t *p_this )
189 return OpenCommon( p_this, false );
193 * Common open function
195 static int OpenCommon( vlc_object_t *p_this, bool b_sub )
197 filter_t *p_filter = (filter_t *)p_this;
198 filter_sys_t *p_sys;
199 BarGraph_t *p_BarGraph;
200 char* i_values = NULL;
202 /* */
203 if( !b_sub && !es_format_IsSimilar( &p_filter->fmt_in, &p_filter->fmt_out ) )
205 msg_Err( p_filter, "Input and output format does not match" );
206 return VLC_EGENERIC;
210 /* */
211 p_filter->p_sys = p_sys = malloc( sizeof( *p_sys ) );
212 if( !p_sys )
213 return VLC_ENOMEM;
214 p_BarGraph = &(p_sys->p_BarGraph);
216 /* */
217 p_sys->p_blend = NULL;
218 if( !b_sub )
221 p_sys->p_blend = filter_NewBlend( VLC_OBJECT(p_filter),
222 &p_filter->fmt_in.video );
223 if( !p_sys->p_blend )
225 //free( p_BarGraph );
226 free( p_sys );
227 return VLC_EGENERIC;
231 /* */
232 config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
233 p_filter->p_cfg );
235 /* create and initialize variables */
236 p_sys->i_pos = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-position" );
237 p_sys->i_pos_x = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-x" );
238 p_sys->i_pos_y = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-y" );
239 p_BarGraph->i_alpha = var_CreateGetIntegerCommand( p_filter,
240 "audiobargraph_v-transparency" );
241 p_BarGraph->i_alpha = __MAX( __MIN( p_BarGraph->i_alpha, 255 ), 0 );
242 i_values = var_CreateGetStringCommand( p_filter, "audiobargraph_v-i_values" );
243 //p_BarGraph->nbChannels = 0;
244 //p_BarGraph->i_values = NULL;
245 parse_i_values(p_BarGraph, i_values);
246 p_BarGraph->alarm = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-alarm" );
247 p_BarGraph->barWidth = var_CreateGetIntegerCommand( p_filter, "audiobargraph_v-barWidth" );
248 p_BarGraph->scale = 400;
250 /* Ignore aligment if a position is given for video filter */
251 if( !b_sub && p_sys->i_pos_x >= 0 && p_sys->i_pos_y >= 0 )
252 p_sys->i_pos = 0;
254 vlc_mutex_init( &p_sys->lock );
255 LoadBarGraph( p_this, p_BarGraph );
256 p_sys->b_spu_update = true;
258 for( int i = 0; ppsz_filter_callbacks[i]; i++ )
259 var_AddCallback( p_filter, ppsz_filter_callbacks[i],
260 BarGraphCallback, p_sys );
262 /* Misc init */
263 if( b_sub )
265 p_filter->pf_sub_filter = FilterSub;
267 else
269 p_filter->pf_video_filter = FilterVideo;
272 free( i_values );
273 return VLC_SUCCESS;
277 * Common close function
279 static void Close( vlc_object_t *p_this )
281 filter_t *p_filter = (filter_t *)p_this;
282 filter_sys_t *p_sys = p_filter->p_sys;
283 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
285 for( int i = 0; ppsz_filter_callbacks[i]; i++ )
286 var_DelCallback( p_filter, ppsz_filter_callbacks[i],
287 BarGraphCallback, p_sys );
289 if( p_sys->p_blend )
290 filter_DeleteBlend( p_sys->p_blend );
292 vlc_mutex_destroy( &p_sys->lock );
294 if( p_BarGraph->p_pic )
296 picture_Release( p_BarGraph->p_pic );
297 p_BarGraph->p_pic = NULL;
299 free( p_BarGraph->i_values );
301 free( p_sys );
305 * Sub filter
307 static subpicture_t *FilterSub( filter_t *p_filter, mtime_t date )
309 filter_sys_t *p_sys = p_filter->p_sys;
310 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
312 subpicture_t *p_spu;
313 subpicture_region_t *p_region;
314 video_format_t fmt;
315 picture_t *p_pic;
317 vlc_mutex_lock( &p_sys->lock );
318 /* Basic test: b_spu_update occurs on a dynamic change */
319 if( !p_sys->b_spu_update )
321 vlc_mutex_unlock( &p_sys->lock );
322 return 0;
325 p_pic = p_BarGraph->p_pic;
327 /* Allocate the subpicture internal data. */
328 p_spu = filter_NewSubpicture( p_filter );
329 if( !p_spu )
330 goto exit;
332 p_spu->b_absolute = p_sys->b_absolute;
333 p_spu->i_start = date;
334 p_spu->i_stop = 0;
335 p_spu->b_ephemer = true;
337 /* Send an empty subpicture to clear the display when needed */
338 if( !p_pic || !p_BarGraph->i_alpha )
339 goto exit;
341 /* Create new SPU region */
342 memset( &fmt, 0, sizeof(video_format_t) );
343 fmt.i_chroma = VLC_CODEC_YUVA;
344 fmt.i_sar_num = fmt.i_sar_den = 1;
345 fmt.i_width = fmt.i_visible_width = p_pic->p[Y_PLANE].i_visible_pitch;
346 fmt.i_height = fmt.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines;
347 fmt.i_x_offset = fmt.i_y_offset = 0;
348 p_region = subpicture_region_New( &fmt );
349 if( !p_region )
351 msg_Err( p_filter, "cannot allocate SPU region" );
352 p_filter->pf_sub_buffer_del( p_filter, p_spu );
353 p_spu = NULL;
354 goto exit;
357 /* */
358 picture_Copy( p_region->p_picture, p_pic );
360 /* where to locate the bar graph: */
361 if( p_sys->i_pos < 0 )
362 { /* set to an absolute xy */
363 p_region->i_align = SUBPICTURE_ALIGN_RIGHT | SUBPICTURE_ALIGN_TOP;
364 p_spu->b_absolute = true;
366 else
367 { /* set to one of the 9 relative locations */
368 p_region->i_align = p_sys->i_pos;
369 p_spu->b_absolute = false;
372 p_region->i_x = p_sys->i_pos_x;
373 p_region->i_y = p_sys->i_pos_y;
375 p_spu->p_region = p_region;
377 p_spu->i_alpha = p_BarGraph->i_alpha ;
379 exit:
380 vlc_mutex_unlock( &p_sys->lock );
382 return p_spu;
386 * Video filter
388 static picture_t *FilterVideo( filter_t *p_filter, picture_t *p_src )
390 filter_sys_t *p_sys = p_filter->p_sys;
391 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
393 picture_t *p_dst = filter_NewPicture( p_filter );
394 if( !p_dst )
395 goto exit;
397 picture_Copy( p_dst, p_src );
399 /* */
400 vlc_mutex_lock( &p_sys->lock );
402 /* */
403 const picture_t *p_pic = p_BarGraph->p_pic;
404 if( p_pic )
406 const video_format_t *p_fmt = &p_pic->format;
407 const int i_dst_w = p_filter->fmt_out.video.i_visible_width;
408 const int i_dst_h = p_filter->fmt_out.video.i_visible_height;
410 if( p_sys->i_pos )
412 if( p_sys->i_pos & SUBPICTURE_ALIGN_BOTTOM )
414 p_sys->i_pos_y = i_dst_h - p_fmt->i_visible_height;
416 else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_TOP) )
418 p_sys->i_pos_y = ( i_dst_h - p_fmt->i_visible_height ) / 2;
420 else
422 p_sys->i_pos_y = 0;
425 if( p_sys->i_pos & SUBPICTURE_ALIGN_RIGHT )
427 p_sys->i_pos_x = i_dst_w - p_fmt->i_visible_width;
429 else if ( !(p_sys->i_pos & SUBPICTURE_ALIGN_LEFT) )
431 p_sys->i_pos_x = ( i_dst_w - p_fmt->i_visible_width ) / 2;
433 else
435 p_sys->i_pos_x = 0;
439 /* */
440 const int i_alpha = p_BarGraph->i_alpha;
441 if( filter_ConfigureBlend( p_sys->p_blend, i_dst_w, i_dst_h, p_fmt ) ||
442 filter_Blend( p_sys->p_blend, p_dst, p_sys->i_pos_x, p_sys->i_pos_y,
443 p_pic, i_alpha ) )
445 msg_Err( p_filter, "failed to blend a picture" );
448 vlc_mutex_unlock( &p_sys->lock );
450 exit:
451 picture_Release( p_src );
452 return p_dst;
455 /*****************************************************************************
456 * Callback to update params on the fly
457 *****************************************************************************/
458 static int BarGraphCallback( vlc_object_t *p_this, char const *psz_var,
459 vlc_value_t oldval, vlc_value_t newval, void *p_data )
461 VLC_UNUSED(oldval);
462 filter_sys_t *p_sys = (filter_sys_t *)p_data;
463 BarGraph_t *p_BarGraph = &(p_sys->p_BarGraph);
464 char* i_values;
465 char* res = NULL;
467 vlc_mutex_lock( &p_sys->lock );
468 if ( !strcmp( psz_var, "audiobargraph_v-x" ) )
470 p_sys->i_pos_x = newval.i_int;
472 else if ( !strcmp( psz_var, "audiobargraph_v-y" ) )
474 p_sys->i_pos_y = newval.i_int;
476 else if ( !strcmp( psz_var, "audiobargraph_v-position" ) )
478 p_sys->i_pos = newval.i_int;
480 else if ( !strcmp( psz_var, "audiobargraph_v-transparency" ) )
482 p_BarGraph->i_alpha = __MAX( __MIN( newval.i_int, 255 ), 0 );
484 else if ( !strcmp( psz_var, "audiobargraph_v-i_values" ) )
486 if( p_BarGraph->p_pic )
488 picture_Release( p_BarGraph->p_pic );
489 p_BarGraph->p_pic = NULL;
491 i_values = strdup( newval.psz_string );
492 free(p_BarGraph->i_values);
493 //p_BarGraph->i_values = NULL;
494 //p_BarGraph->nbChannels = 0;
495 // in case many answer are received at the same time, only keep one
496 res = strchr(i_values, '@');
497 if (res)
498 *res = 0;
499 parse_i_values( p_BarGraph, i_values);
500 LoadBarGraph(p_this,p_BarGraph);
502 else if ( !strcmp( psz_var, "audiobargraph_v-alarm" ) )
504 if( p_BarGraph->p_pic )
506 picture_Release( p_BarGraph->p_pic );
507 p_BarGraph->p_pic = NULL;
509 p_BarGraph->alarm = newval.i_int;
510 LoadBarGraph(p_this,p_BarGraph);
512 else if ( !strcmp( psz_var, "audiobargraph_v-barWidth" ) )
514 if( p_BarGraph->p_pic )
516 picture_Release( p_BarGraph->p_pic );
517 p_BarGraph->p_pic = NULL;
519 p_BarGraph->barWidth = newval.i_int;
520 LoadBarGraph(p_this,p_BarGraph);
522 p_sys->b_spu_update = true;
523 vlc_mutex_unlock( &p_sys->lock );
525 return VLC_SUCCESS;
528 /*****************************************************************************
529 * LoadImage: creates and returns the bar graph image
530 *****************************************************************************/
531 static picture_t *LoadImage( vlc_object_t *p_this, int nbChannels, int* i_values, int scale, int alarm, int barWidth)
533 VLC_UNUSED(p_this);
534 picture_t *p_pic;
535 int i,j;
536 int i_width = 0;
537 int i_line;
538 int moinsTrois, moinsCinq, moinsSept, moinsDix, moinsVingt;
540 if (nbChannels == 0) {
541 i_width = 20;
542 } else {
543 i_width = 2 * nbChannels * barWidth + 10;
546 moinsTrois = 0.71*scale + 20;
547 moinsCinq = 0.56*scale + 20;
548 moinsSept = 0.45*scale + 20;
549 moinsDix = 0.32*scale + 20;
550 moinsVingt = 0.1*scale + 20;
552 p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), i_width+20, scale+30, 1, 1);
554 // blacken the whole picture
555 for( i = 0 ; i < p_pic->i_planes ; i++ )
557 memset( p_pic->p[i].p_pixels, 0x00,
558 p_pic->p[i].i_visible_lines * p_pic->p[i].i_pitch );
561 // side bar
562 for ( i_line = 20; i_line < scale+20; i_line++ ) {
564 #define DrawPointsBlack(a,b) {\
565 for (i=a; i<b; i++) {\
566 *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = 0x00; \
567 *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = 128; \
568 *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = 128; \
569 *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = 0xFF; \
572 #define DrawPointsWhite(a,b) {\
573 for (i=a; i<b; i++) {\
574 *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = 0xFF;\
575 *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = 128;\
576 *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = 128;\
577 *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = 0xFF; \
581 // vertical line
582 DrawPointsBlack(20,22);
583 DrawPointsWhite(22,24);
585 // -3dB
586 if (i_line == moinsTrois - 2) {
587 // 3
588 DrawPointsBlack(16,19);
590 if (i_line == moinsTrois - 1) {
591 // 3
592 DrawPointsBlack(18,19);
593 // limit
594 DrawPointsWhite(24,27);
596 if (i_line == moinsTrois) {
597 // 3
598 DrawPointsBlack(16,19);
599 // limit
600 DrawPointsBlack(24,27);
602 if (i_line == moinsTrois + 1) {
603 // 3
604 DrawPointsBlack(18,19);
605 // limit
606 DrawPointsBlack(24,27);
608 if (i_line == moinsTrois + 2) {
609 // 3
610 DrawPointsBlack(16,19);
613 // -5dB
614 if (i_line == moinsCinq - 2) {
615 // 5
616 DrawPointsBlack(16,19);
618 if (i_line == moinsCinq - 1) {
619 // 5
620 DrawPointsBlack(18,19);
621 // limit
622 DrawPointsWhite(24,27);
624 if (i_line == moinsCinq) {
625 // 5
626 DrawPointsBlack(16,19);
627 // limit
628 DrawPointsBlack(24,27);
630 if (i_line == moinsCinq + 1) {
631 // 5
632 DrawPointsBlack(16,17);
633 // limit
634 DrawPointsBlack(24,27);
636 if (i_line == moinsCinq + 2) {
637 // 5
638 DrawPointsBlack(16,19);
641 // -7dB
642 if (i_line == moinsSept - 2) {
643 // 7
644 DrawPointsBlack(18,19);
646 if (i_line == moinsSept - 1) {
647 // 7
648 DrawPointsBlack(18,19);
649 // limit
650 DrawPointsWhite(24,27);
652 if (i_line == moinsSept) {
653 // 7
654 DrawPointsBlack(18,19);
655 // limit
656 DrawPointsBlack(24,27);
658 if (i_line == moinsSept + 1) {
659 // 7
660 DrawPointsBlack(18,19);
661 // limit
662 DrawPointsBlack(24,27);
664 if (i_line == moinsSept + 2) {
665 // 7
666 DrawPointsBlack(16,19);
670 // -10dB
671 if (i_line == moinsDix - 2) {
672 // 1
673 DrawPointsBlack(14,15);
674 // 0
675 DrawPointsBlack(16,19);
677 if (i_line == moinsDix - 1) {
678 // 1
679 DrawPointsBlack(14,15);
680 // 0
681 DrawPointsBlack(16,17);
682 DrawPointsBlack(18,19);
683 // limit
684 DrawPointsWhite(24,27);
686 if (i_line == moinsDix) {
687 // 1
688 DrawPointsBlack(14,15);
689 // 0
690 DrawPointsBlack(16,17);
691 DrawPointsBlack(18,19);
692 // limit
693 DrawPointsBlack(24,27);
695 if (i_line == moinsDix + 1) {
696 // 1
697 DrawPointsBlack(14,15);
698 // 0
699 DrawPointsBlack(16,17);
700 DrawPointsBlack(18,19);
701 // limit
702 DrawPointsBlack(24,27);
704 if (i_line == moinsDix + 2) {
705 // 1
706 DrawPointsBlack(14,15);
707 // 0
708 DrawPointsBlack(16,19);
711 // -20dB
712 if (i_line == moinsVingt - 2) {
713 // 2
714 DrawPointsBlack(12,15);
715 // 0
716 DrawPointsBlack(16,19);
718 if (i_line == moinsVingt - 1) {
719 // 2
720 DrawPointsBlack(12,13);
721 // 0
722 DrawPointsBlack(16,17);
723 DrawPointsBlack(18,19);
724 // limit
725 DrawPointsWhite(24,27);
727 if (i_line == moinsVingt) {
728 // 2
729 DrawPointsBlack(12,15);
730 // 0
731 DrawPointsBlack(16,17);
732 DrawPointsBlack(18,19);
733 // limit
734 DrawPointsBlack(24,27);
736 if (i_line == moinsVingt + 1) {
737 // 2
738 DrawPointsBlack(14,15);
739 // 0
740 DrawPointsBlack(16,17);
741 DrawPointsBlack(18,19);
742 // limit
743 DrawPointsBlack(24,27);
745 if (i_line == moinsVingt + 2) {
746 // 2
747 DrawPointsBlack(12,15);
748 // 0
749 DrawPointsBlack(16,19);
755 // draw the bars and channel indicators
756 for (i=0; i<nbChannels; i++) {
757 for( j = barWidth+20 ; j < 2*barWidth+20; j++)
759 // channel indicators
760 for ( i_line = 12; i_line < 18; i_line++ ) {
761 // white
762 *(p_pic->p[0].p_pixels +
763 (scale + 30 - i_line - 1) *
764 p_pic->p[0].i_pitch +
765 ( (2*i*barWidth)+j ) ) = 255;
766 *(p_pic->p[1].p_pixels +
767 (scale + 30 - i_line - 1) *
768 p_pic->p[1].i_pitch +
769 ( (2*i*barWidth)+j ) ) = 128;
770 *(p_pic->p[2].p_pixels +
771 (scale + 30 - i_line - 1) *
772 p_pic->p[2].i_pitch +
773 ( (2*i*barWidth)+j ) ) = 128;
774 *(p_pic->p[3].p_pixels +
775 (scale + 30 - i_line - 1) *
776 p_pic->p[3].i_pitch +
777 ( (2*i*barWidth)+j )) = 0xFF;
779 // bars
780 for( i_line = 20; i_line < i_values[i]+20; i_line++ )
782 if (i_line < moinsDix) { // green if < -10 dB
783 *(p_pic->p[0].p_pixels +
784 (scale + 30 - i_line - 1) *
785 p_pic->p[0].i_pitch +
786 ( (2*i*barWidth)+j ) ) = 150;
787 *(p_pic->p[1].p_pixels +
788 (scale + 30 - i_line - 1) *
789 p_pic->p[1].i_pitch +
790 ( (2*i*barWidth)+j ) ) = 44;
791 *(p_pic->p[2].p_pixels +
792 (scale + 30 - i_line - 1) *
793 p_pic->p[2].i_pitch +
794 ( (2*i*barWidth)+j ) ) = 21;
795 *(p_pic->p[3].p_pixels +
796 (scale + 30 - i_line - 1) *
797 p_pic->p[3].i_pitch +
798 ( (2*i*barWidth)+j )) = 0xFF;
799 } else if (i_line < moinsTrois) { // yellow if > -10dB and < -3dB
800 *(p_pic->p[0].p_pixels +
801 (scale + 30 - i_line - 1) *
802 p_pic->p[0].i_pitch +
803 ( (2*i*barWidth)+j ) ) = 226;
804 *(p_pic->p[1].p_pixels +
805 (scale + 30 - i_line - 1) *
806 p_pic->p[1].i_pitch +
807 ( (2*i*barWidth)+j ) ) = 1;
808 *(p_pic->p[2].p_pixels +
809 (scale + 30 - i_line - 1) *
810 p_pic->p[2].i_pitch +
811 ( (2*i*barWidth)+j ) ) = 148;
812 *(p_pic->p[3].p_pixels +
813 (scale + 30 - i_line - 1) *
814 p_pic->p[3].i_pitch +
815 ( (2*i*barWidth)+j )) = 0xFF;
816 } else { // red if > -3 dB
817 *(p_pic->p[0].p_pixels +
818 (scale + 30 - i_line - 1) *
819 p_pic->p[0].i_pitch +
820 ( (2*i*barWidth)+j ) ) = 76;
821 *(p_pic->p[1].p_pixels +
822 (scale + 30 - i_line - 1) *
823 p_pic->p[1].i_pitch +
824 ( (2*i*barWidth)+j ) ) = 85;
825 *(p_pic->p[2].p_pixels +
826 (scale + 30 - i_line - 1) *
827 p_pic->p[2].i_pitch +
828 ( (2*i*barWidth)+j ) ) = 0xFF;
829 *(p_pic->p[3].p_pixels +
830 (scale + 30 - i_line - 1) *
831 p_pic->p[3].i_pitch +
832 ( (2*i*barWidth)+j )) = 0xFF;
840 if (alarm) {// draw the alarm square
841 // bottom
842 for ( i_line = 0; i_line < 10; i_line++ ) {
843 for (i=0; i<i_width+20; i++) {
844 *(p_pic->p[0].p_pixels +
845 (scale + 30 - i_line - 1) *
846 p_pic->p[0].i_pitch + i ) = 76;
847 *(p_pic->p[1].p_pixels +
848 (scale + 30 - i_line - 1) *
849 p_pic->p[1].i_pitch + i ) = 85;
850 *(p_pic->p[2].p_pixels +
851 (scale + 30 - i_line - 1) *
852 p_pic->p[2].i_pitch + i ) = 0xFF;
853 *(p_pic->p[3].p_pixels +
854 (scale + 30 - i_line - 1) *
855 p_pic->p[3].i_pitch + i ) = 0xFF;
858 // top
859 for ( i_line = scale+21; i_line < scale+30; i_line++ ) {
860 for (i=0; i<i_width+20; i++) {
861 *(p_pic->p[0].p_pixels +
862 (scale + 30 - i_line - 1) *
863 p_pic->p[0].i_pitch + i ) = 76;
864 *(p_pic->p[1].p_pixels +
865 (scale + 30 - i_line - 1) *
866 p_pic->p[1].i_pitch + i ) = 85;
867 *(p_pic->p[2].p_pixels +
868 (scale + 30 - i_line - 1) *
869 p_pic->p[2].i_pitch + i ) = 0xFF;
870 *(p_pic->p[3].p_pixels +
871 (scale + 30 - i_line - 1) *
872 p_pic->p[3].i_pitch + i ) = 0xFF;
875 // sides
876 for ( i_line = 9; i_line < scale+21; i_line++ ) {
877 for (i=0; i<10; i++) {
878 *(p_pic->p[0].p_pixels +
879 (scale + 30 - i_line - 1) *
880 p_pic->p[0].i_pitch + i ) = 76;
881 *(p_pic->p[1].p_pixels +
882 (scale + 30 - i_line - 1) *
883 p_pic->p[1].i_pitch + i ) = 85;
884 *(p_pic->p[2].p_pixels +
885 (scale + 30 - i_line - 1) *
886 p_pic->p[2].i_pitch + i ) = 0xFF;
887 *(p_pic->p[3].p_pixels +
888 (scale + 30 - i_line - 1) *
889 p_pic->p[3].i_pitch + i ) = 0xFF;
891 for (i=i_width+11; i<i_width+20; i++) {
892 *(p_pic->p[0].p_pixels +
893 (scale + 30 - i_line - 1) *
894 p_pic->p[0].i_pitch + i ) = 76;
895 *(p_pic->p[1].p_pixels +
896 (scale + 30 - i_line - 1) *
897 p_pic->p[1].i_pitch + i ) = 85;
898 *(p_pic->p[2].p_pixels +
899 (scale + 30 - i_line - 1) *
900 p_pic->p[2].i_pitch + i ) = 0xFF;
901 *(p_pic->p[3].p_pixels +
902 (scale + 30 - i_line - 1) *
903 p_pic->p[3].i_pitch + i ) = 0xFF;
909 return p_pic;
912 /*****************************************************************************
913 * LoadBarGraph: loads the BarGraph images into memory
914 *****************************************************************************/
915 static void LoadBarGraph( vlc_object_t *p_this, BarGraph_t *p_BarGraph )
918 p_BarGraph->p_pic = LoadImage( p_this, p_BarGraph->nbChannels, p_BarGraph->i_values, p_BarGraph->scale, p_BarGraph->alarm, p_BarGraph->barWidth);
919 if( !p_BarGraph->p_pic )
921 msg_Warn( p_this, "error while creating picture" );
926 /*****************************************************************************
927 * parse_i_values : parse i_values parameter and store the corresponding values
928 *****************************************************************************/
929 void parse_i_values( BarGraph_t *p_BarGraph, char *i_values)
931 char* res = NULL;
932 char delim[] = ":";
933 char* tok;
935 p_BarGraph->nbChannels = 0;
936 p_BarGraph->i_values = NULL;
937 res = strtok_r(i_values, delim, &tok);
938 while (res != NULL) {
939 p_BarGraph->nbChannels++;
940 p_BarGraph->i_values = xrealloc(p_BarGraph->i_values,
941 p_BarGraph->nbChannels*sizeof(int));
942 p_BarGraph->i_values[p_BarGraph->nbChannels-1] = __MAX( __MIN( atof(res)*p_BarGraph->scale, p_BarGraph->scale ), 0 );
943 res = strtok_r(NULL, delim, &tok);