You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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.