2013/3/19 Justin Chudgar <justin at justinzane.com>: > I've created a module to ensure that only low frequencies are sent to devices > at the end of an "lfe"/"subwoofer" channel. This module allows the user to > select the master channel, the low pass cutoff frequency (aka corner freq, -3dB > freq) and the number of filter poles. I have received this e-mail and will review the DSP-related part of the file later today (when I return from work). However, even based on this short description and a cursory examination of the file, I can say that some of my criticisms are not addressed. First, it is said nowhere in the comments that you implement a Butterworth IIR filter. Second, you copy the non-LFE channels straight from input to output, and this is a Bad Thing if any filtering is applied to LFE. Please calculate the delay introduced by the filter and apply it to other channels if you still want to copy them (but see below). Unfortunately, I don't know the formula that allows one to calculate the phase delay introduced by the Butterworth filter (don't confuse this with group delay). Still, given some paper, pen, and some time, it should be possible to derive from the transfer function using the low-frequency limit. However, due to the objection below, it is pointless. I still maintain that filtering LFE (and only LFE) is the wrong thing to do at all. It doesn't help with 5.0 concert recordings (as found on music BluRays) and 2.0 recordings (found on audio CDs) where low frequencies are in the non-LFE channels (and should be moved to the LFE channel). Yes, this is a different problem from the one you are trying to fix (you assume that there is some non-LFE content in the LFE channel and try to filter it out). A correct implementation of a digital crossover filter is what will help both of our cases. Given that you now have Butterworth filters (congratulations! but I still have to check it for correctness), implementing a LR4 crossover filter should be easy. According to http://en.wikipedia.org/wiki/Linkwitz?Riley_filter , you have to: 1. Implement a 2nd order (this is not a user-adjustable parameter due to phase considerations, it really must be 2nd order) Butterworth lowpass filter and a 2nd order Butterworth highpass filter for the same user-selected cut-off frequency. 2. Instantiate 4N copies of the filter, where N is the number of channels of the acoustic system. Connect one lowpass filter and one highpass filter to each input channel. After each filter, insert another filter of the same kind. Note that applying a 2nd order Butterworth filter twice is not the same as applying a 4th order Butterworth filter once. 3. Now you have 2N filtered signals: twice-highpass-filtered left, twice-lowpass-filtered left, twice-highpass-filtered right, twice-lowpass-filtered right, ... , twice-highpass-filtered LFE, twice-lowpass-filtered LFE. 4. For non-LFE outputs, give them the sum of the corresponding twice-highpass-filtered input channel and 1/(N-1) of the twice-highpass-filtered LFE input channel. 5. For the LFE output, give it the sum of all twice-lowpass-filtered inputs (both LFE and non-LFE). Note: this can clip, it needs additional discussion what is the correct thing to do with it in PulseAudio context. Applying 1/(N-1) gain to all final outputs (including step (4)) is definitely safe, but users may complain that the filter loses a lot of volume. Maybe a configurable parameter is what's needed. If you want to implement a LR2 crossover instead, do this: 1. Implement a 1st order (this is not a user-adjustable parameter due to phase considerations, it really must be 1st order) lowpass filter and a 1st order highpass filter for the same cut-off frequency. 2. Instantiate 4N copies of the filter, where N is the number of channels of the acoustic system. Connect one lowpass filter and one highpass filter to each input channel. After each filter, insert another filter of the same kind. 3. Now you have 2N filtered signals: twice-highpass-filtered left, twice-lowpass-filtered left, twice-highpass-filtered right, twice-lowpass-filtered right, ... , twice-highpass-filtered LFE, twice-lowpass-filtered LFE. 4. For non-LFE outputs, give them the sum of the corresponding inverted twice-highpass-filtered input channel and 1/(N-1) of the non-inverted twice-highpass-filtered LFE input channel. 5. For the LFE output, give it the sum of all twice-lowpass-filtered non-inverted inputs (both LFE and non-LFE). In both cases, I have sent the (misplaced) high-frequency portion of the LFE channel to all remaining speakers. Feel free to send it only to the center (without the 1/(N-1) factor) or maybe discard, as you did in your module. Or make this an option. -- Alexander E. Patrakov