cleanup of MIDI code dependencies

* make the critical section local to the respective platform instead of polluting everything with system specific symbols.
* moved system specific class declarations into the source file instead of having them in the global header.

This commit temporarily disables the Windows system device because it cannot be done without polluting the global header and still needs a bit of refactoring.
This commit is contained in:
Christoph Oelckers 2017-03-10 16:12:52 +01:00
parent d75e09f545
commit 8d6fe24945
23 changed files with 456 additions and 378 deletions

View file

@ -602,6 +602,7 @@ endif()
# Start defining source files for ZDoom # Start defining source files for ZDoom
set( PLAT_WIN32_SOURCES set( PLAT_WIN32_SOURCES
win32/eaxedit.cpp win32/eaxedit.cpp
win32/critsec.cpp
win32/fb_d3d9.cpp win32/fb_d3d9.cpp
win32/fb_d3d9_wipe.cpp win32/fb_d3d9_wipe.cpp
win32/fb_ddraw.cpp win32/fb_ddraw.cpp
@ -626,6 +627,7 @@ set( PLAT_POSIX_SOURCES
posix/i_steam.cpp ) posix/i_steam.cpp )
set( PLAT_SDL_SOURCES set( PLAT_SDL_SOURCES
posix/sdl/crashcatcher.c posix/sdl/crashcatcher.c
posix/sdl/critsec.cpp
posix/sdl/hardware.cpp posix/sdl/hardware.cpp
posix/sdl/i_gui.cpp posix/sdl/i_gui.cpp
posix/sdl/i_input.cpp posix/sdl/i_input.cpp

View file

@ -19,7 +19,7 @@ typedef int INTBOOL;
#define GUID_DEFINED #define GUID_DEFINED
typedef struct _GUID typedef struct _GUID
{ {
DWORD Data1; uint32_t Data1;
uint16_t Data2; uint16_t Data2;
uint16_t Data3; uint16_t Data3;
uint8_t Data4[8]; uint8_t Data4[8];
@ -46,7 +46,7 @@ union QWORD_UNION
#define FRACUNIT (1<<FRACBITS) #define FRACUNIT (1<<FRACBITS)
typedef int32_t fixed_t; typedef int32_t fixed_t;
typedef DWORD dsfixed_t; // fixedpt used by span drawer typedef uint32_t dsfixed_t; // fixedpt used by span drawer
#define FIXED_MAX (signed)(0x7fffffff) #define FIXED_MAX (signed)(0x7fffffff)
#define FIXED_MIN (signed)(0x80000000) #define FIXED_MIN (signed)(0x80000000)

View file

@ -33,9 +33,25 @@
#include "critsec.h" #include "critsec.h"
#include <pthread.h>
class FInternalCriticalSection
{
public:
FInternalCriticalSection();
~FInternalCriticalSection();
void Enter();
void Leave();
private:
pthread_mutex_t m_mutex;
};
// TODO: add error handling // TODO: add error handling
FCriticalSection::FCriticalSection() FInternalCriticalSection::FInternalCriticalSection()
{ {
pthread_mutexattr_t attributes; pthread_mutexattr_t attributes;
pthread_mutexattr_init(&attributes); pthread_mutexattr_init(&attributes);
@ -46,17 +62,38 @@ FCriticalSection::FCriticalSection()
pthread_mutexattr_destroy(&attributes); pthread_mutexattr_destroy(&attributes);
} }
FCriticalSection::~FCriticalSection() FInternalCriticalSection::~FInternalCriticalSection()
{ {
pthread_mutex_destroy(&m_mutex); pthread_mutex_destroy(&m_mutex);
} }
void FCriticalSection::Enter() void FInternalCriticalSection::Enter()
{ {
pthread_mutex_lock(&m_mutex); pthread_mutex_lock(&m_mutex);
} }
void FCriticalSection::Leave() void FInternalCriticalSection::Leave()
{ {
pthread_mutex_unlock(&m_mutex); pthread_mutex_unlock(&m_mutex);
} }
FInternalCriticalSection *CreateCriticalSection()
{
return new FInternalCriticalSection();
}
void DeleteCriticalSection(FInternalCriticalSection *c)
{
delete c;
}
void EnterCriticalSection(FInternalCriticalSection *c)
{
c->Enter();
}
void LeaveCriticalSection(FInternalCriticalSection *c)
{
c->Leave();
}

View file

@ -1,53 +0,0 @@
/*
** critsec.h
**
**---------------------------------------------------------------------------
** Copyright 2014 Alexey Lysiuk
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#ifndef CRITSEC_H
#define CRITSEC_H
#include <pthread.h>
class FCriticalSection
{
public:
FCriticalSection();
~FCriticalSection();
void Enter();
void Leave();
private:
pthread_mutex_t m_mutex;
};
#endif

View file

@ -2,17 +2,14 @@
// object similar to a mutex but optimized for access by threads belonging to // object similar to a mutex but optimized for access by threads belonging to
// only one process, hence the class name.) // only one process, hence the class name.)
#ifndef CRITSEC_H
#define CRITSEC_H
#include "SDL.h" #include "SDL.h"
#include "SDL_thread.h" #include "SDL_thread.h"
#include "i_system.h" #include "i_system.h"
class FCriticalSection class FInternalCriticalSection
{ {
public: public:
FCriticalSection() FSDLCriticalSection()
{ {
CritSec = SDL_CreateMutex(); CritSec = SDL_CreateMutex();
if (CritSec == NULL) if (CritSec == NULL)
@ -20,7 +17,7 @@ public:
I_FatalError("Failed to create a critical section mutex."); I_FatalError("Failed to create a critical section mutex.");
} }
} }
~FCriticalSection() ~FSDLCriticalSection()
{ {
if (CritSec != NULL) if (CritSec != NULL)
{ {
@ -45,4 +42,22 @@ private:
SDL_mutex *CritSec; SDL_mutex *CritSec;
}; };
#endif FInternalCriticalSection *CreateCriticalSection()
{
return new FInternalCriticalSection();
}
void DeleteCriticalSection(FInternalCriticalSection *c)
{
delete c;
}
void EnterCriticalSection(FInternalCriticalSection *c)
{
c->Enter();
}
void LeaveCriticalSection(FInternalCriticalSection *c)
{
c->Leave();
}

View file

@ -36,6 +36,7 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <mmsystem.h> #include <mmsystem.h>
#define USE_WINDOWS_DWORD
#else #else
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
@ -46,8 +47,6 @@
#include <wordexp.h> #include <wordexp.h>
#include <stdio.h> #include <stdio.h>
#include "mus2midi.h" #include "mus2midi.h"
#define FALSE 0
#define TRUE 1
extern void ChildSigHandler (int signum); extern void ChildSigHandler (int signum);
#endif #endif
@ -347,7 +346,7 @@ static MIDIStreamer *CreateMIDIStreamer(FileReader &reader, EMidiDevice devtype,
// //
//========================================================================== //==========================================================================
static EMIDIType IdentifyMIDIType(DWORD *id, int size) static EMIDIType IdentifyMIDIType(uint32_t *id, int size)
{ {
// Check for MUS format // Check for MUS format
// Tolerate sloppy wads by searching up to 32 bytes for the header // Tolerate sloppy wads by searching up to 32 bytes for the header
@ -400,7 +399,7 @@ MusInfo *I_RegisterSong (FileReader *reader, MidiDeviceSetting *device)
{ {
MusInfo *info = NULL; MusInfo *info = NULL;
const char *fmt; const char *fmt;
DWORD id[32/4]; uint32_t id[32/4];
if (nomusic) if (nomusic)
{ {
@ -501,7 +500,7 @@ retry_as_sndsys:
// Check for CDDA "format" // Check for CDDA "format"
if (id[0] == (('R')|(('I')<<8)|(('F')<<16)|(('F')<<24))) if (id[0] == (('R')|(('I')<<8)|(('F')<<16)|(('F')<<24)))
{ {
DWORD subid; uint32_t subid;
reader->Seek(8, SEEK_CUR); reader->Seek(8, SEEK_CUR);
if (reader->Read (&subid, 4) != 4) if (reader->Read (&subid, 4) != 4)
@ -628,7 +627,7 @@ static bool ungzip(uint8_t *data, int complen, TArray<uint8_t> &newdata)
} }
// Decompress // Decompress
isize = LittleLong(*(DWORD *)(data + complen - 4)); isize = LittleLong(*(uint32_t *)(data + complen - 4));
newdata.Resize(isize); newdata.Resize(isize);
stream.next_in = (Bytef *)compstart; stream.next_in = (Bytef *)compstart;

View file

@ -1,24 +1,4 @@
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define USE_WINDOWS_DWORD
#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0400
#undef _WIN32_WINNT
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#ifndef USE_WINDOWS_DWORD
#define USE_WINDOWS_DWORD
#endif
#include <windows.h>
#include <mmsystem.h>
#else
#define FALSE 0
#define TRUE 1
#endif
#ifdef __APPLE__
#include <AudioToolbox/AudioToolbox.h>
#endif // __APPLE__
#include "tempfiles.h" #include "tempfiles.h"
#include "oplsynth/opl_mus_player.h" #include "oplsynth/opl_mus_player.h"
#include "c_cvars.h" #include "c_cvars.h"
@ -105,83 +85,13 @@ public:
virtual FString GetStats(); virtual FString GetStats();
}; };
// WinMM implementation of a MIDI output device -----------------------------
#ifdef _WIN32 #ifdef _WIN32
class WinMIDIDevice : public MIDIDevice MIDIDevice *CreateWinMIDIDevice(int mididevice);
{ #elif defined __APPLE__
public: MIDIDevice *CreateAudioToolboxMIDIDevice(int mididevice);
WinMIDIDevice(int dev_id);
~WinMIDIDevice();
int Open(MidiCallback, void *userdata);
void Close();
bool IsOpen() const;
int GetTechnology() const;
int SetTempo(int tempo);
int SetTimeDiv(int timediv);
int StreamOut(MidiHeader *data);
int StreamOutSync(MidiHeader *data);
int Resume();
void Stop();
int PrepareHeader(MidiHeader *data);
int UnprepareHeader(MidiHeader *data);
bool FakeVolume();
bool NeedThreadedCallback();
bool Pause(bool paused);
void PrecacheInstruments(const uint16_t *instruments, int count);
protected:
static void CALLBACK CallbackFunc(HMIDIOUT, UINT, DWORD_PTR, DWORD, DWORD);
HMIDISTRM MidiOut;
UINT DeviceID;
DWORD SavedVolume;
MIDIHDR WinMidiHeaders[2];
int HeaderIndex;
bool VolumeWorks;
MidiCallback Callback;
void *CallbackData;
};
#endif #endif
MIDIDevice *CreateTimidityPPMIDIDevice(const char *args);
// AudioToolbox implementation of a MIDI output device ----------------------
#ifdef __APPLE__
class AudioToolboxMIDIDevice : public MIDIDevice
{
public:
virtual int Open(MidiCallback, void *userData) override;
virtual void Close() override;
virtual bool IsOpen() const override;
virtual int GetTechnology() const override;
virtual int SetTempo(int tempo) override;
virtual int SetTimeDiv(int timediv) override;
virtual int StreamOut(MidiHeader *data) override;
virtual int StreamOutSync(MidiHeader *data) override;
virtual int Resume() override;
virtual void Stop() 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;
private:
MusicPlayer m_player = nullptr;
MusicSequence m_sequence = nullptr;
AudioUnit m_audioUnit = nullptr;
CFRunLoopTimerRef m_timer = nullptr;
MusicTimeStamp m_length = 0;
MidiCallback Callback;
Callback m_callback = nullptr;
void* m_userData = nullptr;
static void TimerCallback(CFRunLoopTimerRef timer, void* info);
};
#endif // __APPLE__
// Base class for pseudo-MIDI devices --------------------------------------- // Base class for pseudo-MIDI devices ---------------------------------------
@ -218,46 +128,6 @@ public:
bool Preprocess(MIDIStreamer *song, bool looping); bool Preprocess(MIDIStreamer *song, bool looping);
}; };
// MIDI file played with TiMidity++ and possibly streamed through the Sound System
class TimidityPPMIDIDevice : public PseudoMIDIDevice
{
public:
TimidityPPMIDIDevice(const char *args);
~TimidityPPMIDIDevice();
int Open(MidiCallback, void *userdata);
bool Preprocess(MIDIStreamer *song, bool looping);
bool IsOpen() const;
int Resume();
void Stop();
bool IsOpen();
void TimidityVolumeChanged();
protected:
bool LaunchTimidity();
FTempFileName DiskName;
#ifdef _WIN32
HANDLE ReadWavePipe;
HANDLE WriteWavePipe;
HANDLE ChildProcess;
bool Validated;
bool ValidateTimidity();
#else // _WIN32
int WavePipe[2];
pid_t ChildProcess;
#endif
FString CommandLine;
size_t LoopPos;
static bool FillStream(SoundStream *stream, void *buff, int len, void *userdata);
#ifdef _WIN32
static const char EventName[];
#endif
};
// Base class for software synthesizer MIDI output devices ------------------ // Base class for software synthesizer MIDI output devices ------------------
class SoftSynthMIDIDevice : public MIDIDevice class SoftSynthMIDIDevice : public MIDIDevice
@ -286,7 +156,7 @@ protected:
double NextTickIn; double NextTickIn;
MidiHeader *Events; MidiHeader *Events;
bool Started; bool Started;
DWORD Position; uint32_t Position;
int SampleRate; int SampleRate;
MidiCallback Callback; MidiCallback Callback;
@ -491,10 +361,11 @@ public:
protected: protected:
MIDIStreamer(const char *dumpname, EMidiDevice type); MIDIStreamer(const char *dumpname, EMidiDevice type);
void OutputVolume (DWORD volume); bool CheckExitEvent();
int FillBuffer(int buffer_num, int max_events, DWORD max_time); void OutputVolume (uint32_t volume);
int FillBuffer(int buffer_num, int max_events, uint32_t max_time);
int FillStopBuffer(int buffer_num); int FillStopBuffer(int buffer_num);
DWORD *WriteStopNotes(DWORD *events); uint32_t *WriteStopNotes(uint32_t *events);
int ServiceEvent(); int ServiceEvent();
int VolumeControllerChange(int channel, int volume); int VolumeControllerChange(int channel, int volume);
int ClampLoopCount(int loopcount); int ClampLoopCount(int loopcount);
@ -512,7 +383,7 @@ protected:
virtual bool CheckDone() = 0; virtual bool CheckDone() = 0;
virtual void Precache(); virtual void Precache();
virtual bool SetMIDISubsong(int subsong); virtual bool SetMIDISubsong(int subsong);
virtual DWORD *MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) = 0; virtual uint32_t *MakeEvents(uint32_t *events, uint32_t *max_event_p, uint32_t max_time) = 0;
enum enum
{ {
@ -526,29 +397,20 @@ protected:
SONG_ERROR SONG_ERROR
}; };
#ifdef _WIN32
static DWORD WINAPI PlayerProc (LPVOID lpParameter);
DWORD PlayerLoop();
HANDLE PlayerThread;
HANDLE ExitEvent;
HANDLE BufferDoneEvent;
#endif
MIDIDevice *MIDI; MIDIDevice *MIDI;
DWORD Events[2][MAX_EVENTS*3]; uint32_t Events[2][MAX_EVENTS*3];
MidiHeader Buffer[2]; MidiHeader Buffer[2];
int BufferNum; int BufferNum;
int EndQueued; int EndQueued;
bool VolumeChanged; bool VolumeChanged;
bool Restarting; bool Restarting;
bool InitialPlayback; bool InitialPlayback;
DWORD NewVolume; uint32_t NewVolume;
int Division; int Division;
int Tempo; int Tempo;
int InitialTempo; int InitialTempo;
uint8_t ChannelVolumes[16]; uint8_t ChannelVolumes[16];
DWORD Volume; uint32_t Volume;
EMidiDevice DeviceType; EMidiDevice DeviceType;
bool CallbackIsThreaded; bool CallbackIsThreaded;
int LoopLimit; int LoopLimit;
@ -574,7 +436,7 @@ protected:
void DoRestart(); void DoRestart();
bool CheckDone(); bool CheckDone();
void Precache(); void Precache();
DWORD *MakeEvents(DWORD *events, DWORD *max_events_p, DWORD max_time); uint32_t *MakeEvents(uint32_t *events, uint32_t *max_events_p, uint32_t max_time);
MUSHeader *MusHeader; MUSHeader *MusHeader;
uint8_t *MusBuffer; uint8_t *MusBuffer;
@ -600,13 +462,13 @@ protected:
void DoInitialSetup(); void DoInitialSetup();
void DoRestart(); void DoRestart();
bool CheckDone(); bool CheckDone();
DWORD *MakeEvents(DWORD *events, DWORD *max_events_p, DWORD max_time); uint32_t *MakeEvents(uint32_t *events, uint32_t *max_events_p, uint32_t max_time);
void AdvanceTracks(DWORD time); void AdvanceTracks(uint32_t time);
struct TrackInfo; struct TrackInfo;
void ProcessInitialMetaEvents (); void ProcessInitialMetaEvents ();
DWORD *SendCommand (DWORD *event, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom); uint32_t *SendCommand (uint32_t *event, TrackInfo *track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom);
TrackInfo *FindNextDue (); TrackInfo *FindNextDue ();
uint8_t *MusHeader; uint8_t *MusHeader;
@ -622,15 +484,15 @@ protected:
struct AutoNoteOff struct AutoNoteOff
{ {
DWORD Delay; uint32_t Delay;
uint8_t Channel, Key; uint8_t Channel, Key;
}; };
// Sorry, std::priority_queue, but I want to be able to modify the contents of the heap. // Sorry, std::priority_queue, but I want to be able to modify the contents of the heap.
class NoteOffQueue : public TArray<AutoNoteOff> class NoteOffQueue : public TArray<AutoNoteOff>
{ {
public: public:
void AddNoteOff(DWORD delay, uint8_t channel, uint8_t key); void AddNoteOff(uint32_t delay, uint8_t channel, uint8_t key);
void AdvanceTime(DWORD time); void AdvanceTime(uint32_t time);
bool Pop(AutoNoteOff &item); bool Pop(AutoNoteOff &item);
protected: protected:
@ -660,17 +522,17 @@ protected:
void DoInitialSetup(); void DoInitialSetup();
void DoRestart(); void DoRestart();
bool CheckDone(); bool CheckDone();
DWORD *MakeEvents(DWORD *events, DWORD *max_events_p, DWORD max_time); uint32_t *MakeEvents(uint32_t *events, uint32_t *max_events_p, uint32_t max_time);
void AdvanceTracks(DWORD time); void AdvanceTracks(uint32_t time);
struct TrackInfo; struct TrackInfo;
void ProcessInitialMetaEvents (); void ProcessInitialMetaEvents ();
DWORD *SendCommand (DWORD *event, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom); uint32_t *SendCommand (uint32_t *event, TrackInfo *track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom);
TrackInfo *FindNextDue (); TrackInfo *FindNextDue ();
static DWORD ReadVarLenHMI(TrackInfo *); static uint32_t ReadVarLenHMI(TrackInfo *);
static DWORD ReadVarLenHMP(TrackInfo *); static uint32_t ReadVarLenHMP(TrackInfo *);
uint8_t *MusHeader; uint8_t *MusHeader;
int SongLen; int SongLen;
@ -678,7 +540,7 @@ protected:
TrackInfo *Tracks; TrackInfo *Tracks;
TrackInfo *TrackDue; TrackInfo *TrackDue;
TrackInfo *FakeTrack; TrackInfo *FakeTrack;
DWORD (*ReadVarLen)(TrackInfo *); uint32_t (*ReadVarLen)(TrackInfo *);
NoteOffQueue NoteOffs; NoteOffQueue NoteOffs;
}; };
@ -705,11 +567,11 @@ protected:
void DoInitialSetup(); void DoInitialSetup();
void DoRestart(); void DoRestart();
bool CheckDone(); bool CheckDone();
DWORD *MakeEvents(DWORD *events, DWORD *max_events_p, DWORD max_time); uint32_t *MakeEvents(uint32_t *events, uint32_t *max_events_p, uint32_t max_time);
void AdvanceSong(DWORD time); void AdvanceSong(uint32_t time);
void ProcessInitialMetaEvents(); void ProcessInitialMetaEvents();
DWORD *SendCommand (DWORD *event, EventSource track, DWORD delay, ptrdiff_t room, bool &sysex_noroom); uint32_t *SendCommand (uint32_t *event, EventSource track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom);
EventSource FindNextDue(); EventSource FindNextDue();
uint8_t *MusHeader; uint8_t *MusHeader;

View file

@ -40,9 +40,6 @@
extern HWND Window; extern HWND Window;
extern HINSTANCE g_hInst; extern HINSTANCE g_hInst;
#define USE_WINDOWS_DWORD #define USE_WINDOWS_DWORD
#else
#define FALSE 0
#define TRUE 1
#endif #endif
#include <stdio.h> #include <stdio.h>

View file

@ -25,9 +25,46 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include <AudioToolbox/AudioToolbox.h>
#include "i_musicinterns.h" #include "i_musicinterns.h"
#include "templates.h" #include "templates.h"
// AudioToolbox implementation of a MIDI output device ----------------------
class AudioToolboxMIDIDevice : public MIDIDevice
{
public:
virtual int Open(MidiCallback, void *userData) override;
virtual void Close() override;
virtual bool IsOpen() const override;
virtual int GetTechnology() const override;
virtual int SetTempo(int tempo) override;
virtual int SetTimeDiv(int timediv) override;
virtual int StreamOut(MidiHeader *data) override;
virtual int StreamOutSync(MidiHeader *data) override;
virtual int Resume() override;
virtual void Stop() 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;
private:
MusicPlayer m_player = nullptr;
MusicSequence m_sequence = nullptr;
AudioUnit m_audioUnit = nullptr;
CFRunLoopTimerRef m_timer = nullptr;
MusicTimeStamp m_length = 0;
MidiCallback Callback;
Callback m_callback = nullptr;
void* m_userData = nullptr;
static void TimerCallback(CFRunLoopTimerRef timer, void* info);
};
#define AT_MIDI_CHECK_ERROR(CALL,...) \ #define AT_MIDI_CHECK_ERROR(CALL,...) \
{ \ { \
const OSStatus result = CALL; \ const OSStatus result = CALL; \
@ -289,4 +326,9 @@ void AudioToolboxMIDIDevice::TimerCallback(CFRunLoopTimerRef timer, void* info)
#undef AT_MIDI_CHECK_ERROR #undef AT_MIDI_CHECK_ERROR
MIDIDevice *CreateAudioToolboxMIDTDevice(int mididevice)
{
return new AudioToolboxMIDIDevice(mididevice);
}
#endif // __APPLE__ #endif // __APPLE__

View file

@ -908,7 +908,7 @@ MusInfo *MOD_OpenSong(FileReader &reader)
// safe. We'll restrict MOD loading to 31-instrument modules with known // safe. We'll restrict MOD loading to 31-instrument modules with known
// signatures and let the sound system worry about 15-instrument ones. // signatures and let the sound system worry about 15-instrument ones.
// (Assuming it even supports them) // (Assuming it even supports them)
duh = dumb_read_mod_quick(f, TRUE); duh = dumb_read_mod_quick(f, true);
} }
if (f != NULL) if (f != NULL)

View file

@ -35,6 +35,7 @@
#ifdef HAVE_FLUIDSYNTH #ifdef HAVE_FLUIDSYNTH
// HEADER FILES ------------------------------------------------------------ // HEADER FILES ------------------------------------------------------------
#include "i_midi_win32.h"
#include "i_musicinterns.h" #include "i_musicinterns.h"
#include "templates.h" #include "templates.h"
@ -317,7 +318,7 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
#ifdef _WIN32 #ifdef _WIN32
// On Windows, look for the 4 megabyte patch set installed by Creative's drivers as a default. // On Windows, look for the 4 megabyte patch set installed by Creative's drivers as a default.
char sysdir[MAX_PATH+sizeof("\\CT4MGM.SF2")]; char sysdir[MAX_PATH+sizeof("\\CT4MGM.SF2")];
UINT filepart; uint32_t filepart;
if (0 != (filepart = GetSystemDirectoryA(sysdir, MAX_PATH))) if (0 != (filepart = GetSystemDirectoryA(sysdir, MAX_PATH)))
{ {
strcat(sysdir, "\\CT4MGM.SF2"); strcat(sysdir, "\\CT4MGM.SF2");

View file

@ -92,15 +92,15 @@ struct HMISong::TrackInfo
const uint8_t *TrackBegin; const uint8_t *TrackBegin;
size_t TrackP; size_t TrackP;
size_t MaxTrackP; size_t MaxTrackP;
DWORD Delay; uint32_t Delay;
DWORD PlayedTime; uint32_t PlayedTime;
uint16_t Designation[NUM_HMI_DESIGNATIONS]; uint16_t Designation[NUM_HMI_DESIGNATIONS];
bool Enabled; bool Enabled;
bool Finished; bool Finished;
uint8_t RunningStatus; uint8_t RunningStatus;
DWORD ReadVarLenHMI(); uint32_t ReadVarLenHMI();
DWORD ReadVarLenHMP(); uint32_t ReadVarLenHMP();
}; };
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
@ -131,12 +131,10 @@ extern char MIDI_CommonLengths[15];
HMISong::HMISong (FileReader &reader, EMidiDevice type, const char *args) HMISong::HMISong (FileReader &reader, EMidiDevice type, const char *args)
: MIDIStreamer(type, args), MusHeader(0), Tracks(0) : MIDIStreamer(type, args), MusHeader(0), Tracks(0)
{ {
#ifdef _WIN32 if (!CheckExitEvent())
if (ExitEvent == NULL)
{ {
return; return;
} }
#endif
int len = reader.GetLength(); int len = reader.GetLength();
if (len < 0x100) if (len < 0x100)
{ // Way too small to be HMI. { // Way too small to be HMI.
@ -153,8 +151,8 @@ HMISong::HMISong (FileReader &reader, EMidiDevice type, const char *args)
{ {
SetupForHMI(len); SetupForHMI(len);
} }
else if (((DWORD *)MusHeader)[0] == MAKE_ID('H','M','I','M') && else if (((uint32_t *)MusHeader)[0] == MAKE_ID('H','M','I','M') &&
((DWORD *)MusHeader)[1] == MAKE_ID('I','D','I','P')) ((uint32_t *)MusHeader)[1] == MAKE_ID('I','D','I','P'))
{ {
SetupForHMP(len); SetupForHMP(len);
} }
@ -499,12 +497,12 @@ bool HMISong::CheckDone()
// //
//========================================================================== //==========================================================================
DWORD *HMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) uint32_t *HMISong::MakeEvents(uint32_t *events, uint32_t *max_event_p, uint32_t max_time)
{ {
DWORD *start_events; uint32_t *start_events;
DWORD tot_time = 0; uint32_t tot_time = 0;
DWORD time = 0; uint32_t time = 0;
DWORD delay; uint32_t delay;
start_events = events; start_events = events;
while (TrackDue && events < max_event_p && tot_time <= max_time) while (TrackDue && events < max_event_p && tot_time <= max_time)
@ -524,7 +522,7 @@ DWORD *HMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time)
do do
{ {
bool sysex_noroom = false; bool sysex_noroom = false;
DWORD *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom); uint32_t *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom);
if (sysex_noroom) if (sysex_noroom)
{ {
return events; return events;
@ -552,7 +550,7 @@ DWORD *HMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time)
// //
//========================================================================== //==========================================================================
void HMISong::AdvanceTracks(DWORD time) void HMISong::AdvanceTracks(uint32_t time)
{ {
for (int i = 0; i <= NumTracks; ++i) for (int i = 0; i <= NumTracks; ++i)
{ {
@ -573,9 +571,9 @@ void HMISong::AdvanceTracks(DWORD time)
// //
//========================================================================== //==========================================================================
DWORD *HMISong::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom) uint32_t *HMISong::SendCommand (uint32_t *events, TrackInfo *track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom)
{ {
DWORD len; uint32_t len;
uint8_t event, data1 = 0, data2 = 0; uint8_t event, data1 = 0, data2 = 0;
// If the next event comes from the fake track, pop an entry off the note-off queue. // If the next event comes from the fake track, pop an entry off the note-off queue.
@ -783,7 +781,7 @@ void HMISong::ProcessInitialMetaEvents ()
TrackInfo *track; TrackInfo *track;
int i; int i;
uint8_t event; uint8_t event;
DWORD len; uint32_t len;
for (i = 0; i < NumTracks; ++i) for (i = 0; i < NumTracks; ++i)
{ {
@ -828,7 +826,7 @@ void HMISong::ProcessInitialMetaEvents ()
// //
//========================================================================== //==========================================================================
DWORD HMISong::ReadVarLenHMI(TrackInfo *track) uint32_t HMISong::ReadVarLenHMI(TrackInfo *track)
{ {
return track->ReadVarLenHMI(); return track->ReadVarLenHMI();
} }
@ -839,7 +837,7 @@ DWORD HMISong::ReadVarLenHMI(TrackInfo *track)
// //
//========================================================================== //==========================================================================
DWORD HMISong::ReadVarLenHMP(TrackInfo *track) uint32_t HMISong::ReadVarLenHMP(TrackInfo *track)
{ {
return track->ReadVarLenHMP(); return track->ReadVarLenHMP();
} }
@ -852,9 +850,9 @@ DWORD HMISong::ReadVarLenHMP(TrackInfo *track)
// //
//========================================================================== //==========================================================================
DWORD HMISong::TrackInfo::ReadVarLenHMI() uint32_t HMISong::TrackInfo::ReadVarLenHMI()
{ {
DWORD time = 0, t = 0x80; uint32_t time = 0, t = 0x80;
while ((t & 0x80) && TrackP < MaxTrackP) while ((t & 0x80) && TrackP < MaxTrackP)
{ {
@ -874,9 +872,9 @@ DWORD HMISong::TrackInfo::ReadVarLenHMI()
// //
//========================================================================== //==========================================================================
DWORD HMISong::TrackInfo::ReadVarLenHMP() uint32_t HMISong::TrackInfo::ReadVarLenHMP()
{ {
DWORD time = 0; uint32_t time = 0;
uint8_t t = 0; uint8_t t = 0;
int off = 0; int off = 0;
@ -895,7 +893,7 @@ DWORD HMISong::TrackInfo::ReadVarLenHMP()
// //
//========================================================================== //==========================================================================
void NoteOffQueue::AddNoteOff(DWORD delay, uint8_t channel, uint8_t key) void NoteOffQueue::AddNoteOff(uint32_t delay, uint8_t channel, uint8_t key)
{ {
unsigned int i = Reserve(1); unsigned int i = Reserve(1);
while (i > 0 && (*this)[Parent(i)].Delay > delay) while (i > 0 && (*this)[Parent(i)].Delay > delay)
@ -931,7 +929,7 @@ bool NoteOffQueue::Pop(AutoNoteOff &item)
// //
//========================================================================== //==========================================================================
void NoteOffQueue::AdvanceTime(DWORD time) void NoteOffQueue::AdvanceTime(uint32_t time)
{ {
// Because the time is decreasing by the same amount for every entry, // Because the time is decreasing by the same amount for every entry,
// the heap property is maintained. // the heap property is maintained.
@ -985,7 +983,7 @@ void NoteOffQueue::Heapify()
HMISong::TrackInfo *HMISong::FindNextDue () HMISong::TrackInfo *HMISong::FindNextDue ()
{ {
TrackInfo *track; TrackInfo *track;
DWORD best; uint32_t best;
int i; int i;
// Give precedence to whichever track last had events taken from it. // Give precedence to whichever track last had events taken from it.

View file

@ -1,3 +1,6 @@
#include "i_midi_win32.h"
#include "i_musicinterns.h" #include "i_musicinterns.h"
#include "c_dispatch.h" #include "c_dispatch.h"
#include "i_music.h" #include "i_music.h"
@ -65,7 +68,7 @@ static void MIDIDeviceChanged(int newdev)
} }
#ifdef _WIN32 #ifdef _WIN32
UINT mididevice; unsigned mididevice;
CUSTOM_CVAR (Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {

View file

@ -1,3 +1,6 @@
#include "i_midi_win32.h"
#include "i_musicinterns.h" #include "i_musicinterns.h"
#include "c_cvars.h" #include "c_cvars.h"
#include "cmdlib.h" #include "cmdlib.h"
@ -20,6 +23,46 @@ void ChildSigHandler (int signum)
} }
#endif #endif
class TimidityPPMIDIDevice : public PseudoMIDIDevice
{
public:
TimidityPPMIDIDevice(const char *args);
~TimidityPPMIDIDevice();
int Open(MidiCallback, void *userdata);
bool Preprocess(MIDIStreamer *song, bool looping);
bool IsOpen() const;
int Resume();
void Stop();
bool IsOpen();
void TimidityVolumeChanged();
protected:
bool LaunchTimidity();
FTempFileName DiskName;
#ifdef _WIN32
HANDLE ReadWavePipe;
HANDLE WriteWavePipe;
HANDLE ChildProcess;
bool Validated;
bool ValidateTimidity();
#else // _WIN32
int WavePipe[2];
pid_t ChildProcess;
#endif
FString CommandLine;
size_t LoopPos;
static bool FillStream(SoundStream *stream, void *buff, int len, void *userdata);
#ifdef _WIN32
static const char EventName[];
#endif
};
#ifdef _WIN32 #ifdef _WIN32
@ -183,7 +226,7 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata)
int pipeSize; int pipeSize;
#ifdef _WIN32 #ifdef _WIN32
static SECURITY_ATTRIBUTES inheritable = { sizeof(inheritable), NULL, TRUE }; static SECURITY_ATTRIBUTES inheritable = { sizeof(inheritable), NULL, true };
if (!Validated && !ValidateTimidity ()) if (!Validated && !ValidateTimidity ())
{ {
@ -392,7 +435,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
startup.lpTitle = TimidityTitle; startup.lpTitle = TimidityTitle;
startup.wShowWindow = SW_SHOWMINNOACTIVE; startup.wShowWindow = SW_SHOWMINNOACTIVE;
if (CreateProcess(NULL, CommandLine.LockBuffer(), NULL, NULL, TRUE, if (CreateProcess(NULL, CommandLine.LockBuffer(), NULL, NULL, true,
DETACHED_PROCESS, NULL, NULL, &startup, &procInfo)) DETACHED_PROCESS, NULL, NULL, &startup, &procInfo))
{ {
ChildProcess = procInfo.hProcess; ChildProcess = procInfo.hProcess;
@ -728,3 +771,9 @@ BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
return bSuccess; return bSuccess;
} }
#endif #endif
MIDIDevice *CreateTimidityPPMIDIDevice(const char *args)
{
return new TimidityPPMIDIDevice(args);
}

View file

@ -34,6 +34,18 @@
// HEADER FILES ------------------------------------------------------------ // HEADER FILES ------------------------------------------------------------
#include "i_midi_win32.h"
/*
#ifdef _WIN32
DWORD PlayerLoop();
HANDLE PlayerThread;
HANDLE ExitEvent;
HANDLE BufferDoneEvent;
#endif
*/
#include "i_musicinterns.h" #include "i_musicinterns.h"
#include "templates.h" #include "templates.h"
#include "doomdef.h" #include "doomdef.h"
@ -61,7 +73,9 @@ EXTERN_CVAR(Float, snd_musicvolume)
EXTERN_CVAR(Int, snd_mididevice) EXTERN_CVAR(Int, snd_mididevice)
#ifdef _WIN32 #ifdef _WIN32
extern UINT mididevice; DWORD WINAPI PlayerProc(LPVOID lpParameter);
extern unsigned mididevice;
#endif #endif
extern char MIDI_EventLengths[7]; extern char MIDI_EventLengths[7];
@ -92,11 +106,12 @@ static const uint8_t StaticMIDIhead[] =
MIDIStreamer::MIDIStreamer(EMidiDevice type, const char *args) MIDIStreamer::MIDIStreamer(EMidiDevice type, const char *args)
: :
#ifdef _WIN32 #ifdef _WIN32
PlayerThread(0), ExitEvent(0), BufferDoneEvent(0), //PlayerThread(0), ExitEvent(0), BufferDoneEvent(0),
#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)); 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)
@ -110,6 +125,7 @@ MIDIStreamer::MIDIStreamer(EMidiDevice type, const char *args)
return; return;
} }
#endif #endif
*/
} }
//========================================================================== //==========================================================================
@ -121,15 +137,17 @@ MIDIStreamer::MIDIStreamer(EMidiDevice type, const char *args)
MIDIStreamer::MIDIStreamer(const char *dumpname, EMidiDevice type) MIDIStreamer::MIDIStreamer(const char *dumpname, EMidiDevice type)
: :
#ifdef _WIN32 #ifdef _WIN32
PlayerThread(0), ExitEvent(0), BufferDoneEvent(0), //PlayerThread(0), ExitEvent(0), BufferDoneEvent(0),
#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)); memset(Buffer, 0, sizeof(Buffer));
/*
#ifdef _WIN32 #ifdef _WIN32
BufferDoneEvent = NULL; BufferDoneEvent = NULL;
ExitEvent = NULL; ExitEvent = NULL;
#endif #endif
*/
} }
//========================================================================== //==========================================================================
@ -141,6 +159,7 @@ MIDIStreamer::MIDIStreamer(const char *dumpname, EMidiDevice type)
MIDIStreamer::~MIDIStreamer() MIDIStreamer::~MIDIStreamer()
{ {
Stop(); Stop();
/*
#ifdef _WIN32 #ifdef _WIN32
if (ExitEvent != NULL) if (ExitEvent != NULL)
{ {
@ -151,6 +170,7 @@ MIDIStreamer::~MIDIStreamer()
CloseHandle(BufferDoneEvent); CloseHandle(BufferDoneEvent);
} }
#endif #endif
*/
if (MIDI != NULL) if (MIDI != NULL)
{ {
delete MIDI; delete MIDI;
@ -179,7 +199,7 @@ bool MIDIStreamer::IsMIDI() const
bool MIDIStreamer::IsValid() const bool MIDIStreamer::IsValid() const
{ {
#ifdef _WIN32 #ifdef _WIN32
return ExitEvent != NULL && Division != 0; return /*ExitEvent != NULL &&*/ Division != 0;
#else #else
return Division != 0; return Division != 0;
#endif #endif
@ -264,7 +284,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype) const
{ {
case MDEV_MMAPI: case MDEV_MMAPI:
#ifdef _WIN32 #ifdef _WIN32
return new WinMIDIDevice(mididevice); return CreateWinMIDIDevice(mididevice);
#endif #endif
assert(0); assert(0);
// Intentional fall-through for non-Windows systems. // Intentional fall-through for non-Windows systems.
@ -289,11 +309,11 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype) const
{ {
// The creation of an OPL MIDI device can abort with an error if no GENMIDI lump can be found. // The creation of an OPL MIDI device can abort with an error if no GENMIDI lump can be found.
Printf("Unable to create OPL MIDI device: %s\nFalling back to Sound System playback", err.GetMessage()); Printf("Unable to create OPL MIDI device: %s\nFalling back to Sound System playback", err.GetMessage());
return new SndSysMIDIDevice; return GSnd->CreateMIDIDevice();
} }
case MDEV_TIMIDITY: case MDEV_TIMIDITY:
return new TimidityPPMIDIDevice(Args); return CreateTimidityPPMIDIDevice(Args);
case MDEV_WILDMIDI: case MDEV_WILDMIDI:
return new WildMIDIDevice(Args); return new WildMIDIDevice(Args);
@ -373,6 +393,7 @@ void MIDIStreamer::Play(bool looping, int subsong)
} }
else else
{ {
/*
#ifdef _WIN32 #ifdef _WIN32
if (MIDI->NeedThreadedCallback()) if (MIDI->NeedThreadedCallback())
{ {
@ -389,6 +410,7 @@ void MIDIStreamer::Play(bool looping, int subsong)
} }
else else
#endif #endif
*/
{ {
m_Status = STATE_Playing; m_Status = STATE_Playing;
} }
@ -418,10 +440,12 @@ void MIDIStreamer::StartPlayback()
MusicVolumeChanged(); // set volume to current music's properties MusicVolumeChanged(); // set volume to current music's properties
OutputVolume(Volume); OutputVolume(Volume);
/*
#ifdef _WIN32 #ifdef _WIN32
ResetEvent(ExitEvent); ResetEvent(ExitEvent);
ResetEvent(BufferDoneEvent); ResetEvent(BufferDoneEvent);
#endif #endif
*/
// Fill the initial buffers for the song. // Fill the initial buffers for the song.
BufferNum = 0; BufferNum = 0;
@ -507,6 +531,8 @@ void MIDIStreamer::Resume()
void MIDIStreamer::Stop() void MIDIStreamer::Stop()
{ {
EndQueued = 4; EndQueued = 4;
/*
#ifdef _WIN32 #ifdef _WIN32
if (PlayerThread != NULL) if (PlayerThread != NULL)
{ {
@ -516,6 +542,7 @@ void MIDIStreamer::Stop()
PlayerThread = NULL; PlayerThread = NULL;
} }
#endif #endif
*/
if (MIDI != NULL && MIDI->IsOpen()) if (MIDI != NULL && MIDI->IsOpen())
{ {
MIDI->Stop(); MIDI->Stop();
@ -656,7 +683,7 @@ void MIDIStreamer::WildMidiSetOption(int opt, int set)
// //
//========================================================================== //==========================================================================
void MIDIStreamer::OutputVolume (DWORD volume) void MIDIStreamer::OutputVolume (uint32_t volume)
{ {
if (MIDI != NULL && MIDI->FakeVolume()) if (MIDI != NULL && MIDI->FakeVolume())
{ {
@ -701,6 +728,7 @@ void MIDIStreamer::Callback(void *userdata)
{ {
return; return;
} }
/*
#ifdef _WIN32 #ifdef _WIN32
if (self->PlayerThread != NULL) if (self->PlayerThread != NULL)
{ {
@ -708,6 +736,7 @@ void MIDIStreamer::Callback(void *userdata)
} }
else else
#endif #endif
*/
{ {
self->ServiceEvent(); self->ServiceEvent();
} }
@ -724,6 +753,7 @@ void MIDIStreamer::Callback(void *userdata)
void MIDIStreamer::Update() void MIDIStreamer::Update()
{ {
/*
#ifdef _WIN32 #ifdef _WIN32
// If the PlayerThread is signalled, then it's dead. // If the PlayerThread is signalled, then it's dead.
if (PlayerThread != NULL && if (PlayerThread != NULL &&
@ -785,6 +815,7 @@ void MIDIStreamer::Update()
Stop(); Stop();
} }
#endif #endif
*/
} }
//========================================================================== //==========================================================================
@ -796,9 +827,10 @@ void MIDIStreamer::Update()
//========================================================================== //==========================================================================
#ifdef _WIN32 #ifdef _WIN32
DWORD WINAPI MIDIStreamer::PlayerProc (LPVOID lpParameter) DWORD WINAPI PlayerProc(LPVOID lpParameter)
{ {
return ((MIDIStreamer *)lpParameter)->PlayerLoop(); // return ((MIDIStreamer *)lpParameter)->PlayerLoop();
return 0;
} }
#endif #endif
@ -809,6 +841,7 @@ DWORD WINAPI MIDIStreamer::PlayerProc (LPVOID lpParameter)
// Services MIDI playback events. // Services MIDI playback events.
// //
//========================================================================== //==========================================================================
/*
#ifdef _WIN32 #ifdef _WIN32
DWORD MIDIStreamer::PlayerLoop() DWORD MIDIStreamer::PlayerLoop()
@ -837,8 +870,10 @@ DWORD MIDIStreamer::PlayerLoop()
return MMSYSERR_ERROR; return MMSYSERR_ERROR;
} }
} }
return 0;
} }
#endif #endif
*/
//========================================================================== //==========================================================================
// //
@ -920,7 +955,7 @@ fill:
// //
//========================================================================== //==========================================================================
int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time) int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time)
{ {
if (!Restarting && CheckDone()) if (!Restarting && CheckDone())
{ {
@ -928,9 +963,9 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time)
} }
int i; int i;
DWORD *events = Events[buffer_num], *max_event_p; uint32_t *events = Events[buffer_num], *max_event_p;
DWORD tot_time = 0; uint32_t tot_time = 0;
DWORD time = 0; uint32_t time = 0;
// The final event is for a NOP to hold the delay from the last event. // The final event is for a NOP to hold the delay from the last event.
max_event_p = events + (max_events - 1) * 3; max_event_p = events + (max_events - 1) * 3;
@ -1009,7 +1044,7 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time)
int MIDIStreamer::FillStopBuffer(int buffer_num) int MIDIStreamer::FillStopBuffer(int buffer_num)
{ {
DWORD *events = Events[buffer_num]; uint32_t *events = Events[buffer_num];
int i; int i;
events = WriteStopNotes(events); events = WriteStopNotes(events);
@ -1040,7 +1075,7 @@ int MIDIStreamer::FillStopBuffer(int buffer_num)
// //
//========================================================================== //==========================================================================
DWORD *MIDIStreamer::WriteStopNotes(DWORD *events) uint32_t *MIDIStreamer::WriteStopNotes(uint32_t *events)
{ {
for (int i = 0; i < 16; ++i) for (int i = 0; i < 16; ++i)
{ {
@ -1080,8 +1115,8 @@ void MIDIStreamer::Precache()
// Simulate playback to pick out used instruments. // Simulate playback to pick out used instruments.
while (!CheckDone()) while (!CheckDone())
{ {
DWORD *event_end = MakeEvents(Events[0], &Events[0][MAX_EVENTS*3], 1000000*600); uint32_t *event_end = MakeEvents(Events[0], &Events[0][MAX_EVENTS*3], 1000000*600);
for (DWORD *event = Events[0]; event < event_end; ) for (uint32_t *event = Events[0]; event < event_end; )
{ {
if (MEVENT_EVENTTYPE(event[2]) == 0) if (MEVENT_EVENTTYPE(event[2]) == 0)
{ {
@ -1187,15 +1222,15 @@ void MIDIStreamer::CreateSMF(TArray<uint8_t> &file, int looplimit)
while (!CheckDone()) while (!CheckDone())
{ {
DWORD *event_end = MakeEvents(Events[0], &Events[0][MAX_EVENTS*3], 1000000*600); uint32_t *event_end = MakeEvents(Events[0], &Events[0][MAX_EVENTS*3], 1000000*600);
for (DWORD *event = Events[0]; event < event_end; ) for (uint32_t *event = Events[0]; event < event_end; )
{ {
delay += event[0]; delay += event[0];
if (MEVENT_EVENTTYPE(event[2]) == MEVENT_TEMPO) if (MEVENT_EVENTTYPE(event[2]) == MEVENT_TEMPO)
{ {
WriteVarLen(file, delay); WriteVarLen(file, delay);
delay = 0; delay = 0;
DWORD tempo = MEVENT_EVENTPARM(event[2]); uint32_t tempo = MEVENT_EVENTPARM(event[2]);
file.Push(MIDI_META); file.Push(MIDI_META);
file.Push(MIDI_META_TEMPO); file.Push(MIDI_META_TEMPO);
file.Push(3); file.Push(3);
@ -1208,7 +1243,7 @@ void MIDIStreamer::CreateSMF(TArray<uint8_t> &file, int looplimit)
{ {
WriteVarLen(file, delay); WriteVarLen(file, delay);
delay = 0; delay = 0;
DWORD len = MEVENT_EVENTPARM(event[2]); uint32_t len = MEVENT_EVENTPARM(event[2]);
uint8_t *bytes = (uint8_t *)&event[3]; uint8_t *bytes = (uint8_t *)&event[3];
if (bytes[0] == MIDI_SYSEX) if (bytes[0] == MIDI_SYSEX)
{ {
@ -1398,6 +1433,27 @@ bool MIDIStreamer::SetMIDISubsong(int subsong)
return subsong == 0; return subsong == 0;
} }
//==========================================================================
//
// MIDIStreamer :: CheckExitEvent
//
//
//
//==========================================================================
bool MIDIStreamer::CheckExitEvent()
{
/*
#ifdef _WIN32
if (ExitEvent == NULL)
{
return false;
}
#endif
*/
return true;
}
//========================================================================== //==========================================================================
// //
// MIDIDevice stubs. // MIDIDevice stubs.

View file

@ -96,12 +96,10 @@ static const uint8_t CtrlTranslate[15] =
MUSSong2::MUSSong2 (FileReader &reader, EMidiDevice type, const char *args) MUSSong2::MUSSong2 (FileReader &reader, EMidiDevice type, const char *args)
: MIDIStreamer(type, args), MusHeader(0), MusBuffer(0) : MIDIStreamer(type, args), MusHeader(0), MusBuffer(0)
{ {
#ifdef _WIN32 if (!CheckExitEvent())
if (ExitEvent == NULL)
{ {
return; return;
} }
#endif
uint8_t front[32]; uint8_t front[32];
int start; int start;
@ -260,10 +258,10 @@ void MUSSong2::Precache()
// //
//========================================================================== //==========================================================================
DWORD *MUSSong2::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) uint32_t *MUSSong2::MakeEvents(uint32_t *events, uint32_t *max_event_p, uint32_t max_time)
{ {
DWORD tot_time = 0; uint32_t tot_time = 0;
DWORD time = 0; uint32_t time = 0;
max_time = max_time * Division / Tempo; max_time = max_time * Division / Tempo;

View file

@ -60,8 +60,8 @@ struct MIDISong2::TrackInfo
const uint8_t *TrackBegin; const uint8_t *TrackBegin;
size_t TrackP; size_t TrackP;
size_t MaxTrackP; size_t MaxTrackP;
DWORD Delay; uint32_t Delay;
DWORD PlayedTime; uint32_t PlayedTime;
bool Finished; bool Finished;
uint8_t RunningStatus; uint8_t RunningStatus;
bool Designated; bool Designated;
@ -70,11 +70,11 @@ struct MIDISong2::TrackInfo
uint16_t Designation; uint16_t Designation;
size_t LoopBegin; size_t LoopBegin;
DWORD LoopDelay; uint32_t LoopDelay;
int LoopCount; int LoopCount;
bool LoopFinished; bool LoopFinished;
DWORD ReadVarLen (); uint32_t ReadVarLen ();
}; };
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
@ -108,12 +108,10 @@ MIDISong2::MIDISong2 (FileReader &reader, EMidiDevice type, const char *args)
int p; int p;
int i; int i;
#ifdef _WIN32 if (!CheckExitEvent())
if (ExitEvent == NULL)
{ {
return; return;
} }
#endif
SongLen = reader.GetLength(); SongLen = reader.GetLength();
MusHeader = new uint8_t[SongLen]; MusHeader = new uint8_t[SongLen];
if (reader.Read(MusHeader, SongLen) != SongLen) if (reader.Read(MusHeader, SongLen) != SongLen)
@ -149,13 +147,13 @@ MIDISong2::MIDISong2 (FileReader &reader, EMidiDevice type, const char *args)
// Gather information about each track // Gather information about each track
for (i = 0, p = 14; i < NumTracks && p < SongLen + 8; ++i) for (i = 0, p = 14; i < NumTracks && p < SongLen + 8; ++i)
{ {
DWORD chunkLen = uint32_t chunkLen =
(MusHeader[p+4]<<24) | (MusHeader[p+4]<<24) |
(MusHeader[p+5]<<16) | (MusHeader[p+5]<<16) |
(MusHeader[p+6]<<8) | (MusHeader[p+6]<<8) |
(MusHeader[p+7]); (MusHeader[p+7]);
if (chunkLen + p + 8 > (DWORD)SongLen) if (chunkLen + p + 8 > (uint32_t)SongLen)
{ // Track too long, so truncate it { // Track too long, so truncate it
chunkLen = SongLen - p - 8; chunkLen = SongLen - p - 8;
} }
@ -298,12 +296,12 @@ bool MIDISong2::CheckDone()
// //
//========================================================================== //==========================================================================
DWORD *MIDISong2::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) uint32_t *MIDISong2::MakeEvents(uint32_t *events, uint32_t *max_event_p, uint32_t max_time)
{ {
DWORD *start_events; uint32_t *start_events;
DWORD tot_time = 0; uint32_t tot_time = 0;
DWORD time = 0; uint32_t time = 0;
DWORD delay; uint32_t delay;
start_events = events; start_events = events;
while (TrackDue && events < max_event_p && tot_time <= max_time) while (TrackDue && events < max_event_p && tot_time <= max_time)
@ -323,7 +321,7 @@ DWORD *MIDISong2::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time)
do do
{ {
bool sysex_noroom = false; bool sysex_noroom = false;
DWORD *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom); uint32_t *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom);
if (sysex_noroom) if (sysex_noroom)
{ {
return events; return events;
@ -351,7 +349,7 @@ DWORD *MIDISong2::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time)
// //
//========================================================================== //==========================================================================
void MIDISong2::AdvanceTracks(DWORD time) void MIDISong2::AdvanceTracks(uint32_t time)
{ {
for (int i = 0; i < NumTracks; ++i) for (int i = 0; i < NumTracks; ++i)
{ {
@ -371,9 +369,9 @@ void MIDISong2::AdvanceTracks(DWORD time)
// //
//========================================================================== //==========================================================================
DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom) uint32_t *MIDISong2::SendCommand (uint32_t *events, TrackInfo *track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom)
{ {
DWORD len; uint32_t len;
uint8_t event, data1 = 0, data2 = 0; uint8_t event, data1 = 0, data2 = 0;
int i; int i;
@ -456,7 +454,7 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
case 110: // EMIDI Track Designation - InitBeat only case 110: // EMIDI Track Designation - InitBeat only
// Instruments 4, 5, 6, and 7 are all FM synth. // Instruments 4, 5, 6, and 7 are all FM synth.
// The rest are all wavetable. // The rest are all wavetable.
if (track->PlayedTime < (DWORD)Division) if (track->PlayedTime < (uint32_t)Division)
{ {
if (data2 == 127) if (data2 == 127)
{ {
@ -473,7 +471,7 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
break; break;
case 111: // EMIDI Track Exclusion - InitBeat only case 111: // EMIDI Track Exclusion - InitBeat only
if (track->PlayedTime < (DWORD)Division) if (track->PlayedTime < (uint32_t)Division)
{ {
if (track->Designated && data2 <= 9) if (track->Designated && data2 <= 9)
{ {
@ -485,7 +483,7 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
case 112: // EMIDI Program Change case 112: // EMIDI Program Change
// Ignored unless it also appears in the InitBeat // Ignored unless it also appears in the InitBeat
if (track->PlayedTime < (DWORD)Division || track->EProgramChange) if (track->PlayedTime < (uint32_t)Division || track->EProgramChange)
{ {
track->EProgramChange = true; track->EProgramChange = true;
event = 0xC0 | (event & 0x0F); event = 0xC0 | (event & 0x0F);
@ -496,7 +494,7 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
case 113: // EMIDI Volume case 113: // EMIDI Volume
// Ignored unless it also appears in the InitBeat // Ignored unless it also appears in the InitBeat
if (track->PlayedTime < (DWORD)Division || track->EVolume) if (track->PlayedTime < (uint32_t)Division || track->EVolume)
{ {
track->EVolume = true; track->EVolume = true;
data1 = 7; data1 = 7;
@ -700,7 +698,7 @@ void MIDISong2::ProcessInitialMetaEvents ()
TrackInfo *track; TrackInfo *track;
int i; int i;
uint8_t event; uint8_t event;
DWORD len; uint32_t len;
for (i = 0; i < NumTracks; ++i) for (i = 0; i < NumTracks; ++i)
{ {
@ -747,9 +745,9 @@ void MIDISong2::ProcessInitialMetaEvents ()
// //
//========================================================================== //==========================================================================
DWORD MIDISong2::TrackInfo::ReadVarLen () uint32_t MIDISong2::TrackInfo::ReadVarLen ()
{ {
DWORD time = 0, t = 0x80; uint32_t time = 0, t = 0x80;
while ((t & 0x80) && TrackP < MaxTrackP) while ((t & 0x80) && TrackP < MaxTrackP)
{ {
@ -771,7 +769,7 @@ DWORD MIDISong2::TrackInfo::ReadVarLen ()
MIDISong2::TrackInfo *MIDISong2::FindNextDue () MIDISong2::TrackInfo *MIDISong2::FindNextDue ()
{ {
TrackInfo *track; TrackInfo *track;
DWORD best; uint32_t best;
int i; int i;
// Give precedence to whichever track last had events taken from it. // Give precedence to whichever track last had events taken from it.

View file

@ -34,6 +34,8 @@
// HEADER FILES ------------------------------------------------------------ // HEADER FILES ------------------------------------------------------------
#include "i_midi_win32.h"
#include "i_musicinterns.h" #include "i_musicinterns.h"
#include "templates.h" #include "templates.h"
#include "doomdef.h" #include "doomdef.h"
@ -46,21 +48,22 @@
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
// TYPES ------------------------------------------------------------------- // TYPES -------------------------------------------------------------------
// MIDI file played with TiMidity++ and possibly streamed through the Sound System
struct FmtChunk struct FmtChunk
{ {
DWORD ChunkID; uint32_t ChunkID;
DWORD ChunkLen; uint32_t ChunkLen;
uint16_t FormatTag; uint16_t FormatTag;
uint16_t Channels; uint16_t Channels;
DWORD SamplesPerSec; uint32_t SamplesPerSec;
DWORD AvgBytesPerSec; uint32_t AvgBytesPerSec;
uint16_t BlockAlign; uint16_t BlockAlign;
uint16_t BitsPerSample; uint16_t BitsPerSample;
uint16_t ExtensionSize; uint16_t ExtensionSize;
uint16_t ValidBitsPerSample; uint16_t ValidBitsPerSample;
DWORD ChannelMask; uint32_t ChannelMask;
DWORD SubFormatA; uint32_t SubFormatA;
uint16_t SubFormatB; uint16_t SubFormatB;
uint16_t SubFormatC; uint16_t SubFormatC;
uint8_t SubFormatD[8]; uint8_t SubFormatD[8];
@ -250,7 +253,7 @@ TimidityWaveWriterMIDIDevice::TimidityWaveWriterMIDIDevice(const char *filename,
File = fopen(filename, "wb"); File = fopen(filename, "wb");
if (File != NULL) if (File != NULL)
{ // Write wave header { // Write wave header
DWORD work[3]; uint32_t work[3];
FmtChunk fmt; FmtChunk fmt;
work[0] = MAKE_ID('R','I','F','F'); work[0] = MAKE_ID('R','I','F','F');
@ -259,7 +262,7 @@ TimidityWaveWriterMIDIDevice::TimidityWaveWriterMIDIDevice(const char *filename,
if (3 != fwrite(work, 4, 3, File)) goto fail; if (3 != fwrite(work, 4, 3, File)) goto fail;
fmt.ChunkID = MAKE_ID('f','m','t',' '); fmt.ChunkID = MAKE_ID('f','m','t',' ');
fmt.ChunkLen = LittleLong(DWORD(sizeof(fmt) - 8)); fmt.ChunkLen = LittleLong(uint32_t(sizeof(fmt) - 8));
fmt.FormatTag = LittleShort(0xFFFE); // WAVE_FORMAT_EXTENSIBLE fmt.FormatTag = LittleShort(0xFFFE); // WAVE_FORMAT_EXTENSIBLE
fmt.Channels = LittleShort(2); fmt.Channels = LittleShort(2);
fmt.SamplesPerSec = LittleLong((int)Renderer->rate); fmt.SamplesPerSec = LittleLong((int)Renderer->rate);
@ -305,15 +308,15 @@ TimidityWaveWriterMIDIDevice::~TimidityWaveWriterMIDIDevice()
if (File != NULL) if (File != NULL)
{ {
long pos = ftell(File); long pos = ftell(File);
DWORD size; uint32_t size;
// data chunk size // data chunk size
size = LittleLong(DWORD(pos - 8)); size = LittleLong(uint32_t(pos - 8));
if (0 == fseek(File, 4, SEEK_SET)) if (0 == fseek(File, 4, SEEK_SET))
{ {
if (1 == fwrite(&size, 4, 1, File)) if (1 == fwrite(&size, 4, 1, File))
{ {
size = LittleLong(DWORD(pos - 12 - sizeof(FmtChunk) - 8)); size = LittleLong(uint32_t(pos - 12 - sizeof(FmtChunk) - 8));
if (0 == fseek(File, 4 + sizeof(FmtChunk) + 4, SEEK_CUR)) if (0 == fseek(File, 4 + sizeof(FmtChunk) + 4, SEEK_CUR))
{ {
if (1 == fwrite(&size, 4, 1, File)) if (1 == fwrite(&size, 4, 1, File))

View file

@ -34,6 +34,20 @@
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define USE_WINDOWS_DWORD
#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0400
#undef _WIN32_WINNT
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#ifndef USE_WINDOWS_DWORD
#define USE_WINDOWS_DWORD
#endif
#include <windows.h>
#include <mmsystem.h>
// HEADER FILES ------------------------------------------------------------ // HEADER FILES ------------------------------------------------------------
#include "i_musicinterns.h" #include "i_musicinterns.h"
@ -58,6 +72,43 @@ static bool IgnoreMIDIVolume(UINT id);
// EXTERNAL DATA DECLARATIONS ---------------------------------------------- // EXTERNAL DATA DECLARATIONS ----------------------------------------------
// PRIVATE DATA DEFINITIONS ------------------------------------------------ // PRIVATE DATA DEFINITIONS ------------------------------------------------
// WinMM implementation of a MIDI output device -----------------------------
class WinMIDIDevice : public MIDIDevice
{
public:
WinMIDIDevice(int dev_id);
~WinMIDIDevice();
int Open(MidiCallback, void *userdata);
void Close();
bool IsOpen() const;
int GetTechnology() const;
int SetTempo(int tempo);
int SetTimeDiv(int timediv);
int StreamOut(MidiHeader *data);
int StreamOutSync(MidiHeader *data);
int Resume();
void Stop();
int PrepareHeader(MidiHeader *data);
int UnprepareHeader(MidiHeader *data);
bool FakeVolume();
bool NeedThreadedCallback();
bool Pause(bool paused);
void PrecacheInstruments(const uint16_t *instruments, int count);
protected:
static void CALLBACK CallbackFunc(HMIDIOUT, UINT, DWORD_PTR, DWORD, DWORD);
HMIDISTRM MidiOut;
UINT DeviceID;
DWORD SavedVolume;
MIDIHDR WinMidiHeaders[2];
int HeaderIndex;
bool VolumeWorks;
MidiCallback Callback;
void *CallbackData;
};
// PUBLIC DATA DEFINITIONS ------------------------------------------------- // PUBLIC DATA DEFINITIONS -------------------------------------------------
@ -487,4 +538,10 @@ static bool IgnoreMIDIVolume(UINT id)
return false; return false;
} }
MIDIDevice *CreateWinMIDIDevice(int mididevice)
{
return new WinMIDIDevice(mididevice);
}
#endif #endif

View file

@ -72,15 +72,15 @@ struct XMISong::TrackInfo
const uint8_t *TimbreChunk; const uint8_t *TimbreChunk;
size_t TimbreLen; size_t TimbreLen;
DWORD Delay; uint32_t Delay;
DWORD PlayedTime; uint32_t PlayedTime;
bool Finished; bool Finished;
LoopInfo ForLoops[MAX_FOR_DEPTH]; LoopInfo ForLoops[MAX_FOR_DEPTH];
int ForDepth; int ForDepth;
DWORD ReadVarLen(); uint32_t ReadVarLen();
DWORD ReadDelay(); uint32_t ReadDelay();
}; };
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
@ -111,12 +111,10 @@ extern char MIDI_CommonLengths[15];
XMISong::XMISong (FileReader &reader, EMidiDevice type, const char *args) XMISong::XMISong (FileReader &reader, EMidiDevice type, const char *args)
: MIDIStreamer(type, args), MusHeader(0), Songs(0) : MIDIStreamer(type, args), MusHeader(0), Songs(0)
{ {
#ifdef _WIN32 if (!CheckExitEvent())
if (ExitEvent == NULL)
{ {
return; return;
} }
#endif
SongLen = reader.GetLength(); SongLen = reader.GetLength();
MusHeader = new uint8_t[SongLen]; MusHeader = new uint8_t[SongLen];
if (reader.Read(MusHeader, SongLen) != SongLen) if (reader.Read(MusHeader, SongLen) != SongLen)
@ -313,12 +311,12 @@ bool XMISong::CheckDone()
// //
//========================================================================== //==========================================================================
DWORD *XMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) uint32_t *XMISong::MakeEvents(uint32_t *events, uint32_t *max_event_p, uint32_t max_time)
{ {
DWORD *start_events; uint32_t *start_events;
DWORD tot_time = 0; uint32_t tot_time = 0;
DWORD time = 0; uint32_t time = 0;
DWORD delay; uint32_t delay;
start_events = events; start_events = events;
while (EventDue != EVENT_None && events < max_event_p && tot_time <= max_time) while (EventDue != EVENT_None && events < max_event_p && tot_time <= max_time)
@ -338,7 +336,7 @@ DWORD *XMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time)
do do
{ {
bool sysex_noroom = false; bool sysex_noroom = false;
DWORD *new_events = SendCommand(events, EventDue, time, max_event_p - events, sysex_noroom); uint32_t *new_events = SendCommand(events, EventDue, time, max_event_p - events, sysex_noroom);
if (sysex_noroom) if (sysex_noroom)
{ {
return events; return events;
@ -366,7 +364,7 @@ DWORD *XMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time)
// //
//========================================================================== //==========================================================================
void XMISong::AdvanceSong(DWORD time) void XMISong::AdvanceSong(uint32_t time)
{ {
if (time != 0) if (time != 0)
{ {
@ -387,9 +385,9 @@ void XMISong::AdvanceSong(DWORD time)
// //
//========================================================================== //==========================================================================
DWORD *XMISong::SendCommand (DWORD *events, EventSource due, DWORD delay, ptrdiff_t room, bool &sysex_noroom) uint32_t *XMISong::SendCommand (uint32_t *events, EventSource due, uint32_t delay, ptrdiff_t room, bool &sysex_noroom)
{ {
DWORD len; uint32_t len;
uint8_t event, data1 = 0, data2 = 0; uint8_t event, data1 = 0, data2 = 0;
if (due == EVENT_Fake) if (due == EVENT_Fake)
@ -617,7 +615,7 @@ void XMISong::ProcessInitialMetaEvents ()
{ {
TrackInfo *track = CurrSong; TrackInfo *track = CurrSong;
uint8_t event; uint8_t event;
DWORD len; uint32_t len;
while (!track->Finished && while (!track->Finished &&
track->EventP < track->EventLen - 3 && track->EventP < track->EventLen - 3 &&
@ -646,9 +644,9 @@ void XMISong::ProcessInitialMetaEvents ()
// //
//========================================================================== //==========================================================================
DWORD XMISong::TrackInfo::ReadVarLen() uint32_t XMISong::TrackInfo::ReadVarLen()
{ {
DWORD time = 0, t = 0x80; uint32_t time = 0, t = 0x80;
while ((t & 0x80) && EventP < EventLen) while ((t & 0x80) && EventP < EventLen)
{ {
@ -667,9 +665,9 @@ DWORD XMISong::TrackInfo::ReadVarLen()
// //
//========================================================================== //==========================================================================
DWORD XMISong::TrackInfo::ReadDelay() uint32_t XMISong::TrackInfo::ReadDelay()
{ {
DWORD time = 0, t; uint32_t time = 0, t;
while (EventP < EventLen && !((t = EventChunk[EventP]) & 0x80)) while (EventP < EventLen && !((t = EventChunk[EventP]) & 0x80))
{ {
@ -697,8 +695,8 @@ XMISong::EventSource XMISong::FindNextDue()
} }
// Which is due sooner? The current song or the note-offs? // Which is due sooner? The current song or the note-offs?
DWORD real_delay = CurrSong->Finished ? 0xFFFFFFFF : CurrSong->Delay; uint32_t real_delay = CurrSong->Finished ? 0xFFFFFFFF : CurrSong->Delay;
DWORD fake_delay = NoteOffs.Size() == 0 ? 0xFFFFFFFF : NoteOffs[0].Delay; uint32_t fake_delay = NoteOffs.Size() == 0 ? 0xFFFFFFFF : NoteOffs[0].Delay;
return (fake_delay <= real_delay) ? EVENT_Fake : EVENT_Real; return (fake_delay <= real_delay) ? EVENT_Fake : EVENT_Real;
} }

View file

@ -2055,10 +2055,10 @@ void OpenALSoundRenderer::PrintDriversList()
MIDIDevice* OpenALSoundRenderer::CreateMIDIDevice() const MIDIDevice* OpenALSoundRenderer::CreateMIDIDevice() const
{ {
#ifdef _WIN32 #ifdef _WIN32
extern UINT mididevice; extern unsigned mididevice;
return new WinMIDIDevice(mididevice); return CreateWinMIDIDevice(mididevice);
#elif defined __APPLE__ #elif defined __APPLE__
return new AudioToolboxMIDIDevice; return CreateAudioToolboxMIDIDevice;
#else #else
return new OPLMIDIDevice(nullptr); return new OPLMIDIDevice(nullptr);
#endif #endif

View file

@ -1,22 +1,19 @@
// Wraps a Windows critical section object. // Wraps a Windows critical section object.
#ifndef CRITSEC_H
#define CRITSEC_H
#ifndef _WINNT_ #ifndef _WINNT_
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#define USE_WINDOWS_DWORD #define USE_WINDOWS_DWORD
#endif #endif
class FCriticalSection class FInternalCriticalSection
{ {
public: public:
FCriticalSection() FInternalCriticalSection()
{ {
InitializeCriticalSection(&CritSec); InitializeCriticalSection(&CritSec);
} }
~FCriticalSection() ~FInternalCriticalSection()
{ {
DeleteCriticalSection(&CritSec); DeleteCriticalSection(&CritSec);
} }
@ -39,4 +36,23 @@ private:
CRITICAL_SECTION CritSec; CRITICAL_SECTION CritSec;
}; };
#endif
FInternalCriticalSection *CreateCriticalSection()
{
return new FInternalCriticalSection();
}
void DeleteCriticalSection(FInternalCriticalSection *c)
{
delete c;
}
void EnterCriticalSection(FInternalCriticalSection *c)
{
c->Enter();
}
void LeaveCriticalSection(FInternalCriticalSection *c)
{
c->Leave();
}

View file

@ -175,10 +175,10 @@ FString I_GetLongPathName(FString shortpath);
struct findstate_t struct findstate_t
{ {
DWORD Attribs; uint32_t Attribs;
DWORD Times[3*2]; uint32_t Times[3*2];
DWORD Size[2]; uint32_t Size[2];
DWORD Reserved[2]; uint32_t Reserved[2];
char Name[MAX_PATH]; char Name[MAX_PATH];
char AltName[14]; char AltName[14];
}; };