Home

Using WINMM.DLL

Liberty BASIC Default Variables

Updating in LB

Internet - Downloading a File to Disk

API Corner - Easy Font Manipulations

Multiple Windows and Displays

Mapping Real World Coordinates

Linear and Non-Linear Equations

About Ingemar Bjerle

Submission Guildlines

Newsletter Help

Index

My knowledge of API calls is rather limited, so I rely heavily on help form others in the egroup. The following program is based on the clever Piano.bas originally provided by Alyce Watson with each new release of LB.

Many may not be fully aware of the considerable API routines held in winmm.dll provided with many versions of Windows. Apart form it's use enabling us to play MP3, MIDi, WAV and Video files such as MPEG and AVI, as Piano.bas demonstrates, it has 128 voices installed. No doubt these voices are need to play the MIDi files etc. What I would like to emphasize is the great value these voices can have in producing games, to avoid the use of space consuming WAV files, so popular among many games.

The following program demonstrates how to test any of the voices in a variety of ways, and should provide the ground work to allow you to call up a voice anytime. At the start of your program you need to activate winmm.dll etc by inserting gosub [sblast] . Then whenever you wish to produce a sound insert the following...

instrum = 1 : sndlen = 300 : note = 48 : gosub [newNote]

where instrum is the voice/instrument, sndlen is the length of the note in microseconds, and note is the frequency, with 48 producing the note of C. If you use a sndlen of 1 it will default to the natural length. You can of course repeat notes by doing this:

' START A RACE WITH PEPEATING TINKER BELL
  sndlen = 20 : note = 90 : instrum = 113
  for n = 1 to 40
  gosub [newNote]
  next n

Happy Gaming


' If sounds fail after any program changes,
' then abort LB and rerun the program. Ver. 3.02 & 3.03
    nomainwin
    dx = 1 : dy = 1
    if DisplayWidth > 1000 then dx = 120 : dy = 90
    UpperLeftX = dx : UpperLeftY = dy
    WindowWidth = 800 : WindowHeight = 600
    button #s, "Fast Range", [fast], LL 160, 140
    button #s, "Slow Range", [slow], LL 280, 140
    button #s, "Single Note", [single], LL 400, 140
    button #s, "Music Scale", [scale], LL , 530, 140
    button #s, "Doh Rae Mee", [doh], LL 160, 80
    button #s, "Mee Rae Doh", [mee], LL 280, 80
    button #s, "Voice List ", [list], LL 400, 80
    button #s, "*** QUIT **", [quit], LL 530, 80
    open "Instruments and Sounds" for graphics_nsb as #s
    #s "trapclose [quit]; fill 100 100 1; backcolor 100 100 1"
    #s "font arial 24 bold; color white; place 130 80"
    #s "\Intrumental Voices and Sound Effects."
    #s "font arial 10; place 220 100"
    #s "\produced by Gordon Sweet ver. 2.2 July 2003 using Liberty Basic"
    #s "font arial 18 bold; place 240 140"
    #s "\Select a voice then the effects"
    #s "color yellow; place 220 200; flush"
    instrum = 1 : voice$ = "Grand Piano"

    'read instrument names into array for combobox
    Dim ins$(128) : Dim voice(128) : Dim tone(20)
    restore [info] : For vc = 1 to 128
    Read data$ : voice(vc)=vc : ins$(vc)=data$ 
    Next vc
    restore [notes] : for n = 1 to 15
        read dat : tone(n) = dat
    Next n

    gosub [sblast]       'initialise winmm.dll
    choice = 1 : instrum = 1 'first data
    msg$=space$(20)+"Select an Instrument or Sound."
    msg$=msg$+" If necessary turn up your speakers."

