Skip to content

Commit

Permalink
Added Windows native MIDI support
Browse files Browse the repository at this point in the history
  • Loading branch information
softins committed Nov 28, 2024
1 parent bedd7b0 commit f058359
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 1 deletion.
74 changes: 74 additions & 0 deletions src/sound/asio/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,23 @@ CSound::CSound ( void ( *fpNewCallback ) ( CVector<int16_t>& psData, void* arg )
asioCallbacks.sampleRateDidChange = &sampleRateChanged;
asioCallbacks.asioMessage = &asioMessages;
asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo;

// Optional MIDI initialization --------------------------------------------
if ( iCtrlMIDIChannel != INVALID_MIDI_CH )
{
MidiStart();
}
}

CSound::~CSound()
{
// stop MIDI if running
if ( iCtrlMIDIChannel != INVALID_MIDI_CH )
{
MidiStop();
}

UnloadCurrentDriver();
}

void CSound::ResetChannelMapping()
Expand Down Expand Up @@ -1218,3 +1235,60 @@ int64_t CSound::Flip64Bits ( const int64_t iIn )

return iOut;
}

// Windows Native MIDI support
void CSound::MidiStart()
{
midiPort = 0; // might want to make this settable, Windows allocates device numbers in order

MMRESULT result = midiInOpen ( &hMidiIn, midiPort, (DWORD_PTR) MidiCallback, 0, CALLBACK_FUNCTION );

if ( result != MMSYSERR_NOERROR )
{
qWarning() << "! Failed to open MIDI input device. Error code: " << result;
hMidiIn = 0;
return;
}

result = midiInStart ( hMidiIn );
if ( result != MMSYSERR_NOERROR )
{
qWarning() << "! Failed to start MIDI input. Error code: " << result;
midiInClose ( hMidiIn );
hMidiIn = 0;
return;
}
}

void CSound::MidiStop()
{
// stop MIDI if running
if ( hMidiIn != 0 )
{
midiInStop ( hMidiIn );
midiInClose ( hMidiIn );
}
}

void CALLBACK CSound::MidiCallback ( HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
{
Q_UNUSED ( hMidiIn );
Q_UNUSED ( dwInstance );
Q_UNUSED ( dwParam2 );

if ( wMsg == MIM_DATA )
{
BYTE status = dwParam1 & 0xFF;
BYTE data1 = ( dwParam1 >> 8 ) & 0xFF;
BYTE data2 = ( dwParam1 >> 16 ) & 0xFF;

// copy packet and send it to the MIDI parser
CVector<uint8_t> vMIDIPaketBytes ( 3 );

vMIDIPaketBytes[0] = static_cast<uint8_t> ( status );
vMIDIPaketBytes[1] = static_cast<uint8_t> ( data1 );
vMIDIPaketBytes[2] = static_cast<uint8_t> ( data2 );

pSound->ParseMIDIMessage ( vMIDIPaketBytes );
}
}
10 changes: 9 additions & 1 deletion src/sound/asio/sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class CSound : public CSoundBase
public:
CSound ( void ( *fpNewCallback ) ( CVector<int16_t>& psData, void* arg ), void* arg, const QString& strMIDISetup, const bool, const QString& );

virtual ~CSound() { UnloadCurrentDriver(); }
virtual ~CSound();

virtual int Init ( const int iNewPrefMonoBufferSize );
virtual void Start();
Expand Down Expand Up @@ -134,4 +134,12 @@ class CSound : public CSoundBase
static long asioMessages ( long selector, long value, void* message, double* opt );

char* cDriverNames[MAX_NUMBER_SOUND_CARDS];

// Windows native MIDI
HMIDIIN hMidiIn; // windows handle
UINT midiPort;

void MidiStart();
void MidiStop();
static void CALLBACK MidiCallback ( HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 );
};

0 comments on commit f058359

Please sign in to comment.