How to synchronize the container application with the control |
![]() ![]() ![]() |
By default, Active MIDI DJ Console keeps the container application informed about events occurring on the MIDI system through a number of events; the list of supported events is available on the table below:
Situations |
Corresponding event |
|
|
The configuration of MIDI devices is changed |
|
A MIDI device, previously opened through the MidiDevices.Open method, is disconnected from the system after a manual removal |
|
A MIDI event is received from a MIDI input device |
|
A physical button mapped into the DJ Console profile has been pressed |
|
A physical button mapped into the DJ Console profile has been released. |
|
A physical range control (sliders, jog wheels, rotary knobs, etc.) mapped into the DJ Console profile has been moved |
|
A manual action (for example the pressing of a button, the movement of a slider or of a jog wheel) is performed on a console's physical control which has not been mapped into the DJ Console profile loaded inside the instance of the component or when the reception of events specific for mapped controls has been disabled through a call to the MidiDjConsole.EnableMappedEvents method. |
|
One of the keys on the virtual piano keyboard, previously created through the MidiVirtualKeyboard.Create method, is pressed or released |
Events are for their own nature asynchronous, meaning that they are sent into a queue and managed by the container application with a first-in / first-out policy. Some of the listed events, for example events coming from the input device, may need to be processed in real-time immediately after happening: for this purpose there is the possibility to replace some of the events described above with callback functions provided by the container application; this task can be achieved for the following events:
Event |
Corresponding method for setting the callback function |
|
|
MidiDevices.InputEventCallbackSet method setting the callback function for short MIDI events and for raw MIDI events |
|
MidiDjConsole.CallbackEventSet method having the nEventType parameter set to DJC_EVENT_TYPE_BUTTON_PRESSED and setting the callback function for DJ console events |
|
MidiDjConsole.CallbackEventSet method having the nEventType parameter set to DJC_EVENT_TYPE_BUTTON_RELEASED and setting the callback function for DJ console events |
|
MidiDjConsole.CallbackEventSet method having the nEventType parameter set to DJC_EVENT_TYPE_RANGE_MOVED and setting the callback function for DJ console events |
|
MidiDjConsole.CallbackEventSet method having the nEventType parameter set to DJC_EVENT_TYPE_UNMAPPED and setting the callback function for DJ console events |
Callback functions are predisposed inside the code of the container application and need to have a specific syntax and number of parameters.
Callback function for short MIDI events
[Visual Basic] Public Sub MidiInputShortEventsCallback ( ByVal nDeviceUniqueId As Integer, ByVal nMidiCommand As Integer, ByVal nMidiChannel As Integer, ByVal nMidiData1 As Integer, ByVal nMidiData2 As Integer, ByVal nTimeStamp As Long, ByVal nUserData As Long ) |
[Visual C++] void CALLBACK MidiInputShortEventsCallback ( short nDeviceUniqueId, short nMidiCommand, short nMidiChannel, short nMidiData1, short nMidiData2, long nTimeStamp, long nUserData ); |
Inside your code you could implement the callback by invoking the MidiDevices.InputEventCallbackSet method with the value returned by the AddressOf statement:
[Visual Basic]
Public Sub MidiInputEventsShortCallback(ByVal nDeviceUniqueId As Integer, ByVal nMidiCommand As Integer, _ ByVal nMidiChannel As Integer, ByVal nMidiData1 As Integer, _ ByVal nMidiData2 As Integer, ByVal nTimeStamp As Long, _ ByVal nUserData As Long) Debug.Print "Received short event: " & "nCommand: 0x" & Hex(nMidiCommand) & _ " - nData1: 0x" & Hex(nMidiData1) & _ " - nData2: 0x" & Hex(nMidiData2) End Sub
Private Sub CommandOpenInput_Click()
' open input device Dim nResult As enumDjcErrorCodes nResult = ActiveDjConsole1.MidiDevices.Open(BOOL_TRUE, ComboMidiInputs.ListIndex, m_nIdInputDevice) If nResult <> ERR_DJC_NOERROR Then MsgBox "MIDI device opening failed due to error " & nResult Exit Sub End If
' predispose the callback ActiveDjConsole1.MidiDevices.InputEventsCallbackSet m_nIdInputDevice, BOOL_FALSE, AddressOf MidiInputEventsShortCallback, 0
End Sub
|
[Visual C++ MFC] void CALLBACK MidiInputShortEventsCallback (short nDeviceUniqueId, short nMidiCommand, short nMidiChannel, short nMidiData1, short nMidiData2, long nTimeStamp, long nUserData) { CMidiMonitorDlg *pThis = (CMidiMonitorDlg *) CWnd::FromHandle (HWND (nUserData)); if (pThis == NULL) return;
// invoke the dialog box function that will manage incoming data pThis->ShowEventShort (nDeviceUniqueId, nMidiCommand, nMidiChannel, nMidiData1, nMidiData2, nTimeStamp); }
void CMidiMonitorDlg::OnBnClickedButtonConnect() { // open selected input device long nResult = m_djConsole.GetMidiDevices ().Open (TRUE, m_comboInputDevices.GetCurSel (), &m_nIdInputDevice); if (nResult != ERR_DJC_NOERROR) { CString strMsg; strMsg.Format (_T("MIDI input device opening failed due to error %d"), nResult); AfxMessageBox (strMsg); return; }
// predispose callbacks passing the HWND of the dialog as "user data" m_djConsole.GetMidiDevices ().InputEventsCallbackSet (m_nIdInputDevice, FALSE, long (MidiInputShortEventsCallback), long (GetSafeHwnd ())); }
|
Callback function for raw MIDI events
[Visual Basic] Public Sub MidiInputRawEventsCallback ( ByVal nDeviceUniqueId As Integer, ByVal pBuffer As Long, ByVal nBufferLenght As Long, ByVal nTimeStamp As Long, ByVal nUserData As Long ) |
[Visual C++] void CALLBACK MidiInputRawEventsCallback ( short nDeviceUniqueId, void *pBuffer, long nBufferLenght, long nTimeStamp, long nUserData ); |
Inside your code you could implement the callback by invoking the MidiDevices.InputEventCallbackSet method with the value returned by the AddressOf statement:
[Visual Basic]
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, _ ByRef Source As Any, ByVal bufferLength As Long)
Public Sub MidiInputRawEventsCallback(ByVal nDeviceUniqueId As Integer, ByVal pBuffer As Long, _ ByVal nBufferLenght As Long, ByVal nTimeStamp As Long, _ ByVal nUserData As Long) ' copy raw buffer locally Dim buffTemp() As Byte ReDim buffTemp(nBufferLenght) As Byte Call CopyMemory(buffTemp(0), ByVal pBuffer, nBufferLenght)
Dim strEvent As String Dim i As Long For i = 0 To nBufferLenght - 1 strEvent = strEvent & " 0x" & Hex(buffTemp(i)) Next i Debug.Print "Received raw event: " & strEvent End Sub
Private Sub CommandOpenInput_Click()
' open input device Dim nResult As enumDjcErrorCodes nResult = ActiveDjConsole1.MidiDevices.Open(BOOL_TRUE, ComboMidiInputs.ListIndex, m_nIdInputDevice) If nResult <> ERR_DJC_NOERROR Then MsgBox "MIDI device opening failed due to error " & nResult Exit Sub End If
' predispose the callback ActiveDjConsole1.MidiDevices.InputEventsCallbackSet m_nIdInputDevice, BOOL_FALSE, AddressOf MidiInputRawEventsCallback, 0
End Sub
|
[Visual C++ MFC] void CALLBACK MidiInputRawEventsCallback (short nDeviceUniqueId, void *pBuffer, long nBufferLenght, long nTimeStamp, long nUserData) { CMidiMonitorDlg *pThis = (CMidiMonitorDlg *) CWnd::FromHandle (HWND (nUserData)); if (pThis == NULL) return;
// invoke the dialog box function that will manage incoming data pThis->ShowEventRaw (nDeviceUniqueId, (char *) pBuffer, nBufferLenght, nTimeStamp); }
void CMidiMonitorDlg::OnBnClickedButtonConnect() { // open selected input device long nResult = m_djConsole.GetMidiDevices ().Open (TRUE, m_comboInputDevices.GetCurSel (), &m_nIdInputDevice); if (nResult != ERR_DJC_NOERROR) { CString strMsg; strMsg.Format (_T("MIDI input device opening failed due to error %d"), nResult); AfxMessageBox (strMsg); return; }
// predispose callbacks passing the HWND of the dialog as "user data" m_djConsole.GetMidiDevices ().InputEventsCallbackSet (m_nIdInputDevice, TRUE, long (MidiInputRawEventsCallback), long (GetSafeHwnd ())); }
|
Callback function for DJ console events
[Visual Basic] Public Sub UnmappedEventCallback ( ByVal nMidiCommand As Integer, ByVal nMidiChannel As Integer, ByVal nMidiData1 As Integer, ByVal nMidiData2 As Integer, ByVal nTimeStamp As Long, ByVal nUserData As Long )
Public Sub ButtonEventCallback ( ByVal strControlName As String, ByVal nControlNameLength As Long, ByVal nTimeStamp As Long, ByVal nUserData As Long )
Public Sub RangeCtrlMovedEventCallback ( ByVal strControlName As String, ByVal nControlNameLength As Long, ByVal nValue As Integer, ByVal nTimeStamp As Long, ByVal nUserData As Long ) |
[Visual C++] void CALLBACK UnmappedEventCallback ( short nMidiCommand, short nMidiChannel, short nMidiData1, short nMidiData2, long nTimeStamp, long nUserData );
void CALLBACK ButtonEventCallback ( wchar_t *strControlName, long nControlNameLength, long nTimeStamp, long nUserData );
void CALLBACK RangeCtrlMovedEventCallback ( wchar_t *strControlName, long nControlNameLength, short nValue, long nTimeStamp, long nUserData ); |
Inside your code you could implement the callback by invoking the MidiDjConsole.CallbackEventSet method with the value returned by the AddressOf statement:
[Visual Basic]
Public Sub UnmappedEventCallback(ByVal nMidiCommand As Integer, _ ByVal nMidiChannel As Integer, ByVal nMidiData1 As Integer, _ ByVal nMidiData2 As Integer, ByVal nTimeStamp As Long, _ ByVal nUserData As Long) Debug.Print "Unmapped event: " & "nCommand: " & nMidiCommand & _ " - nData1: " & nMidiData1 & _ " - nData2: " & nMidiData2 End Sub
Public Sub ButtonPressedEventCallback(ByVal strControlName As String, ByVal nControlNameLength As Long, _ ByVal nTimeStamp As Long, ByVal nUserData As Long) Debug.Print "Button pressed event from " & strControlName & " - len: " & nControlNameLength End Sub
Public Sub ButtonReleasedEventCallback(ByVal strControlName As String, ByVal nControlNameLength As Long, _ ByVal nTimeStamp As Long, ByVal nUserData As Long) Debug.Print "Button released event from " & strControlName End Sub
Public Sub RangeControlMovedEventCallback(ByVal strControlName As String, ByVal nControlNameLength As Long, _ ByVal nValue As Integer, _ ByVal nTimeStamp As Long, ByVal nUserData As Long) Debug.Print "Range control moved event from " & strControlName & " - value: " & nValue End Sub
Private Sub CommandOpenInput_Click()
' open input device Dim nResult As enumDjcErrorCodes nResult = ActiveDjConsole1.MidiDevices.Open(BOOL_TRUE, ComboMidiInputs.ListIndex, m_nIdInputDevice) If nResult <> ERR_DJC_NOERROR Then MsgBox "MIDI device opening failed due to error " & nResult Exit Sub End If
' predispose the callbacks ActiveDjConsole1.MidiDjConsole.CallbackEventSet DJC_EVENT_TYPE_UNMAPPED, AddressOf UnmappedEventCallback, 0 ActiveDjConsole1.MidiDjConsole.CallbackEventSet DJC_EVENT_TYPE_BUTTON_PRESSED, AddressOf ButtonPressedEventCallback, 0 ActiveDjConsole1.MidiDjConsole.CallbackEventSet DJC_EVENT_TYPE_BUTTON_RELEASED, AddressOf ButtonReleasedEventCallback, 0 ActiveDjConsole1.MidiDjConsole.CallbackEventSet DJC_EVENT_TYPE_RANGE_MOVED, AddressOf RangeControlMovedEventCallback, 0 End Sub
|
[Visual C++ MFC]
void CALLBACK UnmappedEventCallback (short nMidiCommand, short nMidiChannel, short nMidiData1, short nMidiData2, long nTimeStamp, long nUserData) { CMidiMonitorDlg *pThis = (CMidiMonitorDlg *) CWnd::FromHandle (HWND (nUserData)); if (pThis == NULL) return;
// invoke the dialog box function that will manage unmapped events pThis->ManageUnmappedEvent (nMidiCommand, nMidiChannel, nMidiData1, nMidiData2, nTimeStamp); }
void CALLBACK ButtonPressedEventCallback (wchar_t *wstrControlName, long nControlNameLength, long nTimeStamp, long nUserData) { CString strControlName = wstrControlName; TRACE1 ("\r\nButton pressed: %s", strControlName); }
void CALLBACK ButtonReleasedEventCallback (wchar_t *wstrControlName, long nControlNameLength, long nTimeStamp, long nUserData) { CString strControlName = wstrControlName; TRACE1 ("\r\nButton released: %s", strControlName); }
void CALLBACK RangeCtrlMovedEventCallback (wchar_t *wstrControlName, long nControlNameLength, short nValue, long nTimeStamp, long nUserData) { CString strControlName = wstrControlName; TRACE2 ("\r\nControl moved: %s - value: %d", strControlName, nValue); }
void CMidiMonitorDlg::OnBnClickedButtonConnect() { // open selected input device long nResult = m_djConsole.GetMidiDevices ().Open (TRUE, m_comboInputDevices.GetCurSel (), &m_nIdInputDevice); if (nResult != ERR_DJC_NOERROR) { CString strMsg; strMsg.Format (_T("MIDI input device opening failed due to error %d"), nResult); AfxMessageBox (strMsg); return; }
// predispose callbacks passing the HWND of the dialog as "user data" m_djConsole.GetMidiDjConsole().CallbackEventSet (DJC_EVENT_TYPE_UNMAPPED, long (UnmappedEventCallback), long (GetSafeHwnd ()); m_djConsole.GetMidiDjConsole().CallbackEventSet (DJC_EVENT_TYPE_BUTTON_PRESSED, long (ButtonPressedEventCallback), long (GetSafeHwnd ()); m_djConsole.GetMidiDjConsole().CallbackEventSet (DJC_EVENT_TYPE_BUTTON_RELEASED, long (ButtonReleasedEventCallback), long (GetSafeHwnd ()); m_djConsole.GetMidiDjConsole().CallbackEventSet (DJC_EVENT_TYPE_RANGE_MOVED, long (RangeCtrlMovedEventCallback), long (GetSafeHwnd ()); }
|