MIDI Music and Sound

Top  Previous  Next

Emergence BASIC supports playing wave files and MIDI streams natively.

Playing wave files

To play a wave sound from either memory or a file use the PLAYWAVE function. The sound can be played either synchronously or asynchronous. Synchronous playback will stop your program until the sound is finished playing. The syntax of PLAYWAVE is:

success = PLAYWAVE(filename | memory, flags)

Valid values for flags are:

@SNDASYNC - The sound is played asynchronously and the function returns immediately after beginning the sound.

@SNDSYNC - The sound is played synchronously and the function does not return until the sound ends.

@SNDLOOP - The sound plays repeatedly. You must also specify @SNDASYNC.

@SNDNOSTOP - If a sound is currently playing, the function immediately returns FALSE, without playing the requested sound.

Example:
 

PLAYWAVE "c:\\media\\bark.wav", @SNDASYNC

To stop a sound use an empty string for the name or use NULL. Playing from resources can be accomplished by using a custom resource and LOADRESOURCE to load the wave resource directly into a MEMORY variable.

 

Playing MIDI streams

A MIDI stream is a sequence of notes played either synchronously or asynchronously. The PLAYMIDI$ function provides an easy way to create music for your program. PLAYMIDI$ uses a formatting string describing the notes to be played and the properties of the notes including length, instrument, and velocity. The string is interpreted and converted into the necessary MIDI events for the stream before playing. The syntax of PLAYMIDI$ is:

pThread = PLAYMIDI$( strMidi, OPT bAsync)

strMidi is the note formatting string and can contain the following commands:

A-G {#}n

Plays a note. The # specifies a sharp. n is the duration of the note and can be 1,2,4,8,16,32 or 64 representing whole note, half note, quarter note, eighth note, and so on.

On

Specifies the octave of the notes that follow. There are 11 octaves from 0 to 10 with octave 5 containing middle C. Each octave begins with the C note and ends with the B note.

In

Sets the instrument (patch) to be used for the notes that follow. n can be from 0 to 127.

Vn

Sets the velocity, or volume, of the notes that follow. n ranges from 0 which is completely silent to 127 for full velocity.

Nn

Sets the channel of the notes that follow. n is the channel number and can range from 0 to 15. The default channel is 0. Channel 9 is the built in drum channel for most sound cards.

Rn

Inserts a rest. n specifies the duration of the rest and are the same as note durations.

Tn

Sets the tempo of the music in beats per minute (bpm). Default is 120. n can range from 10 to 300

*

Begins a chord. Any commands between the * and ; are played at the same time index.

;

Ends a chord.

Any other characters in the formatting string are simply ignored allowing separating commands with spaces, tabs or whatever is convenient. The commands are not case sensitive.

Parameters are saved between note commands so it is not necessary to specify the duration, octave, velocity, etc for every note. You only need to specify the numeric parameter when there is a change.

Examples:

PLAYMIDI$ "T120 N0 I25 O5 *C2EG;D4EFG*A2O6CE; *C2EG;D4EFG*A2O7CE;"
PLAYMIDI$ "T180 N0 I0 O5 C8C#DD#EFF#GG#AA#B O6 CC#DD#EFF#GG#AA#B O7 C1"

To play music asynchronously specify TRUE for the optional bAsync parameter. The command will return immediately and the notes will be played in the background while your program continues. PLAYMIDI$ returns a pointer to the stream thread being played that can be passed to the  STOPMIDI$ command. Only one asynchronous stream is allowed at a time by Windows so it will be necessary to stop the previous stream with STOPMIDI$ before starting another one.

Example:

OPENCONSOLE
pThread = PLAYMIDI$( "T180 N0 I0 O5 C8C#DD#EFF#GG#AA#B O6 CC#DD#EFF#GG#AA#B O7 C1", TRUE )
DO:UNTIL INKEY$ <> ""
STOPMIDI$(pThread)
PLAYMIDI$ "T120 N0 I25 O5 *C2EG;D4EFG*A2O6CE; *C2EG;D4EFG*A2O7CE;"

It is not necessary to stop an asynchronous music stream before your program ends. The compiler adds the necessary commands to stop any running streams on exit.