May 15, 2024, 03:04:44 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


play midi notes

Started by soft4fun, October 06, 2008, 06:10:50 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

soft4fun

Hi,
does anyone know how to play midi notes using the functions midiOutOpen, midiOutSetVolume, midiOutShortMsg and midiOutClose of "user32.dll" ?
The mididemo source of EBasic is too complicated for me ! :-[
Thank you !

pistol350

October 06, 2008, 08:35:51 AM #1 Last Edit: October 06, 2008, 08:40:46 AM by pistol350
Hi!
You can find other and easier to use samples in order to learn how to play midi notes.
Here is what i got from the users guide and it's quite easy to understand after reading the "music and sound" chapter of the users guide.

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;"


Additional samples :

PLAYMIDI$("N0 O6 V64 I0 T80 C8 T120 C8 D4 CF T80 E4 R8 C8 T120 C8 D4 CG T80 F4 R8 C8 T120 C8 O7 C4 O6 AFE T80 D4 R8 A#8 T120 A#8 A4 FGF2")


'REQUIRES IBasic Pro
'Steve Boothman aka Bevets and ibDevGroup September 2004
autodefine "off"
DECLARE "user32.dll",LoadCursorA(hInstance:INT,lpCursorName:INT),INT
DECLARE "user32.dll",GetDlgCtrlID(hwnd:INT),INT
DECLARE "user32.dll",GetWindowTextA(hwnd:INT,lpSTRING:STRING,cch:INT),INT
DECLARE "user32.dll",GetSysColor(nIndex:INT),INT
CONST WM_SETCURSOR = 0x20
CONST IDC_HAND = 32649
TYPE note
   def key:Int
   def note:String
   def duration:String
   def rest:String
ENDTYPE
Def NOTEVOLUME,CHANNEL,INSTRUMENT,TEMPO:Int
def oldnote,note,res,run:int
def l,t,c,x,z,offset,keyoffset,buttonoffset:int
def key,oldkey,slide,record,ti,tie,count,pboffset,Abort:Int
def Wnd,WhiteW[29],BlackW[20]:window
Def mypointer,temp,pos:pointer
Def pThread:POINTER
Def White[29],Black[20],bp[20]:Int
Def wkeys[7],bkeys[7],voice[129]:String
def thisnote:String
bp[0]=15,39,87,111,135,183,207,255,279,303,351,375,423,447,471,519,543,591,615,639
White[0]=48,50,52,53,55,57,59,60,62,64,65,67,69,71,72,74,76,77,79,81,83,84,86,88,89,91,93,95,96
Black[0]=49,51,54,56,58,61,63,66,68,70,73,75,78,80,82,85,87,90,92,94
wkeys[0]="A","B","C","D","E","F","G"
bkeys[0]="A","C","D","F","G"
buttonoffset=7
pboffset=0
Gosub AddVoices
l=1:c=2
NOTEVOLUME = 127    :'max is 127
TEMPO=120
CHANNEL=0
INSTRUMENT=21
openwindow Wnd,0,0,800,204,@sysmenu|@caption|@border,0,"",&WndProc
'create black keys first so that they stay on top
For t = 0 To 19
   openwindow BlackW[t],bp[t],24,15,75,@NOCAPTION|@NOAUTODRAW,Wnd,"",&WndProc
   CONTROL BlackW[t],@BUTTON,"#"+chr$(13)+bkeys[l],0,0,16,75,0x50002000,Black[t]
   SetControlColor BlackW[t],Black[t],RGB(255,255,255),RGB(0,0,0)
   l++:c++:If l = 5 Then l = 0
Next t
l=0:c=2
For t = 0 To 28
   openwindow WhiteW[t],l,24,24,120,@NOCAPTION|@NOAUTODRAW,Wnd,"",&WndProc
   CONTROL WhiteW[t],@BUTTON,chr$(13)+chr$(13)+chr$(13)+wkeys[c],0,0,24,120,0x50002000,White[t]
   SetControlColor WhiteW[t],White[t],RGB(0,0,0),RGB(255,255,255)
   l=l+24:c++:If c = 7 Then c = 0
Next t
SetControlColor WhiteW[7],White[7],RGB(0,0,0),RGB(255,240,255)
gosub AddButtonKeys
gosub FinishInit
run=1
waituntil run=0
ListRemoveAll(mypointer,TRUE)
closewindow Wnd

SUB WndProc
select @CLASS
    CASE WM_SETCURSOR
      SetCursor Wnd,@CSCustom,LoadCursorA(0,IDC_HAND)
      If record=2 Then Return 1
       key=GetDlgCtrlID(@CODE)
      IF  (@qual& 0xFFFF0000) / Int(2^16) = 513
         If key > 47 & key < 97
            GetWindowTextA(@CODE,thisnote,5)
            note=key+keyoffset
            Gosub NewNote()
         EndIf
      Else
         GetWindowTextA(@CODE,thisnote,5)
           gosub CheckMouse
      EndIf
      Return 1
    Case @IDCONTROL
        If @ControlID = 500 Then Abort=1
        If @ControlID = 2 Then slide=GetState(Wnd,2)
      If @ControlID = 3
         If Getstate(Wnd,3)
            record=1
            ti=0
              ListRemoveAll(mypointer,TRUE):mypointer = ListCreate()
            temp = ListAdd(mypointer,NEW(note,1))
         Else
            record=2:Abort=0
              pos = ListGetFirst(mypointer)
            If #<Int>pos <> 0 Then Gosub NewNote()
            record=0
         EndIf
      EndIf
      If @ControlID=12
         If buttonoffset > -1
            Gosub octup
         EndIf
      EndIf
      If @ControlID=13
         If buttonoffset < 22
            Gosub octdown
         EndIf
      EndIf
        If @ControlID = 1
            IF (@NOTIFYCODE = @CBNSELCHANGE):'new voice selected from combo
            Def v:String
                res=GetSelected(Wnd,1)
            INSTRUMENT=res
            v=GETSTRING(Wnd,1,GetSelected(Wnd,1))
            For res = 0 To 127
               If v=voice[res]
                  INSTRUMENT=res:res=127
               EndIf
            Next res
            EndIf
        EndIf
   Case @IDHSCROLL
      Select @controlid
         Case 8
            NOTEVOLUME=ScrollInfo(Wnd,@controlid,@CODE,@QUAL,1,1)
            Def volume:Int
            volume=WhatPecentageIs(NOTEVOLUME,128)         :'NOTEVOLUME range 0 - 127
            SetControlText wnd,10,"Volume "+Str$(volume)
         Case 9
            TEMPO=ScrollInfo(Wnd,@controlid,@CODE,@QUAL,1,10)
            SetControlText wnd,11,"Tempo "+Str$(TEMPO)
         Case 13
            Def oldpos,newpos:Int
            oldpos=GETSCROLLPOS(Wnd,13)
            newpos=ScrollInfo(Wnd,@controlid,@CODE,@QUAL,1,1)
            If oldpos > newpos
               If buttonoffset < 22 Then Gosub octdown
            Else
               If oldpos < newpos
                  If buttonoffset > 0 Then Gosub octup
               EndIf
            EndIf
         Case 15
            CHANNEL=ScrollInfo(Wnd,@controlid,@CODE,@QUAL,1,2)   
            SetControlText wnd,14,"Channel "+Str$(CHANNEL)
      EndSelect
    case @IDCREATE
        CenterWindow Wnd
    case @IDCLOSEWINDOW
        run=0
    case @IDMENUPICK
        select @MENUNUM
            case 99:run=0
      endselect
endselect
return
endsub
Sub octup
   SetControlColor WhiteW[buttonoffset],White[buttonoffset],RGB(0,0,0),RGB(255,255,255)
   pboffset=pboffset-12:buttonoffset=buttonoffset-7:keyoffset=keyoffset+12
   If buttonoffset > -1 Then SetControlColor WhiteW[buttonoffset],White[buttonoffset],RGB(0,0,0),RGB(255,240,255)
Return
EndSub
Sub octdown
   If buttonoffset > -1 Then SetControlColor WhiteW[buttonoffset],White[buttonoffset],RGB(0,0,0),RGB(255,255,255)
   pboffset=pboffset+12:buttonoffset=buttonoffset+7:keyoffset=keyoffset-12
   SetControlColor WhiteW[buttonoffset],White[buttonoffset],RGB(0,0,0),RGB(255,240,255)
Return
EndSub
/****************
begin a new note
*****************/
SUB NewNote
    If ti <> 0 Then tie = millisecs() - ti Else tie=0
   If Len(thisnote) =3
      thisnote="#"+Right$(thisnote,1)
   Else
      thisnote=Right$(thisnote,1)
   EndIf
   Def playstring,OCTAVE:String
   note=key+keyoffset
   Select 1
      Case note >= 12 & note <= 23
         OCTAVE="1"
      Case note >= 24 & note <= 35
         OCTAVE="2"
      Case note >= 36 & note <= 47
         OCTAVE="3"
      Case note >= 48 & note <= 59
         OCTAVE="4"
      Case note >= 60 & note <= 71
         OCTAVE="5"
      Case note >= 72 & note <= 83
         OCTAVE="6"
      Case note >= 84 & note <= 95
         OCTAVE="7"
      Case note >= 96 & note <= 107
         OCTAVE="8"
      Default
         OCTAVE="9"
   EndSelect
    ti = millisecs()
   Def tr:String:tr="1"
   If tie <= 2000 Then tr="1"
   If tie <= 1000 Then tr="2"
   If tie <= 500 Then tr="4"
   If tie <= 250 Then tr="8"
   If tie <= 125 Then tr="16"
   If tie <= 63 Then tr="32"
   If tie <= 31 Then tr="64"
   If tie = 0 Then tr="1"
   playstring="T"+LTrim$(Str$(TEMPO))+" N"+LTrim$(Str$(CHANNEL))+" O"+OCTAVE+" I"+LTrim$(Str$(INSTRUMENT))+" V"+LTrim$(Str$(NOTEVOLUME))+" "+thisnote
   If record=1:' recording
      If #<Int>temp Then #<note>temp.duration = tr
        temp = ListAdd(mypointer,NEW(note,1))
      #<note>temp.key = note
      #<note>temp.rest = " R"+tr
        #<note>temp.note = "T"+LTrim$(Str$(TEMPO))+" N"+LTrim$(Str$(CHANNEL))+" O"+OCTAVE+" I"+LTrim$(Str$(INSTRUMENT))+" V"+LTrim$(Str$(NOTEVOLUME))+" "+thisnote
   EndIf
   If record=2:'playback
      STOPMIDI$(pThread)
      While pos <> 0
         Def noteduration,rest:String
           temp = ListGetData(pos)                 :' get data from linked list
           note=#<note>temp.key               :' set note to linked list data
         thisnote=#<note>temp.note
         noteduration=#<note>temp.duration
         rest=#<note>temp.rest
         Gosub SetKeyFocus(pboffset)
         thisnote=thisnote+noteduration+rest
         SetCaption Wnd,thisnote
         PLAYMIDI$(thisnote)
         Wait 1
         If Abort = 0 Then pos = ListGetNext(pos) Else pos = 0
      Wend
   Else:' just playing
      STOPMIDI$(pThread)
      SetCaption Wnd,playstring
      pThread=PLAYMIDI$(playstring,1)
   EndIf
'   If note < 12 | note > 108 Then SetControlColor Wnd,5,RGB(255,0,0),GetSysColor(15) else SetControlColor Wnd,5,RGB(0,0,0),GetSysColor(15)
    return
endsub
Sub SetKeyFocus(offset:Int)
   For t = 0 To 28
      If ControlExists(WhiteW[t],note+offset)
             SetFocus WhiteW[t],note+offset  :' set the focus of the key we are about to play
         t=28
      Else
         If ControlExists(BlackW[t],note+offset)
                SetFocus BlackW[t],note+offset  :' set the focus of the key we are about to play
            t=28
         EndIf
      EndIf
   Next t
Return
EndSub
/******************************************************
mouse is sliding over keyboard, play notes as it slides
*******************************************************/
Sub CheckMouse
    If key > 47 & key < 101
        If key<>oldkey & slide = 1
            note=key
         Gosub SetKeyFocus(0)
         note=key+keyoffset
            Gosub NewNote()
            oldkey=key
        EndIf
    EndIf
    return
endsub
/************
add controls
*************/
Sub AddButtonKeys
Control Wnd,@COMBOBOX,"",556,0,140,146,0x50A00603|@CTCOMBOSORT,1
CONTROL Wnd,@CHECKBOX,"Slide",4,0,70,20,0x50000003,2
CONTROL Wnd,@CHECKBOX,"Record",104,0,70,20,0x50000003,3
CONTROL Wnd,@STATIC,"",0,0,0,0,@CTEDITCENTER,5    :' this is required to set focus to when playing keys
CONTROL Wnd,@EDIT,"",1,160,782,56,0x50A01004,6
CONTROL Wnd,@SCROLLBAR,"",710,0,70,10,0x50000000,8
CONTROL Wnd,@SCROLLBAR,"",710,30,70,10,0x50000000,9
CONTROL Wnd,@STATIC,"",700,10,90,12,@CTEDITCENTER,10
CONTROL Wnd,@STATIC,"",700,40,90,12,@CTEDITCENTER,11
CONTROL Wnd,@STATIC,"",700,70,90,12,@CTEDITCENTER,12
CONTROL Wnd,@SCROLLBAR,"",710,60,70,10,0x50000000,13
CONTROL Wnd,@STATIC,"",700,100,90,12,@CTEDITCENTER,14
CONTROL Wnd,@SCROLLBAR,"",710,90,70,10,0x50000000,15
CONTROL Wnd,@BUTTON,"Abort",180,0,70,20,0x50000001,500
SETSCROLLRANGE Wnd,8,0,127
SETSCROLLPOS Wnd,8,127
SETSCROLLRANGE Wnd,9,10,320
SETSCROLLPOS Wnd,9,120
SETSCROLLRANGE Wnd,13,0,4
SETSCROLLPOS Wnd,13,3
SETSCROLLRANGE Wnd,15,0,15
SETSCROLLPOS Wnd,15,0
SetControlText wnd,10,"Volume 100"
SetControlText wnd,11,"Tempo 120"
SetControlText wnd,12,"Octave"
SetControlText wnd,14,"Channel"
return
endsub
/***********************
add menu, fill combobox
************************/
Sub FinishInit
    begininsertmenu Wnd,0
        MenuTitle "&File"
        MenuItem "E&xit",0,99
    endmenu
    SetWindowColor Wnd,GetSysColor(15)
    SetFont Wnd,"ms sans serif",8,400,0,1
   For   t = 10 To 14:SetFont Wnd,"ms sans serif",6,400,0,t:Next t
   SetFont Wnd,"ms sans serif",6,400,0,11
    'add voice names to combobox:
    Def i:Int
    for i=0 to 127
        AddString Wnd,1,voice[i]
    next i
    SETSELECTED Wnd,1,0
return
endsub
Sub WhatPecentageIs(num1:Float,num2:Float),Float
Return Int((num1/num2)*100)
EndSub
Sub AddVoices
'List of 128 voices, in order of their MIDI index
voice = "Grand Piano","Bright Grand","Electric Grand","Honky Tonk"
voice[4] = "Rhodes","Chorus Piano","Harpsichord","Clavinet"
voice[8] = "Celesta","Glockenspiel","Music Box","Vibraphone"
voice[12] = "Marimba","Xylophone","Tubular Bells","Dulcimer"
voice[16] = "Hammond Organ","Percussion Organ","Rock Organ"
voice[19] = "Church Organ","Reed Organ","Accordion","Harmonica"
voice[23] = "Tango Accordion","Accoustic Nylon Guitar"
voice[25] = "Accoustic Steel Guitar","Electric Jazz Guitar"
voice[27] = "Electric Clean Guitar","Electric Mute Guitar"
voice[29] = "Overdrive Guitar","Distorted Guitar","Guitar Harmonic"
voice[32] = "Accoustic Bass","Electric Bass Finger","Electric Bass Pick"
voice[35] = "Fretless Bass","Slap Bass One","Slap Bass Two"
voice[38] = "Synth Bass One","Synth Bass Two","Violin","Viola","Cello"
voice[43] = "Contrabass","Tremolo Strings","Pizzicato Strings"
voice[46] = "Orchestra Harp","Timpani","String Ensemble One"
voice[49] = "String Ensemble Two","Synth Strings One","Synth Strings Two"
voice[52] = "Choir Ahhs","Voice Oohs","Synth Voice","Orchestra Hit"
voice[56] = "Trumpet","Trombone","Tuba","Mute Trumpet","French Horn"
voice[61] = "Brass Section","Synth Brass One","Synth Brass Two"
voice[64] = "Soprano Sax","Alto Sax","Tenor Sax","Bari Sax","Oboe"
voice[69] = "English Horn","Bassoon","Clarinet","Piccolo","Flute"
voice[74] = "Recorder","Pan Flute","Bottle Blow","Shakuhachi","Whistle"
voice[79] = "Ocarina","Square Wave","Sawtooth","Caliope","Chiff Lead"
voice[84] = "Charang","Solo Synth VX","Brite Saw","Brass and Lead"
voice[88] = "Fantasia Pad","Warm Pad","Poly Synth Pad","Space Vox Pad"
voice[92] = "Bowd Glas Pad","Metal Pad","Halo Pad","Sweep Pad"
voice[96] = "Ice Rain","Sound Track","Crystal","Atmosphere","Brightness"
voice[101] = "Goblin","Echo Drops","Star Theme","Sitar","Banjo","Shamisen"
voice[107] = "Koto","Kalimba","Bagpipe","Fiddle","Shanai"
voice[112] = "Tinkle Bell","Agogo","Steel Drums","Wood Block","Taiko Drum"
voice[117] = "Melodic Tom","Synth Drum","Rev Cymbal"
voice[120] = "Guitar Fret Noise","Breath Noise","Sea Shore","Bird Tweet"
voice[124] = "Phone Ring","Helicopter","Applause","Gunshot"
return
endsub
Sub ScrollInfo(win:Window,cid:Int,code:Int,qual:Int,lineup:Int,pageup:Int),Int
   SELECT code
      Case @SBTHUMBPOS
      Case& @SBTHUMBTRACK
         SETSCROLLPOS win,cid,qual
      Case @SBLINEUP
         SETSCROLLPOS win,cid,(GETSCROLLPOS(win,cid)-lineup)
      Case @SBLINEDOWN
         SETSCROLLPOS win,cid,(GETSCROLLPOS(win,cid)+lineup)
      Case @SBPAGEUP
         SETSCROLLPOS win,cid,(GETSCROLLPOS(win,cid)-pageup)
      Case @SBPAGEDOWN
         SETSCROLLPOS win,cid,(GETSCROLLPOS(win,cid)+pageup)
   EndSelect
Return GETSCROLLPOS(win,cid)
EndSub



Regards,

Peter B.

pistol350

Did you manage to get what you were after ?
Or do you still need more help ?
Regards,

Peter B.