# 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? Sep 15, 2017 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? Sep 15, 2017 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. Sep 15, 2017 at 15:14

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

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$).

Now, eventhough for most technical applications (such as in those communication algorithms) a band of frequencies can be shifted to any desired frequency without a loss of information (which forms the essence of the modulation theory) when it comes to audio perception this does not hold.

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.