Commit 15b614700062dde8801762b1cfd4717a63a2cfd9

Authored by bellard
1 parent 9e89a4be

audio fix (malc)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1137 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 45 additions and 20 deletions
hw/sb16.c
... ... @@ -26,15 +26,16 @@
26 26 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
27 27  
28 28 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
  29 +
  30 +/* #define DEBUG */
  31 +/* #define DEBUG_SB16_MOST */
  32 +
29 33 #ifdef DEBUG
30 34 #define ldebug(...) dolog (__VA_ARGS__)
31 35 #else
32 36 #define ldebug(...)
33 37 #endif
34 38  
35   -/* #define DEBUG */
36   -/* #define DEBUG_SB16_MOST */
37   -
38 39 #define IO_READ_PROTO(name) \
39 40 uint32_t name (void *opaque, uint32_t nport)
40 41 #define IO_WRITE_PROTO(name) \
... ... @@ -206,8 +207,18 @@ static void dma_cmd8 (SB16State *s, int mask, int dma_len)
206 207 s->freq = (1000000 + (tmp / 2)) / tmp;
207 208 }
208 209  
209   - if (-1 != dma_len)
210   - s->block_size = dma_len + 1;
  210 + if (dma_len != -1)
  211 + s->block_size = dma_len << s->fmt_stereo;
  212 + else {
  213 + /* This is apparently the only way to make both Act1/PL
  214 + and SecondReality/FC work
  215 +
  216 + Act1 sets block size via command 0x48 and it's an odd number
  217 + SR does the same with even number
  218 + Both use stereo, and Creatives own documentation states that
  219 + 0x48 sets block size in bytes less one.. go figure */
  220 + s->block_size &= ~s->fmt_stereo;
  221 + }
211 222  
212 223 s->freq >>= s->fmt_stereo;
213 224 s->left_till_irq = s->block_size;
... ... @@ -216,6 +227,9 @@ static void dma_cmd8 (SB16State *s, int mask, int dma_len)
216 227 s->dma_auto = (mask & DMA8_AUTO) != 0;
217 228 s->align = (1 << s->fmt_stereo) - 1;
218 229  
  230 + if (s->block_size & s->align)
  231 + dolog ("warning: unaligned buffer\n");
  232 +
219 233 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
220 234 "dma %d, auto %d, fifo %d, high %d\n",
221 235 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
... ... @@ -260,8 +274,13 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
260 274  
261 275 s->block_size = dma_len + 1;
262 276 s->block_size <<= (s->fmt_bits == 16);
263   - if (!s->dma_auto) /* Miles Sound System ? */
  277 + if (!s->dma_auto) {
  278 + /* It is clear that for DOOM and auto-init this value
  279 + shouldn't take stereo into account, while Miles Sound Systems
  280 + setsound.exe with single transfer mode wouldn't work without it
  281 + wonders of SB16 yet again */
264 282 s->block_size <<= s->fmt_stereo;
  283 + }
265 284  
266 285 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
267 286 "dma %d, auto %d, fifo %d, high %d\n",
... ... @@ -290,6 +309,8 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
290 309 s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
291 310 s->highspeed = 0;
292 311 s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
  312 + if (s->block_size & s->align)
  313 + dolog ("warning: unaligned buffer\n");
293 314  
294 315 if (s->freq)
295 316 s->voice = AUD_open (s->voice, "sb16", s->freq,
... ... @@ -373,6 +394,10 @@ static void command (SB16State *s, uint8_t cmd)
373 394 s->block_size = 0;
374 395 break;
375 396  
  397 + case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
  398 + control (s, 1);
  399 + break;
  400 +
376 401 case 0x20: /* Direct ADC, Juice/PL */
377 402 dsp_out_data (s, 0xff);
378 403 goto warn;
... ... @@ -607,9 +632,7 @@ static void complete (SB16State *s)
607 632 break;
608 633  
609 634 case 0x14:
610   - dma_cmd8 (s, 0, dsp_get_lohi (s));
611   - /* s->can_write = 0; */
612   - /* qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + (ticks_per_sec * 320) / 1000000); */
  635 + dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
613 636 break;
614 637  
615 638 case 0x40:
... ... @@ -626,22 +649,20 @@ static void complete (SB16State *s)
626 649 break;
627 650  
628 651 case 0x48:
629   - s->block_size = dsp_get_lohi (s);
630   - /* s->highspeed = 1; */
  652 + s->block_size = dsp_get_lohi (s) + 1;
631 653 ldebug ("set dma block len %d\n", s->block_size);
632 654 break;
633 655  
634 656 case 0x80:
635 657 {
636   - int samples, bytes;
  658 + int freq, samples, bytes;
637 659 int64_t ticks;
638 660  
639   - if (-1 == s->freq)
640   - s->freq = 11025;
641   - samples = dsp_get_lohi (s);
  661 + freq = s->freq > 0 ? s->freq : 11025;
  662 + samples = dsp_get_lohi (s) + 1;
642 663 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
643   - ticks = bytes ? (ticks_per_sec / (s->freq / bytes)) : 0;
644   - if (!bytes || ticks < ticks_per_sec / 1024)
  664 + ticks = (bytes * ticks_per_sec) / freq;
  665 + if (ticks < ticks_per_sec / 1024)
645 666 pic_set_irq (s->irq, 1);
646 667 else
647 668 qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);
... ... @@ -658,7 +679,7 @@ static void complete (SB16State *s)
658 679  
659 680 case 0xe2:
660 681 d0 = dsp_get_data (s);
661   - dolog ("E2 = %#x\n", d0);
  682 + ldebug ("E2 = %#x\n", d0);
662 683 break;
663 684  
664 685 case 0xe4:
... ... @@ -967,6 +988,9 @@ static IO_WRITE_PROTO(mixer_write_indexw)
967 988 static IO_READ_PROTO(mixer_read)
968 989 {
969 990 SB16State *s = opaque;
  991 +#ifndef DEBUG_SB16_MOST
  992 + if (s->mixer_nreg != 0x82)
  993 +#endif
970 994 ldebug ("mixer_read[%#x] -> %#x\n",
971 995 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
972 996 return s->mixer_regs[s->mixer_nreg];
... ... @@ -1049,8 +1073,9 @@ static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1049 1073 }
1050 1074  
1051 1075 #ifdef DEBUG_SB16_MOST
1052   - ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n",
1053   - dma_pos, free, dma_len, s->left_till_irq, copy, s->block_size);
  1076 + ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
  1077 + dma_pos, free, dma_len, s->left_till_irq, copy, written,
  1078 + s->block_size);
1054 1079 #endif
1055 1080  
1056 1081 while (s->left_till_irq <= 0) {
... ...