Computer music on the radio


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


            this.AddObject(“oSlider”,”MySlider”)


            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


 

Comments (4)

  1. Alan Lukachko says:

    Can this code be run as a program? When I try, it gives an unrecognized command verb error on " ADD OBJECT spn as spinner WITH left=130,;"

  2. Calvin_Hsia says:

    I just tried the code, and it works fine for me. Make sure your copy isn’t doublespaced. That ADD OBJECT line is the first continued line (ends with a ";")

    See this post: http://blogs.msdn.com/calvin_hsia/archive/2005/08/07/448889.aspx