1*9cab9fdeSChristos Margiolis.\" 2*9cab9fdeSChristos Margiolis.\" Copyright (c) 2019 Google LLC, written by Richard Kralovic <riso@google.com> 3*9cab9fdeSChristos Margiolis.\" 4*9cab9fdeSChristos Margiolis.\" All rights reserved. 5*9cab9fdeSChristos Margiolis.\" 6*9cab9fdeSChristos Margiolis.\" Redistribution and use in source and binary forms, with or without 7*9cab9fdeSChristos Margiolis.\" modification, are permitted provided that the following conditions 8*9cab9fdeSChristos Margiolis.\" are met: 9*9cab9fdeSChristos Margiolis.\" 1. Redistributions of source code must retain the above copyright 10*9cab9fdeSChristos Margiolis.\" notice, this list of conditions and the following disclaimer. 11*9cab9fdeSChristos Margiolis.\" 2. Redistributions in binary form must reproduce the above copyright 12*9cab9fdeSChristos Margiolis.\" notice, this list of conditions and the following disclaimer in the 13*9cab9fdeSChristos Margiolis.\" documentation and/or other materials provided with the distribution. 14*9cab9fdeSChristos Margiolis.\" 15*9cab9fdeSChristos Margiolis.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*9cab9fdeSChristos Margiolis.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*9cab9fdeSChristos Margiolis.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*9cab9fdeSChristos Margiolis.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*9cab9fdeSChristos Margiolis.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*9cab9fdeSChristos Margiolis.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*9cab9fdeSChristos Margiolis.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*9cab9fdeSChristos Margiolis.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*9cab9fdeSChristos Margiolis.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*9cab9fdeSChristos Margiolis.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*9cab9fdeSChristos Margiolis.\" SUCH DAMAGE. 26*9cab9fdeSChristos Margiolis.\" 27*9cab9fdeSChristos Margiolis.\" 28*9cab9fdeSChristos Margiolis.Dd February 12, 2025 29*9cab9fdeSChristos Margiolis.Dt VIRTUAL_EQUALIZER 8 30*9cab9fdeSChristos Margiolis.Os 31*9cab9fdeSChristos Margiolis.Sh NAME 32*9cab9fdeSChristos Margiolis.Nm virtual_equalizer 33*9cab9fdeSChristos Margiolis.Nd audio equalizer 34*9cab9fdeSChristos Margiolis.Sh SYNOPSIS 35*9cab9fdeSChristos Margiolis.Nm 36*9cab9fdeSChristos Margiolis.Op Fl h 37*9cab9fdeSChristos Margiolis.Op Fl o 38*9cab9fdeSChristos Margiolis.Op Fl q 39*9cab9fdeSChristos Margiolis.Op Fl d Ar devname 40*9cab9fdeSChristos Margiolis.Op Fl w Ar what 41*9cab9fdeSChristos Margiolis.Op Fl p Ar part 42*9cab9fdeSChristos Margiolis.Op Fl c Ar channels 43*9cab9fdeSChristos Margiolis.Op Fl f Ar file 44*9cab9fdeSChristos Margiolis.Sh DESCRIPTION 45*9cab9fdeSChristos Margiolis.Nm 46*9cab9fdeSChristos Margiolissets the given frequency response for the given 47*9cab9fdeSChristos Margiolis.Xr virtual_oss 8 48*9cab9fdeSChristos Margiolisinstance via the control character device given by the -d option. 49*9cab9fdeSChristos MargiolisThe design goal of this equalizer is to provide precise equalization 50*9cab9fdeSChristos Margiolisfor arbitrary requested frequency response at the expense of higher 51*9cab9fdeSChristos Margiolislatency, utilizing a so-called finite impulse response, FIR, filter. 52*9cab9fdeSChristos Margiolis.Pp 53*9cab9fdeSChristos MargiolisThe requested frequency response is configured via standard input or 54*9cab9fdeSChristos Margiolisthe file specified by the -f option. 55*9cab9fdeSChristos MargiolisThere is one control point in per line. 56*9cab9fdeSChristos MargiolisEach line consists of two numbers, frequency in Hz and requested 57*9cab9fdeSChristos Margiolisamplification. 58*9cab9fdeSChristos MargiolisAmplification between two consecutive control points is a linear 59*9cab9fdeSChristos Margiolisinterpolation of the given control point values. 60*9cab9fdeSChristos Margiolis.Pp 61*9cab9fdeSChristos MargiolisTo make the filter finite, it is windowed in time domain using a Hann 62*9cab9fdeSChristos Margioliswindow. 63*9cab9fdeSChristos MargiolisThe windowing actually modifies the frequency response - the actual 64*9cab9fdeSChristos Margiolisresponse is a convolution of the requested response and spectrum of 65*9cab9fdeSChristos Margiolisthe window. 66*9cab9fdeSChristos MargiolisThis is, however, very close to the requested response. 67*9cab9fdeSChristos Margiolis.Pp 68*9cab9fdeSChristos MargiolisThe following options are available: 69*9cab9fdeSChristos Margiolis.Bl -tag -width indent 70*9cab9fdeSChristos Margiolis.It Fl q 71*9cab9fdeSChristos MargiolisBe quiet and don't print anything to standard output. 72*9cab9fdeSChristos Margiolis.It Fl d Ar device 73*9cab9fdeSChristos MargiolisThe 74*9cab9fdeSChristos Margiolis.Xr virtual_oss 8 75*9cab9fdeSChristos Margioliscontrol character device. 76*9cab9fdeSChristos Margiolis.It Fl w Ar what 77*9cab9fdeSChristos MargiolisSelect what part the FIR filter should apply to. 78*9cab9fdeSChristos MargiolisValid values are: rx_dev, tx_dev, rx_loop and tx_loop. 79*9cab9fdeSChristos MargiolisThe default value is tx_dev. 80*9cab9fdeSChristos Margiolis.It Fl p Ar part 81*9cab9fdeSChristos MargiolisSelect the index of the part given by the -w option to apply the filter to. 82*9cab9fdeSChristos MargiolisDefault is zero. 83*9cab9fdeSChristos Margiolis.It Fl c Ar channels 84*9cab9fdeSChristos MargiolisSelect number of channels to apply filter to, starting at channel zero. 85*9cab9fdeSChristos MargiolisBy default all channels of the given part are updated. 86*9cab9fdeSChristos Margiolis.It Fl f Ar file 87*9cab9fdeSChristos MargiolisRead filter coefficients from the given file instead of standard input. 88*9cab9fdeSChristos Margiolis.It Fl o 89*9cab9fdeSChristos MargiolisTurn equalizer off. 90*9cab9fdeSChristos Margiolis.It Fl h 91*9cab9fdeSChristos MargiolisShow usage. 92*9cab9fdeSChristos Margiolis.El 93*9cab9fdeSChristos Margiolis.Sh EXAMPLES 94*9cab9fdeSChristos MargiolisTo pass only frequencies between 200Hz and 400Hz: 95*9cab9fdeSChristos Margiolis.Bd -literal -offset indent 96*9cab9fdeSChristos Margiolis# Note that the -F and -G options enable FIR filtering. 97*9cab9fdeSChristos Margiolisvirtual_oss -B -C 2 -c 2 -S -Q 0 -b 32 -r 48000 -s 8ms -F 80ms -G 80ms \\ 98*9cab9fdeSChristos Margiolis -f /dev/dsp -d dsp.virtual -t vdsp.ctl 99*9cab9fdeSChristos Margiolis 100*9cab9fdeSChristos Margiolis# For simplex operation use this: 101*9cab9fdeSChristos Margiolisvirtual_oss -B -C 2 -c 2 -S -Q 0 -b 32 -r 48000 -s 8ms -F 80ms -G 80ms \\ 102*9cab9fdeSChristos Margiolis -R /dev/null -O /dev/dsp -d dsp.virtual -t vdsp.ctl 103*9cab9fdeSChristos Margiolis 104*9cab9fdeSChristos Margiolis# Load normalized filter points to avoid sample value overflow 105*9cab9fdeSChristos Margioliscat << EOF | virtual_equalizer -d /dev/vdsp.ctl -w tx_dev -p 0 -c 2 106*9cab9fdeSChristos MargiolisNORMALIZE 107*9cab9fdeSChristos Margiolis199 0.0 108*9cab9fdeSChristos Margiolis200 1.0 109*9cab9fdeSChristos Margiolis400 1.0 110*9cab9fdeSChristos Margiolis401 0.0 111*9cab9fdeSChristos MargiolisEOF 112*9cab9fdeSChristos Margiolis 113*9cab9fdeSChristos Margiolis# Load FIR filter based on sine frequency points 114*9cab9fdeSChristos Margioliscat << EOF | virtual_equalizer -d /dev/vdsp.ctl -w tx_dev -p 0 -c 2 115*9cab9fdeSChristos Margiolis199 0.0 116*9cab9fdeSChristos Margiolis200 1.0 117*9cab9fdeSChristos Margiolis400 1.0 118*9cab9fdeSChristos Margiolis401 0.0 119*9cab9fdeSChristos MargiolisEOF 120*9cab9fdeSChristos Margiolis 121*9cab9fdeSChristos Margiolis.Ed 122*9cab9fdeSChristos Margiolis.Sh SEE ALSO 123*9cab9fdeSChristos Margiolis.Xr virtual_oss 8 124*9cab9fdeSChristos Margiolis.Sh AUTHORS 125*9cab9fdeSChristos Margiolis.Nm 126*9cab9fdeSChristos Margioliswas written by 127*9cab9fdeSChristos Margiolis.An Richard Kralovic riso@google.com . 128