How do you construct common waveforms (square, sawtooth, triangle, noise) from sine wave partials using an IFFT? In the lovely image below we see the addition of sine waves making a square wave. I am coding a wave table synthesiser and thought it would be great to get the user to be able to fiddle with the values of the sine partials and then run an inverse FFT on them to produce the wave form.



I have some code for an FFT and you specify the number of buckets, real and imaginary arrays and the array length. The way it is used in the example is:


Imaginary array has all it's values set to 0
The real array has its 0th element set to 0
The real array has its arrayLength/2 element set to 0
Other values are set in the real array. Every time a value is set in the first half of the array one is set at the opposite end of the array, mirroring whatever is happening in the first half of the real array.
This spits out a single cycle of the waveform constructed using these sine partials


What are some common patterns for filling these partials to generate waveforms. How do you generate a square wave, a triangle wave, a sawtooth? Can you create noise or is that impossible if it is non periodic?

Extra: What are some tricks for producing 'good' waveforms? This is an opinion question, just a bonus if you have something to share about producing waveforms that sound good. (Good in your opinion :)

For those who would find it interesting there is a flash app here that lets you set the levels of the partials in order to construct waveforms, it's fun.
You can find the formulas for a rectangular, square, triangle, sawtooth and rectified sinusoidal waveform in Chapter 13 section The Fourier Series, of the Scientist and Engineer's Guide to Digital Signal Processing by Steven W. Smith. 

If you IFFT a vector of random numbers, you get out another vector of random numbers that approximately follow a Gaussian distribution, due to the central limit theorem and that each time domain number was formed as a linear combination of multiple frequency domain numbers. But it will be periodic so it won't sound like pure noise unless the vector length is huge.

If you want to construct your own arbitrary waveform from line segments you can use:
$$f(x) = \left\{\begin{array}{ll}a + b\ x &amp; \text{if}\ x_0 &lt;= x &lt; x_1\\ 0 &amp; \text{otherwise}\end{array}\right.\\
\hat f(\omega) = \int^{+\infty}_{-\infty} e^{-i\omega\ x} f(x) = \int^{x_1}_{x_0} e^{-i\omega\ x}(a + b\ x) = -\frac{b\ \cos(\omega\ x_0)}{\omega^2} - \frac{(a + b\ x_0)\ \sin(\omega\ x_0)}{\omega} + \frac{b\ \cos(\omega\ x_1)}{\omega^2} + \frac{(a + b\ x_1)\ \sin(\omega\ x_1)}{\omega} + i\ \left(-\frac{(a + b\ x_0)\ \cos(\omega\ x_0)}{\omega} + \frac{b\ \sin(\omega\ x_0)}{\omega^2} + \frac{(a + b\ x_1)\ \cos(\omega\ x_1)}{\omega} - \frac{b\ \sin(\omega\ x_1)}{\omega^2}\right),$$

where $a = \frac{x_0\ y_1 - x_1\ y_0}{x_0 - x_1}$ and $b =\frac{y_0 - y_1}{x_0 - x_1}$ for a line segment starting at $(x_0, y_0)$ and ending at $(x_1, y_1)$ and  $\hat f(\omega)$ is the Fourier transform of $f(x)$. Discretely sampling $\hat f(\omega)$ at multiples of $2\pi$ will make $f(x)$ periodic by 1. If you have more than one segment you can sum their Fourier transforms.