MIDI test

Miscellaneous Forums/Win32 Discussion/MIDI test

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Here is some code to play some MIDI music via the Windows API.

It can use the Windows or your Sound card Midi softsynth device, so no external synth is needed to hear noises.


' MIDI Output test
'
' Ziltch 26/12/2004


Const MAXPNAMELEN =32
Const MidiNoteOn         = $9  ' play note
Const MidiNoteOff        = $8  ' Stop note
Const MidiProgramChange  = $C  ' Change Program
Const MidiControlChange  = $B  ' Change Program

Type MIDIOUTCAPS 
	Field wMid:Short
	Field wPid:Short
	Field vDriverVersion:Short ' MMVERSION 
	Field szPname:String[MAXPNAMELEN]
	Field wTechnology:Short
	Field wVoices:Short
	Field wNotes:Short
	Field wChannelMask:Short
	Field dwSupport:Int
EndType

Type MIDIINCAPS 
	Field wMid:Short
	Field wPid:Short
	Field vDriverVersion:Short'MMVERSION 
	Field szPname:String[MAXPNAMELEN]'CHAR 
	Field dwSupport:Int
EndType

Type MidiHdr 
	Field lpData:Int'LPSTR ptr
	Field dwBufferLength:Int
	Field dwBytesRecorded:Int
	Field dwUser:Int
	Field dwFlags:Int
	Field lpNext:Int 'midihdr_tag ptr
	Field reserved:Int
	Field dwOffset:Int
	Field dwReserved:Int[8]
EndType

Type MidiEvent
	Field dwDeltaTime:Int
	Field dwStreamID:Int
	Field dwEvent:Int
	Field dwParms:Int[1]
EndType


Type MidiStrmBuffVer 
	Field dwVersion:Int
	Field dwMid:Int
	Field dwOEMVersion:Int
EndType 


Type MidiPropTimeDiv 
	Field cbStruct:Int
	Field dwTimeDiv:Int
EndType


Type MidiPropTempo 
	Field cbStruct
	Field dwTempo
EndType


Extern "Os"
' Most functions Untested

Function midiOutGetNumDevs:Int()
Function midiOutClose(hMidiOut:Int)
Function midiOutOpen(lphMidiOut:Int ,uDeviceID:Int,dwCallback:Int,dwInstance:Int,dwFlags:Int)
Function midiOutShortMsg(hMidiOut:Int,dwMsg:Int)
Function midiOutGetDevCapsA( uDeviceID:Int, lpCaps:MIDIOUTCAPS, uSize:Int)

Function midiInGetDevCapsA( uDeviceID:Int, lpCaps:MIDIINCAPS, uSize:Int)

Function midiInStop(hMidiIn:Int)
Function midiInStart(hMidiIn:Int)
Function midiInReset(hMidiIn:Int)
Function midiInPrepareHeader(hMidiIn:Int, lpMidiInHdr:midihdr , uSize:Int)

Function midiInOpen(lphMidiIn:Int, uDeviceID:Int, dwCallback:Int, dwInstance:Int, dwFlags:Int)
Function midiInClose(hMidiIn:Int)
Function midiInMessage(hMidiIn:Int, msg:Int, dw1:Int, dw2:Int)
Function midiInGetNumDevs()
Function midiInGetID(hMidiIn:Int, lpuDeviceID:Int)
Function midiInGetErrorText( err:Int, lpText:String, uSize:Int)

Function midiInAddBuffer(hMidiIn:Int, lpMidiInHdr:midihdr , uSize:Int)

Function midiDisconnect(hmi:Int, hmo:Int, pReserved:Int)
Function midiConnect(hmi:Int, hmo:Int, pReserved:Int)

End Extern


Function SendMidiOut(MidiOutHandle,MidiOutChannel,MidiOutStatus,MidiOutdata1=0,MidiOutData2=0)
   ' MidiChannel = 1-16
   ' Status      = $9 for notes            , $B for ControlChange  , ProgramChange  =$C
   ' Mididata1   = NoteValue (0=C2 127=G8) ,  CC knob / slider     , Instrument (1=piano etc)
   ' Mididata2   = velocity                ,  value of knob/slider

