"padsynth" — Generate a sample table using the padsynth algorithm.

Paul Octavian Nasca's "padsynth algorithm" adds bandwidth to each partial of a periodic weaveform. This bandwidth is heard as color, movement, and additional richness of sound.

First, the waveform is defined by the user as a series of harmonic partials. Then, bandwidth is added by independently spreading each partial of the original waveform from a single frequency across neighboring frequencies, according to a "profile" function: a Gaussian curve, a square, or a rising and then falling expontential.

The partials of the original waveform may be considered to be samples in a discrete Fourier transform of the waveform. Normally there is not an exact one-to-one correspondence between the frequencies of the samples (frequency bins) of the discrete Fourier transform with the frequencies of the partials of the original waveform, because any frequency in the inverse of the discrete Fourier transform might be synthesized by interference between any number of bins. However, the padsynth algorithm uses a simple trick to create this correspondence. The discrete Fourier transform is simply made so large that the frequency of any partial of the original waveform will be very close to the frequency of the corresponding bin in the Fourier transform. Once this correspondence has been created, the bandwidth profile can be applied by centering it over the frequency bin of the original partial, scaling the profile by the bandwidth, and simply multiplying the original partial by each sample of the profile and adding the product to the corresponding bin of the Fourier transform.

As the frequencies of the partials increase, their bandwidth may optionally become wider or (less often) narrower.

Once each partial has been spread out in this way, the discrete Fourier transform may be given random phases, and is then simply inverted to synthesize the desired waveform, which may be used as the wavetable for a digital oscillator.

N.B.: The size of the function table does NOT necessarily reflect one periodic cycle of the waveform that it contains. The fundamental frequency must be used to generate the desired pitch from an oscillator using the function table, e.g.

```
oscillator_hz = desired_hz * (sr / padsynth_size / fundamental_hz)
```

**f** # score_time table_size "padsynth" fundamental_frequency
partial_bandwidth partial_scale harmonic_stretch profile_shape profile_shape_parameter
partial1_amplitude [partial2_amplitude ...]

*table_size* -- Function table size. Should be large,
e.g. 2^18 == 262144. Must be a power of 2 or power-of-2 plus 1 (see *f statement*).

*fundamental_frequency* -- Fundamental frequency for
the generated table.

*partial_bandwidth* -- Bandwidth of each partial in cents.

*partial_scale* -- Scaling factor for bandwidth of each partial (log of increase/decrease
with partial frequency, 0 is no stretch or shrink).

*harmonic_stretch* -- Harmonic stretch/shrink for all partials (1 is harmonic).

*profile_shape* -- Number specifying the shape of the bandwidth profile:
1 = Gaussian, 2 = square, and 3 = exponential

*profile_shape_parameter* -- Parameter passed to the function generating the profile shape, e.g. exponent.

*partial1_amplitude, partial2_amplitude, ...* -- Amplitudes for each partial (may be zero).

Here is an example of the GENpadsynth routine. It uses the files *padsynth_gen.csd*.

**Example 1222. An example of the GENpadsynth routine.**

<CsoundSynthesizer> <CsOptions> -odac </CsOptions> <CsInstruments> sr=44100 ksmps=1 nchnls=2 0dbfs=2000 gispec_len init 2^18 instr 1 prints "Plain sine for frequency/amplitude/distortion comparison.\n" gi_padsynth_1 ftgenonce 0, 0, gispec_len, 10, 1 iattack = 0.08 idecay = 0.1 isustain = 0.25 irelease = 0.2 aenv madsr iattack, idecay, isustain, irelease ifreq cpsmidinn p4 iamp ampdb p5 ibasefreq = 440 ; can be lower or higher frequency; close to played frequency is said to be best ibw_cents = 56.96943 ; width of the peaks, 100 is semitone asig poscil iamp, ifreq, gi_padsynth_1 asig = aenv * asig aleft, aright pan2 asig, 0.5 outs aleft, aright endin instr 2 prints "PadSynth with sine tone.\n" ibasehz = 261.625565 ; p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 gi_padsynth_1 ftgenonce 0, 0, gispec_len, "padsynth", ibasehz, p6, 0.0, 1, 1, 1.0, 1 iattack = 0.08 idecay = 0.1 isustain = 0.25 irelease = 0.2 aenv madsr iattack, idecay, isustain, irelease ifreq cpsmidinn p4 iamp ampdb p5 asig poscil iamp, ifreq*(sr/gispec_len/ibasehz), gi_padsynth_1 asig = aenv * asig aleft, aright pan2 asig, 0.5 outs aleft, aright endin instr 3 prints "PadSynth with harmonics.\n" ibasehz = 261.625565 ; p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 gi_padsynth_1 ftgenonce 0, 0, gispec_len, "padsynth", ibasehz, p6, 1, 1, 1, 1, 0.7600046992, 0.6199994683, 0.9399998784, 0.4400023818, 0.0600003302, 0.8499968648, 0.0899999291, 0.8199964762, 0.3199984133, 0.9400014281, 0.3000001907, 0.120003365, 0.1799997687, 0.5200006366, 0.9300042987 iattack = 0.08 idecay = 0.1 isustain = 0.25 irelease = 0.2 aenv madsr iattack, idecay, isustain, irelease ifreq cpsmidinn p4 iamp ampdb p5 asig poscil iamp, ifreq*(sr/gispec_len/ibasehz), gi_padsynth_1 asig = aenv * asig aleft, aright pan2 asig, 0.5 outs aleft, aright endin instr 4 prints "PadSynth with inharmonic partials.\n" ibasehz = 261.625565 ; p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 gi_padsynth_1 ftgenonce 0, 0, gispec_len, "padsynth", ibasehz, p6, 1, 2, 3, 1, 0.7600046992, 0.6199994683, 0.9399998784, 0.4400023818, 0.0600003302, 0.8499968648, 0.0899999291, 0.8199964762, 0.3199984133, 0.9400014281, 0.3000001907, 0.120003365, 0.1799997687, 0.5200006366, 0.9300042987 iattack = 0.08 idecay = 0.1 isustain = 0.25 irelease = 0.2 aenv madsr iattack, idecay, isustain, irelease ifreq cpsmidinn p4 iamp ampdb p5 asig poscil iamp, ifreq*(sr/gispec_len/ibasehz), gi_padsynth_1 asig = aenv * asig aleft, aright pan2 asig, 0.5 outs aleft, aright endin </CsInstruments> <CsScore> i1 0 2 60.00 60 i1 + 2 72.00 60 i1 + 2 84.00 60 i2 7 2 60.00 60 0.3 i2 + 2 72.00 60 0.3 i2 + 2 84.00 60 0.3 i2 + 2 60.00 60 25 i2 + 2 72.00 60 25 i2 + 2 84.00 60 25 i2 + 2 60.00 60 55 i2 + 2 72.00 60 55 i2 + 2 84.00 60 55 i3 26 2 60.00 60 0.3 i3 + 2 72.00 60 0.3 i3 + 2 84.00 60 0.3 i3 + 2 60.00 60 25 i3 + 2 72.00 60 25 i3 + 2 84.00 60 25 i3 + 2 60.00 60 55 i3 + 2 72.00 60 55 i3 + 2 84.00 60 55 i4 45 2 60.00 60 0.3 i4 + 2 72.00 60 0.3 i4 + 2 84.00 60 0.3 i4 + 2 60.00 60 25 i4 + 2 72.00 60 25 i4 + 2 84.00 60 25 i4 + 2 60.00 60 55 i4 + 2 72.00 60 55 i4 + 2 84.00 60 55 e </CsScore> </CsoundSynthesizer>