3.7 KiB
Surroundize
Tool/PipeWire filter to convert stereo audio to surround, using Ffdshow's DPL2 decoder or Freesurround.
Building
Make sure you have a C++20 compiler and run.
make
If you don't have pipewire, you can compile just the standalone converter with
make surroundize-converter
Usage
There are two binaries currently.
./surroundize-converter --options < input.raw > output.raw
Input must be RAW samples, in stereo 32-bit float format, output will be also
32-bit float samples (channel order depends on the decoder, it's recommended to
set the --channel_map
option). The sample rate can be specified using the
--sample_rate option.
./surroundize-pipewire --options
A pipewire filter to convert stereo surround to surround. There's no auto connect, you have to use a patchbay or wireplumber scripts to connect it. This program allows changing the options run-time by entering the new options on stdin terminate by a newline. Note that multiple options can be specified on one line, separated by spaces (note that there is currently no escape character, so you can't specify values with spaces in them...).
Run any binary with --help
to get a list of available options. As a
convenience, leading dashes are ignored, so you can use just -option=value
or
option=value
instead of --option=value
if you're lazy.
Decoders
There are two decoders in this program (and one dummy which just outputs the input stereo samples without changes, useful for troubleshooting).
freesurround
is the higher quality one, supporting many surround formats, not
just 5.1. ffdshow
is closer to what a real Dolby Pro Logic 2 decoder would do,
faster, and only supports 5.1 output.
With freesurround
the most important option is probably block_size
which
sets the amount of samples to be processed at once. It has to be a power of two
(128, 256, 512, 1024, 2048, 4096, 8192, etc.) and ideally close to 100 ms (the
default 4096 is suitable for 44.1 kHz and 48 kHz). The problem with this is that
freesurround itself has a 0.5 * block_size
latency in itself, so this would
translate to a total latency of 150 ms with 100 ms block sizes (139 ms with 44.1
kHz, 128 ms with 48 kHz) just from the surround conversion! It's OK if you're
just playing music or video where you can fix the A-V sync, but for realtime
input it's probably too much. Here are some results from my totally not
representative listening tests at 48 kHz sound:
4096: Reference, OK
2048: Fine unless you're an audiophile
1024: Artifacts start to become noticeable, but still OK for most purposes
512: It starts to sound like a badly compressed MP3 file and also weird artifacts as sound sources move around.
256 and lower: Pretty bad, if 512 block size is still too much latency you
should look into the ffdshow
decoder instead if you can live with 5.1 output
and worse surround separation.
ffdshow
has way less controls than freesurround
, one useful option here
(with pipewire) is the --preamp
option, as ffdshow has a tendency to make the
output way louder than the input, resulting in clippings. Use it like
--preamp=0.5
for a approx. -6 dB reduction.
LICENSE
Freesurround and ffdshow are licensed under the GPL 2+, and as such this whole
thing is GPL'd. See the wall of text in LICENSE for details and make sure you
don't violate your freedom™ while doing that. pipewire.cpp
contains code from
the pipewire sample filter, licensed under the MIT license. Everything written
by me is licensed under WTFPL 2.0, because fuck copyright lawyers, not that it
matters the slightest.