WAVESHAPING
Waveshaping can in some ways be thought of as a relation to modulation techniques such as frequency or phase modulation. Waveshaping can achieve quite dramatic sound transformations through the application of a very simple process. In FM (frequency modulation) modulation synthesis occurs between two oscillators, waveshaping is implemented using a single oscillator (usually a simple sine oscillator) and a socalled 'transfer function'. The transfer function transforms and shapes the incoming amplitude values using a simple lookup process: if the incoming value is x, the outgoing value becomes y. This can be written as a table with two columns. Here is a simple example:
Incoming (x) Value  Outgoing (y) Value 
0.5 or lower

1 
between 0.5 and 0.5

remain unchanged

0.5 or higher

1 
Illustrating this in an x/y coordinate system results in the following graph:
Basic Implementation Model
Although Csound contains several opcodes for waveshaping, implementing waveshaping from first principles as Csound code is pretty straightforward. The xaxis is the amplitude of every single sample, which is in the range of 1 to +1.^{1} This number has to be used as index to a table which stores the transfer function. To create a table like the one above, you can use Csound's subroutine GEN07^{2} . This statement will create a table of 4096 points in the desired shape:
giTrnsFnc ftgen 0, 0, 4096, 7, 0.5, 1024, 0.5, 2048, 0.5, 1024, 0.5
Now two problems must be solved. First, the index of the function table is not 1 to +1. Rather, it is either 0 to 4095 in the raw index mode, or 0 to 1 in the normalized mode. The simplest solution is to use the normalized index and scale the incoming amplitudes, so that an amplitude of 1 becomes an index of 0, and an amplitude of 1 becomes an index of 1:
aIndx = (aAmp + 1) / 2
The other problem stems from the difference in the accuracy of possible values in a sample and in a function table. Every single sample is encoded in a 32bit floating point number in standard audio applications  or even in a 64bit float in recent Csound.^{3} A table with 4096 points results in a 12bit number, so you will have a serious loss of accuracy (= sound quality) if you use the table values directly.^{4} Here, the solution is to use an interpolating table reader. The opcode tablei (instead of table) does this job. This opcode then needs an extra point in the table for interpolating, so it is wise to use 4097 as size instead of 4096.^{5}
This is the code for the simple waveshaping with the transfer function which has been discussed so far:
EXAMPLE 04E01_Simple_waveshaping.csd
<CsoundSynthesizer> <CsOptions> odac </CsOptions> <CsInstruments> sr = 44100 ksmps = 32 nchnls = 2 0dbfs = 1 giTrnsFnc ftgen 0, 0, 4097, 7, 0.5, 1024, 0.5, 2048, 0.5, 1024, 0.5 giSine ftgen 0, 0, 1024, 10, 1 instr 1 aAmp poscil 1, 400, giSine aIndx = (aAmp + 1) / 2 aWavShp tablei aIndx, giTrnsFnc, 1 outs aWavShp, aWavShp endin </CsInstruments> <CsScore> i 1 0 10 </CsScore> </CsoundSynthesizer>
Powershape
The powershape implements a simple case of waveshaping in an easy use package. Powershape simple raises the amplitude of each sample to the power of some value (referred to in the opcode description as 'shape amount'). A special feature of this opcode is that it retains the positive/negative polarity of the original audio signal (normally raising values to the power of something would result in only positive values). Assuming that our amplitude values range between 1 and 1 and that our exponent (shape amount) is greater than 1, amplitude values of 1, 0 or 1 will remain unchanged whereas a value of 0.5 will distorted by being pushed closer to 1 and a value of 0.5 will be pushed closer to 1. As the exponent value is increased this distortion will increase. A simple example is distorting a sine wave with powershape in which the sine wave will increasingly resemble a square wave (but never entirely) as the exponent value (shape amount) is increased. The following example plays a long randomly glissandoing sine tone which is distorted by a varying amount by powershape. It will be heard that the tone morphs between a sine tone and something resembling a square wave.
EXAMPLE 04E02_powershape.csd
<CsoundSynthesizer> <CsOptions> odac dm0 </CsOptions> <CsInstruments> sr = 44100 ksmps = 1 0dbfs = 1 nchnls = 1 instr 1 koct rspline 5,8,0.1,1 ; random pitch aSig poscil 1,cpsoct(koct) ; create a sine wave kshape rspline 1,500,0.3,3 ; random shape amount aSig powershape aSig,kshape ; 'powershape' distort the sine wave out aSig endin </CsInstruments> <CsScore> i 1 0 120 e </CsScore> </CsoundSynthesizer>
Chebychev Polynomials as Transfer Functions
Coming in a future release of this manual...
 Use the statement 0dbfs=1 in the orchestra header to ensure this.^{^}
 See chapter 03D:FUNCTION TABLES to find more information about creating tables.^{^}
 This is the 'd' in some abbreviations like Csound5.17gnuwin32d.exe (d = double precision floats).^{^}
 Of course you can use an even smaller table if your goal is the degradation of the incoming sound ("distortion"). See chapter 05F for some examples.^{^}
 A table size of a poweroftwo plus one inserts the "extended guard point" as an extension of the last table value, instead of copying the first index to this location. See http://www.csounds.com/manual/html/f.html for more information.^{^}