Apply "non-causal" filter buffer-wise, a.k.a "soft real-time filtering" I am dealing with digital filtering of signals, both offline and in real-time. Typical filtering purposes are highpass filter or bandpass filter.
So far I worked on prerecorded signals (e.g. wav files) so I could use a non-causal filter, such as Python's SciPy filtfilt or MATLAB's filtfilt, which produces zero-phase filtering (see What is zero-phase filtering and forward-backward filtering?). This has the desired effect of canceling any phase distortion. So far it worked very well off-line.
However, since according to theory this kind of filter is non-causal (e.g. the implementation of filtfilt has a stage in which the signal is filtered backwards from its end to its start), it can't be used for &quot;hard&quot; real-time filtering (i.e. reading single sample at a time and immediately filtering it).
I ask if this non-causal filter can be used for &quot;soft&quot; real-time filtering, that is: I read a buffer of n samples, then filter the buffer using filtfilt in the time-domain or by using its frequency response (which is purely real, obtained from the filter by the SciPy function freqz) in the frequency domain (via FFT), and then I read the next buffer and so on.
Another question is what is the recommended way to apply this filter: in the time-domain via filtfilt or in the frequency domain (multiplying the FFT coefficient $F(k)$ with the real positive frequency  response $|H(k)|$)? The purpose is to have a minimally-distorted filtered signal and fast and computationally efficient filtering (to run in &quot;soft&quot; real-time).
Added in edit:
In my application a filtering in the frequency space is desired, and multiplying $F(k)$ by $|H(k)|$ seems to work, even in real-time. But multiplying by the absolute value is like performing zero-phase filtering, which by theory is non-causal. However, since I apply it buffer-wise, this seems to be the loophole. Am I correct?
Thanks.
Overlap-add or overlap-save/scrap with zero-padded data are the common methods of using block based convolution on streaming data.  Pad the convolution (FFT/IFFT fast, or linear) by at least the length of the impulse response above your desired noise floor, minus 1.  The basic idea is that these methods save the remainder of the impulse response that doesn't fit in the current block's filtered results, and applies that remainder to blocks that are processed later.  For linear phase FIR filters, this still incurs as least half the length of the impulse response in latency.