Sub Play (pp$)
 n% = 1
 cmds$ = "ABCDEFGLMNOPT<> "

 While n% <= Len(pp$)            ' Parse play string into commands
  cmd$ = ""
  Do
   cmd$ = cmd$ + Mid$(pp$, n%, 1)
   If Mid$(pp$, n%, 1) = "M" Then
    n% = n% + 1
    cmd$ = cmd$ + Mid$(pp$, n%, 1)
  End If
  n% = n% + 1
 Loop Until InStr(cmds$, Mid$(pp$, n%, 1)) Or n% > Len(pp$)

 ' Initialize starting values
 dot% = 0: QueueNote% = 0
 cmdptr% = 2: tlength% = 0

 ' Process command
 Select Case Left$(UCase$(cmd$), 1)

  Case "<"
   octave% = octave% - 1
   If octave% < 0 Then octave% = 0

  Case ">"
   octave% = octave% + 1
   If octave% > 6 Then octave% = 6

  Case "C"
   note% = octave% * 12 + 1
   QueueNote% = -1

  Case "D"
   note% = octave% * 12 + 3
   QueueNote% = -1

  Case "E"
   note% = octave% * 12 + 5
   QueueNote% = -1

  Case "F"
   note% = octave% * 12 + 6
   QueueNote% = -1

  Case "G"
   note% = octave% * 12 + 8
   QueueNote% = -1

  Case "A"
   note% = octave% * 12 + 10
   QueueNote% = -1

  Case "B"
   note% = octave% * 12 + 12
   QueueNote% = -1

  Case "O"
   octave% = Val(Right$(UCase$(cmd$), Len(cmd$) - 1))
   If octave% < 0 Then octave% = 0
   If octave% > 6 Then octave% = 6

  Case "N"
   note% = Val(Mid$(UCase$(cmd$), 2, 2))
   cmdptr% = cmdptr% + Len(Str$(note%)) - 1
   QueueNote% = -1

  Case "T"
   tempo% = Val(Right$(UCase$(cmd$), Len(cmd$) - 1))
   If tempo% < 32 Then tempo% = 32
   If tempo% > 255 Then tempo% = 255

  Case "L"
   length% = Val(Right$(UCase$(cmd$), Len(cmd$) - 1))
   If length% < 1 Then length% = 1
   If length% > 255 Then length% = 255

  Case "P":  note% = 0
   QueueNote% = 1

  Case "M"
   Select Case Mid$(UCase$(cmd$), 2, 1)
    Case "N": mode% = S_NORMAL
    Case "L": mode% = S_LEGATO
    Case "S": mode% = S_STACCATO
    Case "F": bf$ = "F"
    Case "B": bf$ = "B"
   End Select
  End Select

  '  If command was note or rest, place in queue
  If QueueNote% Then
   Do
    Select Case Mid$(cmd$, cmdptr%, 1)
     Case "+", "#"
      note% = note% + 1
      cmdptr% = cmdptr% + 1
     Case "-"
      note% = note% - 1
      cmdptr% = cmdptr% + 1
     Case "."
      dot% = dot% + 1
      cmdptr% = cmdptr% + 1

     ' Numbers here mean temporary length for current note

     Case "0","1","2","3","4","5","6","7","8","9"
      tlength% = Val(Mid$(cmd$, cmdptr%, 2))
      cmdptr% = cmdptr% + Len(Str$(tlength%)) - 1

    End Select
   Loop Until cmdptr% > Len(cmd$)
   If tlength% = 0 Then tlength% = length%
   status% = PlayNote(1,note%,tempo%,tlength%,mode%,dot%)
  End If
 Wend

 status% = StartSound()           ' Start things going

 If bf$ = "F" Then                ' Remain here if user wants
  While CountVoiceNotes(1) > 0    ' foreground mode
  Wend
 End If
End Sub
