Q(uick)BASIC Statement (Music): PLAY
Quick View
PLAY
A device I/O statement that plays music
Worth knowing
Useful and cross-version information about the programming environments of QBasic and QuickBasic.
Syntax
- PLAY commandstring$
Description/Parameter(s)
commandstring$ | A string expression that contains one or more of the following PLAY commands: |
Octave and tone commands: |
|
Ooctave | Sets the current octave (0 - 6). |
< or > | Moves up or down one octave. |
A - G | Plays the specified note in the current octave. |
Nnote | Plays a specified note (0 - 84) in the seven-octave range (0 is a rest). |
Duration and tempo commands: |
|
Llength | Sets the length of each note (1 - 64). L1 is whole note, L2 is a half note, etc. |
ML | Sets music legato. |
MN | Sets music normal. |
MS | Sets music staccato. |
Ppause | Specifies a pause (1 - 64). P1 is a whole-note pause, P2 is a half-note pause, etc. |
Ttempo | Sets the tempo in quarter notes per minute (32 - 255). |
Mode commands: |
|
MF | Plays music in foreground. |
MB | Plays music in background. |
Suffix commands: |
|
# or + | Turns preceding note into a sharp. |
- | Turns preceding note into a flat. |
. | Plays the preceding note 3/2 as long as specified. |
To execute a PLAY command substring from a PLAY command string, use the "X" command: | |
|
Differences from BASICA
- DRAW and PLAY statements in BASICA that use variables or other command strings within command strings must be modified for QBasic. Use the VARPTR$ function, which returns a string representation of the variable's address:
BASICA Statement | QBasic Equivalent |
DRAW "Xcmdstring$" | DRAW "X" + VARPTR$ (cmdstring$) |
DRAW "TA = angle" | DRAW "TA =" + VARPTR$(angle) |
Example
'Play scale in 7 different octaves
scale$ = "CDEFGAB"
PLAY "L16"
FOR i% = 0 TO 6
PLAY "O" + STR$(i%)
PLAY "X" + VARPTR$(scale$)
NEXT i%
Syntax
- PLAY commandstring
Description/Parameter(s)
The commandstring is a string expression containing one or more music commands. The PLAY statement uses a concept similar to DRAW in that it embeds a music macro language in one statement. A set of commands, used as part of the PLAY statement, specifies a particular action.
commandstring is a stringexpression that contains music commands: | |
Set Octaves and Play Tones |
|
On | Sets current octave (n = 0-6) |
Nn | Plays note n (n = 0-84, 0 is a rest) |
< or > | Up or down one octave |
A-G | Plays A, B, …, G in current octave (+ = sharp, - = flat) |
Set Tone Duration and Tempo |
|
Ln | Sets length of a note (L1 is whole note, L4 is quarter note, etc.) n = 1-64 |
Tn | Sets number of quarter notes per minute (n = 32-255, 120 default |
MS | Each note plays 3/4 of length |
MN | Each note plays 7/8 of length |
ML | Each note plays full length |
Pn | Pause for the duration of n quarternotes (n = 1-64) |
Set Operation |
|
MF | Plays music in foreground |
MB | Plays music in background |
Execute Substrings |
|
X + VARPTR$(string-expression) Executes another command string |
In compiled programs, you should use the VARPTR$(variable) form for variables. For example, the BASICA statements
- PLAY "XA$"
- PLAY "O = I"
should be written for the compiler like this:
- PLAY "X" + VARPTR$(A$)
- PLAY "O=" + VARPTR$(I)
Examples
This example uses ">" to play the scales from octave 0 to octave 6, then reverses with "<" to play the scales from octave 6 to octave 0:
SCALE$ = "CDEFGAB"
PLAY "o0 X" + VARPTR$(SCALE$)
FOR I = 1 TO 6
PLAY ">X" + VARPTR$(SCALE$)
NEXT
PLAY "o6 X" + VARPTR$(SCALE$)
FOR I = 1 TO 6
PLAY "<X" + VARPTR$(SCALE$)
NEXT
This example plays the first few notes of Beethoven's Fifth Symphony:
LISTEN$ = "T180 o2 P2 P8 L8 GGG L2 E-"
FATE$ = "P24 P8 L8 FFF L2 D"
PLAY LISTEN$ + FATE$
Syntax
- PLAY commandstring$
Description/Parameter(s)
commandstring$ | A string expression that contains one or more of the music commands. |
Octave and Tone Commands |
|
o n | Set current octave (n = 0-6). |
< or > | Move up or down one octave. |
A - G | Play A, B, … G in current octave (+ or # = sharp, - = flat). |
Nn | Play a note (n = 0-84, where 0 is a rest). |
Duration and Tempo Commands |
|
Ln | Sets length of a note (n = 1-64, where 64 is 64th note). |
ML | Each note plays full length. |
MN | Each note plays 7/8 of length. |
MS | Each note plays 3/4 of length. |
Pn | Pause for the duration of n quarternotes (n = 1-64). |
Tn | Sets tempo (n = 32-255, 120 quarter notes per minute default). |
Foreground/Background Operation Commands |
|
MF | Plays music in foreground. |
MB | Plays music in background. |
To execute substrings within a PLAY command, use a command of the form: | |
|
- The PLAY statement is not available in OS/2 protected mode.
Usage Notes
- The PLAY statement uses a concept similar to DRAW in that it embeds a music macro language in one statement. A set of commands, used as part of the PLAY statement, specifies a particular action.
- In Microsoft BASIC programs, you should use the VARPTR$(variablename) form for variables. For example, these BASICA statements:
- PLAY "XA$"
- PLAY "O = I"
- should be written like this in Microsoft BASIC:
- PLAY "X" + VARPTR$(A$)
- PLAY "O=" + VARPTR$(I)
Example
This example uses the PLAY statements and the PLAY and VARPTR$ functions to play continuous music by calling an event-handling subroutine when the background music buffer goes from three to two notes.
CLS
'Call subroutine Replay when the music buffer goes from 3 to 2 notes.
ON PLAY(3) GOSUB Replay
'Turn on event trapping for PLAY.
PLAY ON
'Define a string containing the melody.
FElise$ = "o3 L8 E D+ E D+ E o2 B o3 D C L2 o2 A"
PLAY "MB X" + VARPTR$(FElise$)
'Suspend event trapping until next PLAY ON but remember events that occur
'while event trapping is disabled.
PLAY STOP
'Introduce a variable-length delay.
LOCATE 23, 1: PRINT "Press any key to continue."
DO
LOOP WHILE INKEY$ = ""
'Re-enable play event trapping remembering that a PLAY event has occurred.
PLAY ON
LOCATE 23, 1: PRINT "Press any key to stop. "
'Loop until a key is pressed.
DO
GOSUB BackGround
LOOP WHILE INKEY$ = ""
'Disable PLAY event processing.
PLAY OFF
'Count down to 0 notes in the queue.
DO
GOSUB BackGround
LOOP UNTIL NoteCount = 0
END
'PLAY event-handling subroutine.
Replay:
'Increment and print a counter each time.
Count% = Count% + 1
LOCATE 3, 1: PRINT "Replay routine called"; Count%; "time(s)";
'PLAY it again to fill the buffer.
PLAY "MB X" + VARPTR$(FElise$)
RETURN
'Background music queue reporting subroutine.
BackGround:
'Get a notecount.
NoteCount = PLAY(0)
LOCATE 1, 1
PRINT "Background queue notes remaining --> "; NoteCount
'Loop until Notecount changes or equals 0.
DO
LOOP UNTIL NoteCount <> PLAY(0) OR NoteCount = 0
RETURN