aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_midi/fakedsound.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/Input/in_midi/fakedsound.cpp')
-rw-r--r--Src/Plugins/Input/in_midi/fakedsound.cpp244
1 files changed, 244 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_midi/fakedsound.cpp b/Src/Plugins/Input/in_midi/fakedsound.cpp
new file mode 100644
index 00000000..4332f757
--- /dev/null
+++ b/Src/Plugins/Input/in_midi/fakedsound.cpp
@@ -0,0 +1,244 @@
+#include "main.h"
+#include "fakedsound.h"
+
+//DirectMusic output capture hack.
+
+class FakeDirectSoundBuffer : public IDirectSoundBuffer
+{
+private:
+ ULONG ref;
+ CPipe* out;
+ UINT freq;
+ BYTE * buf;
+ UINT buf_size;
+
+ bool playing;
+ DWORD pos_play;
+
+ DWORD samples_played;
+ DWORD start;
+
+ void do_update();
+
+public:
+ ~FakeDirectSoundBuffer()
+ {
+ if (buf) free(buf);
+ };
+
+ HRESULT _stdcall QueryInterface(REFIID iid, void** i)
+ {
+ if (IsEqualIID(iid,IID_IUnknown) || IsEqualIID(iid,IID_IDirectSoundBuffer))
+ {
+ ref++;
+ *i = this;
+ return S_OK;
+ }
+ else return E_NOINTERFACE;
+ }
+
+ ULONG _stdcall AddRef() {return ++ref;};
+ ULONG _stdcall Release()
+ {
+ UINT r=--ref;
+ if (!r)
+ {
+ delete this;
+ }
+ return r;
+ }
+ HRESULT _stdcall GetCaps(LPDSBCAPS _caps)
+ {
+ DSBCAPS caps=
+ {
+ sizeof(DSBCAPS),
+ DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_LOCSOFTWARE,
+ buf_size,
+ 0,0 //CPU crap
+ };
+ *_caps = caps;
+ return S_OK;
+ }
+ HRESULT _stdcall Initialize(LPDIRECTSOUND, LPCDSBUFFERDESC) {return DSERR_ALREADYINITIALIZED;}
+ HRESULT _stdcall SetFormat(LPCWAVEFORMATEX) {return DSERR_INVALIDCALL;}
+ HRESULT _stdcall GetFormat(LPWAVEFORMATEX wfx,DWORD,LPDWORD w)
+ {
+ wfx->wFormatTag=WAVE_FORMAT_PCM;
+ wfx->nChannels=2;
+ wfx->nSamplesPerSec=freq;
+ wfx->nAvgBytesPerSec=4*freq;
+ wfx->nBlockAlign=4;
+ wfx->wBitsPerSample=16;
+ wfx->cbSize=0;
+ if (w) *w=sizeof(WAVEFORMATEX);
+ return S_OK;
+ }
+
+ HRESULT _stdcall GetVolume(long* v) {return S_OK;}
+ HRESULT _stdcall SetVolume(long v) {return S_OK;}
+ HRESULT _stdcall GetPan(long *p) {return S_OK;}
+ HRESULT _stdcall SetPan(long p) {return S_OK;}
+ HRESULT _stdcall GetFrequency(DWORD* f) {*f=freq;return S_OK;}
+ HRESULT _stdcall SetFrequency(DWORD f) {return S_OK;}
+ HRESULT _stdcall GetStatus(DWORD* s)
+ {
+ *s = DSBSTATUS_PLAYING|DSBSTATUS_LOOPING;
+ return S_OK;
+ }
+ HRESULT _stdcall SetCurrentPosition(DWORD) {return S_OK;}
+ HRESULT _stdcall Restore() {return S_OK;}
+
+ HRESULT _stdcall Lock(DWORD wr_cur, DWORD wr_b, void** p1, DWORD* s1, void** p2, DWORD* s2, DWORD flagz)
+ {
+ if (wr_b>buf_size)
+ {
+ return DSERR_INVALIDPARAM;
+ }
+ *p1 = buf + wr_cur;
+ if (wr_cur + wr_b > buf_size)
+ {
+ *s1 = buf_size - wr_cur;
+ *p2 = buf;
+ *s2 = wr_cur+wr_b - buf_size;
+ }
+ else
+ {
+ *s1 = wr_b;
+ *p2 = 0;
+ *s2 = 0;
+ }
+ return S_OK;
+ }
+
+
+ HRESULT _stdcall GetCurrentPosition(LPDWORD p, LPDWORD w)
+ {
+ do_update();
+ if (p) *p=pos_play;
+ if (w) *w=pos_play;
+ return S_OK;
+ }
+
+ HRESULT _stdcall Play(DWORD, DWORD, DWORD)
+ {
+ playing=1;
+ pos_play=0;
+ samples_played=0;
+ start=timeGetTime();
+ return S_OK;
+ }
+
+ HRESULT _stdcall Stop() {do_update();playing=0;return S_OK;}
+ HRESULT _stdcall Unlock(LPVOID, DWORD, LPVOID, DWORD)
+ {
+ do_update();
+ return S_OK;
+ }
+
+ FakeDirectSoundBuffer(UINT _freq,UINT size)
+
+ {
+ ref=1;
+ buf_size=size;
+ buf=(BYTE*)malloc(size);
+ memset(buf,0,size);
+ freq=_freq;
+ out=new CPipe(4,freq);
+ MIDI_core::player_setSource(out);
+ playing=0;
+ pos_play=0;
+ samples_played=0;
+ }
+};
+
+
+
+
+
+void FakeDirectSoundBuffer::do_update()
+{
+ if (playing)
+ {
+ int ds=MulDiv(timeGetTime()-start,freq,1000)-samples_played;
+
+ if (ds>0)
+ {
+ UINT todo=ds*4;
+ while(pos_play+todo>buf_size)
+ {
+ out->WriteData(buf+pos_play,buf_size-pos_play);
+ todo-=buf_size-pos_play;
+ pos_play=0;
+ }
+ if (todo)
+ {
+ out->WriteData(buf+pos_play,todo);
+ pos_play+=todo;
+ //todo=0;
+ }
+ samples_played+=ds;
+ }
+ }
+}
+
+IDirectSoundBuffer* dhb_create(DWORD s,DWORD f)
+{
+ return new FakeDirectSoundBuffer(f,s);
+}
+
+
+//fake IDirectSound crap. one static instance
+
+static DSCAPS h_caps=
+ {
+ sizeof(DSCAPS),
+ DSCAPS_SECONDARY16BIT|DSCAPS_SECONDARYSTEREO,
+ 1000,
+ 100000,
+ 1,
+ 1000,
+ 1000,
+ 1000,//streaming buffers
+ 1000,
+ 1000,
+ 1000,
+ 0,0,0,0,0,0,//3d crap
+ 1024*1024,
+ 1024*1024,
+ 1024*1024,
+ 0,0, //CPU speed crap
+ 0,0 //reserved crap
+ };
+
+class FakeDsound : public IDirectSound
+{
+ ULONG ref:1;
+ HRESULT _stdcall QueryInterface(REFIID iid,void** i)
+ {
+ if (IsEqualIID(iid,IID_IUnknown) || IsEqualIID(iid,IID_IDirectSound))
+ {
+ ref++;
+ *i = this;
+ return S_OK;
+ }
+ else return E_NOINTERFACE;
+ }
+ ULONG _stdcall AddRef() {return ++ref;}
+ ULONG _stdcall Release() {return --ref;}
+ HRESULT _stdcall CreateSoundBuffer(LPCDSBUFFERDESC, LPDIRECTSOUNDBUFFER *, LPUNKNOWN) {return DSERR_INVALIDCALL;}
+ HRESULT _stdcall GetCaps(LPDSCAPS _caps)
+ {
+ *_caps = h_caps;
+ return S_OK;
+ }
+ HRESULT _stdcall DuplicateSoundBuffer(LPDIRECTSOUNDBUFFER, LPDIRECTSOUNDBUFFER *) {return DSERR_INVALIDCALL;}
+ HRESULT _stdcall SetCooperativeLevel(HWND, DWORD) {return S_OK;}
+ HRESULT _stdcall Compact() {return S_OK;}
+ HRESULT _stdcall GetSpeakerConfig(LPDWORD moo) {*moo=0;return S_OK;}
+ HRESULT _stdcall SetSpeakerConfig(DWORD) {return S_OK;}
+ HRESULT _stdcall Initialize(LPCGUID) {return DSERR_ALREADYINITIALIZED;}
+};
+
+static FakeDsound HACK;
+
+IDirectSound * get_ds() {return &HACK;} \ No newline at end of file