Menu

#216 Equalizer and Convolution (FIR) of stereo files.

open
nobody
FIR filter (1)
5
2025-11-25
2018-11-17
Marco Curti
No

Hi All,

I'm the writer of C-3PO plugin for squeezebox server that is mainly an interface over SOX functionalities, like resampling, converting, equalizer, loudness, volume and many others, lastly convolution, trying to use FIR effect.

what I wul dlike to do is simple:

sox.exe stereo_IN.wav mono_1.wav remix 1,1 fir filter1.txt
sox.exe stereo_IN.wav mono_2.wav remix 2,1 fir filter2.txt
sox.exe -M mono_1.wav mono_2.wav stereo_out.wav

and it works like a charm, but - as you probably already know - in Squeezebox server SOX is used in 'real time' using pipes from and to other components, like, i.e. :

stdin | sox -t flac - -t wav - gain -h rate 48000 | stdout

in this context i could not figure out how to accomplish the same.

This is common to all the effects, like equalizer, when you need to behave differently on diferent channels, or I'm missing something here?

I was hoping FIR effect could apply to sterero wav, as is quite usual, then I've then tried to use a 'stereo' version of the filter.txt, produced with sox like that:

sox filter.wav filter.dat

and then removing the header and the first column, resulting in something like:

0 0
0 0
0.000000000000000048337853954449874 -0.0000000000000000073065849268651543
0.00000000000000019416468946424684 0.000000000000000028926625355229495
0.00000000000000043864907854011207 -0.00000000000000006725621240960354
...
0 0
0 0

but it seems to me that it does not matter, fir apply all the coefficients to every channel, no matter the column in the file, resulting in a wrong correction (as it was a filter written for double sample rate).

If It is so, I've no chance, then question is shall we think to have differentiate input for FIR effects maybe using the .dat format as input definition?

Thanks in advance for any help you could give in me in make it work.

Marco.

Discussion

  • Marco Curti

    Marco Curti - 2018-11-17

    What is confusing me is that in the SOX log we have:

    sox INFO sox: effects chain: fir 44100Hz 2 channels

    here the complete log:

    F:\SVILUPPO\06 - sox>sox -V3 PinkNoise_44k_16-bit.wav PN_shelving.wav fir shelving.txt
    sox: SoX v14.4.2
    sox INFO formats: detected file format type `wav'

    Input File : 'PinkNoise_44k_16-bit.wav'
    Channels : 2
    Sample Rate : 44100
    Precision : 16-bit
    Duration : 00:01:00.00 = 2646000 samples = 4500 CDDA sectors
    File Size : 10.6M
    Bit Rate : 1.41M
    Sample Encoding: 16-bit Signed Integer PCM
    Endian Type : little
    Reverse Nibbles: no
    Reverse Bits : no

    sox INFO sox: Overwriting `PN_shelving.wav'

    Output File : 'PN_shelving.wav'
    Channels : 2
    Sample Rate : 44100
    Precision : 16-bit
    Duration : 00:01:00.00 = 2646000 samples = 4500 CDDA sectors
    Sample Encoding: 16-bit Signed Integer PCM
    Endian Type : little
    Reverse Nibbles: no
    Reverse Bits : no
    Comment : 'Processed by SoX'

    sox INFO fir: 32766 coefficients
    sox INFO sox: effects chain: input 44100Hz 2 channels
    sox INFO sox: effects chain: fir 44100Hz 2 channels
    sox INFO sox: effects chain: dither 44100Hz 2 channels
    sox INFO sox: effects chain: output 44100Hz 2 channels

     
  • Marco Curti

    Marco Curti - 2018-11-19

    I've found the way to use a single command line to accomplish the JOB:

    sox -M -t sox "|sox.exe PinkNoise_44k_16-bit.wav -p remix 1,1 fir shelvingHigh.txt" "|sox.exe PinkNoise_44k_16-bit.wav -p remix 2,1 fir shelvingLow.txt" PN_shelving.wav

    whete shelvingHigh and shelvingLow are the mono versions of shelving.txt.

    Usagae of sox/-p avoid any loss of samples that occours using wavas intermediate, Output is 32bit, but could be easily reduced to 16bit and dithered.

    Too bad, seems to me that the output is written only when both input are completely processed, so it's good for batch processing but not for real time (i.e. apply FIR to an incoming stream from Tidal or Qobuz).

    Any idea?

     
  • Martin Guy

    Martin Guy - 2025-11-25

    "sox format" should write the data as it is generated, not all at once when all input has been processed. For real-time use, you'd have to duplicate the input somehow, so that both SoXen can read the same data. You can do this on Unix with

    rm -f fifo1 fifo2
    mkfifo fifo1 fifo2
    tee fifo1 > fifo2 & # Reads stdin and sends it to both fifos
    sox_ng -M -t sox "|sox_ng fifo1 -p remix 1,1 fir filter1.txt" "|sox_ng fifo2 -p remix 2,1 fir filter2.txt" PN_shelving.wav # or "-b 16 -t raw -" to send to stdout

    though it may be better to use -t raw - than -p (which is -t sox -) to avoid any funnies to do with the audio length being unknown when reading from stdin.

    Windows also seems to have named pipes these days, though you may need to write a little program to create them and do the work of "tee" in the background.

    However, see https://codeberg.org/sox_ng/sox_ng/issues/706 where there may be a different
    solution we could implement fairly easily for this specific need.

     

Log in to post a comment.

MongoDB Logo MongoDB