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:
  • PLAY "X"+ VARPTR$(commandstring$)

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:
  • "X" + VARPTR$(stringexpression)
  • 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