comparison libao2/ao_plugin.c @ 4313:1dbffed555a6

Added buffering of output data
author anders
date Wed, 23 Jan 2002 12:28:36 +0000
parents 2cc5737ec923
children 0a95c5074c50
comparison
equal deleted inserted replaced
4312:971836f677a9 4313:1dbffed555a6
23 #define driver() (ao_plugin_local_data.driver) 23 #define driver() (ao_plugin_local_data.driver)
24 24
25 // local data 25 // local data
26 typedef struct ao_plugin_local_data_s 26 typedef struct ao_plugin_local_data_s
27 { 27 {
28 ao_functions_t* driver; // Output driver set in mplayer.c 28 void* buf; // Output data buffer
29 int len; // Amount of data in buffer
30 float bps; // Bytes per second out
31 ao_functions_t* driver; // Output driver
29 ao_plugin_functions_t** plugins; // List of used plugins 32 ao_plugin_functions_t** plugins; // List of used plugins
30 ao_plugin_functions_t* available_plugins[NPL]; // List of available plugins 33 ao_plugin_functions_t* available_plugins[NPL]; // List of available plugins
31 } ao_plugin_local_data_t; 34 } ao_plugin_local_data_t;
32 35
33 static ao_plugin_local_data_t ao_plugin_local_data={NULL,NULL,AO_PLUGINS}; 36 static ao_plugin_local_data_t ao_plugin_local_data={NULL,0,0.0,NULL,NULL,AO_PLUGINS};
34 37
35 // gloabal data 38 // global data
36 volatile ao_plugin_data_t ao_plugin_data; // data used by the plugins 39 volatile ao_plugin_data_t ao_plugin_data; // Data used by the plugins
37 volatile ao_plugin_cfg_t ao_plugin_cfg=CFG_DEFAULTS; // cfg data set in cfg-mplayer.h 40 volatile ao_plugin_cfg_t ao_plugin_cfg=CFG_DEFAULTS; // Set in cfg-mplayer.h
38 41
39 // to set/get/query special features/parameters 42 // to set/get/query special features/parameters
40 static int control(int cmd,int arg){ 43 static int control(int cmd,int arg){
41 switch(cmd){ 44 switch(cmd){
42 case AOCONTROL_SET_PLUGIN_DRIVER: 45 case AOCONTROL_SET_PLUGIN_DRIVER:
100 // open & setup audio device and plugins 103 // open & setup audio device and plugins
101 // return: 1=success 0=fail 104 // return: 1=success 0=fail
102 static int init(int rate,int channels,int format,int flags){ 105 static int init(int rate,int channels,int format,int flags){
103 int ok=1; 106 int ok=1;
104 107
105 /* Create list of plugins from cfg option */ 108 // Create list of plugins from cfg option
106 int i=0; 109 int i=0;
107 if(ao_plugin_cfg.plugin_list){ 110 if(ao_plugin_cfg.plugin_list){
108 if(!add_plugin(i,ao_plugin_cfg.plugin_list)) 111 if(!add_plugin(i,ao_plugin_cfg.plugin_list))
109 return 0; 112 return 0;
110 } 113 }
122 while(plugin(i)&&ok) 125 while(plugin(i)&&ok)
123 ok=plugin(i++)->init(); 126 ok=plugin(i++)->init();
124 127
125 if(!ok) return 0; 128 if(!ok) return 0;
126 129
130 // Calculate bps
131 ao_plugin_local_data.bps=(float)(ao_plugin_data.rate *
132 ao_plugin_data.channels);
133
134 if(ao_plugin_data.format == AFMT_S16_LE ||
135 ao_plugin_data.format == AFMT_S16_BE ||
136 ao_plugin_data.format == AFMT_U16_LE ||
137 ao_plugin_data.format == AFMT_U16_BE)
138 ao_plugin_local_data.bps *= 2;
139
140 if(ao_plugin_data.format == AFMT_S32_LE ||
141 ao_plugin_data.format == AFMT_S32_BE)
142 ao_plugin_local_data.bps *= 4;
143
127 // This should never happen but check anyway 144 // This should never happen but check anyway
128 if(NULL==ao_plugin_local_data.driver) 145 if(NULL==ao_plugin_local_data.driver)
129 return 0; 146 return 0;
130 147
131 ok = driver()->init(ao_plugin_data.rate, 148 ok = driver()->init(ao_plugin_data.rate,
140 while((i>0) && ok) 157 while((i>0) && ok)
141 ok=plugin(--i)->control(AOCONTROL_PLUGIN_SET_LEN,0); 158 ok=plugin(--i)->control(AOCONTROL_PLUGIN_SET_LEN,0);
142 159
143 if(!ok) return 0; 160 if(!ok) return 0;
144 161
162 // Allocate output buffer */
163 if(ao_plugin_local_data.buf)
164 free(ao_plugin_local_data.buf);
165 ao_plugin_local_data.buf=malloc(MAX_OUTBURST);
166
167 if(!ao_plugin_local_data.buf) return 0;
168
145 return 1; 169 return 1;
146 } 170 }
147 171
148 // close audio device 172 // close audio device
149 static void uninit(){ 173 static void uninit(){
151 driver()->uninit(); 175 driver()->uninit();
152 while(plugin(i)) 176 while(plugin(i))
153 plugin(i++)->uninit(); 177 plugin(i++)->uninit();
154 if(ao_plugin_local_data.plugins) 178 if(ao_plugin_local_data.plugins)
155 free(ao_plugin_local_data.plugins); 179 free(ao_plugin_local_data.plugins);
180 if(ao_plugin_local_data.buf)
181 free(ao_plugin_local_data.buf);
156 } 182 }
157 183
158 // stop playing and empty buffers (for seeking/pause) 184 // stop playing and empty buffers (for seeking/pause)
159 static void reset(){ 185 static void reset(){
160 int i=0; 186 int i=0;
161 driver()->reset(); 187 driver()->reset();
162 while(plugin(i)) 188 while(plugin(i))
163 plugin(i++)->reset(); 189 plugin(i++)->reset();
190 ao_plugin_local_data.len=0;
164 } 191 }
165 192
166 // stop playing, keep buffers (for pause) 193 // stop playing, keep buffers (for pause)
167 static void audio_pause(){ 194 static void audio_pause(){
168 driver()->pause(); 195 driver()->pause();
174 } 201 }
175 202
176 // return: how many bytes can be played without blocking 203 // return: how many bytes can be played without blocking
177 static int get_space(){ 204 static int get_space(){
178 double sz=(double)(driver()->get_space()); 205 double sz=(double)(driver()->get_space());
206 if(sz+(double)ao_plugin_local_data.len > (double)MAX_OUTBURST)
207 sz=(double)MAX_OUTBURST-(double)ao_plugin_local_data.len;
179 sz*=ao_plugin_data.sz_mult; 208 sz*=ao_plugin_data.sz_mult;
180 sz+=ao_plugin_data.sz_fix; 209 sz+=ao_plugin_data.sz_fix;
181 return (int)(sz); 210 return (int)(sz);
182 } 211 }
183 212
184 // plays 'len' bytes of 'data' 213 // plays 'len' bytes of 'data'
185 // return: number of bytes played 214 // return: number of bytes played
186 static int play(void* data,int len,int flags){ 215 static int play(void* data,int len,int flags){
187 int i=0; 216 int l,i=0;
188 /* Due to constant buffer sizes in plugins limit length */ 217 // Limit length to avoid over flow in plugins
189 int tmp = get_space(); 218 int tmp = driver()->get_space();
190 int ret_len =(tmp<len)?tmp:len; 219 int ret_len =(tmp<len)?tmp:len;
191 /* Filter data */ 220 // Filter data
192 ao_plugin_data.len=ret_len; 221 ao_plugin_data.len=ret_len;
193 ao_plugin_data.data=data; 222 ao_plugin_data.data=data;
194 while(plugin(i)) 223 while(plugin(i))
195 plugin(i++)->play(); 224 plugin(i++)->play();
196 /* Send data to output */ 225 // Copy data to output buffer
197 //fprintf(stderr, "ao_plugin: ret_len=%d, len=%d\n", ret_len, len); 226 memcpy(ao_plugin_local_data.buf+ao_plugin_local_data.len,
198 len=driver()->play(ao_plugin_data.data,ao_plugin_data.len,flags); 227 ao_plugin_data.data,ao_plugin_data.len);
199 //fprintf(stderr, "ao_plugin: returned len=%d\n", len); 228 // Send data to output
200 229 l=driver()->play(ao_plugin_local_data.buf,
201 if(len!=ao_plugin_data.len) 230 ao_plugin_data.len+ao_plugin_local_data.len,flags);
202 fprintf(stderr,"[ao_plugin] Warning under or over flow in sound plugin\n"); 231 // Save away unsent data
232 ao_plugin_local_data.len=ao_plugin_data.len+ao_plugin_local_data.len-l;
233 memcpy(ao_plugin_local_data.buf,ao_plugin_local_data.buf+l,
234 ao_plugin_local_data.len);
203 235
204 return ret_len; 236 return ret_len;
205 } 237 }
206 238
207 // return: delay in seconds between first and last sample in buffer 239 // return: delay in seconds between first and last sample in buffer
208 static float get_delay(){ 240 static float get_delay(){
209 float delay=driver()->get_delay(); 241 float delay=driver()->get_delay();
242 delay+=(float)ao_plugin_local_data.len/ao_plugin_local_data.bps;
210 delay*=ao_plugin_data.delay_mult; 243 delay*=ao_plugin_data.delay_mult;
211 delay+=ao_plugin_data.delay_fix; 244 delay+=ao_plugin_data.delay_fix;
212 return delay; 245 return delay;
213 } 246 }
214 247