I have a real time series sampled at 32 MHz. So, when I channelized it and plot it against time, I get a Frequency vs. Time image plot where the frequency domain spans 16 MHz. To elaborate, this basically entails taking, say, 2048-sample chunks of data and doing a Fourier Transform on each to get a 1024-channel '16 MHz'-wide Fourier Transform over time (because we only care about positive frequencies). It looks something like this:

A frequency vs. time plot

Every vertical line in that plot is a Fourier Transform of 1024 channels. Which means that the time step between adjacent vertical lines is 2048 samples wide or 64 microseconds wide.

Now, what I want to do is convert this time series so that it looks like it was sampled at 48000 Hz, but not actually. Basically, I want the 16 Mhz frequency channel to correspond to a 24 kHz channel. So, I still want to preserve the structure of the data. So, a naive low-pass filter doesn't work, because I don't actually want to remove the higher frequencies, I just want to "redshift" it all. I want to go from a 0 - 16 MHz band to a 0 - 48 kHz band. But those pulses that pulse at 4 Hz, I still want them to pulse at 4 Hz.

The way I would try to do this, is by binning the channels. So, if I have 1024 channels (as from above) - I'd try to bin them into, say, 32 channels (and compress the spectrum by 32 times) - which basically means that I would take blocks of 32 channels and sum them or average them somehow to get one channel. Now, I really want to compress this spectrum 666 times but it doesn't matter. I really just need to understand how to meaningfully combine multiple Fourier Transforms into one.

Unfortunately, the only way I know how to do this is by taking the amplitude of the Fourier Transforms and then summing up adjacent channels to bin the channels. But this LOSES phase information - and I lose the pulses that I want to survive. So, how do I those these channels into a bin meaningful without losing both phase or amplitude information?

More concisely, my question is the following:

Given N Fourier Transforms of N real functions, is there a meaningful way to get a sum of them without losing phase and amplitude information?

Of course, this doesn't have to be the question if someone knows a better way to handle my overall problem without binning channels.


Mathematically, shifting the frequency of a signal is pretty easy:

Following @OlliNiemitalo's answer, the 0.003 frequency shift can either be done in

  • time domain, or
  • frequency domain.

I recommend doing it in time domain, by multiplying the signal with a complex sinusoid,

$$e^{j 2 \pi f_\text{shift} n},\, n \in\{1,2,\ldots\}$$

that way you can get arbitrary frequency shifts.

Still, you're not right about needing to add up the amplitudes -- what you're doing is probably coherent sampling (i.e., the sampling clock doesn't stop after each 2048 sample chunk and starts with a random delay for the next, but continously runs at a stable frequency), so adding up multiple FFTs without reducing them to their amplitude works -- that's the beauty of the DFT being a linear operation, and the bases of the base transform it is being orthogonal.

Think of it like this:

Assume you add up many ($k$) consecutive FFTs. Because the DFT is linear, it'd be the same as adding up many consecutive 2048-vectors of time samples. What happens then is that things that repeat every 2048 samples get multiplied by $k$, whereas things that don't get attenuated or cancel themselves out. That sounds like a bad thing™, however, you have to realize one thing about the frequencies that the DFT can represent in each bin:

Every bin in the 2048-FFT represents one frequency that is an integer multiple of the fundamental frequency (ie. $\frac{f_\text{sample}}{N_\text{FFT}}$). So things that perfectly fall into each bin already inherently repeat every $N_\text{FFT} = 2048$. Hence, doing that will usually (assuming sufficiently stable sampling clock!) simply improve your SNR by $k$.

Concluding, just add up 2048-vectors of your time signal, and transform the result. You will get a 2048-DFT with an increased SNR, which definitely is meaningful.

  • $\begingroup$ It's probably obvious but I can't seem to understand what $n$ refers to in your function? $\endgroup$ – XYZT Oct 9 '15 at 13:05
  • $\begingroup$ The running index of your series of e^(..) samples, @NikhilMahajan. $\endgroup$ – Marcus Müller Oct 10 '15 at 10:08
  • $\begingroup$ I failed to mention that the data stream I have is a 2-bit time series (Only 4 voltage values, centered at 0 - so really only 2 intensity values possible). So, some amount of binning is required to get SOME complexity, which is why I need it. It's not really a "pitch-shift ready" signal that can naively be transformed. $\endgroup$ – XYZT Oct 11 '15 at 4:01
  • $\begingroup$ bit-depth doesn't really matter -- that gives you an upper limit on SNR in your original samples, @NikhilMahajan, but with oversampling, you can increase that. Google for quantization noise. Adding up consecutive sample vectors really is nothing more than periodic oversampling. $\endgroup$ – Marcus Müller Oct 11 '15 at 19:53

If I am reading you correctly, you want to:

  • Scale frequencies by a factor of 0.003
  • Not scale time

In a musical context this is called pitch shifting, because musical notes follow a logarithmic frequency scale and addition (shifting) in that scale corresponds to multiplication in linear frequency scale. Alternatively, you can do frequency-preserving time stretching, followed by resampling.

It is quite difficult to do pitch shifting / time stretching well, and there is no one perfect way to do it as the optimal algorithm depends on what time-frequency structures you want to preserve. Most known algorithms do not approach it as a pure optimization problem but use heuristics to recognize frequencies in the Fourier transform, following them across analysis frames, and then try to resynthesize the scaled frequencies preserving amplitudes, and phase relationships at transients. Some algorithms are listed in https://en.wikipedia.org/wiki/Audio_time-scale/pitch_modification. It is common to try to counter the "chipmunk effect" of shifting formant frequencies, by preserving the overall spectral envelope, but in your case no such remedies are needed.

You can try Rubber Band, of which there are executable and library versions available. I have found it to give decent results for general audio. The 0.003 ratio is quite extreme, so it may be that you need to factor it into smaller partial ratios.

  • $\begingroup$ "The 0.003 ratio is quite extreme, so it may be that you need to factor it into smaller partial ratios." That is true, but unfortunately pulsar radiation frequencies don't translate well to audio sampling signals. $\endgroup$ – XYZT Oct 9 '15 at 13:07
  • $\begingroup$ Howcome? Was the sampling frequency too high? You could spoof it to be lower. $\endgroup$ – Olli Niemitalo Oct 10 '15 at 4:15
  • $\begingroup$ The original time series is sampled at 32 MHz. Getting it down to hearing levels requires quite some compression and loss of information. The sad fact is that the actual pulsar signal is super weak. And any "simple trick" to reduce the sampling rate usually risks losing it completely. There is also the problem that it's really hard to work with the original signal directly without binning - it's a 4-bit datastream, so it's not possible to naively apply pitch-shifts... $\endgroup$ – XYZT Oct 10 '15 at 5:59
  • $\begingroup$ pulsar radioation sounds like you should use something that is not as tremendously slow as sound hardware -- have you looked at SDR hardware? Even a 20€ USB DVB-T dongle does 2MS/s, which might be really awesome for oversampling/SNR increase reasons. Do you work at arecibo? they should have some USRP N210s lying around, which do that job, but with mjuch better signal performance. $\endgroup$ – Marcus Müller Oct 10 '15 at 10:06
  • $\begingroup$ The question is: Why would you want to have it at hearing levels? It's by no means an audio signal in the first place. $\endgroup$ – Marcus Müller Oct 10 '15 at 10:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.