[which]
    #s "place 200 200" : #s "\";space$(80)
    #s "place 200 200" : #s "\Current Voice No. ";choice;" ";voice$ 
    WindowWidth=470:WindowHeight=100
    UpperLeftX=dx+160:UpperLeftY=dy+240
    Button #p.default, "Quit",[quit],UL,370,15,50,30
    Statictext #p, "Select Voice or Internal Speaker",15,5,200,20
    Combobox #p.ins, ins$(,[instrument],15, 25, 220,580
    Graphicbox #p.g, 0, 0,0,0
    Statictext #p.vol, msg$,15,60,550,40
    Open "Select" For Window_nf As #p
    print #p, "trapclose [quit]"
    Print #p.ins, "select ";voice$
    Print #p.g, "trapclose [quit]"
    mainH=hWnd(#p) : gosub [boxhold]
    boxp = 1 : wait

[instrument]'user selected an instrument voice
    Print #p.ins, "selectionindex?"
    Input #p.ins, choice
    instrum = voice(choice)
    voice$ = ins$(choice)
    #s "place 200 200" : #s "\";space$(80)
    #s "place 200 200" : #s "\Current Voice No. ";choice;" ";voice$ 
    wait

[fast] sndlen = 1 : goto [range]
[slow] sndlen = 100
[range]
    close #p : for note = 50 to 100
        gosub [newNote]
    next note : goto [which]

[single]
    close #p : boxp = 0
    if boxb = 1 then close #b
    WindowWidth = 200: WindowHeight = 120
    UpperLeftX = 300+dx : UpperLeftY = 240+dy
    statictext #b "Length 1/10000", 10, 10, 100, 20
    statictext #b, "Note 10/500", 120, 10, 100, 20
    textbox #b.tbox1, 30, 30, 30, 25
    textbox #b.tbox2, 130, 30, 30, 25
    button #b.default, "Accept", [pass], UL, 60, 60, 42, 25
    open "Enter or Accept" for dialog as #b
    print #b, "trapclose [bfin]" :  boxb = 1
[nopass]
    mainH=hWnd(#b) : gosub [boxhold] ' Prevents loss of Box
    wait
[pass]
    print #b.tbox1, "!contents? A$" : sndlen = val(A$)
    print #b.tbox2, "!contents? B$" : note = val(B$)
    if snflen > 0 and sndlen < 11000 then [bfin]
    if note > 1 and note < 501 then [bfin]
    notice "Invalid Entry!" : goto [nopass]
[bfin] bx=0 : close #b : boxb = 0
    gosub [newNote] : goto [which]

[scale]
    sndlen = 300
    start = 1 : last = 15 : stp = 1
    goto [sels]

[doh]
    sndlen = 600
    start = 9 : last = 11 : stp = 1
    goto [sels]

[mee]
    sndlen = 600
    start = 11 : last = 9 : stp = -1

[sels] close #p
    for n = start to last step stp
        note = tone(n)
        gosub [newNote]
    next n : goto [which]

[sblast]
    'open midi device and obtain handle
    'midi functions return 0 if successful
    struct m, a$ As ptr
    CallDLL #winmm, "midiOutOpen",_
        m As struct,-1 As long,0 As long,_
        0 As long,0 As long,ret As long

    hMidiOut=m.a$.struct    'handle to midi device
    return

[newNote]
    gosub [stopPlay]   'stop previous note
    gosub [doChange]
    gosub [playNewNote]'play new note
    return

[playNewNote]'play new note:
   ' gosub [stopNote]
    event=144   'event 144 = play on channel 1
    low=(note*256)+event
    velocity=127
    hi=velocity*256*256
    dwMsg=low+hi
    CallDLL #winmm, "midiOutShortMsg",hMidiOut As ulong,_
        dwMsg As ulong, ret As ulong

  ' NOTE LENGTH	
    tim = time$("ms") :  while time$("ms") < tim  +sndlen : wend

[stopPlay]'stop all notes from playing
    event=128    'event 128 = stop play
    low=(note*256)+event
    dwMsg=low+hi
    CallDLL #winmm, "midiOutShortMsg",hMidiOut As ulong,_
        dwMsg As ulong, ret As ulong
    timer 0
    RETURN

[doChange]'signal a voice change:
    event=192  'event 192 = change
    voice=instrum-1
    velocity=127
    low=(voice*256)+event
    hi=velocity*256*256
    dwMsg=low+hi
    CallDLL #winmm, "midiOutShortMsg",hMidiOut As ulong,_
        dwMsg As ulong, ret As ulong
    RETURN

[boxhold]
    open "user32" for dll as #user ' prevents losing box
        toTop=(-1 or 0)
        flags=_SWP_NOMOVE or _SWP_NOSIZE
    calldll #user,"SetWindowPos",mainH as ushort,toTop as short,_
    0 as short,0 as short,0 as short,0 as short,flags as ushort,_
    result as void
    close #user : return

[quit]'stop note, close midi device, DLLs, window
    timer 0
    gosub [stopPlay]   'stop all output
    CallDLL #winmm, "midiOutClose", hMidiOut As ulong,_
        ret As ulong

    CallDLL#user32,"ReleaseDC",_
        Wnd As long,hDC As long,result As long
    if boxp = 1 then close #p
    if boxb = 1 then close #b
    Close #s  ' CHANGE #s TO OTHER HANDLES
    End

[list]
    close #p : boxp = 0
    texteditor #L.tb 20,20,0,0 'this is invisible
    Menu #L, "&CONTINUE", "Continue", [cont], "&QUIT", [quitL]
    open "Winmm.dll Voice list" for text_fs as #L
    #L "!trapclose [quitL]"
    #L "!font Courier 10"
    colm = 1 : row  = 1
    For n = 1 to 128
        #L.tb using("###",n);
        #L.tb " ";ins$(n);
        gosub [tbox]
        row = row + 1
        if row = 33 then row = 1 : colm = colm + 25
    Next n
    #L.tb "Note some programs allocate a number 1 less. Click on screen to use Print/Copy etc"
    row = 33 : colm = 2 : gosub [tbox]
    beep : wait
[cont] close #L : goto [which]

[tbox]
    #L.tb "!selectall";
    #L.tb "!cut";
    #L "!select ";colm;" ";row;
    #L "!paste";
    return

[quitL]
    close #L : goto [quit]

[info]
'list of 128 voices, in order of their MIDI indexes
Data "Grand Piano","Bright Grand","Electric Grand","Honky Tonk"
Data "Rhodes","Chorus Piano","Harpsichord","Clavinet"
Data "Celesta","Glockenspiel","Music Box","Vibraphone"
Data "Marimba","Xylophone","Tubular Bells","Dulcimer"
Data "Hammond Organ","Percussion Organ","Rock Organ"
Data "Church Organ","Reed Organ","Accordian","Harmonica"
Data "Tango Accordian","Accoustic Nylon Guitar"
Data "Accoustic Steel Guitar","Electric Jazz Guitar"
Data "Electric Clean Guitar","Electric Mute Guitar"
Data "Overdrive Guitar","Distorted Guitar","Guitar Harmonic"
Data "Accoustic Bass","Electric Bass Finger","Electric Bass Pick"
Data "Fretless Bass","Slap Bass One","Slap Bass Two"
Data "Synth Bass One","Synth Bass Two","Violin","Viola","Cello"
Data "Contrabass","Tremolo Strings","Pizzicato Strings"
Data "Orchestra Harp","Timpani","String Ensemble One"
Data "String Ensemble Two","Synth Strings One","Synth Strings Two"
Data "Choir Ahhs","Voice Oohs","Synth Voice","Orchestra Hit"
Data "Trumpet","Trombone","Tuba","Mute Trumpet","French Horn"
Data "Brass Section","Synth Brass One","Synth Brass Two"
Data "Soprano Sax","Alto Sax","Tenor Sax","Bari Sax","Oboe"
Data "English Horn","Bassoon","Clarinet","Piccolo","Flute"
Data "Recorder","Pan Flute","Bottle Blow","Shakuhachi","Whistle"
Data "Ocarina","Square Wave","Sawtooth","Caliope","Chiff Lead"
Data "Charang","Solo Synth VX","Brite Saw","Brass and Lead"
Data "Fantasia Pad","Warm Pad","Poly Synth Pad","Space Vox Pad"
Data "Bowd Glas Pad","Metal Pad","Halo Pad","Sweep Pad"
Data "Ice Rain","Sound Track","Crystal","Atmosphere","Brightness"
Data "Goblin","Echo Drops","Star Theme","Sitar","Banjo","Shamisen"
Data "Koto","Kalimba","Bagpipe","Fiddle","Shanai"
Data "Tinkle Bell","Agogo","Steel Drums","Wood Block","Taiko Drum"
Data "Melodic Tom","Synth Drum","Rev Cymbal"
Data "Guitar Fret Noise","Breath Noise","Sea Shore","Bird Tweet"
Data "Phone Ring","Helicopter","Applause","Gunshot"

[notes]
Data 48,50,52,53,55,57,59,60,62,64,65,67,69,71,72
REM   C  D  E  F  G  A  B  C  D  E  F  G  A  B  C



Home

Using WINMM.DLL

Liberty BASIC Default Variables

Updating in LB

Internet - Downloading a File to Disk

API Corner - Easy Font Manipulations

Multiple Windows and Displays

Mapping Real World Coordinates

Linear and Non-Linear Equations

About Ingemar Bjerle

Submission Guildlines

Newsletter Help

Index


Home

Using WINMM.DLL

Liberty BASIC Default Variables

Updating in LB

Internet - Downloading a File to Disk

API Corner - Easy Font Manipulations

Multiple Windows and Displays

Mapping Real World Coordinates

Linear and Non-Linear Equations

About Ingemar Bjerle

Submission Guildlines

Newsletter Help

Index