19cab9fdeSChristos Margiolis.\" 29cab9fdeSChristos Margiolis.\" Copyright (c) 2019 Google LLC, written by Richard Kralovic <riso@google.com> 39cab9fdeSChristos Margiolis.\" 49cab9fdeSChristos Margiolis.\" All rights reserved. 59cab9fdeSChristos Margiolis.\" 69cab9fdeSChristos Margiolis.\" Redistribution and use in source and binary forms, with or without 79cab9fdeSChristos Margiolis.\" modification, are permitted provided that the following conditions 89cab9fdeSChristos Margiolis.\" are met: 99cab9fdeSChristos Margiolis.\" 1. Redistributions of source code must retain the above copyright 109cab9fdeSChristos Margiolis.\" notice, this list of conditions and the following disclaimer. 119cab9fdeSChristos Margiolis.\" 2. Redistributions in binary form must reproduce the above copyright 129cab9fdeSChristos Margiolis.\" notice, this list of conditions and the following disclaimer in the 139cab9fdeSChristos Margiolis.\" documentation and/or other materials provided with the distribution. 149cab9fdeSChristos Margiolis.\" 159cab9fdeSChristos Margiolis.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 169cab9fdeSChristos Margiolis.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 179cab9fdeSChristos Margiolis.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 189cab9fdeSChristos Margiolis.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 199cab9fdeSChristos Margiolis.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 209cab9fdeSChristos Margiolis.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 219cab9fdeSChristos Margiolis.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 229cab9fdeSChristos Margiolis.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 239cab9fdeSChristos Margiolis.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 249cab9fdeSChristos Margiolis.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 259cab9fdeSChristos Margiolis.\" SUCH DAMAGE. 269cab9fdeSChristos Margiolis.\" 279cab9fdeSChristos Margiolis.\" 289cab9fdeSChristos Margiolis.Dd February 12, 2025 299cab9fdeSChristos Margiolis.Dt VIRTUAL_EQUALIZER 8 309cab9fdeSChristos Margiolis.Os 319cab9fdeSChristos Margiolis.Sh NAME 329cab9fdeSChristos Margiolis.Nm virtual_equalizer 339cab9fdeSChristos Margiolis.Nd audio equalizer 349cab9fdeSChristos Margiolis.Sh SYNOPSIS 359cab9fdeSChristos Margiolis.Nm 369cab9fdeSChristos Margiolis.Op Fl h 379cab9fdeSChristos Margiolis.Op Fl o 389cab9fdeSChristos Margiolis.Op Fl q 399cab9fdeSChristos Margiolis.Op Fl d Ar devname 409cab9fdeSChristos Margiolis.Op Fl w Ar what 419cab9fdeSChristos Margiolis.Op Fl p Ar part 429cab9fdeSChristos Margiolis.Op Fl c Ar channels 439cab9fdeSChristos Margiolis.Op Fl f Ar file 449cab9fdeSChristos Margiolis.Sh DESCRIPTION 459cab9fdeSChristos Margiolis.Nm 469cab9fdeSChristos Margiolissets the given frequency response for the given 479cab9fdeSChristos Margiolis.Xr virtual_oss 8 489cab9fdeSChristos Margiolisinstance via the control character device given by the -d option. 499cab9fdeSChristos MargiolisThe design goal of this equalizer is to provide precise equalization 509cab9fdeSChristos Margiolisfor arbitrary requested frequency response at the expense of higher 519cab9fdeSChristos Margiolislatency, utilizing a so-called finite impulse response, FIR, filter. 529cab9fdeSChristos Margiolis.Pp 539cab9fdeSChristos MargiolisThe requested frequency response is configured via standard input or 549cab9fdeSChristos Margiolisthe file specified by the -f option. 559cab9fdeSChristos MargiolisThere is one control point in per line. 569cab9fdeSChristos MargiolisEach line consists of two numbers, frequency in Hz and requested 579cab9fdeSChristos Margiolisamplification. 589cab9fdeSChristos MargiolisAmplification between two consecutive control points is a linear 599cab9fdeSChristos Margiolisinterpolation of the given control point values. 609cab9fdeSChristos Margiolis.Pp 619cab9fdeSChristos MargiolisTo make the filter finite, it is windowed in time domain using a Hann 629cab9fdeSChristos Margioliswindow. 639cab9fdeSChristos MargiolisThe windowing actually modifies the frequency response - the actual 649cab9fdeSChristos Margiolisresponse is a convolution of the requested response and spectrum of 659cab9fdeSChristos Margiolisthe window. 669cab9fdeSChristos MargiolisThis is, however, very close to the requested response. 679cab9fdeSChristos Margiolis.Pp 689cab9fdeSChristos MargiolisThe following options are available: 699cab9fdeSChristos Margiolis.Bl -tag -width indent 709cab9fdeSChristos Margiolis.It Fl q 719cab9fdeSChristos MargiolisBe quiet and don't print anything to standard output. 729cab9fdeSChristos Margiolis.It Fl d Ar device 739cab9fdeSChristos MargiolisThe 749cab9fdeSChristos Margiolis.Xr virtual_oss 8 759cab9fdeSChristos Margioliscontrol character device. 769cab9fdeSChristos Margiolis.It Fl w Ar what 779cab9fdeSChristos MargiolisSelect what part the FIR filter should apply to. 789cab9fdeSChristos MargiolisValid values are: rx_dev, tx_dev, rx_loop and tx_loop. 799cab9fdeSChristos MargiolisThe default value is tx_dev. 809cab9fdeSChristos Margiolis.It Fl p Ar part 819cab9fdeSChristos MargiolisSelect the index of the part given by the -w option to apply the filter to. 829cab9fdeSChristos MargiolisDefault is zero. 839cab9fdeSChristos Margiolis.It Fl c Ar channels 849cab9fdeSChristos MargiolisSelect number of channels to apply filter to, starting at channel zero. 859cab9fdeSChristos MargiolisBy default all channels of the given part are updated. 869cab9fdeSChristos Margiolis.It Fl f Ar file 879cab9fdeSChristos MargiolisRead filter coefficients from the given file instead of standard input. 889cab9fdeSChristos Margiolis.It Fl o 899cab9fdeSChristos MargiolisTurn equalizer off. 909cab9fdeSChristos Margiolis.It Fl h 919cab9fdeSChristos MargiolisShow usage. 929cab9fdeSChristos Margiolis.El 939cab9fdeSChristos Margiolis.Sh EXAMPLES 949cab9fdeSChristos MargiolisTo pass only frequencies between 200Hz and 400Hz: 959cab9fdeSChristos Margiolis.Bd -literal -offset indent 969cab9fdeSChristos Margiolis# Note that the -F and -G options enable FIR filtering. 979cab9fdeSChristos Margiolisvirtual_oss -B -C 2 -c 2 -S -Q 0 -b 32 -r 48000 -s 8ms -F 80ms -G 80ms \\ 989cab9fdeSChristos Margiolis -f /dev/dsp -d dsp.virtual -t vdsp.ctl 999cab9fdeSChristos Margiolis 1009cab9fdeSChristos Margiolis# For simplex operation use this: 1019cab9fdeSChristos Margiolisvirtual_oss -B -C 2 -c 2 -S -Q 0 -b 32 -r 48000 -s 8ms -F 80ms -G 80ms \\ 1029cab9fdeSChristos Margiolis -R /dev/null -O /dev/dsp -d dsp.virtual -t vdsp.ctl 1039cab9fdeSChristos Margiolis 1049cab9fdeSChristos Margiolis# Load normalized filter points to avoid sample value overflow 1059cab9fdeSChristos Margioliscat << EOF | virtual_equalizer -d /dev/vdsp.ctl -w tx_dev -p 0 -c 2 1069cab9fdeSChristos MargiolisNORMALIZE 1079cab9fdeSChristos Margiolis199 0.0 1089cab9fdeSChristos Margiolis200 1.0 1099cab9fdeSChristos Margiolis400 1.0 1109cab9fdeSChristos Margiolis401 0.0 1119cab9fdeSChristos MargiolisEOF 1129cab9fdeSChristos Margiolis 1139cab9fdeSChristos Margiolis# Load FIR filter based on sine frequency points 1149cab9fdeSChristos Margioliscat << EOF | virtual_equalizer -d /dev/vdsp.ctl -w tx_dev -p 0 -c 2 1159cab9fdeSChristos Margiolis199 0.0 1169cab9fdeSChristos Margiolis200 1.0 1179cab9fdeSChristos Margiolis400 1.0 1189cab9fdeSChristos Margiolis401 0.0 1199cab9fdeSChristos MargiolisEOF 1209cab9fdeSChristos Margiolis 1219cab9fdeSChristos Margiolis.Ed 1229cab9fdeSChristos Margiolis.Sh SEE ALSO 1239cab9fdeSChristos Margiolis.Xr virtual_oss 8 1249cab9fdeSChristos Margiolis.Sh AUTHORS 1259cab9fdeSChristos Margiolis.Nm 1269cab9fdeSChristos Margioliswas written by 1279cab9fdeSChristos Margiolis.An Richard Kralovic riso@google.com . 128