The Vocoder is a vocal processor that takes in two inputs (one of them being the microphone) and maps the magnitude spectrum of input 1 to the magnitude spectrum of input 2 while retaining the phase spectrum of input 2. This is also known as cross-synthesis, where input 1 is the modulator and input 2 is the carrier. Then the inverse FFT of input 2 is taken and fed to the speaker output. This is a very famous audio effect used extensively. In my case, input 1 was the microphone input and input 2 was a polyphonic midi synthesizer. The key I pressed on the synthesizer generated a MIDI note value which in turn controlled the pitch of my voice going out through the speakers.
The Vocoder has been implemented in ChucK. An audio interface UA 101 was used to setup the microphone input and speaker output, but this is completely optional. QJackctl was used on Linux to setup the connections, but it won't be required for other operating systems. The MIDI keyboard M-AUDIO Oxygen 25 was connected via USB to the laptop.
The ChucK script (that can be downloaded here) contains two functions - midiSynth() and vocoder(). The function midiSynth() sets up the midi keyboard to send midi messages to ChucK, which are then sonified by a BeeThree hammond organ UGen (Unit Generator). The code has been setup to accept multiple midi messages simultaneously so that it is polyphonic.
It is to be noted that BeeThree in ChucK is a child of the FM class, which means it is essentially an FM instrument. Two midi controller knobs are used to control the modulation index and modulation speed of the FM instrument. Additionally BeeThree maybe replaced with any FM instrument you like (e.g: Rhodey, PrecFlut, TubeBell) in real time to give you a new spectrum to play with, making the vocoder quite robust and expressive.
The function vocoder() is where the signal processing takes place. The MIDI synth and the adc input (i.e, mic input) were previously connected to separate FFT UAnae (Unit Analysers). upchuck() is a function that computes the FFT of and stores them in a complex array spectrum. We then run a loop over all the samples of spectrum and convert it into polar coordinates to get the magnitude of the adc input and set it as the magnitude of the MIDI input. Finally, the inverse FFT of the spectrum of the MIDI input is computed and sent to the dac.