If you listen to an AM radio that’s placed near a computer, you can hear interference.  I can put my radio next to my tablet and hear all the calculations being done as my ink handwriting is being converted to text.

The AM frequency range is from 530 to 1710 khz. My Junior High and High School computer (Relaxen und watchen das blinkenlights. What lights?) had a 1.5 µsecond cycle time, or 660 Khz which is right in the middle of the AM band.

Because the PDP-8 had only one general register, called the accumulator, and had only one thread of execution, it was easy to write programs to flash the accumulator at various frequencies that could directly generate tones on an AM Radio. Because sound waves can pass through each other and continue on (wave superposition), making the computer play two notes at once was just trigonometry.

Below is some code to demonstrate. It draws 2 sine waves in red and the sum of those 2 in blue. Initially, the phase difference between them is 0 degrees, so it appears that there is only 1 wave.  The slider changes the relative frequencies of the 2 waves. It’s initial value of 0 means they are the same frequency. The spinner changes the phase difference between the 2. You can change the phase to 180 degrees with the frequencies the same, and see the signals sum to 0. (I guess that’s how noise canceling headphones work  they generate a signal that’s 180 degrees out of phase with the ambient noise.)

As the frequency difference gets large, you can see the sum taking on the shape of the lower frequency wave. This is similar to how FM radio works: the high frequency wave is modulated by the broadcast signal and the low frequency wave is the FM frequency (from 87.5 Mhz to 108 Mhz). (For how black & white TV works on the same signal as color, see Why was the original IBM PC 4.77 Megahertz?)

You can get fancy and add controls for the relative amplitudes of the waves.

PUBLIC ox

ox=CREATEOBJECT("signalform")

ox.show

DEFINE CLASS signalform as form

width=800

height=300

left=300

backcolor=0xffffff

allowoutput=.f.

ADD OBJECT spn as spinner WITH left=130,;

SelectOnEntry=.t.,;

SpinnerLowValue=0,;

SpinnerHighValue=360,;

Increment=10,;

value=0

PROCEDURE init

WITH this.oSlider

.min=-100

.max=100

.SmallChange=5    && a penny

.Value=0

.visible=1

ENDWITH

PROCEDURE keypress(nKeyCode, nShiftAltCtrl)

DO case

CASE nKeyCode=27  && escape

thisform.release

ENDCASE

PROCEDURE activate

thisform.DrawWaves

PROCEDURE DrawWaves

nWaves=2

nTheta= thisform.spn.Value*PI()/180

nFactor=thisform.oSlider.Value/100

thisform.Cls

thisform.Caption=TRANSFORM(nFactor)+" "+TRANSFORM(nTheta)

DIMENSION aFreq[nWaves],ay[nWaves]

FOR i = 1 TO nWaves

aFreq[i]=1+(i-1)*nFactor

ENDFOR

yMax=thisform.Height/4/nWaves

yOffset=thisform.Height/2     && x axis halfway down

thisform.Line(0,yOffset,thisform.Width,yOffset) && draw x axis

xMax=thisform.Width

FOR x =1 TO xMax

y=0

this.ForeColor=RGB(255,0,0)

FOR i=1 TO nWaves

yp=- yMax*SIN(2*PI()*aFreq[i]*x/100+(i-1)*nTheta)

thisform.PSet(x,yp+yOffset)

y= y +yp

ENDFOR

this.ForeColor=RGB(0,0,255)

thisform.PSet(x,y+yOffset)

ENDFOR

PROCEDURE spn.InteractiveChange

thisform.DrawWaves

ENDDEFINE

DEFINE CLASS MySlider as olecontrol

oleclass="MSComctllib.slider.2"

PROCEDURE Change

thisform.DrawWaves

PROCEDURE keypress(nKeyCode, nShiftAltCtrl)

thisform.keypress(nKeyCode, nShiftAltCtrl)

ENDDEFINE