Commit d329a6fb2213e53008a9b1cd186fe2ff258fa272

Authored by bellard
1 parent 7ebb5e41

audip fixes (malc)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@911 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 275 additions and 198 deletions
hw/sb16.c
... ... @@ -26,7 +26,10 @@
26 26 #define MIN(a, b) ((a)>(b)?(b):(a))
27 27 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
28 28  
29   -#define log(...) fprintf (stderr, "sb16: " __VA_ARGS__)
  29 +#define log(...) do { \
  30 + fprintf (stderr, "sb16: " __VA_ARGS__); \
  31 + fputc ('\n', stderr); \
  32 +} while (0)
30 33  
31 34 /* #define DEBUG_SB16 */
32 35 #ifdef DEBUG_SB16
... ... @@ -44,6 +47,8 @@
44 47 #define IO_WRITE_PROTO(name) \
45 48 void name (void *opaque, uint32_t nport, uint32_t val)
46 49  
  50 +static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
  51 +
47 52 static struct {
48 53 int ver_lo;
49 54 int ver_hi;
... ... @@ -76,7 +81,7 @@ typedef struct SB16State {
76 81 int v2x6;
77 82  
78 83 uint8_t in_data[10];
79   - uint8_t out_data[10];
  84 + uint8_t out_data[50];
80 85  
81 86 int left_till_irq;
82 87  
... ... @@ -223,6 +228,20 @@ static void command (SB16State *dsp, uint8_t cmd)
223 228 /* IMS uses those when probing for sound devices */
224 229 return;
225 230  
  231 + case 0x04:
  232 + dsp->needed_bytes = 1;
  233 + break;
  234 +
  235 + case 0x05:
  236 + case 0x0e:
  237 + dsp->needed_bytes = 2;
  238 + break;
  239 +
  240 + case 0x0f:
  241 + dsp->needed_bytes = 1;
  242 + dsp_out_data (dsp, 0);
  243 + break;
  244 +
226 245 case 0x10:
227 246 dsp->needed_bytes = 1;
228 247 break;
... ... @@ -274,8 +293,8 @@ static void command (SB16State *dsp, uint8_t cmd)
274 293 uint8_t d0;
275 294  
276 295 d0 = 4;
277   - if (dsp->fmt_signed) d0 |= 16;
278   - if (dsp->fmt_stereo) d0 |= 32;
  296 + /* if (dsp->fmt_signed) d0 |= 16; */
  297 + /* if (dsp->fmt_stereo) d0 |= 32; */
279 298 dma_cmd (cmd == 0x90 ? 0xc4 : 0xc0, d0, -1);
280 299 cmd = -1;
281 300 break;
... ... @@ -324,6 +343,14 @@ static void command (SB16State *dsp, uint8_t cmd)
324 343 dsp_out_data(dsp, sb.ver_hi);
325 344 return;
326 345  
  346 + case 0xe3:
  347 + {
  348 + int i;
  349 + for (i = sizeof (e3) - 1; i >= 0; --i)
  350 + dsp_out_data (dsp, e3[i]);
  351 + return;
  352 + }
  353 +
327 354 case 0xf2:
328 355 dsp_out_data(dsp, 0xaa);
329 356 dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
... ... @@ -360,6 +387,11 @@ static void complete (SB16State *dsp)
360 387 }
361 388 else {
362 389 switch (dsp->cmd) {
  390 + case 0x05:
  391 + case 0x04:
  392 + case 0x0e:
  393 + case 0x0f:
  394 + break;
363 395  
364 396 case 0x10:
365 397 break;
... ... @@ -425,8 +457,10 @@ static IO_WRITE_PROTO (dsp_write)
425 457  
426 458 iport = nport - sb.port;
427 459  
  460 + ldebug ("write %#x %#x\n", nport, iport);
428 461 switch (iport) {
429 462 case 0x6:
  463 + control (0);
430 464 if (0 == val)
431 465 dsp->v2x6 = 0;
432 466 else if ((1 == val) && (0 == dsp->v2x6)) {
... ... @@ -477,7 +511,7 @@ static IO_READ_PROTO (dsp_read)
477 511 if (dsp->out_data_len) {
478 512 retval = dsp->out_data[--dsp->out_data_len];
479 513 } else {
480   - log("empty output buffer\n");
  514 + log("empty output buffer");
481 515 goto error;
482 516 }
483 517 break;
... ... @@ -487,7 +521,7 @@ static IO_READ_PROTO (dsp_read)
487 521 break;
488 522  
489 523 case 0xd: /* timer interrupt clear */
490   - log("timer interrupt clear\n");
  524 + log("timer interrupt clear");
491 525 goto error;
492 526  
493 527 case 0xe: /* data available status | irq 8 ack */
... ... @@ -669,7 +703,7 @@ static int magic_of_irq (int irq)
669 703 case 10:
670 704 return 8;
671 705 default:
672   - log ("bad irq %d\n", irq);
  706 + log ("bad irq %d", irq);
673 707 return 2;
674 708 }
675 709 }
... ... @@ -687,7 +721,7 @@ static int irq_of_magic (int magic)
687 721 case 8:
688 722 return 10;
689 723 default:
690   - log ("bad irq magic %d\n", magic);
  724 + log ("bad irq magic %d", magic);
691 725 return 2;
692 726 }
693 727 }
... ...
... ... @@ -24,6 +24,7 @@
24 24 #include "vl.h"
25 25  
26 26 #ifndef _WIN32
  27 +#include <ctype.h>
27 28 #include <fcntl.h>
28 29 #include <errno.h>
29 30 #include <stdio.h>
... ... @@ -32,6 +33,7 @@
32 33 #include <stdlib.h>
33 34 #include <limits.h>
34 35 #include <inttypes.h>
  36 +#include <sys/mman.h>
35 37 #include <sys/types.h>
36 38 #include <sys/ioctl.h>
37 39 #include <sys/soundcard.h>
... ... @@ -90,25 +92,38 @@ static inline uint32_t lsbindex (uint32_t u)
90 92 ldebug ("ioctl " #args " = %d\n", ret); \
91 93 } while (0)
92 94  
93   -static int audio_fd = -1;
94   -static int freq;
95   -static int conf_nfrags = 4;
96   -static int conf_fragsize;
97   -static int nfrags;
98   -static int fragsize;
99   -static int bufsize;
100   -static int nchannels;
101   -static int fmt;
102   -static int rpos;
103   -static int wpos;
104   -static int atom;
105   -static int live;
106   -static int leftover;
107   -static int bytes_per_second;
108   -static void *buf;
109   -static enum {DONT, DSP, TID} estimate = TID;
110   -
111   -static void (*copy_fn)(void *, void *, int);
  95 +static struct {
  96 + int fd;
  97 + int freq;
  98 + int bits16;
  99 + int nchannels;
  100 + int rpos;
  101 + int wpos;
  102 + int live;
  103 + int oss_fmt;
  104 + int bytes_per_second;
  105 + int is_mapped;
  106 + void *buf;
  107 + int bufsize;
  108 + int nfrags;
  109 + int fragsize;
  110 + int old_optr;
  111 + int leftover;
  112 + uint64_t old_ticks;
  113 + void (*copy_fn)(void *, void *, int);
  114 +} oss = { .fd = -1 };
  115 +
  116 +static struct {
  117 + int try_mmap;
  118 + int nfrags;
  119 + int fragsize;
  120 +} conf = {
  121 + .try_mmap = 0,
  122 + .nfrags = 4,
  123 + .fragsize = 4096
  124 +};
  125 +
  126 +static enum {DONT, DSP, TID} est = DONT;
112 127  
113 128 static void copy_no_conversion (void *dst, void *src, int size)
114 129 {
... ... @@ -141,70 +156,124 @@ static void pab (struct audio_buf_info *abinfo)
141 156 rpos, wpos, live);
142 157 }
143 158  
144   -void AUD_reset (int rfreq, int rnchannels, audfmt_e rfmt)
  159 +static void do_open ()
