I’’m synthesising a simple sine wave using the IFFT. I’m controlling the pitch of the sine wave by controlling the bin number and the phase for that bin number.

I’ve synthesised an F whose frequency is very close to a bin centre frequency and everything looks good.

enter image description here

however when I detune that same note away from the bin centre frequency I start to get additional harmonics showing up. Like this: (Note the -30db peak just after the significant peak, and the appearance of signal all the way to the left.)

Why is this occurring???

enter image description here

  • 1
    $\begingroup$ You need to tell us how you synthesize a sine wave using ifft, if the frequency is between bins. $\endgroup$ – Matt L. Jun 12 '16 at 10:20
  • $\begingroup$ Basically, I'm pitch shifting the harmonic by calculating the phase delta of the desired frequency relative to the centre frequency expected phase, then adding the delta to the expected phase increase. This results in the desired pitch however I get the above small additional harmonic which I'm not expecting (given its a sine wave) $\endgroup$ – cixelsyd Jun 12 '16 at 10:40
  • 1
    $\begingroup$ @cixelsyd not 100% sure I can follow you there; would you mind adding that as a formula to your question? $\endgroup$ – Marcus Müller Jun 12 '16 at 14:27
  • $\begingroup$ @MarcusMüller MattL. This may be the technique that OP is using: blogs.zynaptiq.com/bernsee/pitch-shifting-using-the-ft $\endgroup$ – MBaz Jun 13 '16 at 1:58

Note that additive overlapped windows of pure sinewaves of different phases will not produce a pure sinewave. The difference may include something like a low frequency beat note, which might explain the low frequency content in the 2nd spectrum. Modulation side-bands might explain the nearby higher peak. See trigonometric sum and difference formulas.

Splitting the magnitude of your between bin frequency between the two (or more) nearest bins using Sinc interpolation might help reduce your artifacts somewhat, depending on how you do your delta phase correction/interpolation between windows.

  • $\begingroup$ Thanks for weighing in Hotpaw2. At the moment Im not splitting the magnitude across the two nearest bins and I suspected that might be the cause. Is there a standard way of calculating this split? i.e. is it linear? I would have thought it would be something more guassian? $\endgroup$ – cixelsyd Jun 12 '16 at 23:19
  • $\begingroup$ Sinc interpolation is the proper split. $\endgroup$ – hotpaw2 Jun 12 '16 at 23:32
  • $\begingroup$ How would I implement this in the context of the bin magnitude? Sorry I know I'm showing my ignorance. I did perform the obligatory google search but now I'm confused. $\endgroup$ – cixelsyd Jun 13 '16 at 5:07
  • $\begingroup$ @cixelsyd : That sounds like it might be appropriate as a separate and new question. $\endgroup$ – hotpaw2 Jun 13 '16 at 5:45

This is likely due to a truncation of your sine wave in the time interval you have chosen, such that there is not an integer multiple number of sine wave cycles chosen. I am guessing that your frequency view that you provide above is a subsequent measurement (DFT) from the resulting time domain waveform you have created, and not a view of your original frequency function you are using to create the time domain waveform (as the original function in the frequency domain would not have those artifacts!).

That said, the specific answer will depend on how exactly you create and repeat/extend the final time domain waveform from the fixed length IFFT result that you get, but below are some insights on the effects of waveform truncation in the time domain that may help you to understand how you may be getting such artifacts.

A direct and concise mathematical answer of frequency effects from waveform truncation can be derived by describing your fixed length (sampled) waveform in the time domain as an infinite length waveform multiplied that is not truncated by a rectangular (boxcar) window. Multiplication in the time domain is convolution in the frequency domain, so the result of a boxcar window truncation would be convolving the frequency you would get without truncation with a sinc function (or when sampled, the approximation of a sinc function).

