Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove the word "Interface" from the name of interfaces, as it's redundant. #501

Merged
merged 5 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 81 additions & 22 deletions src/api/Client/WinMM/MidiSrvPort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ CMidiPort::RuntimeClassInitialize(GUID sessionId, std::wstring& interfaceId, Mid
TraceLoggingValue((int)flow, "MidiFlow"),
TraceLoggingValue(flags, "flags"));

TRANSPORTCREATIONPARAMS transportCreationParams { MidiDataFormats_ByteStream, MidiApi_Winmm };
TRANSPORTCREATIONPARAMS transportCreationParams { MidiDataFormats_ByteStream, WINMM_APIID };
DWORD mmcssTaskId {0};
LARGE_INTEGER qpc{ 0 };

Expand Down Expand Up @@ -433,6 +433,7 @@ CMidiPort::Callback(_In_ PVOID data, _In_ UINT size, _In_ LONGLONG position, LON
if (MIDI_SYSEX == *callbackData)
{
m_IsInSysex = true;
m_RunningStatus = 0;
}

if (m_IsInSysex)
Expand Down Expand Up @@ -505,7 +506,6 @@ CMidiPort::Callback(_In_ PVOID data, _In_ UINT size, _In_ LONGLONG position, LON
// next iteration will require a new buffer.
if (buffer->dwBufferLength == buffer->dwBytesRecorded)
{

RETURN_IF_FAILED(CompleteLongBuffer(MIM_LONGDATA, position));
}
}
Expand All @@ -522,38 +522,97 @@ CMidiPort::Callback(_In_ PVOID data, _In_ UINT size, _In_ LONGLONG position, LON
else
{
// not in a sysex, process this as a normal message
// Guaranteed to have at least 1 byte worth of data available
// at this point.
BYTE status = callbackData[0];
BYTE data1 = 0;
BYTE data2 = 0;
bool dataWritten = false;

// system messages which are not real-time terminate
// running status
if ((status >= MIDI_SYSEX) && (status <= MIDI_EOX))
{
m_RunningStatus = 0;
}

BYTE status;
BYTE data1;
BYTE data2;

// if this is true, running status is active
if(0 == (*callbackData & MIDI_STATUSBYTEFILTER))
// tune request, timing, etc. are all 1 byte messages.
if (status >= MIDI_TUNEREQUEST &&
callbackDataRemaining >= 1)
{
// running status required, but not previously set,
// this isn't a valid message
RETURN_HR_IF(E_FAIL, 0 == m_RunningStatus);
status = m_RunningStatus;
data1 = callbackData[0];
data2 = callbackData[1];
callbackData+=1;
callbackDataRemaining-=1;
dataWritten = true;
}
else
// song select is the only 2 byte message
else if (status == MIDI_SONGSELECT &&
callbackDataRemaining >= 2)
{
data1 = callbackData[1];
callbackData+=2;
callbackDataRemaining-=2;
dataWritten = true;
}
// all other status byte messages are 3 bytes,
// MIDI_MTC, MIDI_SONGPP, and anything less than 0xF0
else if (0 != (status & MIDI_STATUSBYTEFILTER) &&
callbackDataRemaining >= 3)
{
status = callbackData[0];
if(status < MIDI_SYSEX) // don't save system common or system realtime as running status
{
m_RunningStatus = status;
}

data1 = callbackData[1];
data2 = callbackData[2];
callbackData+=3;
callbackDataRemaining-=3;
dataWritten = true;
}
// if it's not a message with a status byte, it should be
// running status, which requires 2 bytes, and our running
// status should be valid.
else if((0 == (status & MIDI_STATUSBYTEFILTER)) &&
(0 != (m_RunningStatus & MIDI_STATUSBYTEFILTER)) &&
callbackDataRemaining >= 2)
{
status = m_RunningStatus;
data1 = callbackData[0];
data2 = callbackData[1];

// Convert from the QPC time to the number of ticks elapsed from the start time.
DWORD ticks = (DWORD) (((position - startTime) / m_qpcFrequency) * 1000.0);
UINT32 midiMessage = status | (data1 << 8) | (data2 << 16);
WinmmClientCallback(MIM_DATA, midiMessage, ticks);
callbackData+=3;
callbackDataRemaining-=3;
// running status only consumes 2 bytes
callbackData+=2;
callbackDataRemaining-=2;
dataWritten = true;
}
else
{
// this is an unknown condition, the amount of available
// data doesn't align to the type of message being processed,
// or we don't have a status byte and aren't in a running status.

assert(0);

callbackData+=1;
callbackDataRemaining-=1;
// data not written, this byte ignored.

TraceLoggingWrite(
WdmAud2TelemetryProvider::Provider(),
MIDI_TRACE_EVENT_WARNING,
TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
TraceLoggingLevel(WINEVENT_LEVEL_WARNING),
TraceLoggingWideString(L"Invalid state, dropping data", MIDI_TRACE_EVENT_MESSAGE_FIELD),
TraceLoggingPointer(this, "this"));
}

if (dataWritten)
{
// Convert from the QPC time to the number of ticks elapsed from the start time.
DWORD ticks = (DWORD) (((position - startTime) / m_qpcFrequency) * 1000.0);
UINT32 midiMessage = status | (data1 << 8) | (data2 << 16);
WinmmClientCallback(MIM_DATA, midiMessage, ticks);
}
}

// before we continue on to the next buffer, we need to find out if the
Expand Down
5 changes: 5 additions & 0 deletions src/api/Client/WinMM/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <memory>
#include <string>

#include <assert.h>
#include <wrl\module.h>
#include <avrt.h>
#include <wil\com.h>
Expand Down Expand Up @@ -53,3 +54,7 @@ MMRESULT MMRESULT_FROM_HRESULT(HRESULT hResult);

extern bool g_ProcessIsTerminating;

#ifndef WINMM_APIID
#define WINMM_APIID {0x159f7ef3,0xb022,0x4cb7,{0xad,0x3f,0x6,0x42,0x21,0xbc,0x64,0x18}}
#endif

1 change: 1 addition & 0 deletions src/api/Drivers/MinMidi/Driver/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#define PAGED_CODE_SEG __declspec(code_seg("PAGE"))
#define INIT_CODE_SEG __declspec(code_seg("INIT"))
#define NONPAGED_CODE_SEG __declspec(code_seg("NOPAGE"))

#define NT_RETURN_IF_NTSTATUS_FAILED(status) do {\
if(!NT_SUCCESS(status)) { \
Expand Down
8 changes: 3 additions & 5 deletions src/api/Drivers/MinMidi/Driver/MidiPin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,28 +602,26 @@ MidiPin::Process(
}

_Use_decl_annotations_
PAGED_CODE_SEG
NONPAGED_CODE_SEG
void MidiPin::WorkerThread(PVOID context)
{
PAGED_CODE();
auto midiPin = reinterpret_cast<MidiPin*>(context);
midiPin->HandleIo();
}

__drv_maxIRQL(PASSIVE_LEVEL)
PAGED_CODE_SEG
NONPAGED_CODE_SEG
void
MidiPin::HandleIo()
{
PAGED_CODE();

// This function handles both sending and receiving midi messages
// when cyclic buffering is being used.
// This implememtation loops the midi out data back to midi in.
NTSTATUS status = STATUS_SUCCESS;

// start with the even reset to indicate that the thread is running
m_ThreadExitedEvent.clear();
m_ThreadExitEvent.clear();

if (m_Pin->DataFlow == KSPIN_DATAFLOW_IN)
{
Expand Down
4 changes: 2 additions & 2 deletions src/api/Drivers/MinMidi/Driver/MidiPin.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class MidiPin
static KSTART_ROUTINE WorkerThread;

__drv_maxIRQL(PASSIVE_LEVEL)
PAGED_CODE_SEG
NONPAGED_CODE_SEG
void
HandleIo();

Expand Down Expand Up @@ -231,7 +231,7 @@ class MidiPin

// worker thread that handles IO across the shared memory
PKTHREAD m_WorkerThread {nullptr};
wil::kernel_event_auto_reset m_ThreadExitEvent;
wil::kernel_event_manual_reset m_ThreadExitEvent;
wil::kernel_event_manual_reset m_ThreadExitedEvent {true};

// m_StandardStreamingLock m_LoopbackMessageQueue are only used
Expand Down
1 change: 1 addition & 0 deletions src/api/Drivers/MinMidi2/Driver/Pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Module Name:

#define PAGED_CODE_SEG __declspec(code_seg("PAGE"))
#define INIT_CODE_SEG __declspec(code_seg("INIT"))
#define NONPAGED_CODE_SEG __declspec(code_seg("NOPAGE"))

#ifdef __cplusplus
extern "C" {
Expand Down
4 changes: 3 additions & 1 deletion src/api/Drivers/MinMidi2/Driver/StreamEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,17 @@ StreamEngine::Cleanup()
}

_Use_decl_annotations_
NONPAGED_CODE_SEG
void
StreamEngine::WorkerThread(
PVOID context
)
{
PAGED_CODE();
auto streamEngine = reinterpret_cast<StreamEngine*>(context);
streamEngine->HandleIo();
}

NONPAGED_CODE_SEG
void
StreamEngine::HandleIo()
{
Expand All @@ -132,6 +133,7 @@ StreamEngine::HandleIo()

// start with the even reset to indicate that the thread is running
m_ThreadExitedEvent.clear();
m_ThreadExitEvent.clear();

if (AcxPinGetId(m_Pin) == MidiPinTypeMidiOut)
{
Expand Down
4 changes: 2 additions & 2 deletions src/api/Drivers/MinMidi2/Driver/StreamEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class StreamEngine
static KSTART_ROUTINE WorkerThread;

__drv_maxIRQL(PASSIVE_LEVEL)
PAGED_CODE_SEG
NONPAGED_CODE_SEG
void
HandleIo();

Expand Down Expand Up @@ -184,7 +184,7 @@ class StreamEngine

// worker thread that handles IO across the shared memory
PKTHREAD m_WorkerThread {nullptr};
wil::kernel_event_auto_reset m_ThreadExitEvent;
wil::kernel_event_manual_reset m_ThreadExitEvent;
wil::kernel_event_manual_reset m_ThreadExitedEvent {true};

// m_StandardStreamingLock m_LoopbackMessageQueue are only used
Expand Down
Loading