'   print hex$(MidiOutChannel or (MidiOutdata2 shl 16) or (MidiOutdata1 shl 8 ) or (MidiOutStatus shl 4))

   ret = midiOutShortMsg(MidiOutHandle,( (MidiOutdata2 Shl 16) | (MidiOutdata1 Shl 8 ) | (MidiOutStatus Shl 4) | MidiOutChannel))
   Return ret
End Function


OutDevID=0 ' <  Change this if No sound. (Devices start at -1 )
Local Instruments:String[129]


'Subtract 1 from this list For Instrument
Instruments[1] = "Acoustic Grand Piano"

Instruments[2] = "Bright Piano" 	
Instruments[3] = "Electric Grand Piano" 	
Instruments[4] = "Honky-Tonk Piano"
Instruments[5] = "Electric piano 1" 	
Instruments[6] = "Electric Piano 2" 	
Instruments[7] = "Harpsichord" 	
Instruments[8] = "Clavinet" 	
Instruments[9] = "Celesta" 	
Instruments[10] = "Glockenspiel" 	
Instruments[11] = "Music Box" 	
Instruments[12] = "Vibraphone" 	
Instruments[13] = "Marimba" 	
Instruments[14] = "Xylophone" 	
Instruments[15] = "Tubular bells" 	
Instruments[16] = "Dulcimer" 	
Instruments[17] = "Drawbar Organ" 	

Instruments[18] = "Percussive Organ"	
Instruments[19] = "Rock Organ" 	
Instruments[20] = "Church Organ" 	
Instruments[21] = "Reed Organ" 	
Instruments[22] = "Accordion" 	
Instruments[23] = "Harmonica" 	
Instruments[24] = "Tango Accordion" 	
Instruments[25] = "Nylon String Guitar" 	
Instruments[26] = "Steel String Guitar" 	
Instruments[27] = "Jazz Guitar" 	
Instruments[28] = "Clean Electric Guitar" 	
Instruments[29] = "Muted Electric Guitar" 	
Instruments[30] = "Overdrive Guitar" 	
Instruments[31] = "Distortion Guitar" 	
Instruments[32] = "Guitar Harmonics" 	
Instruments[33] = "Accoustic Bass"  	
Instruments[34] = "Fingered Bass" 	
Instruments[35] = "Picked Bass" 	
Instruments[36] = "Fretless Bass" 	
Instruments[37] = "Slap Bass 1" 	
Instruments[38] = "Slap Bass 2"	
Instruments[39] = "Synth Bass 1"	
Instruments[40] = "Synth Bass 2"	
Instruments[41] = "Violin" 	
Instruments[42] = "Viola" 	
Instruments[43] = "Cello" 	
Instruments[44] = "Contrabass" 	
Instruments[45] = "Tremolo Strings" 	
Instruments[46] = "Pizzicato Strings" 
Instruments[47] = "Orchestral Harp" 	
Instruments[48] = "Timpani" 	
Instruments[49] = "String Ensemble 1" 	
Instruments[50] = "String Ensemble 2" 
Instruments[51] = "Synth Strings 1" 	
Instruments[52] = "Synth Strings 2" 	
Instruments[53] = "Choir ahh" 	
Instruments[54] = "Choir oohh" 	
Instruments[55] = "Synth Voice" 	
Instruments[56] = "Orchestral Hit" 	
Instruments[57] = "Trumpet" 	
Instruments[58] = "Trombone" 
Instruments[59] = "Tuba"	
Instruments[60] = "Muted Trumpet" 	
Instruments[61] = "French Horn" 	
Instruments[62] = "Brass Section" 	
Instruments[63] = "Synth Brass 1" 	
Instruments[64] = "Synth Brass 2" 	
Instruments[65] = "Soprano Sax"  	 
Instruments[66] = "Alto Sax" 	
Instruments[67] = "Tenor Sax" 	
Instruments[68] = "Baritone Sax" 	
Instruments[69] = "Oboe" 	
Instruments[70] = "English Horn" 	
Instruments[71] = "Bassoon" 	
Instruments[72] = "Clarinet" 	
Instruments[73] = "Piccolo" 	
Instruments[74] = "Flute" 	
Instruments[75] = "Recorder" 	
Instruments[76] = "Pan flute" 	
Instruments[77] = "Blown Bottle" 	
Instruments[78] = "Shakuhachi" 	
Instruments[79] = "Whistle" 	
Instruments[80] = "Ocarina" 	
Instruments[81] = "Square Wave" 	
Instruments[82] = "Sawtooth Wave" 	
Instruments[83] = "Caliope"	
Instruments[84] = "Chiff" 	
Instruments[85] = "Charang" 	
Instruments[86] = "Voice" 	
Instruments[87] = "Fifths" 	
Instruments[88] = "Bass & Lead" 	
Instruments[89] = "New Age" 	
Instruments[90] = "Warm" 	
Instruments[91] = "PolySynth" 	
Instruments[92] = "Choir" 	
Instruments[93] = "Bowed" 	
Instruments[94] = "Metallic" 
Instruments[95] = "Halo" 	
Instruments[96] = "Sweep" 	
Instruments[97] = "FX: Rain"
Instruments[98] = "FX: Soundtrack"
Instruments[99] = "FX: Crystal"
Instruments[100] = "FX: Atmosphere"
Instruments[101] = "FX: Brightness"
Instruments[102] = "FX: Goblins"
Instruments[103] = "FX: Echo Drops"
Instruments[104] = "FX: Star Theme"
Instruments[105] = "Sitar"
Instruments[106] = "Banjo"
Instruments[107] = "Shamisen"
Instruments[108] = "Koto"
Instruments[109] = "Kalimba"
Instruments[110] = "Bagpipe"
Instruments[111] = "Fiddle"
Instruments[112] = "Shanai"
Instruments[113] = "Tinkle bell"
Instruments[114] = "Agogo"
Instruments[115] = "Steel Drums"
Instruments[116] = "Woodblock"
Instruments[117] = "Taiko Drum"
Instruments[118] = "Melodic Tom"
Instruments[119] = "Synth Drum"
Instruments[120] = "Reverse Cymbal"
Instruments[121] = "Guitar Fret Noise"
Instruments[122] = "Breath Noise"
Instruments[123] = "Seashore"
Instruments[124] = "Bird Tweet"
Instruments[125] = "Telephone Ring"
Instruments[126] = "Helicopter"
Instruments[127] = "Applause"
Instruments[128] = "Gunshot"