I like to view the resulting effect by picturing the time domain waveform extending from minus infinity to positive infinity in time, made up of your specific waveform snippet (IFFT result) continuously repeating in time. For a direct DFT this analogy this is mathematically valid (meaning the DFT over the finite time interval would match the DTFT of the same sequence repeating it time (just that the DTFT would be a continuous function and the DFT would be samples of this function- see below). Repetition in the time domain over an interval T results in a FT with discrete impulses in the frequency domain spaced at 1/T.).

From this view it may be clearer to see the effects of truncation: if we had 1.5 cycles of a sine wave in your time interval, the sine wave would suddenly snap every 1.5 cycles in the repeating waveform, requiring higher frequencies to achieve this "snap" that takes place in time. In contrast if you had an exact integer number of cycles (for a samples system, samples 0 to N-1, where sample 0 would be identical to the sample N for a pure undistorted sine wave), then the FT result (and DFT and DTFT) would only exist at one frequency location with 0 elsewhere; as expected for a pure tone.

FT, DTFT, DFT Background

I reference FT, DTFT, and DFT above, so I included this graphic and primer below to help clear up any confusion for those less familiar.

enter image description here

What is shown is the FT (or CTFT), DTFT, and DFT for a pure tone (that in "truth" extends from minus infinity to infinity in time), along with a modulated waveform of finite bandwidth. In the Fourier Transforms, the tone is shown in blue while the modulated waveform is shown in red, and $\omega_s$ is the sampling frequency.

The CTFT is the Continuous Time Fourier Transform, or Fourier Transform (FT) for short.

$$ X(\omega) = \int_{t=-\infty}^\infty x(t)e^{-j\omega t}dt $$


continuous in time -> aperiodic in frequency

aperiodic in time -> continuous in frequency

The DTFT is the Discrete Time Fourier Transform; the time interval still goes from minus infinity to infinity, but the system is now sampled. It is a sampled FT, which create repetition in frequency.

$$ X(\omega) = \sum_{n=-\infty}^\infty x[n]e^{-j\omega n} $$


discrete in time -> periodic in frequency

aperiodic in time -> continuous in frequency

The DFT is the Discrete Fourier Transform; the time interval is defined over a finite interval. There is an implied periodicity in time, meaning if you made a waveform by repeating this one in time from minus infinity to infinity, the DTFT of this periodic waveform would match the DFT at the DFT sample locations (see plot above).

$$ X[k] = \sum_{n=0}^{N-1}x[n] e^{-j\omega_o k/n} $$


discrete in time -> periodic in frequency (implied)

periodic in time (implied) -> discrete in frequency

*note the time domain and frequency domain waveforms are not really periodic, as they only exist over a finite number of samples- but I like to make this interpretation, as if you did repeat the waveform in both domains you would get the same valued discrete samples (but they would be continuous waveforms with zero values in between). This interpretation has been extremely helpful for me in working with mixed signal (analog/digital) systems.

  • $\begingroup$ Thanks for the detailed answer Dan. To answer a few of your questions I am convolving the sound using an overlap and add function with 75% overlap or 4x oversampling. I am also using a cosine window (Hanning) window. I am recalculating the phase every frame in order to advance it the harmonics phase in line with the oversampling. I thought this would be enough to eliminate the aliasing. $\endgroup$ – cixelsyd Jun 12 '16 at 19:28
  • $\begingroup$ Yes agreed and now you have my interest; if you are processing in Matlab or Python please email me your file and script and I will see if I can add any further insight but sounds like you are doing all the right things. $\endgroup$ – Dan Boschen Jun 12 '16 at 20:59
  • $\begingroup$ (boschen@loglin.com) $\endgroup$ – Dan Boschen Jun 12 '16 at 21:28
  • $\begingroup$ @ Dan Boschen I don't have Matlab or Python, are you ok with my C++ synthesis code? $\endgroup$ – cixelsyd Jun 12 '16 at 21:53
  • $\begingroup$ Unfortunately not as easily. $\endgroup$ – Dan Boschen Jun 12 '16 at 22:24

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.