mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-18 23:52:02 +00:00
- 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:
parent
bc63c664f2
commit
bfd968a88c
6 changed files with 79 additions and 47 deletions
|
@ -39,15 +39,17 @@ EXTERN_CVAR (Float, timidity_mastervolume)
|
||||||
|
|
||||||
// A device that provides a WinMM-like MIDI streaming interface -------------
|
// A device that provides a WinMM-like MIDI streaming interface -------------
|
||||||
|
|
||||||
#ifndef _WIN32
|
struct MidiHeader
|
||||||
struct MIDIHDR
|
|
||||||
{
|
{
|
||||||
uint8_t *lpData;
|
uint8_t *lpData;
|
||||||
DWORD dwBufferLength;
|
uint32_t dwBufferLength;
|
||||||
DWORD dwBytesRecorded;
|
uint32_t dwBytesRecorded;
|
||||||
MIDIHDR *lpNext;
|
MidiHeader *lpNext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MOD_MIDIPORT = 1,
|
MOD_MIDIPORT = 1,
|
||||||
|
@ -92,12 +94,12 @@ public:
|
||||||
virtual int GetTechnology() const = 0;
|
virtual int GetTechnology() const = 0;
|
||||||
virtual int SetTempo(int tempo) = 0;
|
virtual int SetTempo(int tempo) = 0;
|
||||||
virtual int SetTimeDiv(int timediv) = 0;
|
virtual int SetTimeDiv(int timediv) = 0;
|
||||||
virtual int StreamOut(MIDIHDR *data) = 0;
|
virtual int StreamOut(MidiHeader *data) = 0;
|
||||||
virtual int StreamOutSync(MIDIHDR *data) = 0;
|
virtual int StreamOutSync(MidiHeader *data) = 0;
|
||||||
virtual int Resume() = 0;
|
virtual int Resume() = 0;
|
||||||
virtual void Stop() = 0;
|
virtual void Stop() = 0;
|
||||||
virtual int PrepareHeader(MIDIHDR *data);
|
virtual int PrepareHeader(MidiHeader *data);
|
||||||
virtual int UnprepareHeader(MIDIHDR *data);
|
virtual int UnprepareHeader(MidiHeader *data);
|
||||||
virtual bool FakeVolume();
|
virtual bool FakeVolume();
|
||||||
virtual bool Pause(bool paused) = 0;
|
virtual bool Pause(bool paused) = 0;
|
||||||
virtual bool NeedThreadedCallback();
|
virtual bool NeedThreadedCallback();
|
||||||
|
@ -125,12 +127,12 @@ public:
|
||||||
int GetTechnology() const;
|
int GetTechnology() const;
|
||||||
int SetTempo(int tempo);
|
int SetTempo(int tempo);
|
||||||
int SetTimeDiv(int timediv);
|
int SetTimeDiv(int timediv);
|
||||||
int StreamOut(MIDIHDR *data);
|
int StreamOut(MidiHeader *data);
|
||||||
int StreamOutSync(MIDIHDR *data);
|
int StreamOutSync(MidiHeader *data);
|
||||||
int Resume();
|
int Resume();
|
||||||
void Stop();
|
void Stop();
|
||||||
int PrepareHeader(MIDIHDR *data);
|
int PrepareHeader(MidiHeader *data);
|
||||||
int UnprepareHeader(MIDIHDR *data);
|
int UnprepareHeader(MidiHeader *data);
|
||||||
bool FakeVolume();
|
bool FakeVolume();
|
||||||
bool NeedThreadedCallback();
|
bool NeedThreadedCallback();
|
||||||
bool Pause(bool paused);
|
bool Pause(bool paused);
|
||||||
|
@ -142,6 +144,8 @@ protected:
|
||||||
HMIDISTRM MidiOut;
|
HMIDISTRM MidiOut;
|
||||||
UINT DeviceID;
|
UINT DeviceID;
|
||||||
DWORD SavedVolume;
|
DWORD SavedVolume;
|
||||||
|
MIDIHDR WinMidiHeaders[2];
|
||||||
|
int HeaderIndex;
|
||||||
bool VolumeWorks;
|
bool VolumeWorks;
|
||||||
|
|
||||||
void (*Callback)(unsigned int, void *);
|
void (*Callback)(unsigned int, void *);
|
||||||
|
@ -162,11 +166,11 @@ public:
|
||||||
virtual int GetTechnology() const override;
|
virtual int GetTechnology() const override;
|
||||||
virtual int SetTempo(int tempo) override;
|
virtual int SetTempo(int tempo) override;
|
||||||
virtual int SetTimeDiv(int timediv) override;
|
virtual int SetTimeDiv(int timediv) override;
|
||||||
virtual int StreamOut(MIDIHDR *data) override;
|
virtual int StreamOut(MidiHeader *data) override;
|
||||||
virtual int StreamOutSync(MIDIHDR *data) override;
|
virtual int StreamOutSync(MidiHeader *data) override;
|
||||||
virtual int Resume() override;
|
virtual int Resume() override;
|
||||||
virtual void Stop() 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 FakeVolume() override { return true; }
|
||||||
virtual bool Pause(bool paused) override;
|
virtual bool Pause(bool paused) override;
|
||||||
virtual bool Preprocess(MIDIStreamer *song, bool looping) override;
|
virtual bool Preprocess(MIDIStreamer *song, bool looping) override;
|
||||||
|
@ -201,8 +205,8 @@ public:
|
||||||
bool Pause(bool paused);
|
bool Pause(bool paused);
|
||||||
int Resume();
|
int Resume();
|
||||||
void Stop();
|
void Stop();
|
||||||
int StreamOut(MIDIHDR *data);
|
int StreamOut(MidiHeader *data);
|
||||||
int StreamOutSync(MIDIHDR *data);
|
int StreamOutSync(MidiHeader *data);
|
||||||
int SetTempo(int tempo);
|
int SetTempo(int tempo);
|
||||||
int SetTimeDiv(int timediv);
|
int SetTimeDiv(int timediv);
|
||||||
FString GetStats();
|
FString GetStats();
|
||||||
|
@ -275,8 +279,8 @@ public:
|
||||||
int GetTechnology() const;
|
int GetTechnology() const;
|
||||||
int SetTempo(int tempo);
|
int SetTempo(int tempo);
|
||||||
int SetTimeDiv(int timediv);
|
int SetTimeDiv(int timediv);
|
||||||
int StreamOut(MIDIHDR *data);
|
int StreamOut(MidiHeader *data);
|
||||||
int StreamOutSync(MIDIHDR *data);
|
int StreamOutSync(MidiHeader *data);
|
||||||
int Resume();
|
int Resume();
|
||||||
void Stop();
|
void Stop();
|
||||||
bool Pause(bool paused);
|
bool Pause(bool paused);
|
||||||
|
@ -288,7 +292,7 @@ protected:
|
||||||
double Division;
|
double Division;
|
||||||
double SamplesPerTick;
|
double SamplesPerTick;
|
||||||
double NextTickIn;
|
double NextTickIn;
|
||||||
MIDIHDR *Events;
|
MidiHeader *Events;
|
||||||
bool Started;
|
bool Started;
|
||||||
DWORD Position;
|
DWORD Position;
|
||||||
int SampleRate;
|
int SampleRate;
|
||||||
|
@ -541,7 +545,7 @@ protected:
|
||||||
|
|
||||||
MIDIDevice *MIDI;
|
MIDIDevice *MIDI;
|
||||||
DWORD Events[2][MAX_EVENTS*3];
|
DWORD Events[2][MAX_EVENTS*3];
|
||||||
MIDIHDR Buffer[2];
|
MidiHeader Buffer[2];
|
||||||
int BufferNum;
|
int BufferNum;
|
||||||
int EndQueued;
|
int EndQueued;
|
||||||
bool VolumeChanged;
|
bool VolumeChanged;
|
||||||
|
|
|
@ -114,12 +114,12 @@ int AudioToolboxMIDIDevice::SetTimeDiv(int timediv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioToolboxMIDIDevice::StreamOut(MIDIHDR* data)
|
int AudioToolboxMIDIDevice::StreamOut(MidiHeader* data)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioToolboxMIDIDevice::StreamOutSync(MIDIHDR* data)
|
int AudioToolboxMIDIDevice::StreamOutSync(MidiHeader* data)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -170,9 +170,9 @@ void AudioToolboxMIDIDevice::Stop()
|
||||||
AT_MIDI_CHECK_ERROR(MusicPlayerStop(m_player));
|
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;
|
DWORD position = 0;
|
||||||
|
|
||||||
while (nullptr != events)
|
while (nullptr != events)
|
||||||
|
|
|
@ -96,6 +96,7 @@ MIDIStreamer::MIDIStreamer(EMidiDevice type, const char *args)
|
||||||
#endif
|
#endif
|
||||||
MIDI(0), Division(0), InitialTempo(500000), DeviceType(type), Args(args)
|
MIDI(0), Division(0), InitialTempo(500000), DeviceType(type), Args(args)
|
||||||
{
|
{
|
||||||
|
memset(Buffer, 0, sizeof(Buffer));
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
BufferDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
BufferDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
if (BufferDoneEvent == NULL)
|
if (BufferDoneEvent == NULL)
|
||||||
|
@ -124,6 +125,7 @@ MIDIStreamer::MIDIStreamer(const char *dumpname, EMidiDevice type)
|
||||||
#endif
|
#endif
|
||||||
MIDI(0), Division(0), InitialTempo(500000), DeviceType(type), DumpFilename(dumpname)
|
MIDI(0), Division(0), InitialTempo(500000), DeviceType(type), DumpFilename(dumpname)
|
||||||
{
|
{
|
||||||
|
memset(Buffer, 0, sizeof(Buffer));
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
BufferDoneEvent = NULL;
|
BufferDoneEvent = NULL;
|
||||||
ExitEvent = 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);
|
events = MakeEvents(events, max_event_p, max_time);
|
||||||
}
|
}
|
||||||
memset(&Buffer[buffer_num], 0, sizeof(MIDIHDR));
|
memset(&Buffer[buffer_num], 0, sizeof(MidiHeader));
|
||||||
Buffer[buffer_num].lpData = (LPSTR)Events[buffer_num];
|
Buffer[buffer_num].lpData = (uint8_t *)Events[buffer_num];
|
||||||
Buffer[buffer_num].dwBufferLength = DWORD((LPSTR)events - Buffer[buffer_num].lpData);
|
Buffer[buffer_num].dwBufferLength = uint32_t((uint8_t *)events - Buffer[buffer_num].lpData);
|
||||||
Buffer[buffer_num].dwBytesRecorded = Buffer[buffer_num].dwBufferLength;
|
Buffer[buffer_num].dwBytesRecorded = Buffer[buffer_num].dwBufferLength;
|
||||||
if (0 != (i = MIDI->PrepareHeader(&Buffer[buffer_num])))
|
if (0 != (i = MIDI->PrepareHeader(&Buffer[buffer_num])))
|
||||||
{
|
{
|
||||||
|
@ -1021,9 +1023,9 @@ int MIDIStreamer::FillStopBuffer(int buffer_num)
|
||||||
events[2] = MEVT_NOP << 24;
|
events[2] = MEVT_NOP << 24;
|
||||||
events += 3;
|
events += 3;
|
||||||
|
|
||||||
memset(&Buffer[buffer_num], 0, sizeof(MIDIHDR));
|
memset(&Buffer[buffer_num], 0, sizeof(MidiHeader));
|
||||||
Buffer[buffer_num].lpData = (LPSTR)Events[buffer_num];
|
Buffer[buffer_num].lpData = (uint8_t*)Events[buffer_num];
|
||||||
Buffer[buffer_num].dwBufferLength = DWORD((LPSTR)events - Buffer[buffer_num].lpData);
|
Buffer[buffer_num].dwBufferLength = DWORD((uint8_t*)events - Buffer[buffer_num].lpData);
|
||||||
Buffer[buffer_num].dwBytesRecorded = Buffer[buffer_num].dwBufferLength;
|
Buffer[buffer_num].dwBytesRecorded = Buffer[buffer_num].dwBufferLength;
|
||||||
if (0 != (i = MIDI->PrepareHeader(&Buffer[buffer_num])))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1469,7 +1471,7 @@ int MIDIDevice::PrepareHeader(MIDIHDR *header)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int MIDIDevice::UnprepareHeader(MIDIHDR *header)
|
int MIDIDevice::UnprepareHeader(MidiHeader *header)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,7 +177,7 @@ bool PseudoMIDIDevice::Pause(bool paused)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int PseudoMIDIDevice::StreamOutSync(MIDIHDR *header)
|
int PseudoMIDIDevice::StreamOutSync(MidiHeader *header)
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -189,7 +189,7 @@ int PseudoMIDIDevice::StreamOutSync(MIDIHDR *header)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int PseudoMIDIDevice::StreamOut(MIDIHDR *header)
|
int PseudoMIDIDevice::StreamOut(MidiHeader *header)
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -238,7 +238,7 @@ void SoftSynthMIDIDevice::Stop()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int SoftSynthMIDIDevice::StreamOutSync(MIDIHDR *header)
|
int SoftSynthMIDIDevice::StreamOutSync(MidiHeader *header)
|
||||||
{
|
{
|
||||||
CritSec.Enter();
|
CritSec.Enter();
|
||||||
StreamOut(header);
|
StreamOut(header);
|
||||||
|
@ -255,7 +255,7 @@ int SoftSynthMIDIDevice::StreamOutSync(MIDIHDR *header)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int SoftSynthMIDIDevice::StreamOut(MIDIHDR *header)
|
int SoftSynthMIDIDevice::StreamOut(MidiHeader *header)
|
||||||
{
|
{
|
||||||
header->lpNext = NULL;
|
header->lpNext = NULL;
|
||||||
if (Events == NULL)
|
if (Events == NULL)
|
||||||
|
@ -266,7 +266,7 @@ int SoftSynthMIDIDevice::StreamOut(MIDIHDR *header)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MIDIHDR **p;
|
MidiHeader **p;
|
||||||
|
|
||||||
for (p = &Events; *p != NULL; p = &(*p)->lpNext)
|
for (p = &Events; *p != NULL; p = &(*p)->lpNext)
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -75,6 +75,8 @@ WinMIDIDevice::WinMIDIDevice(int dev_id)
|
||||||
{
|
{
|
||||||
DeviceID = MAX<DWORD>(dev_id, 0);
|
DeviceID = MAX<DWORD>(dev_id, 0);
|
||||||
MidiOut = 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
Loading…
Reference in a new issue