# How to perform a block-wise frequency down-shift?

I'm writing a Python function that shifts the frequency of an audio signal down to a specified range. I perform the downshift by multiplying the time series with a complex exponential, and then low-pass filter the result to remove the cyclic effect of the low frequencies shifting into the higher ones.

The function will be used to process an audio signal block by block in a loop. My question is, what will be the effect of starting the index $n$ of the complex exponetial at zero for each block?

$$X \big(e^{j2 \pi (f-f_0)}\big) = \mathscr{F} \Big\{ x[n] \cdot e^{j2 \pi f_0 n} \Big\}$$

Where $n \in \{0,..N-1\}$, and $N$ is the block length.

Intuitively, I'm thinking there would be an inconsistent phase-shift between blocks, but I'm not sure.

is there a way to avoid this, without continually incrementing the index throughout the life of the program?

Here's the code:

from numpy import fft, pi, r_, exp, int16, array, fromstring, zeros
from scipy.signal import firwin, lfilter

def shiftFreq(data, cutoff, fs, hist=None):
""" Downshift audio data

Parameters
------------
data: str
Binary data string of 16-bit audio data
cutoff: float
The new max frequency component after downshift and filtering
fs: float
Sample rate of audio data
hist: ndarray
Filter delay line

"""
data = fromstring(data, dtype=int16)
N = len(data)
num_taps = 128
delay = num_taps - 2
nyquist = fs/2

# initialize history
if hist is None:
hist = zeros(delay, dtype=data.dtype)

# Down-shift the data
shift = nyquist - cutoff
n = r_[0: N]
new_data = (data * exp(-1j * 2 * pi * shift * n/fs)).real

# Apply lowpass filter to remove cyclic effect
fir = firwin(num_taps, cutoff, nyq=nyquist)
new_data, hist = lfilter(fir, 1, new_data, zi=hist)

return int16(new_data).tostring(), hist


As an aside, are there other caveats I should be aware when performing a down-shift, that I haven't accounted for here?

• there is a pretty easy answer to your question as sorta stated. but is this, frequency shifting, what you really want to do? or do you want to perform pitch shifting? – robert bristow-johnson Sep 15 '17 at 2:36
• What I'm essentially trying to do is take a sound near the upper limit of human hearing and make it more audible. I suppose I could do that with pitch shifting as well. I'm less familiar with how to do that, though. It would probably sound better, but how would I perserve the signal duration? – orodbhen Sep 15 '17 at 9:08
• the way that pitch shifting preserves signal duration is by use of splicing. even in the form of a frequency-domain pitch shifter, when you down-pitch a signal, it keeps the signal duration the same by somehow splicing out redundant periods. – robert bristow-johnson Sep 15 '17 at 15:14

Yes there's one and let me put one of the most important caveats when performing frequency modifications. An acoustic sound signal (in the form of a music, speech etc) will physically exist in a so called harmonic structure (for more indepth discussions see sound synthesis, sound analysis etc.) whose immediate implication is that the perception of the frequency content is in octaves rather than linear frequency decades (an octave is the span of frequencies between $f_0$ and $2 f_0$).
It's easy to see that the harmonic structure of the audio band will be distorted when a complete band is shifted to other frequencies in a linear manner. As a solid example consider a primitive audio waveform composed of $440$ Hz, $880$ Hz and $1320$ Hz (these are $f_0$, $2f_0$ and $3f_0$ of an absurd instrument, more natural instruments will have more complicated structures including inharmonicities etc.)
Now if you linearly shift this waveform base from $f_0$ to $1.5 f_0$ then the new frequency distribution will be $1.5f_0$ , $2.5f_0$ and $3.5f_0$ which are no more harmonics. This creates an important problem in natural pitch shifting applications.