Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Add latency sysctl to adjust hw blocksize and hence ...
details: https://anonhg.NetBSD.org/src/rev/5ab5d6b2e852
branches: trunk
changeset: 827402:5ab5d6b2e852
user: nat <nat%NetBSD.org@localhost>
date: Thu Oct 26 22:38:27 2017 +0000
description:
Add latency sysctl to adjust hw blocksize and hence latency of the mixer.
usage: sysctl -w hw.hdafg0.lantency="value in milliseconds"
It is possible to set the latency of the mixer unless a static blocksize
is configured by the underlying hardware driver (pad, vcaudio on RPI).
Documentation updates to audio.4 will occur in a follow up commit.
OK christos@. XXX pullup-8.
diffstat:
sys/dev/audio.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++---
sys/dev/audiovar.h | 3 +-
2 files changed, 77 insertions(+), 6 deletions(-)
diffs (160 lines):
diff -r 3d86fee53b28 -r 5ab5d6b2e852 sys/dev/audio.c
--- a/sys/dev/audio.c Thu Oct 26 10:56:57 2017 +0000
+++ b/sys/dev/audio.c Thu Oct 26 22:38:27 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: audio.c,v 1.414 2017/10/25 08:12:38 maya Exp $ */
+/* $NetBSD: audio.c,v 1.415 2017/10/26 22:38:27 nat Exp $ */
/*-
* Copyright (c) 2016 Nathanial Sloss <nathanialsloss%yahoo.com.au@localhost>
@@ -148,7 +148,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.414 2017/10/25 08:12:38 maya Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.415 2017/10/26 22:38:27 nat Exp $");
#ifdef _KERNEL_OPT
#include "audio.h"
@@ -205,6 +205,7 @@
#define DPRINTFN(n,x)
#endif
+#define PREFILL_BLOCKS 3 /* no. audioblocks required to start stream */
#define ROUNDSIZE(x) (x) &= -16 /* round to nice boundary */
#define SPECIFIED(x) ((int)(x) != ~0)
#define SPECIFIED_CH(x) ((x) != (u_char)~0)
@@ -313,6 +314,7 @@
static int audio_sysctl_frequency(SYSCTLFN_PROTO);
static int audio_sysctl_precision(SYSCTLFN_PROTO);
static int audio_sysctl_channels(SYSCTLFN_PROTO);
+static int audio_sysctl_latency(SYSCTLFN_PROTO);
static int audiomatch(device_t, cfdata_t, void *);
static void audioattach(device_t, device_t, void *);
@@ -498,6 +500,7 @@
sc->sc_recopens = 0;
sc->sc_aivalid = false;
sc->sc_ready = true;
+ sc->sc_latency = audio_blk_ms * PREFILL_BLOCKS;
sc->sc_format[0].mode = AUMODE_PLAY | AUMODE_RECORD;
sc->sc_format[0].encoding =
@@ -793,6 +796,15 @@
sysctl_createv(&sc->sc_log, 0, NULL, NULL,
CTLFLAG_READWRITE,
+ CTLTYPE_INT, "latency",
+ SYSCTL_DESCR("latency"),
+ audio_sysctl_latency, 0,
+ (void *)sc, 0,
+ CTL_HW, node->sysctl_num,
+ CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(&sc->sc_log, 0, NULL, NULL,
+ CTLFLAG_READWRITE,
CTLTYPE_BOOL, "multiuser",
SYSCTL_DESCR("allow multiple user acess"),
NULL, 0,
@@ -2634,8 +2646,8 @@
{
int blksize;
- blksize = parm->sample_rate * audio_blk_ms / 1000 *
- parm->channels * parm->precision / NBBY;
+ blksize = parm->sample_rate * sc->sc_latency * parm->channels /
+ 1000 * parm->precision / NBBY / PREFILL_BLOCKS;
return blksize;
}
@@ -4106,7 +4118,7 @@
&sc->sc_encodings);
if (error == 0)
- error = audiosetinfo(sc, &ai, false, vc);
+ error = audiosetinfo(sc, &ai, true, vc);
return error;
}
@@ -5955,6 +5967,64 @@
return error;
}
+/* sysctl helper to set audio latency */
+static int
+audio_sysctl_latency(SYSCTLFN_ARGS)
+{
+ struct sysctlnode node;
+ struct audio_softc *sc;
+ int t, error;
+
+ node = *rnode;
+ sc = node.sysctl_data;
+
+ t = sc->sc_latency;
+ node.sysctl_data = &t;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL)
+ return error;
+
+ mutex_enter(sc->sc_lock);
+
+ /* This may not change when a virtual channel is open */
+ if (sc->sc_opens || sc->sc_recopens) {
+ mutex_exit(sc->sc_lock);
+ return EBUSY;
+ }
+
+ if (t < 0 || t > 4000) {
+ mutex_exit(sc->sc_lock);
+ return EINVAL;
+ }
+
+ if (t == 0)
+ sc->sc_latency = audio_blk_ms * PREFILL_BLOCKS;
+ else
+ sc->sc_latency = (unsigned int)t;
+
+ error = audio_set_vchan_defaults(sc,
+ AUMODE_PLAY | AUMODE_PLAY_ALL | AUMODE_RECORD);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "Error setting latency, "
+ "latency restored to default\n");
+ sc->sc_latency = audio_blk_ms * PREFILL_BLOCKS;
+ error = audio_set_vchan_defaults(sc,
+ AUMODE_PLAY | AUMODE_PLAY_ALL | AUMODE_RECORD);
+ }
+
+ if (sc->sc_vchan_params.sample_rate > 0 &&
+ sc->sc_vchan_params.channels > 0 &&
+ sc->sc_vchan_params.precision > 0) {
+ sc->sc_latency = sc->sc_hwvc->sc_mpr.blksize * 1000 *
+ PREFILL_BLOCKS / sc->sc_vchan_params.sample_rate /
+ sc->sc_vchan_params.channels * NBBY /
+ sc->sc_vchan_params.precision;
+ }
+ mutex_exit(sc->sc_lock);
+
+ return error;
+}
+
static int
vchan_autoconfig(struct audio_softc *sc)
{
diff -r 3d86fee53b28 -r 5ab5d6b2e852 sys/dev/audiovar.h
--- a/sys/dev/audiovar.h Thu Oct 26 10:56:57 2017 +0000
+++ b/sys/dev/audiovar.h Thu Oct 26 22:38:27 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: audiovar.h,v 1.65 2017/09/24 23:40:41 nat Exp $ */
+/* $NetBSD: audiovar.h,v 1.66 2017/10/26 22:38:27 nat Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -205,6 +205,7 @@
bool sc_rec_started;
bool sc_writeme;
bool sc_ready; /* audio hw configured properly */
+ unsigned int sc_latency;
int sc_opens;
int sc_recopens;
bool sc_dying;
Home |
Main Index |
Thread Index |
Old Index