XinT = Xint is not a Theremin
XinT was designed and built as a final project for the class E3940 Microprocessor Systems Lab at Columbia University by Jason Bessette, Anders Pearson, Anish Trivedi, and Cho-nan Tsai. The goal of the project was to combine our expertise in software and hardware to produce a new device that made innovative use of the Z-80 8-bit microprocessor.
"In 1920 the Russian physicist Leon Theremin demonstrated the musical instrument that has since become known simply as the Theremin. Theremin died in November 1993, but his instrument lives on, occasionally being performed in concerts or used in soundtracks. The Theremin is unique in that it is played without there being any physical contact whatsoever between the performer and the instrument. The pitch of the instrument is controlled by the proximity of the player's hand to an antenna (mounted vertically in the original design). A second antenna (traditionally mounted horizontally) senses the proximity of the player's other hand and controls the volume of the tone. The experience of playing the device is far removed from that of performing music using a 'traditional' instrument. There is a perpetual feedback mechanism associated with the playing of the Theremin.
The feedback loop begins with the position of the player's hands, and next involves the sound produced, until finally the player processes what he/she hears and changes the position of his/her hands accordingly. A successful playing style requires the ability that a given pitch and volume of tone can be accurately converged on, and held by the player. Thus a competent Thereminist must have a good 'ear for music' and also good reflex action. Expert Theremin players have been few and far between with only a few names reflected upon when the instrument is mentioned."
from http://www.physics.gla.ac.uk/~kskeldon/PubSci/exhibits/E9/
The goal of our project was to bring the Theremin into the 21st century, combining the power of the instrument with the flexibility of a microprocessor controller. It is still played the same way as a traditional Theremin with one antenna for pitch and one for volume and no physical contact needed between the instrument and the musician. However, a few new features were added.
As we quickly discovered, with no physical feedback, the Theremin is an easy instrument to play but not as easy to play well. Playing a sequence of music on a traditional Theremin requires pinpoint positioning of the player's hand and an uncommonly precise ear for pitch. One of our aims was to make the instrument easier to play by implementing "air frets". We took advantage of the microprocessor to map the output of the Theremin onto only the frequencies that produce musical notes such as C, C#, etc. This produces an effect similar to the fretting of stringed instruments such as guitars. With frets, there is some room for error with the position of the hand; it's much easier to find the right range that produces the desired note and slight unintentional movements won't make notes go sour. Since the capacitance of the hand-antenna system changes inversely with the square of the distance between the two (affecting the output pitch or volume in a similar relationship), the instrument by default is much more sensitive as one gets closer to the antenna, with much of the space further away being "wasted", requiring large movements to produce small changes in the output. Fretting allowed us to offset this effect, producing a more even output response over the entire input range. Furthermore, simple changes to the software allows the fretting to be remapped arbitrarily. Eg, our project demo involved fretting the instrument to a C-major key; ie, the only notes it would produce with fretting on were C,D,E,F,G,A, and B (the notes in a C-major scale) over several octaves. Other keys could easily be programmed in. Of course, since fretting makes techniques such as vibrato or glosses between notes impossible, it can be disabled for the advanced Thereminists with a simple switch.
Since we had a whopping 300 bytes or so of RAM left over on our Z-80, we decided that no electronic instrument would be complete without basic record, playback, and looping features. Using basic run-length encoding and fine-tuning sample rates, we were able to record up to several minutes of music using just those 300 bytes (with fretting on. without fretting, only 25 seconds or so could be recorded) which could then be played back or looped.
A Theremin works by means of the heterodyning or beat frequency concept. Heterodyning effect is created by two high radio frequency waves of similar but varying frequency combining and creating a lower audible frequency, equal to the difference between the two radio frequencies (approximately 20 Hz to 20,000 Hz). To build a Theremin we used the University of Glasgow's digital Theremin schematic: http://www.physics.gla.ac.uk/~kskeldon/PubSci/exhibits/E9/.
For both volume and pitch circuits, two very high square wave oscillations are made via Schmitt-triggered 2 input NAND gates (4093). One is a reference oscillation that can be tuned and the other varies depending upon hand to antenna proximity, which is a variable capacitance. When the hand approaches the antenna the frequency should change. We believe the XOR combines these two oscillations and the multivibrator produces a DC offset. The output of the multivibrator is sent through a lowpass op-amp filter and DC decoupled by multiple RC networks. This DC level is used to control either the VCO or VCA.
XinT is not a Theremin. XinT is a microprocessor controlled Theremin.
For our project, we broke the original circuit right before the inputs to the VCO and VCA (where the signal is DC) and inserted the Z-80. The two antennas essentially produce two DC levels that are converted to digital and read by the Z-80. One antenna supplies a pitch byte and the other supplies a volume byte. The Z-80 then outputs bytes that are converted to analog and used to control a voltage-controlled-oscillator (pitch) and a voltage-controlled-amplifier (volume). The Z-80 can store these bytes for recording, do nothing and directly output them (Theremin mode), or implement a fretting routine that maps pitch bytes to specific values that will produce a musical note.
This diagram shows the overall design of the XinT hardware.
program variables/flags:
MODE = (PASS | RECORD | PLAYBACK)
FRET = (ON | OFF)
NOTE = [PITCH, VOLUME, DURATION]
MEM_POINTER = memory address to get next note from or store to
PREV_PITCH = the pitch of the last note recorded
PREV_VOLUME = the volume of the last note recorded
COUNTER = 0
main loop, executed every 10th of a second or so,
called by timer interrupt:
local variables: pitch, volume
check record button
if it's depressed, set MODE = RECORD
if MODE previously was RECORD
and record button is now not depressed,
write current NOTE to memory followed by "stop" byte
reset DURATION counter
if MODE is now RECORD and was previously not RECORD,
reset MEM_POINTER to beginning of memory area
check playback button
if it's depressed, set MODE = PLAYBACK
if MODE is now PLAYBACK and previously wasn't,
reset MEM_POINTER to beginning of memory area
if neither record, nor playback buttons are depressed,
set MODE = PASS
check fret switch and set FRET to ON or OFF accordingly
sample pitch and volume info from input
if FRET = ON
discretize pitch
discretize volume
if MODE = PASS
NOTE.PITCH = pitch
NOTE.VOLUME = volume
if MODE = RECORD
NOTE.PITCH = pitch
NOTE.VOLUME = volume
compare NOTE.PITCH to PREV_PITCH
and NOTE.VOLUME to PREV_VOLUME
if both are the same,
increment NOTE.DURATION
if either are different,
write NOTE to location pointed to MEM_POINTER
reset NOTE.DURATION to 1
increment MEM_POINTER
PREV_PITCH = NOTE.PITCH
PREV_VOLUME = NOTE.VOLUME
if MODE = PLAYBACK
increment COUNTER
if COUNTER > NOTE.DURATION
get new NOTE from location pointed to by MEM_POINTER
reset COUNTER
increment MEM_POINTER
if location MEM_POINTER is "stop" byte,
reset MEM_POINTER to beginning of memory area
send NOTE.PITCH and NOTE.VOLUME to output
also see the flowchart.
coming soon. (We have some recordings but still need to digitize them).
In the end, the hardware was overall very successful, although numerous problems arose in debugging the circuits. The antenna circuitry was built step by step; the first time it didn't work at all. Two oscillations (about 2.6 MHz) were made in the beginning but basically that was it. The antenna response was completely random and unreliable. The solution to this problem was to start over and redo the circuit with as few chips as possible and with point-to-point wiring. This greatly enhanced the effectiveness of the entire circuit and antenna response. At this point the signal died at the output of the multivibrator. So the 1uf capacitor at that point was switched with a 500pf capacitor and the signal reappeared. Step by step, the next point at which the signal died was at the output of the opamp. This was the most difficult obstacle in the antenna circuitry. The antenna response was fairly reliable at that point and the hand/antenna proximity caused the output of the multivibrator to change in DC offset and a discrete change in frequency (due to Schmitt triggers). It seemed more likely that the DC offset was the most important portion of the signal to isolate because we needed a DC signal for the ADC's. Analyzing the circuit, it was learned that this signal was sent through an RC network, a lowpass opamp filter, and another RC network. This is what converts the varying frequency/offset signal into merely a DC offset. First step was to analyze the frequency characteristics of the opamp. Its output still contained unwanted frequencies; therefore, to decrease the cutoff frequency the gain of the opamp needs to be increased. In fact the gain was increased from about 5 to 33 by replacing the 100 kOhm resistor at the inverting terminal input to 15 kOhm. This succeeded in eliminating unwanted frequencies. The output of the opamp was then completely converted to a DC signal after the final RC network (10uF, 1 kOhm).
The next, and most frustrating part, was tuning the circuit so that the hand/antenna proximity actually made a usable effect on the DC output. The initial 20k potentiometer was used to tune the reference oscillation and at some specific resistance value, the two initial oscillations would be in phase and have the same frequency. Then, as the hand approached the antenna it would change the phase and frequency of one of the oscillations and the two would combine at the XOR. It took about 2 to 3 days to finally find a point at which the antenna response was perfect. Such a response required that the DC signal was stable regardless of the location of the hand. Often, if the antenna was approached too quickly the DC signal would jump and scatter. Other times the output (DC) would respond well within a certain range but outside of that range it would jump and scatter. Eventually the best tuning achieved further allowed the antenna to be touched without a jump in the output.
Once this tuning was achieved the next step was to adjust the range of the DC output. Since it needed to be the input of an ADC the range should be from 0 to 5 volts. At first this didn't seem possible and we planned to either implement an opamp to amplify the signal or to change the setup of the ADC so that it would use the input as best as it could. Fortunately (and luckily), the DC output was tuned to exactly 0 to 5 volts by adjusting the final 2 potentiometers (see schematic). One of these would affect the current flow into the opamp, either increasing or decreasing it. This had the effect of basically offsetting the output of the opamp. By tuning this value the DC output could be set to zero. As the hand approached the antenna this would increase to about 1 volt. Adjustment of the 100k pot increased the output to 0-5 volts instead of 0-1 volts, since this pot controlled the gain of the opamp. In the end the antenna response was perfect and the output DC voltage level was between 0 and 5 volts exactly.
At the other end of the spectrum, that is, the VCO and VCA, things were running smoothly. The VCO and VCA circuits were setup and worked very well on the first try. The only issues here were that the control voltage for the VCA needed to be between 1 and 0 volts, 0 making the largest amplification (loudest volume) and 1 the quietest. We were expecting the opposite - that 0 control would make the least amplification. Not a problem though because software can modify the output to the DAC's so that they easily give us 1 to 0 volts. The VCO however, presented a major problem. It worked. but it sounded horrible. It produced a noisy square wave that sounded like buzzing bees or static. There was no way we wanted to demo that sound so we got on the phone and ordered the VCO that the original circuit called for (John Kazana had originally given us a LM331 VCO chip to use). When this came in we immediately set it up and it sounded much better, providing a sine wave output. Unfortunately, at low frequencies (below about 300 Hz) it began to distort and turn into a noisy square wave again. At that I used the scope to read the supply voltage. It showed that the supply had about an entire half-volt of noise on it. I took a 10uF capacitor and placed it between the supply and ground and it cut the noise in half. After replacing the power supply themselves with the digital power supplies from the EE Lab, the signal was even further enhanced. This helped out our VCO a lot because it kept the frequency much more stable. Previously the VCO frequency output would jump back and forth even if its control input remained constant. Now this problem only occurs at lower frequencies. In the end, the quality of the output was very good for high and medium frequencies and very poor for low frequencies. Because of this (and also as mentioned in software section), the software was written to implement only about 2 octaves in a frequency range that had the best quality. We would have preferred to use 2 or 3 octaves in the lowest frequency range (20 - 1000 Hz) because bass sounds better, and less annoying, than high-pitched sounds.
There were two other important circuitry changes made. The first was made to protect the ADC's. We learned (the hard way) that if you give an ADC an input of more than 5V it will burn up. Sometimes during power-up or because the antenna wasn't tuned properly, the input voltage to the ADC's would spike and reach almost 11V. This would instantly ruin them. So we had to add two opamps, one for each ADC, that would clip any voltage over 5V. This method proved very successful and prevented the further demise of ADC's.
A second addition had to be made to account for the VCO input. To operate in a linear range and to produce a nice-sounding sine wave, the VCO needed a control voltage (input) of approximately 6-5 V. Higher control produced a lower frequency; lower control produced a higher frequency. Unfortunately the DAC's would only supply between 0 and 1.5 V. To boost this output range into the range we needed we had to implement another opamp that inserted a DC offset. The setup is shown in the final schematic diagrams. Basically this Voffset can be changed at any time to change the region in which XinT operates by changing the input to the VCO. If Voffset is higher then XinT will operate in the low-quality low-frequency region; a smaller Voffset makes XinT operate in the high-quality high-frequency region.
As with any non-trivial program, particularly one written in assembly language, there were plenty of bugs to be found and fixed over the course of construction and testing. Overall, our software design was fairly solid so the majority of these were typos and fencepost errors; many easily spotted but many others were more subtle requiring hours of painful debugging with breakpoints and stepping through the code.
The only substantial change that had to be made to the software during implementation was the mechanism behind frettipng. Originally, for simplicity, a simple lookup table of 256 bytes was built. Each byte in the table contained an output byte value that would produce a desired note. The input pitch byte was used as an index into this table. While this table approach proved useful for experimentation finding the notes and input ranges, it soon proved cumbersome and it was decided that the table was taking up too much memory that could be put to better use as space for recording. In its place, a two-tiered system was built. A lookup table for output pitches was still necessary but certain optimizations could be made. The stability (or lack thereof) of the VCO gave us about 27 different notes over about 3 octaves that we could generate reliably and accurately with a single output value from the Z-80. The bytes that produced these notes were put into a table (taking up 27 bytes in all). Then, a second table for ranges was built. The fretting algorithm looped over the ranges table incrementing a counter each time and comparing the value in the table with the input pitch byte. When the value in the table was found to be larger than the input byte, it broke out of the loop and then used the current value of the counter as an index into the output notes table to retrieve the resulting note.
We made a mistake in our original address decoding for the four devices used. It was first setup so that only one ADC or one DAC could be on at once. That way we wouldn't have the Z-80 mixing up pitch and volume bytes. When this decoding was built, the Z-80 would crash. What was happening was that some instruction was being executed either in startup or at any random time that put and address on the address bus that happened to chip select both an ADC and a DAC. The Z-80 would crash because there were two devices trying to use the data bus at once. Our original decoding considered the ADC's and DAC's separate - only one ADC and one DAC on at a time. The problem was fixed by decoding address bits A0 and A1 with a 2-4 decoder. That way only one single device could access the data bus at once and the Z-80 would not crash.
The XinT team would like to thank the teaching staff: Prof. Campbell, John Kazana, Michael Kounavis, Vassilis Stachtos, and Suhail Mohiuddin for their valuable assistance and input on the project. We would also like to thank the other teams in the class for not killing us even after we spent hours assaulting them with loud, high-pitched noises as we tested and tuned the instrument in the lab.
Theremin World
Analogue
and Digital Theremin
Theremin
Schematics
Frequency
and Wavelength chart