Hallo,
I need help on MIDI file,
and precisely about retrieving
few note values
(mainly the "Velocity" value,
corrisponding to the intensity
of a played note)
while the MIDI is playing.
(If you don't kow,
the "Velocity" value is a value
stored in the MIDI file).
- - - - -
I'm using DirectX (Dx7vb.dll)
to manage (Start, Stop ...)
the MIDI file,
but if my problem can be solved
also without using DirectX
or by using an external (free)
..dll or .ocx,
it is good the same.
- - - - -
Scenario (very simple scenario):
I'm playing a MIDI file using
the DirectX commands
(by the Dx7vb.dll file;
if you have DirectX8 or DirectX9
things should not be very different).
No problem in this.
Now I want to retrieve some "live" information
while the Midi file is playing,
so I decide it cold be a good solution
to implement a 'callback' function.
I found a snippet of code
that allows me to retrieve the information
about the Start, the Stop...
of the Midi file.
No problem in this.
See below, if you like,
the snippet of code that performs the
'callback' task
(note: if you don't already have
on your project
the lines of code that allow you
to play a Midi file,
this solely snippet of code won't work;
if you want that playing code
I'll provide you with it).
- - - - -
BUT..
I don't want to retrieve
the Start, the Stop...
of the Midi file.
I want to retrieve some information
about the current played notes
(most of all their Velocity value).
I presume that I need to use the
DMUS_NOTE_PMSG type
or
DMUS_CURVE_PMSG type
and their
..Velocity sub-parameter
also
I should indicate the channel
I'm retrieving the played notes from
(note:
in a 'standard' Midi file there are 16 channels;
if it is not a 'standard' Midi
you have 1 big channel only,
but my program splits it
in 16 separated channels
so to ultimately have
a 16 channels Midi file)
also
when I build the 'callback' strucutre
I think I have to change the parameter
DMUS_NOTIFY_ON_SEGMENT
of
myPerf.AddNotificationType DMUS_NOTIFY_ON_SEGMENT
(see below the snippet of code,
under the sections 3 and 5 )
and use another parameter,
(maybe the
DMUS_NOTIFY_ON_MEASUREANDBEAT parameter ?)
- - - - -
If you need more explanations
I'll povide you with links where to download
the Dx7vb.dll,
the playing code,
a 'standard' Midi file
more details...
- - - - -
I previously post this request in several NGs,
but I got no answers
(= nobody answered me).
I don't know because it is a difficult task
or because those NGs are poorly populated.
==== ==== ==== ==== =====
==== ==== ==== ==== =====
Callback snippet of code.
''' 1 On the References section
' of your VB project
' you have to absolutely
' reference the Dx7vb.dll file
' (you find it under the 'Project' menu),
''' 2 On the Declarations section
'among the other declarations, you have to add these:
Implements DirectXEvent 'creates the "DirectXEvent_DXCallback"
function.
Private myEvent As Long 'An Event handle
Dim myPerf As DirectMusicPerformance
''' 3 On the Load or Initialize or whatever you like event,
but before you start playing the Midi file
'among the other initialization stuff, you have to add these:
Set myPerf = Dx.DirectMusicPerformanceCreate
Call myPerf.Init(Nothing, hwnd)
myPerf.SetPort -1, 1
myPerf.AddNotificationType DMUS_NOTIFY_ON_SEGMENT 'relay messages
about the segment
myEvent = Dx.CreateEvent(Me)
myPerf.SetNotificationHandle myEvent 'used to identify the messages
''' 4 On the DirectXEvent_DXCallback
'Private Sub DirectXEvent_DXCallback(ByVal eventid As Long)
If eventid = myEvent Then 'the message is our message
Dim myMSG As DMUS_NOTIFICATION_PMSG
Select Case myMSG.lNotificationOption
Case DMUS_NOTIFICATION_SEGABORT
Debug.Print "MESSAGE: DMUS_NOTIFICATION_SEGABORT"
Case DMUS_NOTIFICATION_SEGEND
Debug.Print "MESSAGE: DMUS_NOTIFICATION_SEGEND"
Case DMUS_NOTIFICATION_SEGSTART
Debug.Print "MESSAGE: DMUS_NOTIFICATION_SEGSTART"
Case Else
Debug.Print "MESSAGE: Unknown"
End Select
End If
'End Sub
''' 5 On the Unload event
'now we discard all
myPerf.RemoveNotificationType DMUS_NOTIFY_ON_SEGMENT
Dx.DestroyEvent myEvent
If ObjPtr(dmSeg) Then Set dmSeg = Nothing
If ObjPtr(dmLoader) Then Set dmLoader = Nothing
If ObjPtr(Dx) Then Set Dx = Nothing
==== ==== ==== ==== =====
==== ==== ==== ==== =====