NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/39204
The following reply was made to PR kern/39204; it has been noted by GNATS.
From: Nat Sloss <nathanialsloss%yahoo.com.au@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: kern/39204
Date: Fri, 11 May 2012 23:57:39 +1000
Hi,
I think I fixed the problem. I had broken audio when booted from and saving
to harddrive, more so when booted from and saving to usb, and it was even
more broken in emulated in qemu.
What fixed it was adding a delay before the call to start output in pad_read.
The delay would work for one of the scenarios above but not for the others.
More delay was needed for usb and qemu. And then I discovered that the writer
was only scheduled at the end of audio pint. So calling start output in
quick succession resulted in silence being copied.
I also found that audio would skip on small reads less than PADBLKSIZE and
this was because of the second call to start output outside of the while loop
in pad_read as it was no longer necessary as there was a delay ensuring that
data was in the stream.
So after attempting many different things I came up with this patch:
--- pad.c.orig 2012-01-27 16:58:34.000000000 +1100
+++ pad.c 2012-05-11 23:35:22.000000000 +1000
@@ -54,6 +54,7 @@
#define PADUNIT(x) minor(x)
extern struct cfdriver pad_cd;
+extern struct cfdriver audio_cd;
typedef struct pad_block {
uint8_t *pb_ptr;
@@ -333,14 +334,21 @@
{
pad_softc_t *sc;
pad_block_t pb;
+ struct audio_softc *ac;
void (*intr)(void *);
void *intrarg;
- int err;
+ int err, i, used;
sc = device_lookup_private(&pad_cd, PADUNIT(dev));
if (sc == NULL)
return ENXIO;
+ for (i = 0; i < 256; i++) {
+ ac = device_lookup_private(&audio_cd, i);
+ if (ac->hw_hdl == sc)
+ break;
+ }
+
err = 0;
mutex_enter(&sc->sc_lock);
@@ -356,6 +364,18 @@
continue;
}
+ mutex_exit(&sc->sc_lock);
+ i = 0;
+ while ((used = audio_stream_get_used(ac->sc_pustream)) <
+ PAD_BLKSIZE * 2 && used < ac->sc_pr.usedlow) {
+ softint_schedule(ac->sc_sih_wr);
+ DELAY(250);
+ i++;
+ if (i > 8000)
+ break;
+ }
+ mutex_enter(&sc->sc_lock);
+
if (intr) {
mutex_enter(&sc->sc_intr_lock);
(*intr)(intrarg);
@@ -374,11 +394,6 @@
intrarg = sc->sc_intrarg;
}
- if (intr) {
- mutex_enter(&sc->sc_intr_lock);
- (*intr)(intrarg);
- mutex_exit(&sc->sc_intr_lock);
- }
mutex_exit(&sc->sc_lock);
return err;
This solves the problem for harddrive with 1 GHz cpu, usb and qemu situations.
If audio is not broken for you try using pad in an qemu emulation and you
will find with the un-patched version is gives broken audio, but with the
patch above it is fixed.
Note: This patch is my own work which I submit freely under the NetBSD
license.
I hope this helps.
Regards,
Nat.
Home |
Main Index |
Thread Index |
Old Index