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.

94 lines
3.7 KiB
Markdown

Surroundize
===========
Tool/PipeWire filter to convert stereo audio to surround, using
[Ffdshow][ffdshow tryout]'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.
[ffdshow tryout]: https://ffdshow-tryout.sourceforge.net/
[freesurround]: https://hydrogenaud.io/index.php/topic,52235.0.html