145 160 {
146   - int fmt_;
147   - int bits16;
  161 + int mmmmssss;
  162 + audio_buf_info abinfo;
  163 + int fmt, freq, nchannels;
148 164  
149   - if (-1 == audio_fd) {
150   - AUD_open (rfreq, rnchannels, rfmt);
151   - return;
  165 + if (oss.buf) {
  166 + if (-1 == munmap (oss.buf, oss.bufsize)) {
  167 + ERRFail ("failed to unmap audio buffer %p %d",
  168 + oss.buf, oss.bufsize);
  169 + }
  170 + oss.buf = NULL;
152 171 }
153 172  
154   - switch (rfmt) {
155   - case AUD_FMT_U8:
156   - bits16 = 0;
157   - fmt_ = AFMT_U8;
158   - copy_fn = copy_no_conversion;
159   - atom = 1;
160   - break;
  173 + if (-1 != oss.fd)
  174 + close (oss.fd);
161 175  
162   - case AUD_FMT_S8:
163   - Fail ("can not play 8bit signed");
  176 + oss.fd = open ("/dev/dsp", O_RDWR | O_NONBLOCK);
  177 + if (-1 == oss.fd) {
  178 + ERRFail ("can not open /dev/dsp");
  179 + }
164 180  
165   - case AUD_FMT_S16:
166   - bits16 = 1;
167   - fmt_ = AFMT_S16_LE;
168   - copy_fn = copy_no_conversion;
169   - atom = 2;
170   - break;
  181 + fmt = oss.oss_fmt;
  182 + freq = oss.freq;
  183 + nchannels = oss.nchannels;
  184 +
  185 + IOCTL ((oss.fd, SNDCTL_DSP_RESET, 1));
  186 + IOCTL ((oss.fd, SNDCTL_DSP_SAMPLESIZE, &fmt));
  187 + IOCTL ((oss.fd, SNDCTL_DSP_CHANNELS, &nchannels));
  188 + IOCTL ((oss.fd, SNDCTL_DSP_SPEED, &freq));
  189 + IOCTL ((oss.fd, SNDCTL_DSP_NONBLOCK));
  190 +
  191 + mmmmssss = (conf.nfrags << 16) | conf.fragsize;
  192 + IOCTL ((oss.fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss));
  193 +
  194 + if ((oss.oss_fmt != fmt)
  195 + || (oss.nchannels != nchannels)
  196 + || (oss.freq != freq)) {
  197 + Fail ("failed to set audio parameters\n"
  198 + "parameter | requested value | obtained value\n"
  199 + "format | %10d | %10d\n"
  200 + "channels | %10d | %10d\n"
  201 + "frequency | %10d | %10d\n",
  202 + oss.oss_fmt, fmt,
  203 + oss.nchannels, nchannels,
  204 + oss.freq, freq);
  205 + }
171 206  
172   - case AUD_FMT_U16:
173   - bits16 = 1;
174   - fmt_ = AFMT_S16_LE;
175   - copy_fn = copy_u16_to_s16;
176   - atom = 2;
177   - break;
  207 + IOCTL ((oss.fd, SNDCTL_DSP_GETOSPACE, &abinfo));
178 208  
179   - default:
180   - abort ();
181   - }
  209 + oss.nfrags = abinfo.fragstotal;
  210 + oss.fragsize = abinfo.fragsize;
  211 + oss.bufsize = oss.nfrags * oss.fragsize;
  212 + oss.old_optr = 0;
182 213  
183   - if ((fmt_ == fmt) && (bits16 + 1 == nchannels) && (rfreq == freq))
184   - return;
  214 + oss.bytes_per_second = (freq << (nchannels >> 1)) << oss.bits16;
  215 +
  216 + linfo ("bytes per second %d\n", oss.bytes_per_second);
  217 +
  218 + linfo ("fragments %d, fragstotal %d, fragsize %d, bytes %d, bufsize %d\n",
  219 + abinfo.fragments,
  220 + abinfo.fragstotal,
  221 + abinfo.fragsize,
  222 + abinfo.bytes,
  223 + oss.bufsize);
  224 +
  225 + oss.buf = MAP_FAILED;
  226 + oss.is_mapped = 0;
  227 +
  228 + if (conf.try_mmap) {
  229 + oss.buf = mmap (NULL, oss.bufsize, PROT_WRITE, MAP_SHARED, oss.fd, 0);
  230 + if (MAP_FAILED == oss.buf) {
  231 + int err;
  232 +
  233 + err = errno;
  234 + log ("failed to mmap audio, size %d, fd %d\n"
  235 + "syserr: %s\n",
  236 + oss.bufsize, oss.fd, strerror (err));
  237 + }
185 238 else {
186   - AUD_open (rfreq, rnchannels, rfmt);
  239 + est = TID;
  240 + oss.is_mapped = 1;
  241 + }
  242 + }
  243 +
  244 + if (MAP_FAILED == oss.buf) {
  245 + est = TID;
  246 + oss.buf = mmap (NULL, oss.bufsize, PROT_READ | PROT_WRITE,
  247 + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  248 + if (MAP_FAILED == oss.buf) {
  249 + ERRFail ("mmap audio buf, size %d", oss.bufsize);
  250 + }
  251 + }
  252 +
  253 + oss.rpos = 0;
  254 + oss.wpos = 0;
  255 + oss.live = 0;
  256 +
  257 + if (oss.is_mapped) {
  258 + int trig;
  259 +
  260 + trig = 0;
  261 + IOCTL ((oss.fd, SNDCTL_DSP_SETTRIGGER, &trig));
  262 + trig = PCM_ENABLE_OUTPUT;
  263 + IOCTL ((oss.fd, SNDCTL_DSP_SETTRIGGER, &trig));
187 264 }
188 265 }
189 266  
190   -void AUD_open (int rfreq, int rnchannels, audfmt_e rfmt)
  267 +static void maybe_open (int req_freq, int req_nchannels,
  268 + audfmt_e req_fmt, int force_open)
191 269 {
192   - int fmt_;
193   - int mmmmssss;
194   - struct audio_buf_info abinfo;
195   - int _fmt;
196   - int _freq;
197   - int _nchannels;
198   - int bits16;
  270 + int oss_fmt, bits16;
199 271  
200   - bits16 = 0;
201   -
202   - switch (rfmt) {
  272 + switch (req_fmt) {
203 273 case AUD_FMT_U8:
204 274 bits16 = 0;
205   - fmt_ = AFMT_U8;
206   - copy_fn = copy_no_conversion;
207   - atom = 1;
  275 + oss_fmt = AFMT_U8;
  276 + oss.copy_fn = copy_no_conversion;
208 277 break;
209 278  
210 279 case AUD_FMT_S8:
... ... @@ -212,111 +281,42 @@ void AUD_open (int rfreq, int rnchannels, audfmt_e rfmt)
212 281  
213 282 case AUD_FMT_S16:
214 283 bits16 = 1;
215   - fmt_ = AFMT_S16_LE;
216   - copy_fn = copy_no_conversion;
217   - atom = 2;
  284 + oss_fmt = AFMT_S16_LE;
  285 + oss.copy_fn = copy_no_conversion;
218 286 break;
219 287  
220 288 case AUD_FMT_U16:
221 289 bits16 = 1;
222   - fmt_ = AFMT_S16_LE;
223   - copy_fn = copy_u16_to_s16;
224   - atom = 2;
  290 + oss_fmt = AFMT_S16_LE;
  291 + oss.copy_fn = copy_u16_to_s16;
225 292 break;
226 293  
227 294 default:
228 295 abort ();
229 296 }
230 297  
231   - if (buf) {
232   - free (buf);
233   - buf = 0;
234   - }
235   -
236   - if (-1 != audio_fd)
237   - close (audio_fd);
238   -
239   - audio_fd = open ("/dev/dsp", O_WRONLY | O_NONBLOCK);
240   - if (-1 == audio_fd) {
241   - ERRFail ("can not open /dev/dsp");
242   - }
243   -
244   - _fmt = fmt_;
245   - _freq = rfreq;
246   - _nchannels = rnchannels;
247   -
248   - IOCTL ((audio_fd, SNDCTL_DSP_RESET, 1));
249   - IOCTL ((audio_fd, SNDCTL_DSP_SAMPLESIZE, &_fmt));
250   - IOCTL ((audio_fd, SNDCTL_DSP_CHANNELS, &_nchannels));
251   - IOCTL ((audio_fd, SNDCTL_DSP_SPEED, &_freq));
252   - IOCTL ((audio_fd, SNDCTL_DSP_NONBLOCK));
253   -
254   - /* from oss.pdf:
255   -
256   - The argument to this call is an integer encoded as 0xMMMMSSSS (in
257   - hex). The 16 least significant bits determine the fragment
258   - size. The size is 2^SSSS. For examp le SSSS=0008 gives fragment
259   - size of 256 bytes (2^8). The minimum is 16 bytes (SSSS=4) and the
260   - maximum is total_buffer_size/2. Some devices or processor
261   - architectures may require larger fragments - in this case the
262   - requested fragment size is automatically increased.
263   -
264   - So ahem... 4096 = 2^12, and grand total 0x0004000c
265   - */
266   -
267   - mmmmssss = (conf_nfrags << 16) | conf_fragsize;
268   - IOCTL ((audio_fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss));
269   -
270   - linfo ("_fmt = %d, fmt = %d\n"
271   - "_channels = %d, rnchannels = %d\n"
272   - "_freq = %d, freq = %d\n",
273   - _fmt, fmt_,
274   - _nchannels, rnchannels,
275   - _freq, rfreq);
276   -
277   - if (_fmt != fmt_) {
278   - Fail ("format %d != %d", _fmt, fmt_);
279   - }
280   -
281   - if (_nchannels != rnchannels) {
282   - Fail ("channels %d != %d", _nchannels, rnchannels);
  298 + if (force_open
  299 + || (-1 == oss.fd)
  300 + || (oss_fmt != oss.oss_fmt)
  301 + || (req_nchannels != oss.nchannels)
  302 + || (req_freq != oss.freq)
  303 + || (bits16 != oss.bits16)) {
  304 + oss.oss_fmt = oss_fmt;
  305 + oss.nchannels = req_nchannels;
  306 + oss.freq = req_freq;
  307 + oss.bits16 = bits16;
  308 + do_open ();
283 309 }
  310 +}
284 311  
285   - if (_freq != rfreq) {
286   - Fail ("freq %d != %d", _freq, rfreq);
287   - }
288   -
289   - IOCTL ((audio_fd, SNDCTL_DSP_GETOSPACE, &abinfo));
290   -
291   - nfrags = abinfo.fragstotal;
292   - fragsize = abinfo.fragsize;
293   - freq = _freq;
294   - fmt = _fmt;
295   - nchannels = rnchannels;
296   - atom <<= nchannels >> 1;
297   - bufsize = nfrags * fragsize;
298   -
299   - bytes_per_second = (freq << (nchannels >> 1)) << bits16;
300   -
301   - linfo ("bytes per second %d\n", bytes_per_second);
302   -
303   - linfo ("fragments %d, fragstotal %d, fragsize %d, bytes %d, bufsize %d\n",
304   - abinfo.fragments,
305   - abinfo.fragstotal,
306   - abinfo.fragsize,
307   - abinfo.bytes,
308   - bufsize);
309   -
310   - if (NULL == buf) {
311   - buf = malloc (bufsize);
312   - if (NULL == buf) {
313   - abort ();
314   - }
315   - }
  312 +void AUD_reset (int req_freq, int req_nchannels, audfmt_e req_fmt)
  313 +{
  314 + maybe_open (req_freq, req_nchannels, req_fmt, 0);
  315 +}
316 316  
317   - rpos = 0;
318   - wpos = 0;
319   - live = 0;
  317 +void AUD_open (int req_freq, int req_nchannels, audfmt_e req_fmt)
  318 +{
  319 + maybe_open (req_freq, req_nchannels, req_fmt, 1);
320 320 }
321 321  
322 322 int AUD_write (void *in_buf, int size)
... ... @@ -324,27 +324,27 @@ int AUD_write (void *in_buf, int size)
324 324 int to_copy, temp;
325 325 uint8_t *in, *out;
326 326  
327   - to_copy = MIN (bufsize - live, size);
  327 + to_copy = MIN (oss.bufsize - oss.live, size);
328 328  
329 329 temp = to_copy;
330 330  
331 331 in = in_buf;
332   - out = buf;
  332 + out = oss.buf;
333 333  
334 334 while (temp) {
335 335 int copy;
336 336  
337   - copy = MIN (temp, bufsize - wpos);
338   - copy_fn (out + wpos, in, copy);
  337 + copy = MIN (temp, oss.bufsize - oss.wpos);
  338 + oss.copy_fn (out + oss.wpos, in, copy);
339 339  
340   - wpos += copy;
341   - if (wpos == bufsize) {
342   - wpos = 0;
  340 + oss.wpos += copy;
  341 + if (oss.wpos == oss.bufsize) {
  342 + oss.wpos = 0;
343 343 }
344 344  
345 345 temp -= copy;
346 346 in += copy;
347   - live += copy;
  347 + oss.live += copy;
348 348 }
349 349  
350 350 return to_copy;
... ... @@ -356,10 +356,34 @@ void AUD_run (void)
356 356 int bytes;
357 357 struct audio_buf_info abinfo;
358 358  
359   - if (0 == live)
  359 + if (0 == oss.live)
360 360 return;
361 361  
362   - res = ioctl (audio_fd, SNDCTL_DSP_GETOSPACE, &abinfo);
  362 + if (oss.is_mapped) {
  363 + count_info info;
  364 +
  365 + res = ioctl (oss.fd, SNDCTL_DSP_GETOPTR, &info);
  366 + if (-1 == res) {
  367 + int err;
  368 +
  369 + err = errno;
  370 + lwarn ("SNDCTL_DSP_GETOPTR failed with %s\n", strerror (err));
  371 + return;
  372 + }
  373 +
  374 + if (info.ptr > oss.old_optr) {
  375 + bytes = info.ptr - oss.old_optr;
  376 + }
  377 + else {
  378 + bytes = oss.bufsize + info.ptr - oss.old_optr;
  379 + }
  380 +
  381 + oss.old_optr = info.ptr;
  382 + oss.live -= bytes;
  383 + return;
  384 + }
  385 +
  386 + res = ioctl (oss.fd, SNDCTL_DSP_GETOSPACE, &abinfo);
363 387  
364 388 if (-1 == res) {
365 389 int err;
... ... @@ -369,7 +393,7 @@ void AUD_run (void)
369 393 }
370 394  
371 395 bytes = abinfo.bytes;
372   - bytes = MIN (live, bytes);
  396 + bytes = MIN (oss.live, bytes);
373 397 #if 0
374 398 bytes = (bytes / fragsize) * fragsize;
375 399 #endif
... ... @@ -377,9 +401,9 @@ void AUD_run (void)
377 401 while (bytes) {
378 402 int left, play, written;
379 403  
380   - left = bufsize - rpos;
  404 + left = oss.bufsize - oss.rpos;
381 405 play = MIN (left, bytes);
382   - written = write (audio_fd, (void *) ((uint32_t) buf + rpos), play);
  406 + written = write (oss.fd, (void *) ((uint32_t) oss.buf + oss.rpos), play);
383 407  
384 408 if (-1 == written) {
385 409 if (EAGAIN == errno || EINTR == errno) {
... ... @@ -391,12 +415,12 @@ void AUD_run (void)
391 415 }
392 416  
393 417 play = written;
394   - live -= play;
395   - rpos += play;
  418 + oss.live -= play;
  419 + oss.rpos += play;
396 420 bytes -= play;
397 421  
398   - if (rpos == bufsize) {
399   - rpos = 0;
  422 + if (oss.rpos == oss.bufsize) {
  423 + oss.rpos = 0;
400 424 }
401 425 }
402 426 }
... ... @@ -406,7 +430,7 @@ static int get_dsp_bytes (void)
406 430 int res;
407 431 struct count_info info;
408 432  
409   - res = ioctl (audio_fd, SNDCTL_DSP_GETOPTR, &info);
  433 + res = ioctl (oss.fd, SNDCTL_DSP_GETOPTR, &info);
410 434 if (-1 == res) {
411 435 int err;
412 436  
... ... @@ -420,22 +444,22 @@ static int get_dsp_bytes (void)
420 444 }
421 445 }
422 446  
423   -void AUD_adjust_estimate (int _leftover)
  447 +void AUD_adjust_estimate (int leftover)
424 448 {
425   - leftover = _leftover;
  449 + oss.leftover = leftover;
426 450 }
427 451  
428 452 int AUD_get_free (void)
429 453 {
430 454 int free, elapsed;
431 455  
432   - free = bufsize - live;
  456 + free = oss.bufsize - oss.live;
433 457  
434 458 if (0 == free)
435 459 return 0;
436 460  
437 461 elapsed = free;
438   - switch (estimate) {
  462 + switch (est) {
439 463 case DONT:
440 464 break;
441 465  
... ... @@ -456,16 +480,15 @@ int AUD_get_free (void)
456 480  
457 481 case TID:
458 482 {
459   - static uint64_t old_ticks;
460 483 uint64_t ticks, delta;
461 484 uint64_t ua_elapsed;
462 485 uint64_t al_elapsed;
463 486  
464 487 ticks = qemu_get_clock(rt_clock);
465   - delta = ticks - old_ticks;
466   - old_ticks = ticks;
  488 + delta = ticks - oss.old_ticks;
  489 + oss.old_ticks = ticks;
467 490  
468   - ua_elapsed = (delta * bytes_per_second) / 1000;
  491 + ua_elapsed = (delta * oss.bytes_per_second) / 1000;
469 492 al_elapsed = ua_elapsed & ~3ULL;
470 493  
471 494 ldebug ("tid elapsed %llu bytes\n", ua_elapsed);
... ... @@ -475,7 +498,7 @@ int AUD_get_free (void)
475 498 else
476 499 elapsed = al_elapsed;
477 500  
478   - elapsed += leftover;
  501 + elapsed += oss.leftover;
479 502 }
480 503 }
481 504  
... ... @@ -490,27 +513,47 @@ int AUD_get_free (void)
490 513  
491 514 int AUD_get_live (void)
492 515 {
493   - return live;
  516 + return oss.live;
494 517 }
495 518  
496 519 int AUD_get_buffer_size (void)
497 520 {
498   - return bufsize;
  521 + return oss.bufsize;
  522 +}
  523 +
  524 +#define QC_OSS_FRAGSIZE "QEMU_OSS_FRAGSIZE"
  525 +#define QC_OSS_NFRAGS "QEMU_OSS_NFRAGS"
  526 +#define QC_OSS_MMAP "QEMU_OSS_MMAP"
  527 +
  528 +static int get_conf_val (const char *key, int defval)
  529 +{
  530 + int val = defval;
  531 + char *strval;
  532 +
  533 + strval = getenv (key);
  534 + if (strval) {
  535 + val = atoi (strval);
  536 + }
  537 +
  538 + return val;
499 539 }
500 540  
501 541 void AUD_init (void)
502 542 {
503 543 int fsp;
504   - int _fragsize = 4096;
505 544  
506 545 DEREF (pab);
507 546  
508   - fsp = _fragsize;
  547 + conf.fragsize = get_conf_val (QC_OSS_FRAGSIZE, conf.fragsize);
  548 + conf.nfrags = get_conf_val (QC_OSS_NFRAGS, conf.nfrags);
  549 + conf.try_mmap = get_conf_val (QC_OSS_MMAP, conf.try_mmap);
  550 +
  551 + fsp = conf.fragsize;
509 552 if (0 != (fsp & (fsp - 1))) {
510 553 Fail ("fragment size %d is not power of 2", fsp);
511 554 }
512 555  
513   - conf_fragsize = lsbindex (fsp);
  556 + conf.fragsize = lsbindex (fsp);
514 557 }
515 558  
516 559 #else
... ...