300 lines
8.7 KiB
C++
300 lines
8.7 KiB
C++
// Copyright (c) 1998-1999 Microsoft Corporation
|
|
/*
|
|
* Internal function prototypes for DMusic32.dll
|
|
*/
|
|
#ifndef _DM32P_
|
|
#define _DM32P_
|
|
|
|
#include "..\shared\dmusiccp.h"
|
|
#include "tpool.h"
|
|
|
|
#define THREAD_KILL_TIMEOUT 5000
|
|
#define THREAD_WORK_BUFFER_SIZE 4096
|
|
|
|
#define QWORD_ALIGN(x) (((x) + 7) & ~7)
|
|
|
|
#define MIDI_CHANNELS 16
|
|
|
|
/* DevIoctl.c - MMDEVLDR hooks we use
|
|
*/
|
|
extern BOOL WINAPI OpenMMDEVLDR(void);
|
|
extern VOID WINAPI CloseMMDEVLDR(void);
|
|
extern VOID WINAPI CloseVxDHandle(DWORD hVxDHandle);
|
|
|
|
/* From Win32 kernel
|
|
*/
|
|
extern "C" DWORD WINAPI OpenVxDHandle(HANDLE hEvent);
|
|
|
|
// 10 ms in 100ns units
|
|
//
|
|
#define FIXED_LEGACY_LATENCY_OFFSET (10L * 10L * 1000L)
|
|
|
|
class CEmulateLatencyClock : public IReferenceClock
|
|
{
|
|
public:
|
|
// IUnknown
|
|
//
|
|
STDMETHODIMP QueryInterface(const IID &iid, void **ppv);
|
|
STDMETHODIMP_(ULONG) AddRef();
|
|
STDMETHODIMP_(ULONG) Release();
|
|
|
|
// IReferenceClock
|
|
//
|
|
STDMETHODIMP GetTime(REFERENCE_TIME *pTime);
|
|
STDMETHODIMP AdviseTime(REFERENCE_TIME baseTime,
|
|
REFERENCE_TIME streamTime,
|
|
HANDLE hEvent,
|
|
DWORD * pdwAdviseCookie);
|
|
|
|
STDMETHODIMP AdvisePeriodic(REFERENCE_TIME startTime,
|
|
REFERENCE_TIME periodTime,
|
|
HANDLE hSemaphore,
|
|
DWORD * pdwAdviseCookie);
|
|
|
|
STDMETHODIMP Unadvise(DWORD dwAdviseCookie);
|
|
|
|
// Class
|
|
//
|
|
CEmulateLatencyClock(IReferenceClock *pMasterClock);
|
|
~CEmulateLatencyClock();
|
|
|
|
void Close();
|
|
|
|
private:
|
|
long m_cRef;
|
|
IReferenceClock *m_pMasterClock;
|
|
};
|
|
|
|
// Struct for holding a property item supported by the synth
|
|
//
|
|
|
|
class CDirectMusicEmulatePort;
|
|
|
|
typedef HRESULT (CDirectMusicEmulatePort::*GENPROPHANDLER)(ULONG ulId, BOOL fSet, LPVOID pbBuffer, PULONG cbBuffer);
|
|
|
|
#define GENPROP_F_STATIC 0x00000000
|
|
#define GENPROP_F_FNHANDLER 0x00000001
|
|
|
|
|
|
struct GENERICPROPERTY
|
|
{
|
|
const GUID *pguidPropertySet; // What property set?
|
|
ULONG ulId; // What item?
|
|
|
|
ULONG ulSupported; // Get/Set flags for QuerySupported
|
|
|
|
ULONG ulFlags; // GENPROP_F_xxx
|
|
|
|
LPVOID pPropertyData; // Data to be returned
|
|
ULONG cbPropertyData; // and its size
|
|
|
|
GENPROPHANDLER pfnHandler; // Handler fn iff GENPROP_F_FNHANDLER
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CDirectMusicEmulatePort :
|
|
public IDirectMusicPort,
|
|
public IDirectMusicPortP,
|
|
public IDirectMusicThru,
|
|
public IDirectMusicPortPrivate,
|
|
public IKsControl
|
|
{
|
|
public:
|
|
// IUnknown
|
|
//
|
|
STDMETHODIMP QueryInterface(const IID &iid, void **ppv);
|
|
STDMETHODIMP_(ULONG) AddRef();
|
|
STDMETHODIMP_(ULONG) Release();
|
|
|
|
// IDirectMusicPort
|
|
//
|
|
STDMETHODIMP PlayBuffer(LPDIRECTMUSICBUFFER pBuffer);
|
|
STDMETHODIMP SetReadNotificationHandle(HANDLE hEvent);
|
|
STDMETHODIMP Read(LPDIRECTMUSICBUFFER pBuffer);
|
|
STDMETHODIMP DownloadInstrument(IDirectMusicInstrument*,
|
|
IDirectMusicDownloadedInstrument**,
|
|
DMUS_NOTERANGE*,
|
|
DWORD);
|
|
STDMETHODIMP UnloadInstrument(IDirectMusicDownloadedInstrument*);
|
|
|
|
STDMETHODIMP GetLatencyClock(IReferenceClock **ppClock);
|
|
STDMETHODIMP GetRunningStats(LPDMUS_SYNTHSTATS pStats);
|
|
STDMETHODIMP Compact();
|
|
STDMETHODIMP GetCaps(LPDMUS_PORTCAPS pPortCaps);
|
|
STDMETHODIMP DeviceIoControl(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
|
|
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
|
|
STDMETHODIMP SetNumChannelGroups(DWORD dwNumChannelGroups);
|
|
STDMETHODIMP GetNumChannelGroups(LPDWORD pdwNumChannelGroups);
|
|
STDMETHODIMP Activate(BOOL fActivate);
|
|
STDMETHODIMP SetChannelPriority(DWORD dwChannelGroup, DWORD dwChannel, DWORD dwPriority);
|
|
STDMETHODIMP GetChannelPriority(DWORD dwChannelGroup, DWORD dwChannel, LPDWORD pdwPriority);
|
|
STDMETHODIMP SetDirectSound(LPDIRECTSOUND pDirectSound, LPDIRECTSOUNDBUFFER pDirectSoundBuffer);
|
|
STDMETHODIMP GetFormat(LPWAVEFORMATEX pWaveFormatEx, LPDWORD pdwWaveFormatExSize, LPDWORD pdwBufferSize);
|
|
|
|
// IDirectMusicThru
|
|
STDMETHODIMP ThruChannel(DWORD dwSourceChannelGroup,
|
|
DWORD dwSourceChannel,
|
|
DWORD dwDestinationChannelGroup,
|
|
DWORD dwDestinationChannel,
|
|
LPDIRECTMUSICPORT pDestinationPort);
|
|
|
|
// IDirectMusicPortP
|
|
//
|
|
STDMETHODIMP DownloadWave(
|
|
IN IDirectSoundWave *pWave,
|
|
OUT IDirectSoundDownloadedWaveP **ppWave,
|
|
IN REFERENCE_TIME rtStartHint
|
|
);
|
|
|
|
STDMETHODIMP UnloadWave(
|
|
IN IDirectSoundDownloadedWaveP *pWave
|
|
);
|
|
|
|
STDMETHODIMP AllocVoice(
|
|
IN IDirectSoundDownloadedWaveP *pWave,
|
|
IN DWORD dwChannel,
|
|
IN DWORD dwChannelGroup,
|
|
IN REFERENCE_TIME rtStart,
|
|
IN SAMPLE_TIME stLoopStart,
|
|
IN SAMPLE_TIME stLoopEnd,
|
|
OUT IDirectMusicVoiceP **ppVoice
|
|
);
|
|
|
|
STDMETHODIMP AssignChannelToBuses(
|
|
IN DWORD dwChannelGroup,
|
|
IN DWORD dwChannel,
|
|
IN LPDWORD pdwBuses,
|
|
IN DWORD cBusCount
|
|
);
|
|
|
|
STDMETHODIMP SetSink(
|
|
IN IDirectSoundConnect *pSinkConnect
|
|
);
|
|
|
|
STDMETHODIMP GetSink(
|
|
IN IDirectSoundConnect **ppSinkConnect
|
|
);
|
|
|
|
// IKsControl
|
|
STDMETHODIMP KsProperty(
|
|
IN PKSPROPERTY Property,
|
|
IN ULONG PropertyLength,
|
|
IN OUT LPVOID PropertyData,
|
|
IN ULONG DataLength,
|
|
OUT PULONG BytesReturned
|
|
);
|
|
|
|
STDMETHODIMP KsMethod(
|
|
IN PKSMETHOD Method,
|
|
IN ULONG MethodLength,
|
|
IN OUT LPVOID MethodData,
|
|
IN ULONG DataLength,
|
|
OUT PULONG BytesReturned
|
|
);
|
|
|
|
STDMETHODIMP KsEvent(
|
|
IN PKSEVENT Event,
|
|
IN ULONG EventLength,
|
|
IN OUT LPVOID EventData,
|
|
IN ULONG DataLength,
|
|
OUT PULONG BytesReturned
|
|
);
|
|
|
|
// IDirectMusicPortPrivate
|
|
STDMETHODIMP Close();
|
|
STDMETHODIMP Report();
|
|
STDMETHODIMP StartVoice(
|
|
DWORD dwVoiceId,
|
|
DWORD dwChannel,
|
|
DWORD dwChannelGroup,
|
|
REFERENCE_TIME rtStart,
|
|
DWORD dwDLId,
|
|
LONG prPitch,
|
|
LONG veVolume,
|
|
SAMPLE_TIME stVoiceStart,
|
|
SAMPLE_TIME stLoopStart,
|
|
SAMPLE_TIME stLoopEnd
|
|
);
|
|
|
|
STDMETHODIMP StopVoice(
|
|
DWORD dwVoiceID,
|
|
REFERENCE_TIME rtStop
|
|
);
|
|
|
|
STDMETHODIMP GetVoiceState(
|
|
DWORD dwVoice[],
|
|
DWORD cbVoice,
|
|
DMUS_VOICE_STATE VoiceState[]
|
|
);
|
|
|
|
STDMETHODIMP Refresh(
|
|
DWORD dwDownloadID,
|
|
DWORD dwFlags
|
|
);
|
|
|
|
// Class
|
|
//
|
|
CDirectMusicEmulatePort(PORTENTRY *pPE, CDirectMusic *pDM);
|
|
~CDirectMusicEmulatePort();
|
|
HRESULT Init(LPDMUS_PORTPARAMS pPortParams);
|
|
|
|
HRESULT LegacyCaps(ULONG ulId, BOOL fSet, LPVOID pbBuffer, PULONG cbBuffer);
|
|
|
|
DWORD InputWorker();
|
|
DWORD TimerWorker();
|
|
|
|
|
|
|
|
private:
|
|
long m_cRef;
|
|
UINT m_id;
|
|
BOOL m_fIsOutput;
|
|
HANDLE m_hDevice;
|
|
CDirectMusic *m_pDM;
|
|
DWORD m_hVxDEvent;
|
|
DMUS_PORTCAPS dmpc;
|
|
IReferenceClock *m_pMasterClock;
|
|
CEmulateLatencyClock *m_pLatencyClock;
|
|
IDirectMusicPortNotify *m_pNotify;
|
|
|
|
HANDLE m_hAppEvent;
|
|
HANDLE m_hDataReady;
|
|
HANDLE m_hKillThreads;
|
|
HANDLE m_hCaptureThread;
|
|
BYTE m_WorkBuffer[THREAD_WORK_BUFFER_SIZE];
|
|
DWORD m_dwWorkBufferTileInfo;
|
|
DWORD m_p1616WorkBuffer;
|
|
EVENT_POOL m_FreeEvents;
|
|
EVENT_QUEUE m_ReadEvents;
|
|
CRITICAL_SECTION m_csEventQueues;
|
|
BOOL m_fCSInitialized;
|
|
|
|
IDirectMusicBuffer *m_pThruBuffer;
|
|
LPDMUS_THRU_CHANNEL m_pThruMap;
|
|
|
|
long m_lActivated;
|
|
|
|
BOOL m_fSyncToMaster;
|
|
LONGLONG m_lTimeOffset;
|
|
|
|
private:
|
|
static GENERICPROPERTY m_aProperty[];
|
|
static const int m_nProperty;
|
|
static GENERICPROPERTY *FindPropertyItem(REFGUID rguid, ULONG ulId);
|
|
|
|
private:
|
|
HRESULT InitializeClock();
|
|
HRESULT InitializeCapture();
|
|
void InputWorkerDataReady();
|
|
void ThruEvent(DMEVENT *pEvent);
|
|
void MasterToSlave(REFERENCE_TIME *prt);
|
|
void SlaveToMaster(REFERENCE_TIME *prt);
|
|
void SyncClocks();
|
|
};
|
|
|
|
#endif
|