home *** CD-ROM | disk | FTP | other *** search
- '-------------------------------------------------------------------
- '
- ' Q U I C K B A S I C
- '
- ' ███ ███ █████ ████ █████
- ' █ █ █ █ █ █ █ █
- ' █ █ █ █ █ █ █
- ' █ █ █ █████ ████ █████
- '
- ' QBMIDI(TM) Library and Sample Programs
- '
- ' Q B M - D E M 1 . B A S
- '
- ' T U T O T I A L A N D D E M O
- '
- ' S H A R E W A R E V E R S I O N 1 . 0
- '
- ' Developed by:
- ' AskUs! Technology Specialists
- ' PO Box 737
- ' Bountiful, UT 84011-0737
- '
- ' QBMIDI allows you to easily access a Roland Midi Processing
- ' Unit (MPU401) or compatible MIDI controller from QuickBASIC
- ' version 4.X. QBMIDI uses the files QBMIDI.QLB or QBMIDI.LIB
- ' which contain several simple to use call routines that enable
- ' you access to your MPU401 controller ... and your synthesizers!
- '
- ' If you're just learning QuickBASIC we'll show you how to
- ' start QuickBASIC with these MIDI routines available in real
- ' time, so you can edit and hear your programs work while
- ' in the QuickBASIC environment. We've also tried to show you
- ' a better understanding of using CALLS to subs, just in case you
- ' have been reluctant to try them.
- '
- ' For sake of readability and understanding for new programmers,
- ' we've tried to write the examples in a simple to understand way
- ' rather than using boolean and subs that would speed things up at
- ' the expense of understandability. We also use FOR NEXT loops for
- ' timing delays and yes we know they're not accurate at all speeds
- ' and suggest you use time delay routines suitable for your system.
- ' You experienced folk will see many obvious places for program
- ' improvement and by all means .... improve! But, for this first
- ' lesson, we've written at a greatly simplified level.
- '
- '
- ' QBMIDI is a Trademark of AskUs! Technology Specialists
- ' (c) 1990 AskUs. All rights reserved.
- '
- '---------------------------------------------------------------------
-
-
- '---------------------------------------------------------------------
- '
- ' Writing A Program That Uses QBMIDI
- '
- ' Since all QBMIDI routines deal in integer numbers, usually from 0 to
- ' 255 we use the DEFINT A-Z command to make using integer variables
- ' easier. Using integer yields greater execution speed and saves memory
- ' space. Also, if you compile your programs to .EXE and you avoid the
- ' floating point library (by not using floating point numbers or
- ' functions , your program size should be much smaller by up to 20K.
- '---------------------------------------------------------------------
-
- DEFINT A-Z 'Always use integers unless specified for speed and space savings
-
- '---------------------------------------------------------------------
- ' Display Headings
- '---------------------------------------------------------------------
-
- SCREEN 0 'Select normal text screen 0
- CLS 'Clear screen
- COLOR 15 'Use Bright white
- PRINT "QuickBASIC MIDI DEMO ";
- PRINT "Shareware Version 1.0 ";
- PRINT "(c) 1990 AskUs!"
- COLOR 7 'Use Normal white
- PRINT STRING$(80, "─") 'Print line across top of screen
- VIEW PRINT 4 TO 25 'Set viewport so messages can scroll under while leaving heading intact
-
- '------------------------------------------------------------------------
- ' You access the QBMIDI routines by calling them as we would call a SUB
- ' procedure or other add-in library routines. In the next executable
- ' line we call the SeeIfMPUExists routine to do just that .. see if a
- ' MIDI controller is present. If one is found then the variable called
- ' Found will be set to the value -1, otherwise the Found variable will
- ' come back as Zero to indicate a controller was not present.
- '
- ' Now let's call the routine and handle it according to what's found.
- ' Obviously, if a controller is not found, you'd probably hang your CPU
- ' if you tried to continue, so we exit with an error message.
- '------------------------------------------------------------------------
-
- CALL SeeIfMPUExists(Found) 'Check for Midi Processing Unit, Sets Found to -1 if a MPU is found
- IF Found THEN 'If found then display found message
- PRINT "MPU Found"
- ELSE 'Otherwise, if not found end program
- PRINT "MPU Not Found"
- END
- END IF
-
- '------------------------------------------------------------------------
- ' The next routine, ResetMPU, lets you restore the Midi Processing Unit
- ' to its power up state. We like to issue a reset before starting our
- ' programs to clear out any changes that may have been made by another
- ' MIDI program - and it is much cleaner than asking you to turn your
- ' computer off to clear the unit. ResetMPU will NOT turn off notes
- ' you may have left on and typically is used only once at the beginning
- ' of your program.
- '
- ' No variable is returned with this Call, so you omit the parenthesis
- ' and a variable name when calling.
- '------------------------------------------------------------------------
-
- CALL ResetMPU 'Reset MPU to Power up defaults - just in case another program left if with settings changed
-
- '------------------------------------------------------------------------
- ' Following is some normal text to tell you what's going on ...
- '------------------------------------------------------------------------
-
- CLS
- COLOR 15
- PRINT "WELCOME TO QBMIDI ... AND A QUICK SAMPLE OF ITS USE"
- COLOR 7
- PRINT
- PRINT "When running this program we'll describe functions available to you"
- PRINT "from QBMIDI and refer you to parts of the source code for a better"
- PRINT "explanation of what's happening. We think the best way to learn is from"
- PRINT "example, so we've included well documented examples within this source."
- PRINT
- PRINT "To continue with this program, you'll need the following:"
- PRINT " IBM COMPATIBLE COMPUTER (6MHz 286 or better is recommended)"
- PRINT " MIDI CONTROLLER (Roland MPU401, Voyetra OP-4001, or equivalent)"
- PRINT " attached to the computer, (appx. $100.00 item)"
- PRINT " SYNTHESIZER with Midi inputs and outputs (appx. $150.00 and up"
- PRINT " depending on features and type of technology used)"
- PRINT " MIDI CABLES connecting the Controller to the Synthesizer ($15.00ea)."
- PRINT " Be sure MIDI OUT on the controller is connected to IN on the synth"
- PRINT " and IN on the controller hooks to OUT on the synth."
- PRINT " AMPLIFIED SPEAKER, most higher end synthesizers use external amps."
- PRINT
- PRINT "If you've got the above then hook it up and turn it on! If not, please"
- PRINT "check with your local musicians shop about purchase (appx. costs given above)."
- PRINT
- GOSUB PressAnyKeyAndAllowExit 'Ask for any keypress or Esc to exit
-
- '------------------------------------------------------------------------
- ' Now we'll actually play a few notes to see if your system is working
- '------------------------------------------------------------------------
-
- CLS
- COLOR 15
- PRINT "LET'S PLAY A SCALE TO CHECK IF THINGS ARE WORKING"
- COLOR 7
- PRINT
- PRINT "We'll now play a scale to make sure all is working. To do this we've set"
- PRINT "up a FOR NEXT loop to increment the notes when calling the QBMIDI command "
- PRINT "PlayNote. Midi will recognizes note values from 1 to 127, but we'll play"
- PRINT "only from 41 to 107 since most synthesizers sound a bit muddy at the bottom"
- PRINT "and top ends."
- PRINT
- PRINT "Make sure all components are on, plugged in correctly. Select a sound from"
- PRINT "your front panel on your synthesizer and then press a key to hear your"
- PRINT "QuickBASIC and QBMIDI play a scale."
- PRINT
- GOSUB PressAnyKeyAndAllowExit 'Ask for any keypress or Esc to exit
-
- '------------------------------------------------------------------------
- ' In the next loop, we use the CALL PlayNote command to send a Note
- ' value and velocity value to the MIDI instrument attached. With this
- ' call routine, we set the variables Note and Velocity before calling
- ' PlayNote.
- '
- ' Explanation of variables:
- '
- ' NOTE indicates what pitch or note to play. Each key on a keyboard has
- ' been assigned a number from 1 to 127, with middle C being 60. Some
- ' synthesizers won't play extremely low or high notes or they remap them
- ' to lowest possible notes. This causes you to hear the same notes repeat
- ' when playing a scale from 1 to 127.
- '
- ' VELOCITY indicates the amount of pressure applied when striking the
- ' note from a keyboard. If you are playing a soft piece of music, the
- ' velocity may range from 40 to 80. If playing loud, you may hit the
- ' keys harder, thereby increasing the velocity of the keypress. You
- ' specify how hard the key is pressed from 1 (softest) to 127 (hardest).
- '
- ' Valid ranges for PlayNote variables are:
- '
- ' Note = 1 to 127 1 being lowest note possible, 127 the highest
- ' Velocity = 1 to 127 1 being soft touch, 127 being hardest touch
- '
- ' Once a sound has been turned on, it will stay on until you turn it
- ' off. Turn it off by sending a velocity of Zero (0) to PlayNote
- ' along with the Note you wish to turn off. In the following example
- ' we turn on a note, wait a while, then turn it off using Velocity of 0.
- '
- ' No variables are changed, so the Note and Velocity variables are left
- ' intact so you can call repeatedly, without resetting the variable.
- '------------------------------------------------------------------------
-
- Note = 38 'Starting note (hopefully above the muddy notes on some keyboards)
- DO 'Begin a loop to play the scale
- Note = Note + 3 'Increment Note by 3 (Change to 1 and re-run)
-
- LOCATE , 1 'Put cursor at beginning of line
- PRINT "Not playing note ... "; 'Display message
- COLOR 15 'Set text to high brightness
- PRINT Note; " "; 'Display current not being played
- COLOR 7 'Set text color to normal brightness
- Velocity = 120 'Strong Key Strike Velocities (Range os 1 - 127)
- CALL PlayNote(Note, Velocity) 'Send the Note out Midi to all Synths attached
-
- FOR tmp = 1 TO 15000: NEXT tmp 'Wait a little while (Modify on you machine as needed)
-
- Velocity = 0 'Now turn off the note by sending a velocity of Zero along with which note to make zero
- CALL PlayNote(Note, Velocity) 'Send the Note out Midi to all Synths attached
-
- LOOP UNTIL Note > 105
-
- PRINT
- PRINT
- PRINT "You should have heard a scale played in steps of every third note. If not"
- PRINT "check your connections, volume, and sound you've selected then restart."
- PRINT
- GOSUB PressAnyKeyAndAllowExit 'Ask for any keypress or Esc to exit
-
-
- '------------------------------------------------------------------------
- ' Create a chord by calling PlayNote several times, specifying different
- ' notes for each call, then waiting to turn off the note.
- '------------------------------------------------------------------------
-
- CLS
- COLOR 15
- PRINT "CHORDS"
- COLOR 7
- PRINT
- PRINT "Now we'll play a three part chord. This is done by sending three PlayNote"
- PRINT "commands in succession, and leaving all three turned on until we individually"
- PRINT "turn them back off. Let's listen to a chord."
- GOSUB PressAnyKeyAndAllowExit 'Ask for any keypress or Esc to exit
-
- '------------------------------------------------------------------------
- ' Three PlayNote Commands Are Issued with Velocities Set to 120 (Quite Hard)
- '------------------------------------------------------------------------
-
- Velocity = 120 'Strong Key Strike Velocities (Range os 1 - 127)
- Note = 29 'Note Range is between 1 - 127
- CALL PlayNote(Note, Velocity) 'Send the Note out Midi to all Synths attached
-
- Velocity = 120 'Strong Key Strike Velocities (Range os 1 - 127)
- Note = 41 'Note Range is between 1 - 127
- CALL PlayNote(Note, Velocity) 'Send the Note out Midi to all Synths attached
-
- Velocity = 120 'Strong Key Strike Velocities (Range os 1 - 127)
- Note = 60 'Note Range is between 1 - 127
- CALL PlayNote(Note, Velocity) 'Send the Note out Midi to all Synths attached to turn the Middle C off
-
- PRINT
- PRINT "You're hearing a three part chord. Notes 29, 41 and 60 were turned on"
- PRINT "above and currently still on. Press any key to turn the chord off."
- GOSUB PressAnyKey
-
- '------------------------------------------------------------------------
- ' Now We'll turn off the chord by issuing the Same three PlayNote Commands
- ' except we'll set Velocity to zero. Since PlayNote variables are not
- ' changed, we can specify Velocity once then for all three CALLS.
- '------------------------------------------------------------------------
-
- Velocity = 0 'Set velocity to zero to turn off note
-
- Note = 29 'Note Range is between 1 - 127
- CALL PlayNote(Note, Velocity) 'Send the Note out Midi to all Synths attached
-
- Note = 41 'Note Range is between 1 - 127
- CALL PlayNote(Note, Velocity) 'Send the Note out Midi to all Synths attached
-
- Note = 60 'Note Range is between 1 - 127
- CALL PlayNote(Note, Velocity) 'Send the Note out Midi to all Synths attached to turn the Middle C off
-
- PRINT
- PRINT "Now the chord has been turned off."
- GOSUB PressAnyKeyAndAllowExit 'Ask for any keypress or Esc to exit
-
-
- '------------------------------------------------------------------------
- ' Now we'll show changes in Velocity values
- '------------------------------------------------------------------------
-
- CLS
- COLOR 15
- PRINT "VELOCITY VALUES"
- COLOR 7
- PRINT "Whenever a note is turned on using PlayNote you must specify the note"
- PRINT "to play and a velocity value. Velocity value indicates how hard the key"
- PRINT "would have been pressed if playing from a keyboard. 1 is softest up to 127"
- PRINT "as hardest hit possible. To shut off a note, we send the velocity as 0."
- PRINT
- PRINT "We'll now play the same chord at a three velocity levels, 20, 70 and 127."
- PRINT
- PRINT "Listen to a Velocity value of 20 (simulated light pressure on keyboard)"
- GOSUB PressAnyKey
-
- '------------------------------------------------------------------------
- ' Set the notes we'll use for this chord and call a GOSUB created to play
- ' the chord (and save some space in this program).
- '------------------------------------------------------------------------
-
- Note1 = 60 'First note in chord
- Note2 = 41 'Second Note in chord
- Note3 = 29 'Third note in chord
-
- '------------------------------------------------------------------------
- ' Now set velocity and GOSUB to play the chord
- '------------------------------------------------------------------------
-
- Velocity = 20 'Soft Key Strike Velocities (Range os 1 - 127)
- GOSUB PlayThreeNoteChord 'We'll use a subroutine to save some space
-
- PRINT "It's light pressure and may not be heard unless your volume is up."
- GOSUB PressAnyKey
-
- '------------------------------------------------------------------------
- ' After you've pressed a key, we'll send Zero Velocity to turn off the
- ' chord
- '------------------------------------------------------------------------
-
- Velocity = 0 'Shut off Notes
- GOSUB PlayThreeNoteChord 'We'll use a subroutine to save some space
-
- '------------------------------------------------------------------------
- ' Now repeat for Velocity 70
- '------------------------------------------------------------------------
-
- PRINT
- PRINT "Listen to a Velocity value of 70 (simulated medium pressure on keyboard)"
- GOSUB PressAnyKey
-
- Velocity = 70 'Medium Key Strike Velocities (Range os 1 - 127)
- GOSUB PlayThreeNoteChord 'We'll use a subroutine to save some space
-
- PRINT "This medium pressure should sound about twice as loud as the previous."
- GOSUB PressAnyKey
-
- Velocity = 0 'Shut off Notes
- GOSUB PlayThreeNoteChord 'We'll use a subroutine to save some space
-
- '------------------------------------------------------------------------
- ' Now repeat for Velocity 127
- '------------------------------------------------------------------------
-
- PRINT
- PRINT "Listen to a Velocity value of 127 (simulated hardest pressure on keyboard)"
- GOSUB PressAnyKey
-
- Velocity = 127 'Loudest Key Strike Velocities (Range os 1 - 127)
- GOSUB PlayThreeNoteChord 'We'll use a subroutine to save some space
-
- PRINT "Playing the hardest hit pressure (velocity) available."
- GOSUB PressAnyKey
-
- Velocity = 0 'Shut off Notes
- GOSUB PlayThreeNoteChord 'We'll use a subroutine to save some space
-
- PRINT
- PRINT "You can also change Velocity within the notes of a chord where each key"
- PRINT "receives a different pressure when pressed. We suggest you try a little"
- PRINT "experimenting with this ... a bit later."
- PRINT
- GOSUB PressAnyKeyAndAllowExit 'Ask for any keypress or Esc to exit
-
-
-
- CLS
- COLOR 15
- PRINT "PLAY SCALE OF CHORDS"
- COLOR 7
- PRINT
- PRINT "We'll combine the parts learned so far (play a scale and play a chord) into"
- PRINT "a scale of Chords. We set up a loop for play the scale but call three PlayNote"
- PRINT "commands at a time to play the chord. Let's listen."
- GOSUB PressAnyKeyAndAllowExit 'Ask for any keypress or Esc to exit
-
- PRINT
-
- Note = 38 'Starting note (hopefully above the muddy notes on some keyboards)
- DO 'Begin a loop to play the scale
- Note = Note + 3 'Increment Note by 3 (Change to 1 and re-run)
-
- Velocity = 120 'Strong Key Strike Velocities (Range os 1 - 127)
- Note1 = Note - 12 'Subtract 12 for bottom note in chord
- Note2 = Note 'Mid note stays the same
- Note3 = Note + 19 'Add 19 to get upper note in chord
-
- LOCATE , 1 'Put cursor at beginning of line
- PRINT "Now playing notes ... "; 'Display message
- COLOR 15 'Set text to high brightness
- PRINT Note1; " "; 'Display current not being played
- PRINT Note2; " "; 'Display current not being played
- PRINT Note3; " "; 'Display current not being played
- COLOR 7 'Set text color to normal brightness
-
- GOSUB PlayThreeNoteChord
-
- FOR tmp = 1 TO 15000: NEXT tmp 'Wait a while
-
- Velocity = 0 'Now turn off the note by sending a velocity of Zero along with which note to make zero
- GOSUB PlayThreeNoteChord
-
- LOOP UNTIL Note > 105
-
- Velocity = 120 'Hard pressure
- Note1 = 29 'First note in chord
- Note2 = 41 'Second Note in chord
- Note3 = 60 'Third note in chord
- GOSUB PlayThreeNoteChord 'We'll use a subroutine to save some space
-
- LOCATE , 1 'Put cursor at beginning of line
- PRINT "Now playing notes ... "; 'Display message
- COLOR 15 'Set text to high brightness
- PRINT Note1; " "; 'Display current not being played
- PRINT Note2; " "; 'Display current not being played
- PRINT Note3; " "; 'Display current not being played
- COLOR 7 'Set text color to normal brightness
-
- FOR tmp = 1 TO 20000 'Wait quite a while
- FOR j = 1 TO 10 'Increase by factor of 10
- NEXT j 'Next
- NEXT tmp 'Loop til 20,000
-
- Velocity = 0 'Shut off Notes
- GOSUB PlayThreeNoteChord 'We'll use a subroutine to save some space
-
- PRINT
- GOSUB PressAnyKey 'Ask for any keypress or Esc to exit
-
-
- '----------------------------------------------------------------------
- ' A final closing note to display
- '----------------------------------------------------------------------
-
- CLS
- COLOR 15
- PRINT "WHAT NEXT"
- COLOR 7
- PRINT
- PRINT "List out this program and modify it using your imagination. If you wish to"
- PRINT "go further with MIDI than this program allows, we suggest you consider"
- PRINT "purchase of the QBMIDI MUSICIANS VERSION that provides advanced features"
- PRINT "including independent sound control by midi channel, bulk sound data dumps"
- PRINT "and saves, and much more. See the QBMIDI.DOC file for more info."
- PRINT
- PRINT "We hope you like our beginners intro to MIDI and QBMIDI. Experiment and"
- PRINT "have fun. We've found that making music with Computers is far more enjoyable"
- PRINT "than writing other types of programs. And besides, our world doesn't need"
- PRINT "another amortization, biorythm or ultimate menu shell program."
- PRINT
- PRINT "AskUs! for more information or Tell Us what you'd like by writing us at:"
- PRINT
- PRINT " AskUs!, PO Box 737, Bountiful, UT 84011-0737"
- PRINT
-
- END
-
-
-
- '------------------------------- G O S U B S ------------------------------------
-
-
- '----------------------------------------------------------------------
- ' When playing chords, it's easiest to GOSUB to a routine that plays
- ' or shuts off all three (or more) notes in the cord. We've played
- ' three notes simultaneously but more can be played in a chord or
- ' at once by adding another CALL PlayNote. Experiment and have fun!
- '----------------------------------------------------------------------
-
- PlayThreeNoteChord:
-
- 'Note1, Note2 and Note3 should contain the notes to play
- 'Velocity should contain desired play velocity or 0 to shut off the
- 'note currently playing.
-
- CALL PlayNote(Note1, Velocity)
- CALL PlayNote(Note2, Velocity)
- CALL PlayNote(Note3, Velocity)
-
- RETURN
-
-
- '----------------------------------------------------------------------
- ' We use the press any key in two forms. One that allows exit to the
- ' system and one that doesn't. We don't allow an exit while notes are
- ' being played. Again, it's lengthy for readability purposes only.
- '----------------------------------------------------------------------
-
- PressAnyKeyAndAllowExit:
- ExitAllowed = -1 'Set flag (Variable) showing that exit is acceptable
-
- PressAnyKey: 'Display message at bottom, wait for key, check for escape and end or erase message and return
- DO 'Start simple loop to clear out keyboard buffer, just in case characters were left there
- LOOP UNTIL INKEY$ = "" 'Loop until no more keys are found
- COLOR 15 'Use bright level text
- PRINT "Press any key "; 'Display message
- IF ExitAllowed THEN 'If Exit OK then ...
- PRINT "(or Esc to quit)"; 'Display extended message to say it's ok to use escape
- END IF 'End of If Exit check
- COLOR 7 'Go back to Normal level text
- DO 'Start loop to wait for keypress
- a$ = INKEY$ 'Look for keypress using inkey
- LOOP UNTIL LEN(a$) 'Loop until length of A$ is greater than 0, in otherwords loop until a character is in A$, LEN(A$)>1
- IF ExitAllowed = -1 THEN 'If Exit OK then check if escape was pressed
- IF a$ = CHR$(27) THEN 'Check for the escape key
- PRINT 'Space to next line
- PRINT "Program stopped" 'Display what happened
- END 'End the program
- END IF 'End of Check for escape key If condition
- END IF 'End of Exit Allowed If condition
- LOCATE , 1 'Send cursor back to beginning of line
- PRINT STRING$(42, " "); 'Erase the Press any key message
- LOCATE , 1 'Send cursor back to beginning of line for next line to print
- ExitAllowed = 0 'Set exit OK flag to false in case it was used this time in
- RETURN 'Jump back where Gosub brought us here
-
-
-