home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Tool Box
/
SIMS_2.iso
/
tool
/
sound
/
vb_mid
/
midihook.frm
< prev
next >
Wrap
Text File
|
1995-02-05
|
16KB
|
332 lines
VERSION 2.00
Begin Form frmMidiHook
BackColor = &H00C0C0C0&
BorderStyle = 3 'Fixed Double
Caption = "Midi Hook"
ClientHeight = 615
ClientLeft = 645
ClientTop = 7725
ClientWidth = 2010
ControlBox = 0 'False
Height = 1020
Left = 585
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 615
ScaleWidth = 2010
Top = 7380
Width = 2130
Begin MsgHook MidiHook
Left = 690
Top = 120
End
End
Option Explicit
Dim iLoNibble As Integer
Dim iHiNibble As Integer
Dim iMtcHours As Integer
Dim iMtcMinutes As Integer
Dim iMtcSeconds As Integer
Dim iMtcFrames As Integer
Sub MidiHook_Message (iMsg As Integer, iRet1 As Integer, lMidiMessage As Long, iRet2 As Integer, lRet3 As Long)
Dim iMidiStatus As Integer
Dim iMidiData1 As Integer
Dim iMidiData2 As Integer
Dim iMtcData As Integer
Dim lTotalFrames As Long
'The code inside this Procedure must be selfcontained
'without calling any other Procedure or DoEvents or Refresh...
'
'The whole Procedure execution should not take longer than 8ms.
'
'This version seems very long but the program
'actually only executes a few lines of it
'based on the Ifs.. and Select Cases... decissions
If iMsg <> MIM_DATA Then Exit Sub 'just for safety
'Unpack lMidiMessage
iMidiStatus = lMidiMessage And &HFF& 'First byte
iMidiData1 = (lMidiMessage And &HFF00&) / 256 'Second byte
iMidiData2 = (lMidiMessage And &HFF0000) / 65536'Third byte
'Filter RealTime Midi Messages except MTC
If iMidiStatus >= &HF0 And iMidiStatus <> MTC_QFRAME Then Exit Sub
'Filter here any other Status if necessary.
'(i.e. PITCH_BEND, CHANNEL_PRESSURE, POLY_KEY_PRESS, etc.)
If iMidiStatus = MTC_QFRAME Then 'Hooked message is a MTC quarter frame message
'You may show here a screen representation of MTC In.
'********************************************
'SPECIFIC TO THIS APPLICATION
If bVisualMtc = True Then
If frmVBSeq.picMtcIn.BackColor = LED_OFF Then 'If MTC In led is off
frmVBSeq.picMtcIn.BackColor = LED_ON 'Switch MTC In led on
End If
lMtcInTime = timeGetTime() 'Save current system time for switch off calculations
End If
'********************************************
If bMTCThru = True Then 'Global Flag
If hMidiOut <> NO_HANDLE Then 'If iOutDevice Opened...
vntRet = midiOutShortMsg(hMidiOut, lMidiMessage) 'send it out
'You may show here a screen representation of MTC Out.
'**********************************************
'SPECIFIC TO THIS APPLICATION
If bVisualMtc = True Then
If frmVBSeq.picMtcOut.BackColor = LED_OFF Then 'If MTC Out led is off
frmVBSeq.picMtcOut.BackColor = LED_ON 'Switch MTC Out led on
End If
lMtcOutTime = timeGetTime() 'Save current system time for switch off calculations
End If
'**********************************************
End If
End If
'We're only interested in decoding MTC while we are in external sync
If nSyncMode = SYNC_EXTERNAL Then
'MTC Data=Second Byte of lMidiMessage
iMtcData = iMidiData1
'Quarter Frame Message Identifier=hiNibble of iMtcData
Select Case (iMtcData And &HF0)
Case &H0: 'Quarter Frame Message indicating Frames loNibble
If nQfIdExpected <> &H0 Then 'Discontinous MTC
bInSync = False 'Out of sync
nQfIdExpected = &H0 'start over
Else
'Frames loNibble=loNibble of iMtcData
iLoNibble = (iMtcData And &HF)
'If we're in sync, increase Time Counter (milliseconds per quarter frame)
If bInSync = True Then lMtcTime = lMtcTime + fMsPerQF
nQfIdExpected = &H10 'Expected next Quarter Frame Message
End If
Case &H10: 'Quarter Frame Message indicating Frames hiNibble
If nQfIdExpected <> &H10 Then 'Discontinous MTC
bInSync = False 'Out of sync
nQfIdExpected = &H0 'start over
Else
'Frames hiNibble=Bit 0 of iMtcData
iHiNibble = (iMtcData And &H1)
iMtcFrames = (iHiNibble * 16) + iLoNibble 'Pack Frame Number
'If we're in sync, increase Time Counter
If bInSync = True Then lMtcTime = lMtcTime + fMsPerQF
nQfIdExpected = &H20 'Expected next Quarter Frame Message
End If
Case &H20: 'Quarter Frame Message indicating seconds loNibble
If nQfIdExpected <> &H20 Then 'Discontinous MTC -> resync
bInSync = False 'Out of sync
nQfIdExpected = &H0 'start over
Else
'Seconds LoNibble=LoNibble of iMtcData
iLoNibble = (iMtcData And &HF)
'If we're in sync, increase Time Counter
If bInSync = True Then lMtcTime = lMtcTime + fMsPerQF
nQfIdExpected = &H30 'Expected next Quarter Frame Message
End If
Case &H30: 'Quarter Frame Message indicating seconds hiNibble
If nQfIdExpected <> &H30 Then 'Discontinous MTC -> resync
bInSync = False 'Out of sync
nQfIdExpected = &H0 'start over
Else
'Seconds HiNibble=bits 0 & 1 of iMtcData
iHiNibble = (iMtcData And &H3)
iMtcSeconds = (iHiNibble * 16) + iLoNibble 'pack Seconds Number
'If we're in sync...
If bInSync = True Then
'increase Time Counter
lMtcTime = lMtcTime + fMsPerQF
'4th quarter frame->Increase Frame Counter
nMtcTotalFrames = nMtcTotalFrames + 1
End If
nQfIdExpected = &H40 'Expected next Quarter Frame Message
End If
Case &H40: 'Quarter Frame Message indicating Minutes iLoNibble
If nQfIdExpected <> &H40 Then 'Discontinous MTC -> resync
bInSync = False 'Out of sync
nQfIdExpected = &H0 'start over
Else
'Minutes LoNibble=LoNibble of iMtcData
iLoNibble = (iMtcData And &HF)
'If we're in sync, increase Time Counter
If bInSync = True Then lMtcTime = lMtcTime + fMsPerQF
nQfIdExpected = &H50 'Expected next Quarter Frame Message
End If
Case &H50: 'Quarter Frame Message indicating Minutes hiNibble
If nQfIdExpected <> &H50 Then 'Discontinous MTC -> resync
bInSync = False 'Out of sync
nQfIdExpected = &H0 'start over
Else
'Minutes HiNibble=Bits 0 & 1 of iMtcData
iHiNibble = (iMtcData And &H3)
iMtcMinutes = (iHiNibble * 16) + iLoNibble 'pack Minutes Number
'If we're in sync, increase Time Counter
If bInSync = True Then lMtcTime = lMtcTime + fMsPerQF
nQfIdExpected = &H60 'Expected next Quarter Frame Message
End If
Case &H60: 'Quarter Frame Message indicating Hours loNibble
If nQfIdExpected <> &H60 Then 'Discontinous MTC -> resync
bInSync = False 'Out of sync
nQfIdExpected = &H0 'start over
Else
iLoNibble = (iMtcData And &HF) 'Hours iLoNibble
'If we're in sync, increase Time Counter
If bInSync = True Then lMtcTime = lMtcTime + fMsPerQF
nQfIdExpected = &H70 'Expected next Quarter Frame Message
End If
Case &H70: 'Quarter Frame Message indicating Hours hiNibble
If nQfIdExpected <> &H70 Then 'Discontinous MTC -> resync
bInSync = False 'Out of sync
nQfIdExpected = &H0 'start over
Else
'Hours HiNibble=Bit 0 of iMtcData
iHiNibble = (iMtcData And &H1)
iMtcHours = (iHiNibble * 16) + iLoNibble 'pack Hours Number
'Set bDebug = True to test arriving MTC in Debug Window
'Only works in Visual Basic environement
If bDebug = True Then
Debug.Print iMtcHours; ":"; iMtcMinutes; ":";
Debug.Print iMtcSeconds; ":"; iMtcFrames
End If
'nMtcMode is packed in Bits 1 & 2 of iMtcData
'Test if received MTC is in the expected frame mode
If (iMtcData And &H6) / 2 <> nMtcMode Then
bMtcModeError = True 'poll this flag if necessary
bInSync = False 'Out of sync
nQfIdExpected = &H0 'start over
Exit Sub
End If
'We are two frames late because we've spent 8 Quarter Frames (2 Frames)
'to read and pack a complete MTC message, thus...
iMtcFrames = iMtcFrames + 2
If bInSync = True Then
'Is new MTC message continuous with the previous one?
lTotalFrames = nFramesPerSecond * (iMtcHours * 3600& + iMtcMinutes * 60& + iMtcSeconds) + iMtcFrames
If lTotalFrames - nMtcTotalFrames <> 1 Then
'Wrap from 23:59:59:24 to 00:00:00:00 not implemented!
'Dropped frames in 30 f/s drop frame mode also not implemented
bInSync = False 'Discontinous MTC -> Out of sync
nQfIdExpected = &H0 'start over
Else
'Actualize Time Counter
lMtcTime = CLng(CSng(lTotalFrames) * fMsPerFrame)
'8th Quarter Frame Message->Increase Frame Counter
nMtcTotalFrames = nMtcTotalFrames + 1
End If
Else
'We were out of sync but...
'a new complete valid MTC message has been received !!
nNewMTC = nNewMTC + 1 'Increase New MTC counter
'Calculate new Frame Counter (long integer operation).
nMtcTotalFrames = (iMtcHours * 3600& + iMtcMinutes * 60& + iMtcSeconds) * nFramesPerSecond + iMtcFrames
'Calculate new milliseconds Time Counter (float operation).
lMtcTime = CLng(CSng(nMtcTotalFrames) * fMsPerFrame)
'Now we are in sync
bInSync = True
End If
nQfIdExpected = &H0 'ID of expected next Quarter Frame Message
End If
End Select
End If
Else 'Received Midi Message is Midi Data (not MTC)
'You may show here a screen representation of MidiData In.
'*********************************************
'SPECIFIC TO THIS APPLICATION
If bVisualData = True Then
If frmVBSeq.picDataIn.BackColor = LED_OFF Then
frmVBSeq.picDataIn.BackColor = LED_ON
End If
lDataInTime = timeGetTime()
End If
'*********************************************
If bMidiThru = True Then 'Global Flag
If hMidiOut <> NO_HANDLE Then
vntRet = midiOutShortMsg(hMidiOut, lMidiMessage) 'send it out
'You may show here a screen representation of Midi Data Out.
'*********************************************
'SPECIFIC TO THIS APPLICATION
If bVisualData = True Then
If frmVBSeq.picDataOut.BackColor = LED_OFF Then
frmVBSeq.picDataOut.BackColor = LED_ON
End If
lDataOutTime = timeGetTime()
End If
'**********************************************
End If
End If
'Here you may save the Midi Data just received (or do whatever with it...)
'***********************************************************************************
'SPECIFIC TO THIS APPLICATION
'Save Midi Data only if we are in recording mode
If bRec = True Then
'Increase RecBuffer Size 1K if needed
If (nRecCounter Mod 1024) = 0 Then
ReDim Preserve aRecBuffer(nRecCounter + 1024)
End If
If nSyncMode = SYNC_INTERNAL Then
'Save packed Midi Message
aRecBuffer(nRecCounter).MidiData = lMidiMessage
'Time = Initial Offset + milliseconds ellapsed since Start Recording
aRecBuffer(nRecCounter).TimeStamp = lOffsetTime + (timeGetTime() - lInitTime)
'increase recorded messages counter
nRecCounter = nRecCounter + 1
Else 'external sync
'save only if we're in sync with MTC
If bInSync = True Then
aRecBuffer(nRecCounter).MidiData = lMidiMessage
'Time=current MTC time in milliseconds
aRecBuffer(nRecCounter).TimeStamp = lMtcTime
nRecCounter = nRecCounter + 1
Else
'An incoming Midi Data message is lost
'because it was received while we were out of sync
nRecErrors = nRecErrors + 1
'You may inform the user, but not in this procedure!!!!
End If
End If
End If
'**************************************************************************************
End If
End Sub