1 /*****************************************************************************
2 * scope.c : Scope effect module
3 *****************************************************************************
4 * Copyright (C) 2002 VideoLAN
5 * $Id: scope.c,v 1.5 2002/03/18 19:14:52 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
28 #include <string.h> /* strdup() */
31 #include <videolan/vlc.h>
34 #include "video_output.h"
36 #include "audio_output.h" /* aout_thread_t */
38 #define SCOPE_WIDTH 320
39 #define SCOPE_HEIGHT 240
40 #define SCOPE_ASPECT (VOUT_ASPECT_FACTOR*SCOPE_WIDTH/SCOPE_HEIGHT)
42 /*****************************************************************************
43 * Capabilities defined in the other files.
44 *****************************************************************************/
45 static void aout_getfunctions( function_list_t
* p_function_list
);
47 /*****************************************************************************
48 * aout_sys_t: scope audio output method descriptor
49 *****************************************************************************
50 * This structure is part of the audio output thread descriptor.
51 * It describes some scope specific variables.
52 *****************************************************************************/
53 typedef struct aout_sys_s
55 struct aout_thread_s aout
;
56 struct aout_fifo_s
*p_aout_fifo
;
58 struct vout_thread_s
*p_vout
;
62 /*****************************************************************************
63 * Build configuration tree.
64 *****************************************************************************/
69 SET_DESCRIPTION( "scope effect module" )
70 ADD_CAPABILITY( AOUT
, 0 )
71 ADD_SHORTCUT( "scope" )
75 aout_getfunctions( &p_module
->p_functions
->aout
);
78 MODULE_DEACTIVATE_START
79 MODULE_DEACTIVATE_STOP
81 /*****************************************************************************
83 *****************************************************************************/
84 static int aout_Open ( aout_thread_t
*p_aout
);
85 static int aout_SetFormat ( aout_thread_t
*p_aout
);
86 static int aout_GetBufInfo ( aout_thread_t
*p_aout
, int i_buffer_info
);
87 static void aout_Play ( aout_thread_t
*p_aout
,
88 byte_t
*buffer
, int i_size
);
89 static void aout_Close ( aout_thread_t
*p_aout
);
91 /*****************************************************************************
92 * Functions exported as capabilities. They are declared as static so that
93 * we don't pollute the namespace too much.
94 *****************************************************************************/
95 static void aout_getfunctions( function_list_t
* p_function_list
)
97 p_function_list
->functions
.aout
.pf_open
= aout_Open
;
98 p_function_list
->functions
.aout
.pf_setformat
= aout_SetFormat
;
99 p_function_list
->functions
.aout
.pf_getbufinfo
= aout_GetBufInfo
;
100 p_function_list
->functions
.aout
.pf_play
= aout_Play
;
101 p_function_list
->functions
.aout
.pf_close
= aout_Close
;
104 /*****************************************************************************
105 * aout_Open: open a scope effect plugin
106 *****************************************************************************/
107 static int aout_Open( aout_thread_t
*p_aout
)
111 /* Allocate structure */
112 p_aout
->p_sys
= malloc( sizeof( aout_sys_t
) );
113 if( p_aout
->p_sys
== NULL
)
115 intf_ErrMsg("error: %s", strerror(ENOMEM
) );
119 psz_method
= config_GetPszVariable( "aout" );
133 /* Open video output */
134 p_aout
->p_sys
->p_vout
=
135 vout_CreateThread( NULL
, SCOPE_WIDTH
, SCOPE_HEIGHT
,
136 FOURCC_I420
, SCOPE_ASPECT
);
138 if( p_aout
->p_sys
->p_vout
== NULL
)
140 intf_ErrMsg( "aout scope error: no suitable vout module" );
141 free( p_aout
->p_sys
);
145 /* Open audio output */
146 p_aout
->p_sys
->aout
.i_format
= p_aout
->i_format
;
147 p_aout
->p_sys
->aout
.i_rate
= p_aout
->i_rate
;
148 p_aout
->p_sys
->aout
.i_channels
= p_aout
->i_channels
;
150 p_aout
->p_sys
->aout
.p_module
= module_Need( MODULE_CAPABILITY_AOUT
, "",
151 (void *)&p_aout
->p_sys
->aout
);
152 if( p_aout
->p_sys
->aout
.p_module
== NULL
)
154 intf_ErrMsg( "aout scope error: no suitable aout module" );
155 vout_DestroyThread( p_aout
->p_sys
->p_vout
, NULL
);
156 free( p_aout
->p_sys
);
160 #define aout_functions p_aout->p_sys->aout.p_module->p_functions->aout.functions.aout
161 p_aout
->p_sys
->aout
.pf_open
= aout_functions
.pf_open
;
162 p_aout
->p_sys
->aout
.pf_setformat
= aout_functions
.pf_setformat
;
163 p_aout
->p_sys
->aout
.pf_getbufinfo
= aout_functions
.pf_getbufinfo
;
164 p_aout
->p_sys
->aout
.pf_play
= aout_functions
.pf_play
;
165 p_aout
->p_sys
->aout
.pf_close
= aout_functions
.pf_close
;
166 #undef aout_functions
171 /*****************************************************************************
172 * aout_SetFormat: set the output format
173 *****************************************************************************/
174 static int aout_SetFormat( aout_thread_t
*p_aout
)
178 /* Force the output method */
179 p_aout
->p_sys
->aout
.i_format
= p_aout
->i_format
;
180 p_aout
->p_sys
->aout
.i_channels
= p_aout
->i_channels
;
181 p_aout
->p_sys
->aout
.i_rate
= p_aout
->i_rate
;
184 * Initialize audio device
186 i_ret
= p_aout
->p_sys
->aout
.pf_setformat( &p_aout
->p_sys
->aout
);
193 if( p_aout
->p_sys
->aout
.i_format
!= p_aout
->i_format
194 || p_aout
->p_sys
->aout
.i_channels
!= p_aout
->i_channels
)
196 intf_ErrMsg( "aout error: plugin isn't cooperative" );
200 p_aout
->i_channels
= p_aout
->p_sys
->aout
.i_channels
;
201 p_aout
->i_format
= p_aout
->p_sys
->aout
.i_format
;
202 p_aout
->i_rate
= p_aout
->p_sys
->aout
.i_rate
;
207 /*****************************************************************************
208 * aout_GetBufInfo: buffer status query
209 *****************************************************************************/
210 static int aout_GetBufInfo( aout_thread_t
*p_aout
, int i_buffer_limit
)
212 return p_aout
->p_sys
->aout
.pf_getbufinfo( &p_aout
->p_sys
->aout
,
216 /*****************************************************************************
217 * aout_Play: play a sound samples buffer
218 *****************************************************************************
219 * This function writes a buffer of i_length bytes in the socket
220 *****************************************************************************/
221 static void aout_Play( aout_thread_t
*p_aout
, byte_t
*p_buffer
, int i_size
)
224 int i_index
, i_image
;
228 /* Play the real sound */
229 p_aout
->p_sys
->aout
.pf_play( &p_aout
->p_sys
->aout
, p_buffer
, i_size
);
231 for( i_image
= 0; (i_image
+ 1) * SCOPE_WIDTH
* 8 < i_size
; i_image
++ )
233 /* Don't stay here forever */
234 if( mdate() >= p_aout
->date
- 10000 )
239 /* This is a new frame. Get a structure from the video_output. */
240 while( ( p_outpic
= vout_CreatePicture( p_aout
->p_sys
->p_vout
, 0, 0, 0 ) )
247 msleep( VOUT_OUTMEM_SLEEP
);
250 /* Blank the picture */
251 for( i_index
= 0 ; i_index
< p_outpic
->i_planes
; i_index
++ )
253 memset( p_outpic
->p
[i_index
].p_pixels
, i_index
? 0x80 : 0x00,
254 p_outpic
->p
[i_index
].i_lines
* p_outpic
->p
[i_index
].i_pitch
);
257 /* We only support 2 channels for now */
258 for( i_index
= 0 ; i_index
< 2 ; i_index
++ )
261 for( j
= 0 ; j
< 3 ; j
++ )
263 ppp_area
[i_index
][j
] =
264 p_outpic
->p
[j
].p_pixels
+ i_index
* p_outpic
->p
[j
].i_lines
265 / p_aout
->i_channels
* p_outpic
->p
[j
].i_pitch
;
269 for( i_index
= 0, p_sample
= (u16
*)p_buffer
;
270 i_index
< SCOPE_WIDTH
;
276 for( i
= 0 ; i
< 2 ; i
++ )
279 i_value
= *p_sample
++ / 256 + 128;
281 + p_outpic
->p
[0].i_pitch
* i_index
/ SCOPE_WIDTH
282 + p_outpic
->p
[0].i_lines
* i_value
/ 512
283 * p_outpic
->p
[0].i_pitch
) = 0xbf;
285 + p_outpic
->p
[1].i_pitch
* i_index
/ SCOPE_WIDTH
286 + p_outpic
->p
[1].i_lines
* i_value
/ 512
287 * p_outpic
->p
[1].i_pitch
) = 0xff;
290 i_value
= *p_sample
++ / 256 + 128;
292 + p_outpic
->p
[0].i_pitch
* i_index
/ SCOPE_WIDTH
293 + p_outpic
->p
[0].i_lines
* i_value
/ 512
294 * p_outpic
->p
[0].i_pitch
) = 0x9f;
296 + p_outpic
->p
[2].i_pitch
* i_index
/ SCOPE_WIDTH
297 + p_outpic
->p
[2].i_lines
* i_value
/ 512
298 * p_outpic
->p
[2].i_pitch
) = 0xdd;
302 /* Display the picture - FIXME: find a better date :-) */
303 vout_DatePicture( p_aout
->p_sys
->p_vout
, p_outpic
,
304 p_aout
->date
+ i_image
* 20000 );
305 vout_DisplayPicture( p_aout
->p_sys
->p_vout
, p_outpic
);
307 p_buffer
+= SCOPE_WIDTH
* 4;
311 /*****************************************************************************
312 * aout_Close: close the Esound socket
313 *****************************************************************************/
314 static void aout_Close( aout_thread_t
*p_aout
)
316 p_aout
->p_sys
->aout
.pf_close( &p_aout
->p_sys
->aout
);
317 module_Unneed( p_aout
->p_sys
->aout
.p_module
);
318 vout_DestroyThread( p_aout
->p_sys
->p_vout
, NULL
);
319 free( p_aout
->p_sys
);