@@ -463,7 +463,7 @@ CMidiPort::Callback(_In_ PVOID data, _In_ UINT size, _In_ LONGLONG position, LON
463
463
BYTE inProgressMidiMessage[3 ]{ 0 }; // status, data 1, data 2
464
464
BYTE countMidiMessageBytesReceived = 0 ;
465
465
466
- BYTE immediateSingleByteMessage { 0 }; // real time or other single-byte message that could interrupt the in-progress message
466
+ BYTE prioritySingleByteMessage { 0 }; // real time or other single-byte message that could interrupt the in-progress message
467
467
468
468
LPMIDIHDR buffer{ nullptr };
469
469
@@ -479,7 +479,7 @@ CMidiPort::Callback(_In_ PVOID data, _In_ UINT size, _In_ LONGLONG position, LON
479
479
// do not add it to the inProgressMidiMessage or any buffer even though
480
480
// this shouldn't happen with midisrv-supplied message data
481
481
482
- immediateSingleByteMessage = *callbackData;
482
+ prioritySingleByteMessage = *callbackData;
483
483
}
484
484
else if (!m_IsInSysex)
485
485
{
@@ -488,7 +488,10 @@ CMidiPort::Callback(_In_ PVOID data, _In_ UINT size, _In_ LONGLONG position, LON
488
488
{
489
489
// we're not in SysEx mode, but this byte was provided
490
490
// so we'll send it anyway
491
- immediateSingleByteMessage = *callbackData;
491
+ // Convert from the QPC time to the number of ticks elapsed from the start time.
492
+ DWORD ticks = (DWORD)(((position - startTime) / m_qpcFrequency) * 1000.0 );
493
+ DWORD_PTR midiMessage = *callbackData;
494
+ WinmmClientCallback (MIM_ERROR, midiMessage, ticks);
492
495
}
493
496
else if (MIDI_BYTE_IS_SYSEX_START_STATUS (*callbackData))
494
497
{
@@ -539,10 +542,9 @@ CMidiPort::Callback(_In_ PVOID data, _In_ UINT size, _In_ LONGLONG position, LON
539
542
{
540
543
// Handle a data byte, and not sysex.
541
544
542
- if (countMidiMessageBytesReceived > 0 && countMidiMessageBytesReceived < 3 )
545
+ if (countMidiMessageBytesReceived >= 1 && countMidiMessageBytesReceived < 3 )
543
546
{
544
- inProgressMidiMessage[countMidiMessageBytesReceived] = *callbackData;
545
- countMidiMessageBytesReceived++;
547
+ inProgressMidiMessage[countMidiMessageBytesReceived++] = *callbackData;
546
548
}
547
549
else
548
550
{
@@ -551,9 +553,9 @@ CMidiPort::Callback(_In_ PVOID data, _In_ UINT size, _In_ LONGLONG position, LON
551
553
// to do that. We could even put in a reg setting to control this behavior.
552
554
553
555
// Convert from the QPC time to the number of ticks elapsed from the start time.
554
- DWORD ticks = (DWORD)(((position - startTime) / m_qpcFrequency) * 1000.0 );
555
- UINT32 midiMessage = *callbackData;
556
- WinmmClientCallback (MIM_ERROR, midiMessage, ticks);
556
+ // DWORD ticks = (DWORD)(((position - startTime) / m_qpcFrequency) * 1000.0);
557
+ // DWORD_PTR midiMessage = *callbackData;
558
+ // WinmmClientCallback(MIM_ERROR, midiMessage, ticks);
557
559
}
558
560
}
559
561
}
@@ -621,40 +623,46 @@ CMidiPort::Callback(_In_ PVOID data, _In_ UINT size, _In_ LONGLONG position, LON
621
623
622
624
}
623
625
624
- if (immediateSingleByteMessage > 0 )
626
+ if (MIDI_BYTE_IS_STATUS_BYTE (prioritySingleByteMessage) )
625
627
{
626
628
// Convert from the QPC time to the number of ticks elapsed from the start time.
627
629
DWORD ticks = (DWORD)(((position - startTime) / m_qpcFrequency) * 1000.0 );
628
- UINT32 midiMessage = *callbackData ;
630
+ DWORD_PTR midiMessage{ prioritySingleByteMessage } ;
629
631
WinmmClientCallback (MIM_DATA, midiMessage, ticks);
630
632
631
- immediateSingleByteMessage = 0 ;
633
+ prioritySingleByteMessage = 0 ;
632
634
}
633
635
634
636
// do we have a complete non-SysEx message to send? If so, send it
635
- if (countMidiMessageBytesReceived == 3 && MIDI_MESSAGE_IS_THREE_BYTES (inProgressMidiMessage[0 ]) ||
636
- countMidiMessageBytesReceived == 2 && MIDI_MESSAGE_IS_TWO_BYTES (inProgressMidiMessage[0 ]) ||
637
- countMidiMessageBytesReceived == 1 && MIDI_MESSAGE_IS_ONE_BYTE (inProgressMidiMessage[0 ]))
637
+ if (countMidiMessageBytesReceived > 0 )
638
638
{
639
- // Convert from the QPC time to the number of ticks elapsed from the start time.
640
- DWORD ticks = (DWORD)(((position - startTime) / m_qpcFrequency) * 1000.0 );
641
- UINT32 midiMessage{ inProgressMidiMessage[0 ] };
642
-
643
- if (MIDI_MESSAGE_IS_TWO_BYTES (inProgressMidiMessage[0 ]) || MIDI_MESSAGE_IS_THREE_BYTES (inProgressMidiMessage[0 ]))
639
+ if (countMidiMessageBytesReceived == 3 && MIDI_MESSAGE_IS_THREE_BYTES (inProgressMidiMessage[0 ]) ||
640
+ countMidiMessageBytesReceived == 2 && MIDI_MESSAGE_IS_TWO_BYTES (inProgressMidiMessage[0 ]) ||
641
+ countMidiMessageBytesReceived == 1 && MIDI_MESSAGE_IS_ONE_BYTE (inProgressMidiMessage[0 ]))
644
642
{
645
- midiMessage |= (inProgressMidiMessage[1 ] << 8 );
646
- }
643
+ // Convert from the QPC time to the number of ticks elapsed from the start time.
644
+ DWORD ticks = (DWORD)(((position - startTime) / m_qpcFrequency) * 1000.0 );
645
+ DWORD_PTR midiMessage{ static_cast <DWORD_PTR>(inProgressMidiMessage[0 ]) };
647
646
648
- if (MIDI_MESSAGE_IS_THREE_BYTES (inProgressMidiMessage[0 ]))
649
- {
650
- midiMessage |= (inProgressMidiMessage[2 ] << 16 );
651
- }
647
+ if (MIDI_MESSAGE_IS_TWO_BYTES (inProgressMidiMessage[ 0 ]) || MIDI_MESSAGE_IS_THREE_BYTES (inProgressMidiMessage[0 ]))
648
+ {
649
+ midiMessage |= (static_cast <DWORD_PTR>( inProgressMidiMessage[1 ]) << 8 );
650
+ }
652
651
653
- WinmmClientCallback (MIM_DATA, midiMessage, ticks);
652
+ if (MIDI_MESSAGE_IS_THREE_BYTES (inProgressMidiMessage[0 ]))
653
+ {
654
+ midiMessage |= (static_cast <DWORD_PTR>(inProgressMidiMessage[2 ]) << 16 );
655
+ }
656
+
657
+ WinmmClientCallback (MIM_DATA, midiMessage, ticks);
658
+
659
+ // reset for next message
660
+ countMidiMessageBytesReceived = 0 ;
654
661
655
- // reset for next message
656
- countMidiMessageBytesReceived = 0 ;
657
- inProgressMidiMessage[0 ] = 0 ;
662
+ inProgressMidiMessage[0 ] = 0 ;
663
+ inProgressMidiMessage[1 ] = 0 ;
664
+ inProgressMidiMessage[2 ] = 0 ;
665
+ }
658
666
}
659
667
660
668
// move to the next byte of data in the loop
@@ -712,9 +720,30 @@ CMidiPort::SendMidiMessage(UINT32 midiMessage)
712
720
// This should be on an initialized midi out port
713
721
RETURN_HR_IF (E_INVALIDARG, nullptr == m_MidisrvTransport);
714
722
723
+ // NOTE: sizeof(midiMessage) there is not correct for how the service reads data. This results
724
+ // in extra 00 byte data being sent to the service, and then in the translator, being read as
725
+ // running status values for the initial status byte.
726
+
727
+ UINT messageSize{ sizeof (UINT32) };
728
+ byte status = midiMessage & 0x000000FF ;
729
+ // byte* messagePointer = (byte*)(&midiMessage);
730
+
731
+ if (MIDI_MESSAGE_IS_ONE_BYTE (status))
732
+ {
733
+ messageSize = 1 ;
734
+ }
735
+ else if (MIDI_MESSAGE_IS_TWO_BYTES (status))
736
+ {
737
+ messageSize = 2 ;
738
+ }
739
+ else if (MIDI_MESSAGE_IS_THREE_BYTES (status))
740
+ {
741
+ messageSize = 3 ;
742
+ }
743
+
715
744
// send the message to the transport
716
745
// pass a timestamp of 0 to bypass scheduler
717
- RETURN_IF_FAILED (m_MidisrvTransport->SendMidiMessage (&midiMessage, sizeof (midiMessage) , 0 ));
746
+ RETURN_IF_FAILED (m_MidisrvTransport->SendMidiMessage (&midiMessage, messageSize , 0 ));
718
747
}
719
748
720
749
return S_OK;
@@ -759,7 +788,8 @@ CMidiPort::SendLongMessage(LPMIDIHDR buffer)
759
788
// pass a timestamp of 0 to bypass scheduler
760
789
// TODO: based on the buffer length, this message may require chunking into smaller
761
790
// pieces to ensure it fits into the cross process queue.
762
- RETURN_IF_FAILED (m_MidisrvTransport->SendMidiMessage (buffer->lpData , buffer->dwBufferLength , 0 ));
791
+ //
792
+ RETURN_IF_FAILED (m_MidisrvTransport->SendMidiMessage (buffer->lpData , buffer->dwBytesRecorded , 0 ));
763
793
}
764
794
765
795
// mark the buffer as completed
0 commit comments