instrument = 103'
DelayTime# = 500
Velocity =  50
MidiChannel = 1
MoreDelay# = 1
Local MidiOut:Int
Local MidiOutHandle:Int Ptr 

MidiOutHandle = Varptr MidiOut

Print " Midi Test - Computer Made Music"

Print "-----------------------------------"

ok=midiOutOpen(Int(MidiOutHandle),OutDevID,0,0, 0)

'Print "ok = "+ok + " MidiOutHandle = "+MidiOutHandleI+ "  MidiOut  "+midiout

SendMidiOut(MidiOut,MidiChannel,MidiProgramChange,instrument)

While Not KeyHit(KEY_ESCAPE)

  If Rand(10) = 1 Then
  
  End If
  Count = Count + 1
  NoteCount  = NoteCount + 1
  If NoteCount/16.0 = Int(NoteCount/16) Then
    instrument = 89
    MoreDelay# = 2
    Octave = -4
    MidiChannel = 4
    Velocity = Rand(80)+50

  ElseIf NoteCount/8.0 = Int(NoteCount/8) Then
    instrument = 50
    MoreDelay# = 2
    Octave = -6
    MidiChannel = 3
    Velocity = Rand(80)+50

  else If NoteCount/4.0 = Int(NoteCount/4) Then
    Velocity = Rand(40)+50
    MidiChannel = 2
    instrument = 51
    Octave = 1
    MoreDelay# = 1

  Else
    MidiChannel = 1
    instrument =103
    MoreDelay# = .1
    Octave = 2
    Velocity = Rand(20)+50
    
  End If 

  If Lastinstrument <> instrument Then SendMidiOut(MidiOut,MidiChannel,MidiProgramChange,instrument)
  Lastinstrument = instrument

  Note = ((Sin(Count/32.0)*4.5)*4+55+(Rand(Sin(Count/2.0)*4.5)*2*Octave)) Mod 128'Note range = 0 - 127


  SendMidiOut(MidiOut,MidiChannel,MidiNoteOn,Note,velocity)
  Print Instruments[instrument-1] +" Note = "+note+" Velocity = "+Velocity

  Delay DelayTime*MoreDelay
  SendMidiOut(MidiOut,MidiChannel,MidiNoteOff,Note)

  If NoteCount > 500 Then Exit

wend


midiOutClose(MidiOut)


Next MIDI input....