Mercurial > mplayer.hg
annotate libao2/ao_plugin.c @ 6295:3368f774d9a4
use offsets/pitches for OSD too
author | arpi |
---|---|
date | Mon, 03 Jun 2002 22:29:49 +0000 |
parents | 2eec40929570 |
children | 76baa05a63ab |
rev | line source |
---|---|
6237 | 1 #include "../config.h" |
2 | |
3096 | 3 #include <stdio.h> |
4 #include <stdlib.h> | |
6237 | 5 #include <string.h> |
3096 | 6 |
3194
1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
anders
parents:
3107
diff
changeset
|
7 #include "afmt.h" |
3096 | 8 #include "audio_out.h" |
9 #include "audio_out_internal.h" | |
10 | |
11 #include "audio_plugin.h" | |
12 | |
13 static ao_info_t info = | |
14 { | |
15 "Plugin audio output", | |
16 "plugin", | |
17 "Anders", | |
18 "" | |
19 }; | |
20 | |
21 LIBAO_EXTERN(plugin) | |
22 | |
3107 | 23 #define plugin(i) (ao_plugin_local_data.plugins[i]) |
24 #define driver() (ao_plugin_local_data.driver) | |
3096 | 25 |
3107 | 26 // local data |
3096 | 27 typedef struct ao_plugin_local_data_s |
28 { | |
4313 | 29 void* buf; // Output data buffer |
30 int len; // Amount of data in buffer | |
6027
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
31 int channels; |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
32 int format; |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
33 int bpm; //bit of format |
4313 | 34 float bps; // Bytes per second out |
35 ao_functions_t* driver; // Output driver | |
3107 | 36 ao_plugin_functions_t** plugins; // List of used plugins |
3194
1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
anders
parents:
3107
diff
changeset
|
37 ao_plugin_functions_t* available_plugins[NPL]; // List of available plugins |
3096 | 38 } ao_plugin_local_data_t; |
39 | |
6027
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
40 static ao_plugin_local_data_t ao_plugin_local_data={NULL,0,0,0,0,0.0,NULL,NULL,AO_PLUGINS}; |
3096 | 41 |
4313 | 42 // global data |
4896 | 43 volatile ao_plugin_data_t ao_plugin_data; // Data used by the plugins |
4859 | 44 ao_plugin_cfg_t ao_plugin_cfg=CFG_DEFAULTS; // Set in cfg-mplayer.h |
3096 | 45 |
46 // to set/get/query special features/parameters | |
47 static int control(int cmd,int arg){ | |
3107 | 48 switch(cmd){ |
49 case AOCONTROL_SET_PLUGIN_DRIVER: | |
50 ao_plugin_local_data.driver=(ao_functions_t*)arg; | |
51 return CONTROL_OK; | |
4859 | 52 case AOCONTROL_GET_VOLUME: |
53 case AOCONTROL_SET_VOLUME: | |
54 { | |
55 int r=audio_plugin_volume.control(cmd,arg); | |
56 if(CONTROL_OK != r) | |
57 return driver()->control(cmd,arg); | |
58 else | |
59 return r; | |
60 } | |
3107 | 61 default: |
62 return driver()->control(cmd,arg); | |
63 } | |
64 return CONTROL_UNKNOWN; | |
65 } | |
66 | |
67 // Recursive function for adding plugins | |
68 // return 1 for success and 0 for error | |
69 int add_plugin(int i,char* cfg){ | |
70 int cnt=0; | |
71 // Find end of plugin name | |
72 while((cfg[cnt]!=',')&&(cfg[cnt]!='\0')&&(cnt<100)) cnt++; | |
73 if(cnt >= 100) | |
74 return 0; | |
75 | |
3680 | 76 // Is this the last iteration or just another plugin |
3107 | 77 if(cfg[cnt]=='\0'){ |
5773 | 78 ao_plugin_local_data.plugins=malloc((i+2)*sizeof(ao_plugin_functions_t*)); |
3107 | 79 if(ao_plugin_local_data.plugins){ |
80 ao_plugin_local_data.plugins[i+1]=NULL; | |
81 // Find the plugin matching the cfg string name | |
82 cnt=0; | |
83 while(ao_plugin_local_data.available_plugins[cnt] && cnt<20){ | |
84 if(0==strcmp(ao_plugin_local_data.available_plugins[cnt]->info->short_name,cfg)){ | |
85 ao_plugin_local_data.plugins[i]=ao_plugin_local_data.available_plugins[cnt]; | |
86 return 1; | |
87 } | |
88 cnt++; | |
89 } | |
90 printf("[plugin]: Invalid plugin: %s \n",cfg); | |
91 return 0; | |
92 } | |
93 else | |
94 return 0; | |
95 } else { | |
96 cfg[cnt]='\0'; | |
97 if(add_plugin(i+1,&cfg[cnt+1])){ | |
98 cnt=0; | |
99 // Find the plugin matching the cfg string name | |
100 while(ao_plugin_local_data.available_plugins[cnt] && cnt < 20){ | |
101 if(0==strcmp(ao_plugin_local_data.available_plugins[cnt]->info->short_name,cfg)){ | |
102 ao_plugin_local_data.plugins[i]=ao_plugin_local_data.available_plugins[cnt]; | |
103 return 1; | |
104 } | |
105 cnt++; | |
106 } | |
107 printf("[plugin]: Invalid plugin: %s \n",cfg); | |
108 return 0; | |
109 } | |
110 else | |
111 return 0; | |
112 } | |
113 return 0; // Will never happen... | |
3096 | 114 } |
115 | |
116 // open & setup audio device and plugins | |
117 // return: 1=success 0=fail | |
118 static int init(int rate,int channels,int format,int flags){ | |
119 int ok=1; | |
120 | |
4313 | 121 // Create list of plugins from cfg option |
3096 | 122 int i=0; |
3194
1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
anders
parents:
3107
diff
changeset
|
123 if(ao_plugin_cfg.plugin_list){ |
1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
anders
parents:
3107
diff
changeset
|
124 if(!add_plugin(i,ao_plugin_cfg.plugin_list)) |
3107 | 125 return 0; |
126 } | |
3096 | 127 |
128 /* Set input parameters and itterate through plugins each plugin | |
129 changes the parameters according to its output */ | |
6027
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
130 |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
131 ao_plugin_local_data.format=format; |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
132 ao_plugin_local_data.channels=channels; |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
133 ao_plugin_local_data.bpm=audio_out_format_bits(format); |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
134 |
3096 | 135 ao_plugin_data.rate=rate; |
136 ao_plugin_data.channels=channels; | |
137 ao_plugin_data.format=format; | |
138 ao_plugin_data.sz_mult=1; | |
139 ao_plugin_data.sz_fix=0; | |
140 ao_plugin_data.delay_mult=1; | |
141 ao_plugin_data.delay_fix=0; | |
142 i=0; | |
143 while(plugin(i)&&ok) | |
144 ok=plugin(i++)->init(); | |
145 | |
146 if(!ok) return 0; | |
147 | |
4313 | 148 // Calculate bps |
149 ao_plugin_local_data.bps=(float)(ao_plugin_data.rate * | |
150 ao_plugin_data.channels); | |
6027
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
151 ao_plugin_local_data.bps*=audio_out_format_bits(ao_plugin_data.format)/8; |
4313 | 152 |
3107 | 153 // This should never happen but check anyway |
154 if(NULL==ao_plugin_local_data.driver) | |
155 return 0; | |
156 | |
3096 | 157 ok = driver()->init(ao_plugin_data.rate, |
3107 | 158 ao_plugin_data.channels, |
159 ao_plugin_data.format, | |
160 flags); | |
3096 | 161 if(!ok) return 0; |
162 | |
163 /* Now that the driver is initialized we can calculate and set the | |
164 input and output buffers for each plugin */ | |
165 ao_plugin_data.len=driver()->get_space(); | |
3107 | 166 while((i>0) && ok) |
3194
1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
anders
parents:
3107
diff
changeset
|
167 ok=plugin(--i)->control(AOCONTROL_PLUGIN_SET_LEN,0); |
3107 | 168 |
169 if(!ok) return 0; | |
3096 | 170 |
4374
0a95c5074c50
Fixed sig 11 caused by resampling plugin, some cosmetic changes and speed improvements
anders
parents:
4313
diff
changeset
|
171 // Allocate output buffer |
4313 | 172 if(ao_plugin_local_data.buf) |
173 free(ao_plugin_local_data.buf); | |
174 ao_plugin_local_data.buf=malloc(MAX_OUTBURST); | |
175 | |
176 if(!ao_plugin_local_data.buf) return 0; | |
177 | |
3096 | 178 return 1; |
179 } | |
180 | |
181 // close audio device | |
182 static void uninit(){ | |
183 int i=0; | |
184 driver()->uninit(); | |
185 while(plugin(i)) | |
186 plugin(i++)->uninit(); | |
3107 | 187 if(ao_plugin_local_data.plugins) |
188 free(ao_plugin_local_data.plugins); | |
5050 | 189 ao_plugin_local_data.plugins=NULL; |
4313 | 190 if(ao_plugin_local_data.buf) |
191 free(ao_plugin_local_data.buf); | |
5050 | 192 ao_plugin_local_data.buf=NULL; |
3096 | 193 } |
194 | |
195 // stop playing and empty buffers (for seeking/pause) | |
196 static void reset(){ | |
197 int i=0; | |
198 driver()->reset(); | |
199 while(plugin(i)) | |
200 plugin(i++)->reset(); | |
4313 | 201 ao_plugin_local_data.len=0; |
3096 | 202 } |
203 | |
204 // stop playing, keep buffers (for pause) | |
205 static void audio_pause(){ | |
206 driver()->pause(); | |
207 } | |
208 | |
209 // resume playing, after audio_pause() | |
210 static void audio_resume(){ | |
211 driver()->resume(); | |
212 } | |
213 | |
214 // return: how many bytes can be played without blocking | |
215 static int get_space(){ | |
6027
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
216 double sz; |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
217 int isz; |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
218 sz=(double)(driver()->get_space()); |
4313 | 219 if(sz+(double)ao_plugin_local_data.len > (double)MAX_OUTBURST) |
220 sz=(double)MAX_OUTBURST-(double)ao_plugin_local_data.len; | |
3096 | 221 sz*=ao_plugin_data.sz_mult; |
222 sz+=ao_plugin_data.sz_fix; | |
6027
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
223 isz=(int)(sz); |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
224 isz-=isz%(ao_plugin_local_data.channels*ao_plugin_local_data.bpm/8); |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
225 return isz; |
3096 | 226 } |
227 | |
228 // plays 'len' bytes of 'data' | |
229 // return: number of bytes played | |
230 static int play(void* data,int len,int flags){ | |
4313 | 231 int l,i=0; |
232 // Limit length to avoid over flow in plugins | |
4922 | 233 int tmp = get_space(); |
3096 | 234 int ret_len =(tmp<len)?tmp:len; |
4375 | 235 if(ret_len){ |
236 // Filter data | |
237 ao_plugin_data.len=ret_len; | |
238 ao_plugin_data.data=data; | |
6027
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
239 |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
240 // update plugins and uncoment that |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
241 // ao_plugin_data.channels=ao_plugin_local_data.channels; |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
242 // ao_plugin_data.format=ao_plugin_local_data.format; |
7c26ef54ff14
fixed sdl+resample bug coused by float point to int rounding error
iive
parents:
5773
diff
changeset
|
243 |
4376 | 244 while(plugin(i)) |
4375 | 245 plugin(i++)->play(); |
246 // Copy data to output buffer | |
247 memcpy(ao_plugin_local_data.buf+ao_plugin_local_data.len, | |
248 ao_plugin_data.data,ao_plugin_data.len); | |
249 // Send data to output | |
250 l=driver()->play(ao_plugin_local_data.buf, | |
251 ao_plugin_data.len+ao_plugin_local_data.len,flags); | |
252 // Save away unsent data | |
253 ao_plugin_local_data.len=ao_plugin_data.len+ao_plugin_local_data.len-l; | |
254 memcpy(ao_plugin_local_data.buf,ao_plugin_local_data.buf+l, | |
255 ao_plugin_local_data.len); | |
256 } | |
3096 | 257 return ret_len; |
258 } | |
259 | |
260 // return: delay in seconds between first and last sample in buffer | |
261 static float get_delay(){ | |
262 float delay=driver()->get_delay(); | |
4313 | 263 delay+=(float)ao_plugin_local_data.len/ao_plugin_local_data.bps; |
3096 | 264 delay*=ao_plugin_data.delay_mult; |
265 delay+=ao_plugin_data.delay_fix; | |
266 return delay; | |
267 } | |
268 | |
269 | |
3279
d6ea11bed983
Commandline interface to ao_plugin updated according to mplayers complex parameter format and plugin pl_format finished (alpha code needs testing)
anders
parents:
3194
diff
changeset
|
270 |
d6ea11bed983
Commandline interface to ao_plugin updated according to mplayers complex parameter format and plugin pl_format finished (alpha code needs testing)
anders
parents:
3194
diff
changeset
|
271 |