sndctl(8): Implement EQ controls
Sponsored by: The FreeBSD Foundation MFC after: 1 week Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/15
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd December 2, 2025
|
||||
.Dd April 17, 2026
|
||||
.Dt SNDCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -82,6 +82,8 @@ The device controls are as follows:
|
||||
.It bitperfect Ta Boolean Ta Read/Write Ta Bit-perfect mode enabled
|
||||
.It autoconv Ta Boolean Ta Read/Write Ta Auto-conversions enabled
|
||||
.It realtime Ta Boolean Ta Read/Write Ta Real-time mode enabled
|
||||
.It eq Ta Boolean Ta Read/Write Ta Equalization enabled
|
||||
.It eq_preamp Ta String Ta Read/Write Ta Equalization preamp value (in dB)
|
||||
.It play Ta Group Ta Read Ta Playback properties
|
||||
.It play.format Ta String Ta Read/Write Ta Playback format
|
||||
.It play.rate Ta Number Ta Read/Write Ta Playback sample rate
|
||||
|
||||
@@ -97,6 +97,8 @@ struct snd_dev {
|
||||
int bitperfect;
|
||||
int realtime;
|
||||
int autoconv;
|
||||
int eq;
|
||||
char eq_preamp[BUFSIZ];
|
||||
struct {
|
||||
char format[FMTSTR_LEN];
|
||||
int rate;
|
||||
@@ -130,6 +132,8 @@ struct map {
|
||||
static int mod_bitperfect(struct snd_dev *, void *);
|
||||
static int mod_autoconv(struct snd_dev *, void *);
|
||||
static int mod_realtime(struct snd_dev *, void *);
|
||||
static int mod_eq(struct snd_dev *, void *);
|
||||
static int mod_eq_preamp(struct snd_dev *, void *);
|
||||
static int mod_play_vchans(struct snd_dev *, void *);
|
||||
static int mod_play_rate(struct snd_dev *, void *);
|
||||
static int mod_play_format(struct snd_dev *, void *);
|
||||
@@ -149,6 +153,8 @@ static struct snd_ctl dev_ctls[] = {
|
||||
{ "bitperfect", F(bitperfect), NUM, mod_bitperfect },
|
||||
{ "autoconv", F(autoconv), NUM, mod_autoconv },
|
||||
{ "realtime", F(realtime), NUM, mod_realtime },
|
||||
{ "eq", F(eq), NUM, mod_eq },
|
||||
{ "eq_preamp", F(eq_preamp), STR, mod_eq_preamp },
|
||||
{ "play", F(play), GRP, NULL },
|
||||
{ "play.format", F(play.format), STR, mod_play_format },
|
||||
{ "play.rate", F(play.rate), NUM, mod_play_rate },
|
||||
@@ -436,6 +442,7 @@ read_dev(char *path)
|
||||
struct sndstioc_nv_arg arg;
|
||||
struct snd_dev *dp = NULL;
|
||||
struct snd_chan *ch;
|
||||
char buf[64];
|
||||
size_t nitems, nchans, i, j;
|
||||
int fd, caps, unit, t1, t2, t3;
|
||||
|
||||
@@ -557,6 +564,14 @@ read_dev(char *path)
|
||||
if (t1 == 0 && t2 == 0 && t3 == 0)
|
||||
dp->realtime = 1;
|
||||
|
||||
snprintf(buf, sizeof(buf), "dev.pcm.%d.eq", dp->unit);
|
||||
if (sysctl_int(buf, NULL, &dp->eq))
|
||||
xo_err(1, "%s: sysctl", dp->name);
|
||||
|
||||
snprintf(buf, sizeof(buf), "dev.pcm.%d.eq_preamp", dp->unit);
|
||||
if (sysctl_str(buf, NULL, dp->eq_preamp, sizeof(dp->eq_preamp)))
|
||||
xo_err(1, "%s: sysctl", dp->name);
|
||||
|
||||
if (!nvlist_exists(nvlist_get_nvlist(di[i],
|
||||
SNDST_DSPS_PROVIDER_INFO), SNDST_DSPS_SOUND4_CHAN_INFO))
|
||||
xo_errx(1, "%s: channel info list empty", dp->name);
|
||||
@@ -842,6 +857,32 @@ mod_realtime(struct snd_dev *dp, void *arg)
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static int
|
||||
mod_eq(struct snd_dev *dp, void *arg)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (dp->from_user)
|
||||
return (-1);
|
||||
|
||||
snprintf(buf, sizeof(buf), "dev.pcm.%d.eq", dp->unit);
|
||||
|
||||
return (sysctl_int(buf, arg, &dp->eq));
|
||||
}
|
||||
|
||||
static int
|
||||
mod_eq_preamp(struct snd_dev *dp, void *arg)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (dp->from_user)
|
||||
return (-1);
|
||||
|
||||
snprintf(buf, sizeof(buf), "dev.pcm.%d.eq_preamp", dp->unit);
|
||||
|
||||
return (sysctl_str(buf, arg, dp->eq_preamp, sizeof(dp->eq_preamp)));
|
||||
}
|
||||
|
||||
static int
|
||||
mod_play_vchans(struct snd_dev *dp, void *arg)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user