home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / QBAS / QB4MIDI.ZIP / QBM-DEM2.BAS < prev    next >
BASIC Source File  |  1990-11-28  |  32KB  |  623 lines

  1.      '-------------------------------------------------------------------
  2.      '
  3.      '                     Q U I C K  B A S I C
  4.      '
  5.      '                   ███ ███ █████ ████  █████
  6.      '                   █ █ █ █   █   █   █   █
  7.      '                   █  █  █   █   █   █   █
  8.      '                   █  █  █ █████ ████  █████
  9.      '
  10.      '               QBMIDI(TM) Library Sample Programs
  11.      '
  12.      '                    Q B M - D E M 2 . B A S
  13.      '
  14.      '                M U S I C    G E N E R A T O R
  15.      '
  16.      '          S H A R E W A R E    V E R S I O N    1 . 0
  17.      '
  18.      '                         Developed by:
  19.      '                 AskUs! Technology Specialists
  20.      '                          PO Box 737
  21.      '                    Bountiful, UT 84011-0737
  22.      '
  23.      '-------------------------------------------------------------------
  24.     
  25.      DECLARE SUB GetKeypress (AsciiValueOfKey%, WaitUntilKeyIsPressed%)
  26.      DECLARE SUB DispTextLeftJust (Row%, Col%, Text$, Attribute%)
  27.      DECLARE SUB DispTextCenter (Row%, Text$, Attribute%)
  28.      DECLARE SUB DispNumbLeftJust (Row%, Col%, Number%, Attribute%)
  29.  
  30.  
  31.      DEFINT A-Z                                                  'Set all variables to integer unless specified
  32.  
  33.      CONST False = 0, True = NOT False                           'Set true and false constants (usable in all subs)
  34.      CONST Bright = 15, Normal = 7                               'Set colors to use (also usable in all subs)
  35.      CONST EscapeKey = 27, SpaceBar = 32                         'Set values to check for when keys are pressed
  36.      CONST UpArrow = -72, DownArrow = -80
  37.      CONST LeftArrow = -75, RightArrow = -77
  38.      CONST HomeKey = -71, EndKey = -79
  39.      CONST PageUp = -73, PageDown = -81
  40.      CONST JKey = 74, NKey = 78, PKey = 80
  41.      CONST RKey = 82, TKey = 84, VKey = 86
  42.      CONST SKey = 83, Minus = 45, Plus = 43
  43.  
  44.      DIM Note(1 TO 6), Text$(1 TO 7)                             'Make small array for notes and functions that are displayed
  45.  
  46.      Text$(1) = " Jump Method   "                                'Set Functions to be displayed
  47.      Text$(2) = " Random Pause  "
  48.      Text$(3) = " Patch Number  "
  49.      Text$(4) = " Tempo %       "
  50.      Text$(5) = " Step Per Jump "
  51.      Text$(6) = " Notes/Chord   "
  52.      Text$(7) = " Velocity      "
  53.  
  54.      '-------------------------------------------------------------------
  55.      ' See if a midi unit is installed in system
  56.      '-------------------------------------------------------------------
  57.  
  58.      CALL SeeIfMPUExists(Found)                                  'See if unit exists in system
  59.      IF Found = False THEN                                       'If MPU controller not found then error message and exit
  60.           PRINT "Midi Controller not found or not responding."
  61.           END
  62.      END IF
  63.      CALL ResetMpu                                               'Reset just in case some other program left if modified
  64.      CALL SetDataInStopMode                                      'Minimize intelligence provided by MPU 401 or equivalent
  65.      CALL OmniModeOn                                             'Set all midi data going to all midi channels
  66.      CALL SetToPolyMode                                          'Set multivoice on
  67.  
  68.      '-------------------------------------------------------------------
  69.      ' Display titles and a border
  70.      '-------------------------------------------------------------------
  71.  
  72.      GOSUB DisplayBorderAndTitles                                'Call local SUB to clear screen and display border and initial screen of text
  73.  
  74.  
  75.      '-------------------------------------------------------------------
  76.      ' Set defaults - at initial runtime for starting point
  77.      '-------------------------------------------------------------------
  78.  
  79.      JumpMethod = False                                          'Random Method (True) or Drunk (False)
  80.      RandomPause = False                                         'Insert Random pauses enabled on True
  81.      PatchNumber = 64                                            'Sounds like a good number to start with
  82.      Tempo = 50                                                 'Set tempo to 100, moderate- May need to be changed when compiled
  83.      JumpStep = 5                                                'Jump by fives when in drunken mode
  84.      NotesPerChord = 2                                           'Play one note at a time to start
  85.      Velocity = 64                                               'Moderate strike velocity
  86.  
  87.      GOSUB RedisplaySettings                                     'Show them on screen for the first time
  88.      Selected = 1                                                'Which item is selected for editing
  89.      GOSUB UpdateSelectedItem                                    'Show selected item
  90.  
  91.  
  92.      '-------------------------------------------------------------------
  93.      ' Check to see if they wish to continue
  94.      '-------------------------------------------------------------------
  95.  
  96.      Text$ = "Press any key to begin or Esc to exit"
  97.      Row = 22
  98.      CALL DispTextCenter(Row, Text$, Normal)                     'Call local sub to display centered text
  99.  
  100.      WaitUntilKeyIsPressed = True
  101.      CALL GetKeypress(Keypress, WaitUntilKeyIsPressed)                         'Keypress contains ASCII value of key, -ASCII if extended key
  102.      IF Keypress = 27 THEN CLS : END                             'Exit program if escape key was kit
  103.  
  104.  
  105.      '-------------------------------------------------------------------
  106.      ' Change message at bottom
  107.      '-------------------------------------------------------------------
  108.  
  109.      Text$ = "  Press Space to Pause, Esc to stop  "
  110.      CALL DispTextCenter(22, Text$, Normal)
  111.  
  112.  
  113.      '-------------------------------------------------------------------
  114.      ' Change patch to default patch before sending any notes
  115.      '-------------------------------------------------------------------
  116.  
  117.      CALL ChangePatchTo(PatchNumber)                             'Call QBMIDI function
  118.  
  119.  
  120.      '-------------------------------------------------------------------
  121.      ' Start loop to play notes based on Random numbers and constraints
  122.      ' given.  Allow user to change constraints while running (listening).
  123.      '-------------------------------------------------------------------
  124.  
  125.      RANDOMIZE TIMER                                             'Setup random number generator seed using internal clock
  126.  
  127.      DO
  128.     
  129.           '-------------------------------------------------------------------
  130.           ' If pause hasn't been turned on then go play new notes, otherwise skip and just look for keypresses
  131.           '-------------------------------------------------------------------
  132.  
  133.           IF PauseOn = 0 THEN
  134.  
  135.                '-------------------------------------------------------------------
  136.                'Select New Starting Note based on Jump Method selected
  137.                'where Random is truly random and drunk simulates a drunk stagger
  138.                'moving from side to side based on Random number given
  139.                '-------------------------------------------------------------------
  140.  
  141.                IF JumpMethod THEN                                     'Random method
  142.                     StartingNote = (RND * 60) + 36                    'Select random Starting note between 36 and 96
  143.  
  144.                ELSE                                                   'Drunk method
  145.                     SeedNote = (RND * 99) + 1                         'Get seed between 1 and 100
  146.                     IF SeedNote > 50 THEN                             'If over fifty then jump up by Jump Step increment
  147.                          StartingNote = StartingNote + JumpStep       'Set Starting note up by Jump step
  148.                          IF StartingNote > 90 THEN StartingNote = 90  'If too high, then set at 80
  149.                     ELSE
  150.                          StartingNote = StartingNote - JumpStep       'Jump down by JumpStep increment
  151.                          IF StartingNote < 42 THEN StartingNote = 42  'If too low, set bottom at 42
  152.                     END IF
  153.  
  154.                END IF
  155.  
  156.                '-------------------------------------------------------------------
  157.                ' Get ready to play next selected notes by truning off the ones
  158.                ' currently playing - if any
  159.                '-------------------------------------------------------------------
  160.  
  161.                i = 0                                                  'Set counter to zero
  162.                DO                                                     'Start loop
  163.                     i = i + 1                                         'Increment counter
  164.                     IF Note(i) THEN                                   'If not was on, turn it off
  165.                          CALL PlayNote(Note(i), 0)                    'Call PlayNote with velocity of zero
  166.                     ELSE                                              'Until Note(i)=0
  167.                          EXIT DO                                      'Exit sub
  168.                     END IF
  169.                     Note(i) = 0                                       'Clear the Note to 0
  170.                LOOP UNTIL i = 6                                       'Loop until all six have been turned off
  171.  
  172.                '-------------------------------------------------------------------
  173.                ' Set values for notes to play or leave at zero if not to play
  174.                '-------------------------------------------------------------------
  175.          
  176.                Note(1) = StartingNote                                 'Set center point note
  177.                IF NotesPerChord > 1 THEN Note(2) = StartingNote + 4   'If two notes are to be played, then calc second note
  178.                IF NotesPerChord > 2 THEN Note(3) = StartingNote - 5   'If three then ... same
  179.                IF NotesPerChord > 3 THEN Note(4) = StartingNote + 7   'And so on ..
  180.                IF NotesPerChord > 4 THEN Note(5) = StartingNote + 12
  181.                IF NotesPerChord > 5 THEN Note(6) = StartingNote - 12
  182.  
  183.                '-------------------------------------------------------------------
  184.                ' Play the actual notes until you find a 0 then exit do loop
  185.                '-------------------------------------------------------------------
  186.          
  187.                i = 0                                                  'Set counter to zero
  188.                DO                                                     'Start loop
  189.                     i = i + 1                                         'Increment counter
  190.                     IF Note(i) THEN                                   'If a note value exists then play it
  191.                          CALL PlayNote(Note(i), Velocity)             'Call the play routine
  192.                     ELSE                                              'Until no more notes are found
  193.                          EXIT DO                                      'Exit loop early if less than 6 notes are to be played
  194.                     END IF
  195.                LOOP UNTIL i = 6                                       'Exit if all six have been played
  196.  
  197.           ELSE                                                        'If already paused
  198.                IF RandomPause THEN                                    'If Ok to use random pause then
  199.                     PauseOn = PauseOn + 1                             'If already paused increment counter
  200.                     IF PauseOn > LengthOfPause THEN                   'If Time limit exceeded then
  201.                          PauseOn = 0                                  'Turn off pause flag
  202.                          GOSUB ClearPauseMessage                      'Clear message off screen and continue
  203.                          LengthOfPause = 0                            'Clear length of pause so we know to reset it later
  204.                     END IF
  205.                END IF
  206.           END IF
  207.  
  208.           '-------------------------------------------------------------------
  209.           ' If Random Pauses allowed then calculate pause delay and time to next pause
  210.           ' or increment counter while waiting for next pause
  211.           '-------------------------------------------------------------------
  212.  
  213.           IF RandomPause THEN                                         'If random pause OK
  214.                IF LengthOfPause = 0 THEN                              'And length has not been set
  215.                     ChordsToPlayBeforePause = RND * 70 + 5            'Set number of chords to play before pausing
  216.                     LengthOfPause = RND * 75                          'Set length of pause
  217.                     ChordsPlayed = 0                                  'Set chords played counter to zero (for when we need it)
  218.                END IF
  219.           
  220.                IF PauseOn = 0 THEN                                    'If pause is not on then
  221.                     ChordsPlayed = ChordsPlayed + 1                   'Increment chord counter
  222.                     IF ChordsPlayed > ChordsToPlayBeforePause THEN    'and check against number of chords to play before pause
  223.                          PauseOn = 1                                  'And if equal, set pause to on
  224.                          GOSUB DisplayPauseMessage                    'Display pause message
  225.                     END IF
  226.                END IF
  227.           END IF
  228.  
  229.  
  230.           '-------------------------------------------------------------------
  231.           ' Wait for correct time with regards to tempo setting, checking KB for valid keypresses
  232.           '-------------------------------------------------------------------
  233.  
  234.           Time = 0                                                    'Clear time counter
  235.           DO                                                          'Start timing delay loop
  236.                Time = Time + 1                                        'Increment time counter
  237.                CALL GetKeypress(Keypress, False)                      'See if key has been pressed
  238.                IF Keypress THEN GOSUB HandleKeypress                  'If so then gosub to check it
  239.                IF Time > Tempo * 2 THEN EXIT DO                       'Check if enough time has passed
  240.  
  241.                '-------------------------------------------------------------------
  242.                ' While waiting - look at the midi port for data being sent back to us
  243.                ' from the MPU and from devices attached .. ie keyboards, etc.
  244.                '
  245.                ' For this example, we'll look for patch changes and reflect them
  246.                ' on screen.
  247.                '
  248.                ' The CALL ReceiveMidiData(Value) routine returns a -1 if no
  249.                ' data is coming in from MIDI port, and the actual values if
  250.                ' data is present.  See the Midi 1.0 specification for a full
  251.                ' list of commands returned from devices connected. Many devices
  252.                ' send only the command change once until functions are changed.
  253.                ' Meaning, if you change the patch from the keyboard, you'll get
  254.                ' a 192 as the command then the number as the patch pressed. If you
  255.                ' press another patch, it skips sending the 192 since you're already
  256.                ' in that mode. Pressing a note on the keyboard sends a 144 then the
  257.                ' note and then velocity. Each subsequent note will not be preceeded
  258.                ' by a 144 unless another command occurred inbetween (for example
  259.                ' a patch change).
  260.                '
  261.                ' Some opular commands returned are (See your MIDI spec for more):
  262.                ' Value = 192       Patch Change, followed by patch number
  263.                ' Value = 144       Note on/off, followed by Note and velocity
  264.                ' Value = 176       Portamento On/off
  265.                '
  266.                'Suggestion:
  267.                ' Insert a print statement to view what's happening when you
  268.                ' select functions or play from your Keyboard
  269.                '-------------------------------------------------------------------
  270.               
  271.                CALL ReceiveMidiData(Value)                            'Look at data coming in from Midi
  272.                IF Value <> -1 THEN                                    'If -1, no data is present
  273.                     IF PatchChangeOn THEN                             'If Previous data was patchchange then this data is patch number so make the change
  274.                          IF Value < 127 THEN                          'If not a command then it's still a patch
  275.                               PatchNumber = Value                     'Set patch to Value received
  276.                               GOSUB RedisplaySettings                 'Show them on screen for the first time
  277.                          END IF
  278.                     END IF
  279.                     IF Value > 127 THEN                               'If value >127 then command was received
  280.                          IF Value = 192 THEN                          'If 192 then a patch change came in
  281.                               PatchChangeOn = True                    'So set Patch change on so next value read will be read above
  282.                          ELSE                                         'Otherwise ignore
  283.                               PatchChangeOn = False
  284.                          END IF
  285.                     END IF
  286.                END IF
  287.                     
  288.           LOOP                                                        'Loop until time passes
  289.  
  290.      LOOP                                                             'Loop for next note
  291.      END                                                              'Should never get to this end
  292.  
  293.  
  294. ChangeKeyToRightArrow:           
  295.     
  296.      '-------------------------------------------------------------------
  297.      ' If item is already selected then control jumps here to change the key pressed to right arrow
  298.      ' before entering handle Keypress routine. This lets you press the key letter and increment the value
  299.      '-------------------------------------------------------------------
  300.  
  301.      Keypress = RightArrow
  302.      
  303.  
  304. HandleKeypress:
  305.     
  306.      '-------------------------------------------------------------------
  307.      ' Handle Keypressed or ignore if not value
  308.      '-------------------------------------------------------------------
  309.  
  310.      SELECT CASE Keypress
  311.           CASE RightArrow, Plus
  312.                SELECT CASE Selected
  313.                     CASE 1                                            'JumpMethod
  314.                          IF JumpMethod = False THEN JumpMethod = True ELSE JumpMethod = False
  315.                     CASE 2                                            'Random Pause
  316.                          IF RandomPause = True THEN RandomPause = False ELSE RandomPause = True
  317.                     CASE 3                                            'Patch Number
  318.                          PatchNumber = PatchNumber + 1
  319.                          IF PatchNumber > 127 THEN PatchNumber = 0
  320.                          CALL ChangePatchTo(PatchNumber)
  321.                     CASE 4                                            'Tempo
  322.                          Tempo = Tempo - 5
  323.                          IF Tempo < 20 THEN Tempo = 20
  324.                     CASE 5                                            'Jump per step
  325.                          JumpStep = JumpStep + 1
  326.                          IF JumpStep > 12 THEN JumpStep = 12
  327.                     CASE 6                                            'Notes/Chord
  328.                          NotesPerChord = NotesPerChord + 1
  329.                          IF NotesPerChord > 6 THEN NotesPerChord = 6
  330.                     CASE 7                                            'Velocity
  331.                          Velocity = Velocity + 2
  332.                          IF Velocity > 127 THEN Velocity = 127
  333.                END SELECT
  334.                GOSUB RedisplaySettings                                'Show them on screen for the first time
  335.  
  336.           CASE LeftArrow, Minus
  337.                SELECT CASE Selected
  338.                     CASE 1                                            'JumpMethod
  339.                          IF JumpMethod = False THEN JumpMethod = True ELSE JumpMethod = False
  340.                     CASE 2                                            'Random Pause
  341.                          IF RandomPause = True THEN RandomPause = False ELSE RandomPause = True
  342.                     CASE 3                                            'Patch Number
  343.                          PatchNumber = PatchNumber - 1
  344.                          IF PatchNumber < 0 THEN PatchNumber = 127
  345.                          CALL ChangePatchTo(PatchNumber)
  346.                     CASE 4                                            'Tempo
  347.                          Tempo = Tempo + 5
  348.                          IF Tempo > 500 THEN Tempo = 500
  349.                     CASE 5                                            'Jump per step
  350.                          JumpStep = JumpStep - 1
  351.                          IF JumpStep < 1 THEN JumpStep = 1
  352.                     CASE 6                                            'Notes/Chord
  353.                          NotesPerChord = NotesPerChord - 1
  354.                          IF NotesPerChord < 1 THEN NotesPerChord = 1
  355.                     CASE 7                                            'Velocity
  356.                          Velocity = Velocity - 2
  357.                          IF Velocity < 1 THEN Velocity = 1
  358.                END SELECT
  359.                GOSUB RedisplaySettings                                'Show them on screen for the first time
  360.  
  361.           CASE SpaceBar
  362.                IF PauseOn THEN
  363.                     PauseOn = 0
  364.                     GOSUB ClearPauseMessage                           'Clear the message on screen
  365.                ELSE
  366.                     PauseOn = 1
  367.                     GOSUB DisplayPauseMessage                         'Display message
  368.                END IF
  369.                RETURN
  370.  
  371.           CASE EscapeKey                                              'Check for keypress
  372.                GOTO EndNow
  373.           CASE JKey
  374.                IF Selected = 1 THEN GOTO ChangeKeyToRightArrow        'If already selected then change keypress to right arrow allowing them to increment value
  375.                Selected = 1                                           'Otherwise set selected item at 1
  376.           CASE RKey
  377.                IF Selected = 2 THEN GOTO ChangeKeyToRightArrow        'Ditto
  378.                Selected = 2
  379.           CASE PKey
  380.                IF Selected = 3 THEN GOTO ChangeKeyToRightArrow
  381.                Selected = 3
  382.           CASE TKey
  383.                IF Selected = 4 THEN GOTO ChangeKeyToRightArrow
  384.                Selected = 4
  385.           CASE SKey
  386.                IF Selected = 5 THEN GOTO ChangeKeyToRightArrow
  387.                Selected = 5
  388.           CASE NKey
  389.                IF Selected = 6 THEN GOTO ChangeKeyToRightArrow
  390.                Selected = 6
  391.           CASE VKey
  392.                IF Selected = 7 THEN GOTO ChangeKeyToRightArrow
  393.                Selected = 7
  394.           CASE UpArrow
  395.                Selected = Selected - 1: IF Selected = 0 THEN Selected = 7
  396.           CASE DownArrow
  397.                Selected = Selected + 1: IF Selected = 8 THEN Selected = 1
  398.           CASE PageUp, HomeKey
  399.                Selected = 1
  400.           CASE PageDown, EndKey
  401.                Selected = 7
  402.      END SELECT
  403.      GOSUB UpdateSelectedItem                                         'Redraw items and highlight selected item
  404.      RETURN
  405.  
  406.  
  407. RedisplaySettings:
  408.  
  409.      '-------------------------------------------------------------------
  410.      ' Update settings on screen
  411.      '-------------------------------------------------------------------
  412.  
  413.      'Note: Col and Offset were already set in Borders routine
  414.  
  415.      IF JumpMethod THEN Text$ = "Random" ELSE Text$ = "Drunk "
  416.      CALL DispTextLeftJust(14, Col + Offset, Text$, Bright)
  417.  
  418.      IF RandomPause THEN Text$ = "On " ELSE Text$ = "Off"
  419.      CALL DispTextLeftJust(15, Col + Offset, Text$, Bright)
  420.  
  421.      CALL DispNumbLeftJust(16, Col + Offset, PatchNumber, Bright)
  422.      T1 = (Tempo - 50) * 100                                     'Calc Tempo in Percent
  423.      T1 = T1 / 450
  424.      T1 = 100 - T1
  425.      CALL DispNumbLeftJust(17, Col + Offset, T1, Bright)
  426.      CALL DispNumbLeftJust(18, Col + Offset, JumpStep, Bright)
  427.      CALL DispNumbLeftJust(19, Col + Offset, NotesPerChord, Bright)
  428.      CALL DispNumbLeftJust(20, Col + Offset, Velocity, Bright)
  429.  
  430.      RETURN
  431.  
  432.  
  433.  
  434. ClearPauseMessage:
  435.  
  436.      '-------------------------------------------------------------------
  437.      ' Display Paused messages
  438.      '-------------------------------------------------------------------
  439.  
  440.      CALL DispTextLeftJust(15, Col + Offset + 12, "        ", Normal)
  441.      Pause = 0
  442.      LengthOfPause = 0
  443.      Text$ = "  Press Space to Pause, Esc to stop  "
  444.      CALL DispTextCenter(22, Text$, Normal)
  445.      RETURN
  446.  
  447. DisplayPauseMessage:
  448.     
  449.      '-------------------------------------------------------------------
  450.      ' Clear Paused messages and redisplay what to do at bottom
  451.      '-------------------------------------------------------------------
  452.  
  453.      COLOR 0, Normal                                             'Set to Reverse momentairly
  454.      CALL DispTextLeftJust(15, Col + Offset + 12, " Paused ", 0) 'Display as black
  455.      COLOR Normal, 0                                             'Restore to normal
  456.      Text$ = "  Press Space to Continue, Esc to stop  "
  457.      CALL DispTextCenter(22, Text$, Normal)
  458.      RETURN
  459.  
  460.  
  461. DisplayBorderAndTitles:
  462.  
  463.      '-------------------------------------------------------------------
  464.      ' Borders and titles are used just once, so we've put them down
  465.      ' here and Gosub once to get things started.  This could have been
  466.      ' placed in a SUB function and called instead, but we like to only
  467.      ' put routines called often in Subs.
  468.      '-------------------------------------------------------------------
  469.     
  470.      SCREEN 0                                                    'Set text screen
  471.      CLS 0                                                       'Clear screen to black
  472.  
  473.      Row = 1                                                     'Which Row
  474.      Col = 1                                                     'Which Column
  475.      Text$ = "╔" + STRING$(77, 205) + "╗"                        'Text to be displayed
  476.      CALL DispTextLeftJust(Row, Col, Text$, Normal)              'Call local SUB that displays text left justified
  477.  
  478.      Text$ = "║"
  479.      FOR Row = 2 TO 24
  480.           CALL DispTextLeftJust(Row, 1, Text$, Normal)
  481.           CALL DispTextLeftJust(Row, 79, Text$, Normal)
  482.      NEXT Row
  483.  
  484.      Row = 24
  485.      Text$ = "╚" + STRING$(77, 205) + "╝"
  486.      CALL DispTextLeftJust(Row, Col, Text$, Normal)
  487.  
  488.      Row = 1
  489.      Text$ = "    QBMIDI(TM) DEMO - MUSIC GENERATOR    "
  490.      Attribute = Bright
  491.      CALL DispTextCenter(Row, Text$, Attribute)
  492.  
  493.      Text$ = " (C) 1990 AskUs! Technology Specialists, Box 737, Bountiful, UT 84011 "     'Bottom title
  494.      CALL DispTextCenter(25, Text$, Normal)
  495.  
  496.      Text$ = "This demonstration program uses the QBMIDI library to provide access"
  497.      CALL DispTextCenter(4, Text$, Normal)
  498.  
  499.      Text$ = "your MIDI instruments via an MPU401 or compatible controller. Change"
  500.      CALL DispTextCenter(5, Text$, Normal)
  501.  
  502.      Text$ = "the parameters below to hear different sound combinations.          "
  503.      CALL DispTextCenter(6, Text$, Normal)
  504.  
  505.      Text$ = "Use the Cursor Up/Down keys or Key letter to select function"
  506.      CALL DispTextCenter(8, Text$, Normal)
  507.  
  508.      Text$ = "Right/Left Cursor to change value, space to pause/re-start"
  509.      CALL DispTextCenter(9, Text$, Normal)
  510.  
  511.      Col = 27
  512.      Offset = 17
  513.  
  514.      Text$ = "Function"
  515.      CALL DispTextLeftJust(12, Col, Text$, Normal)
  516.  
  517.      Text$ = "Setting"
  518.      CALL DispTextLeftJust(12, Col + Offset, Text$, Normal)
  519.  
  520.      Text$ = "-----------"
  521.      CALL DispTextLeftJust(13, Col, Text$, Normal)
  522.  
  523.      Text$ = "-------"
  524.      CALL DispTextLeftJust(13, Col + Offset, Text$, Normal)
  525.     
  526.     
  527. UpdateSelectedItem:
  528.     
  529.      '-------------------------------------------------------------------
  530.      ' Redray items and highlight the one that Selected =
  531.      '-------------------------------------------------------------------
  532.  
  533.      Item = 0
  534.      StartRow = 13
  535.      DO
  536.           Item = Item + 1
  537.           IF Item = Selected THEN
  538.                Attribute = 0
  539.                COLOR 0, Normal
  540.                CALL DispTextLeftJust(StartRow + Item, Col - 1, Text$(Item), 0)
  541.                COLOR Normal, 0
  542.           ELSE
  543.                CALL DispTextLeftJust(StartRow + Item, Col - 1, Text$(Item), Normal)
  544.                CALL DispTextLeftJust(StartRow + Item, Col - 1, LEFT$(Text$(Item), 2), Bright)
  545.           END IF
  546.      LOOP UNTIL Item = 7
  547.      RETURN
  548.  
  549.  
  550. EndNow:
  551.     
  552.      '-------------------------------------------------------------------
  553.      ' End the program, but shut off all notes before leaving
  554.      '-------------------------------------------------------------------
  555.  
  556.      CALL AllNotesOff                                            'Don't exit without shutting off all notes (it shuts off immediately, unlike Velocity=0 that uses normal decay value of patch)
  557.      CLS                                                         'Clear screen just to keep things tidy
  558.      END
  559.  
  560. SUB DispNumbLeftJust (Row, Col, Number, Attribute) STATIC
  561.  
  562.      LOCATE Row, Col - 1
  563.      COLOR Attribute
  564.      PRINT Number; "   ";
  565.      COLOR Normal
  566.  
  567.  
  568.  
  569. END SUB
  570.  
  571. SUB DispTextCenter (Row, Text$, Attribute) STATIC
  572.  
  573.      LOCATE Row, 40 - LEN(Text$) / 2
  574.      COLOR Attribute
  575.      PRINT Text$;
  576.      COLOR Normal
  577.  
  578. END SUB
  579.  
  580.  SUB DispTextLeftJust (Row, Col, Text$, Attribute) STATIC
  581.  
  582.      LOCATE Row, Col
  583.      COLOR Attribute
  584.      PRINT Text$;
  585.      COLOR Normal
  586.  
  587. END SUB
  588.  
  589. SUB GetKeypress (AsciiValueOfKey, WaitUntilKeyIsPressed)
  590.  
  591.      AsciiValueOfKey = 0                                    'Clear variable
  592.      ExtendedKey = 0                                        'Turn off extended key flag (used to show that function key was pressed)
  593.  
  594.      IF WaitUntilKeyIsPressed THEN
  595.  
  596.           DO: LOOP UNTIL INKEY$ = ""                        'Clear out keys that may be sitting in buffer
  597.  
  598.           DO                                                'Loop until a key is pressed
  599.                Key$ = INKEY$
  600.           LOOP WHILE Key$ = ""
  601.  
  602.      ELSE
  603.  
  604.           Key$ = INKEY$
  605.           WaitUntilKeyIsPressed = 0
  606.           IF LEN(Key$) = 0 THEN EXIT SUB
  607.      END IF
  608.  
  609.      IF LEN(Key$) > 1 THEN                                  'Check for extended key (F1, Cursor, etc.) by checking for length variable >1
  610.           Key$ = RIGHT$(Key$, 1)                            'If extended then get right character in variable
  611.           ExtendedKey = -1                                  'Set flag to show extended key was pressed
  612.      END IF
  613.  
  614.      AsciiValueOfKey = (ASC(UCASE$(Key$)))                  'Place ASCII value in variable to be returned
  615.      
  616.  
  617.      IF ExtendedKey THEN                                    'If extended then convert to minus
  618.           AsciiValueOfKey = -AsciiValueOfKey                'Convert to minus number to show extended key
  619.      END IF
  620.  
  621. END SUB
  622.  
  623.