- uncoupled the MIDI player from Windows system structures.

The approach being used here caused the entire sound system to be infested by windows.h, just to avoid copying around a handful of variables in one place, effectively preventing any compiling optimization.
Windows will now use the same internally defined structure for all MIDI processing which only for actual submission to the system player will be converted to the internal format.
This commit is contained in:
Christoph Oelckers 2017-03-10 12:01:29 +01:00
parent bc63c664f2
commit bfd968a88c
6 changed files with 79 additions and 47 deletions

View file

@ -39,15 +39,17 @@ EXTERN_CVAR (Float, timidity_mastervolume)
// A device that provides a WinMM-like MIDI streaming interface -------------
#ifndef _WIN32
struct MIDIHDR
struct MidiHeader
{
uint8_t *lpData;
DWORD dwBufferLength;
DWORD dwBytesRecorded;
MIDIHDR *lpNext;
uint32_t dwBufferLength;
uint32_t dwBytesRecorded;
MidiHeader *lpNext;
};
#ifndef _WIN32
enum
{
MOD_MIDIPORT = 1,
@ -92,12 +94,12 @@ public:
virtual int GetTechnology() const = 0;
virtual int SetTempo(int tempo) = 0;
virtual int SetTimeDiv(int timediv) = 0;
virtual int StreamOut(MIDIHDR *data) = 0;
virtual int StreamOutSync(MIDIHDR *data) = 0;
virtual int StreamOut(MidiHeader *data) = 0;
virtual int StreamOutSync(MidiHeader *data) = 0;
virtual int Resume() = 0;
virtual void Stop() = 0;
virtual int PrepareHeader(MIDIHDR *data);
virtual int UnprepareHeader(MIDIHDR *data);
virtual int PrepareHeader(MidiHeader *data);
virtual int UnprepareHeader(MidiHeader *data);
virtual bool FakeVolume();
virtual bool Pause(bool paused) = 0;
virtual bool NeedThreadedCallback();
@ -125,12 +127,12 @@ public:
int GetTechnology() const;
int SetTempo(int tempo);
int SetTimeDiv(int timediv);
int StreamOut(MIDIHDR *data);
int StreamOutSync(MIDIHDR *data);
int StreamOut(MidiHeader *data);
int StreamOutSync(MidiHeader *data);
int Resume();
void Stop();
int PrepareHeader(MIDIHDR *data);
int UnprepareHeader(MIDIHDR *data);
int PrepareHeader(MidiHeader *data);
int UnprepareHeader(MidiHeader *data);
bool FakeVolume();
bool NeedThreadedCallback();
bool Pause(bool paused);
@ -142,6 +144,8 @@ protected:
HMIDISTRM MidiOut;
UINT DeviceID;
DWORD SavedVolume;
MIDIHDR WinMidiHeaders[2];
int HeaderIndex;
bool VolumeWorks;
void (*Callback)(unsigned int, void *);
@ -162,11 +166,11 @@ public:
virtual int GetTechnology() const override;
virtual int SetTempo(int tempo) override;
virtual int SetTimeDiv(int timediv) override;
virtual int StreamOut(MIDIHDR *data) override;
virtual int StreamOutSync(MIDIHDR *data) override;
virtual int StreamOut(MidiHeader *data) override;
virtual int StreamOutSync(MidiHeader *data) override;
virtual int Resume() override;
virtual void Stop() override;
virtual int PrepareHeader(MIDIHDR* data) override;
virtual int PrepareHeader(MidiHeader* data) override;
virtual bool FakeVolume() override { return true; }
virtual bool Pause(bool paused) override;
virtual bool Preprocess(MIDIStreamer *song, bool looping) override;
@ -201,8 +205,8 @@ public:
bool Pause(bool paused);
int Resume();
void Stop();
int StreamOut(MIDIHDR *data);
int StreamOutSync(MIDIHDR *data);
int StreamOut(MidiHeader *data);
int StreamOutSync(MidiHeader *data);
int SetTempo(int tempo);
int SetTimeDiv(int timediv);
FString GetStats();
@ -275,8 +279,8 @@ public:
int GetTechnology() const;
int SetTempo(int tempo);
int SetTimeDiv(int timediv);
int StreamOut(MIDIHDR *data);
int StreamOutSync(MIDIHDR *data);
int StreamOut(MidiHeader *data);
int StreamOutSync(MidiHeader *data);
int Resume();
void Stop();
bool Pause(bool paused);
@ -288,7 +292,7 @@ protected:
double Division;
double SamplesPerTick;
double NextTickIn;
MIDIHDR *Events;
MidiHeader *Events;
bool Started;
DWORD Position;
int SampleRate;
@ -541,7 +545,7 @@ protected:
MIDIDevice *MIDI;
DWORD Events[2][MAX_EVENTS*3];
MIDIHDR Buffer[2];
MidiHeader Buffer[2];
int BufferNum;
int EndQueued;
bool VolumeChanged;

View file

@ -114,12 +114,12 @@ int AudioToolboxMIDIDevice::SetTimeDiv(int timediv)
return 0;
}
int AudioToolboxMIDIDevice::StreamOut(MIDIHDR* data)
int AudioToolboxMIDIDevice::StreamOut(MidiHeader* data)
{
return 0;
}
int AudioToolboxMIDIDevice::StreamOutSync(MIDIHDR* data)
int AudioToolboxMIDIDevice::StreamOutSync(MidiHeader* data)
{
return 0;
}
@ -170,9 +170,9 @@ void AudioToolboxMIDIDevice::Stop()
AT_MIDI_CHECK_ERROR(MusicPlayerStop(m_player));
}
int AudioToolboxMIDIDevice::PrepareHeader(MIDIHDR* data)
int AudioToolboxMIDIDevice::PrepareHeader(MidiHeader* data)
{
MIDIHDR* events = data;
MidiHeader* events = data;
DWORD position = 0;
while (nullptr != events)

View file

@ -96,6 +96,7 @@ MIDIStreamer::MIDIStreamer(EMidiDevice type, const char *args)
#endif
MIDI(0), Division(0), InitialTempo(500000), DeviceType(type), Args(args)
{
memset(Buffer, 0, sizeof(Buffer));
#ifdef _WIN32
BufferDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (BufferDoneEvent == NULL)
@ -124,6 +125,7 @@ MIDIStreamer::MIDIStreamer(const char *dumpname, EMidiDevice type)
#endif
MIDI(0), Division(0), InitialTempo(500000), DeviceType(type), DumpFilename(dumpname)
{
memset(Buffer, 0, sizeof(Buffer));
#ifdef _WIN32
BufferDoneEvent = NULL;
ExitEvent = NULL;
@ -989,9 +991,9 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time)
}
events = MakeEvents(events, max_event_p, max_time);
}
memset(&Buffer[buffer_num], 0, sizeof(MIDIHDR));
Buffer[buffer_num].lpData = (LPSTR)Events[buffer_num];
Buffer[buffer_num].dwBufferLength = DWORD((LPSTR)events - Buffer[buffer_num].lpData);
memset(&Buffer[buffer_num], 0, sizeof(MidiHeader));
Buffer[buffer_num].lpData = (uint8_t *)Events[buffer_num];
Buffer[buffer_num].dwBufferLength = uint32_t((uint8_t *)events - Buffer[buffer_num].lpData);
Buffer[buffer_num].dwBytesRecorded = Buffer[buffer_num].dwBufferLength;
if (0 != (i = MIDI->PrepareHeader(&Buffer[buffer_num])))
{
@ -1021,9 +1023,9 @@ int MIDIStreamer::FillStopBuffer(int buffer_num)
events[2] = MEVT_NOP << 24;
events += 3;
memset(&Buffer[buffer_num], 0, sizeof(MIDIHDR));
Buffer[buffer_num].lpData = (LPSTR)Events[buffer_num];
Buffer[buffer_num].dwBufferLength = DWORD((LPSTR)events - Buffer[buffer_num].lpData);
memset(&Buffer[buffer_num], 0, sizeof(MidiHeader));
Buffer[buffer_num].lpData = (uint8_t*)Events[buffer_num];
Buffer[buffer_num].dwBufferLength = DWORD((uint8_t*)events - Buffer[buffer_num].lpData);
Buffer[buffer_num].dwBytesRecorded = Buffer[buffer_num].dwBufferLength;
if (0 != (i = MIDI->PrepareHeader(&Buffer[buffer_num])))
{
@ -1456,7 +1458,7 @@ bool MIDIDevice::Preprocess(MIDIStreamer *song, bool looping)
//
//==========================================================================
int MIDIDevice::PrepareHeader(MIDIHDR *header)
int MIDIDevice::PrepareHeader(MidiHeader *header)
{
return 0;
}
@ -1469,7 +1471,7 @@ int MIDIDevice::PrepareHeader(MIDIHDR *header)
//
//==========================================================================
int MIDIDevice::UnprepareHeader(MIDIHDR *header)
int MIDIDevice::UnprepareHeader(MidiHeader *header)
{
return 0;
}

View file

@ -177,7 +177,7 @@ bool PseudoMIDIDevice::Pause(bool paused)
//
//==========================================================================
int PseudoMIDIDevice::StreamOutSync(MIDIHDR *header)
int PseudoMIDIDevice::StreamOutSync(MidiHeader *header)
{
assert(0);
return 0;
@ -189,7 +189,7 @@ int PseudoMIDIDevice::StreamOutSync(MIDIHDR *header)
//
//==========================================================================
int PseudoMIDIDevice::StreamOut(MIDIHDR *header)
int PseudoMIDIDevice::StreamOut(MidiHeader *header)
{
assert(0);
return 0;

View file

@ -238,7 +238,7 @@ void SoftSynthMIDIDevice::Stop()
//
//==========================================================================
int SoftSynthMIDIDevice::StreamOutSync(MIDIHDR *header)
int SoftSynthMIDIDevice::StreamOutSync(MidiHeader *header)
{
CritSec.Enter();
StreamOut(header);
@ -255,7 +255,7 @@ int SoftSynthMIDIDevice::StreamOutSync(MIDIHDR *header)
//
//==========================================================================
int SoftSynthMIDIDevice::StreamOut(MIDIHDR *header)
int SoftSynthMIDIDevice::StreamOut(MidiHeader *header)
{
header->lpNext = NULL;
if (Events == NULL)
@ -266,7 +266,7 @@ int SoftSynthMIDIDevice::StreamOut(MIDIHDR *header)
}
else
{
MIDIHDR **p;
MidiHeader **p;
for (p = &Events; *p != NULL; p = &(*p)->lpNext)
{ }

View file

@ -75,6 +75,8 @@ WinMIDIDevice::WinMIDIDevice(int dev_id)
{
DeviceID = MAX<DWORD>(dev_id, 0);
MidiOut = 0;
HeaderIndex = 0;
memset(WinMidiHeaders, 0, sizeof(WinMidiHeaders));
}
//==========================================================================
@ -323,9 +325,11 @@ bool WinMIDIDevice::Pause(bool paused)
//
//==========================================================================
int WinMIDIDevice::StreamOut(MIDIHDR *header)
int WinMIDIDevice::StreamOut(MidiHeader *header)
{
return midiStreamOut(MidiOut, header, sizeof(MIDIHDR));
auto syshdr = (MIDIHDR*)header->lpNext;
assert(syshdr == &WinMidiHeaders[0] || syshdr == &WinMidiHeaders[1]);
return midiStreamOut(MidiOut, syshdr, sizeof(MIDIHDR));
}
//==========================================================================
@ -334,9 +338,11 @@ int WinMIDIDevice::StreamOut(MIDIHDR *header)
//
//==========================================================================
int WinMIDIDevice::StreamOutSync(MIDIHDR *header)
int WinMIDIDevice::StreamOutSync(MidiHeader *header)
{
return midiStreamOut(MidiOut, header, sizeof(MIDIHDR));
auto syshdr = (MIDIHDR*)header->lpNext;
assert(syshdr == &WinMidiHeaders[0] || syshdr == &WinMidiHeaders[1]);
return midiStreamOut(MidiOut, syshdr, sizeof(MIDIHDR));
}
//==========================================================================
@ -345,9 +351,19 @@ int WinMIDIDevice::StreamOutSync(MIDIHDR *header)
//
//==========================================================================
int WinMIDIDevice::PrepareHeader(MIDIHDR *header)
int WinMIDIDevice::PrepareHeader(MidiHeader *header)
{
return midiOutPrepareHeader((HMIDIOUT)MidiOut, header, sizeof(MIDIHDR));
// This code depends on the driving implementation only having two buffers that get passed alternatingly.
// If there were more buffers this would require more intelligent handling.
assert(header->lpNext == nullptr);
MIDIHDR *syshdr = &WinMidiHeaders[HeaderIndex ^= 1];
memset(syshdr, 0, sizeof(MIDIHDR));
syshdr->lpData = (LPSTR)header->lpData;
syshdr->dwBufferLength = header->dwBufferLength;
syshdr->dwBytesRecorded = header->dwBytesRecorded;
// this device does not use the lpNext pointer to link MIDI events so use it to point to the system data structure.
header->lpNext = (MidiHeader*)syshdr;
return midiOutPrepareHeader((HMIDIOUT)MidiOut, syshdr, sizeof(MIDIHDR));
}
//==========================================================================
@ -356,9 +372,19 @@ int WinMIDIDevice::PrepareHeader(MIDIHDR *header)
//
//==========================================================================
int WinMIDIDevice::UnprepareHeader(MIDIHDR *header)
int WinMIDIDevice::UnprepareHeader(MidiHeader *header)
{
return midiOutUnprepareHeader((HMIDIOUT)MidiOut, header, sizeof(MIDIHDR));
auto syshdr = (MIDIHDR*)header->lpNext;
if (syshdr != nullptr)
{
assert(syshdr == &WinMidiHeaders[0] || syshdr == &WinMidiHeaders[1]);
header->lpNext = nullptr;
return midiOutUnprepareHeader((HMIDIOUT)MidiOut, syshdr, sizeof(MIDIHDR));
}
else
{
return MMSYSERR_NOERROR;
}
}
//==========================================================================