From abe722778f7a16d438dfa5b4dd64143d8348a108 Mon Sep 17 00:00:00 2001 From: Eric Pouech <Eric.Pouech@wanadoo.fr> Date: Sun, 31 Oct 1999 02:23:49 +0000 Subject: [PATCH] Added built-in msacm.drv and midimap.drv drivers. --- Makefile.in | 6 +- configure | 4 + configure.in | 2 + dlls/Makefile.in | 2 + dlls/winmm/midimap/.cvsignore | 2 + dlls/winmm/midimap/Makefile.in | 21 ++ dlls/winmm/midimap/midimap.c | 284 ++++++++++++++++++ dlls/winmm/midimap/midimap.spec | 7 + dlls/winmm/wavemap/.cvsignore | 2 + dlls/winmm/wavemap/Makefile.in | 21 ++ dlls/winmm/wavemap/msacm.spec | 7 + dlls/winmm/wavemap/wavemap.c | 501 ++++++++++++++++++++++++++++++++ loader/loadorder.c | 1 + relay32/builtin32.c | 4 + wine.ini | 1 + 15 files changed, 864 insertions(+), 1 deletion(-) create mode 100644 dlls/winmm/midimap/.cvsignore create mode 100644 dlls/winmm/midimap/Makefile.in create mode 100644 dlls/winmm/midimap/midimap.c create mode 100644 dlls/winmm/midimap/midimap.spec create mode 100644 dlls/winmm/wavemap/.cvsignore create mode 100644 dlls/winmm/wavemap/Makefile.in create mode 100644 dlls/winmm/wavemap/msacm.spec create mode 100644 dlls/winmm/wavemap/wavemap.c diff --git a/Makefile.in b/Makefile.in index a268e97a80d..6f8cfe57554 100644 --- a/Makefile.in +++ b/Makefile.in @@ -71,6 +71,8 @@ LIBSUBDIRS = \ dlls/winmm/mcicda \ dlls/winmm/mciseq \ dlls/winmm/mciwave \ + dlls/winmm/midimap \ + dlls/winmm/wavemap \ dlls/winmm/wineoss \ dlls/winspool \ dlls/wnaspi32 \ @@ -170,13 +172,15 @@ LIBOBJS = \ dlls/winaspi/winaspi.o \ dlls/windebug/windebug.o \ dlls/wing/wing.o \ + dlls/winmm/winmm.o \ dlls/winmm/mcianim/mcianim.drv.o \ dlls/winmm/mciavi/mciavi.drv.o \ dlls/winmm/mcicda/mcicda.drv.o \ dlls/winmm/mciseq/mciseq.drv.o \ dlls/winmm/mciwave/mciwave.drv.o \ + dlls/winmm/midimap/midimap.drv.o \ + dlls/winmm/wavemap/msacm.drv.o \ dlls/winmm/wineoss/wineoss.o \ - dlls/winmm/winmm.o \ dlls/winspool/winspool.o \ dlls/wnaspi32/wnaspi32.o \ files/files.o \ diff --git a/configure b/configure index f083a6281bb..49cbdfc5eb4 100755 --- a/configure +++ b/configure @@ -5673,6 +5673,8 @@ dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile +dlls/winmm/midimap/Makefile +dlls/winmm/wavemap/Makefile dlls/winmm/wineoss/Makefile dlls/winspool/Makefile dlls/wnaspi32/Makefile @@ -5874,6 +5876,8 @@ dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile +dlls/winmm/midimap/Makefile +dlls/winmm/wavemap/Makefile dlls/winmm/wineoss/Makefile dlls/winspool/Makefile dlls/wnaspi32/Makefile diff --git a/configure.in b/configure.in index 33075bf2aea..d15357caa8c 100644 --- a/configure.in +++ b/configure.in @@ -880,6 +880,8 @@ dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile +dlls/winmm/midimap/Makefile +dlls/winmm/wavemap/Makefile dlls/winmm/wineoss/Makefile dlls/winspool/Makefile dlls/wnaspi32/Makefile diff --git a/dlls/Makefile.in b/dlls/Makefile.in index 1df81853880..0efcaf5668e 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -6,6 +6,7 @@ SUBDIRS = \ crtdll \ dciman32 \ dplayx \ + dsound \ imagehlp \ imm32 \ lzexpand \ @@ -32,6 +33,7 @@ SUBDIRS = \ winaspi \ windebug \ wing \ + winmm \ winspool \ wnaspi32 diff --git a/dlls/winmm/midimap/.cvsignore b/dlls/winmm/midimap/.cvsignore new file mode 100644 index 00000000000..7c829838d67 --- /dev/null +++ b/dlls/winmm/midimap/.cvsignore @@ -0,0 +1,2 @@ +Makefile +midimap.spec.c diff --git a/dlls/winmm/midimap/Makefile.in b/dlls/winmm/midimap/Makefile.in new file mode 100644 index 00000000000..6d587abfd25 --- /dev/null +++ b/dlls/winmm/midimap/Makefile.in @@ -0,0 +1,21 @@ +DEFS = @DLLFLAGS@ -D__WINE__ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = midimap.drv + +SPEC_SRCS = \ + midimap.spec + +C_SRCS = \ + midimap.c + +all: $(MODULE).o + +@MAKE_RULES@ + +call32.s: $(BUILD) + $(BUILD) @BUILDFLAGS@ -o $@ -call32 + +### Dependencies: diff --git a/dlls/winmm/midimap/midimap.c b/dlls/winmm/midimap/midimap.c new file mode 100644 index 00000000000..42a7525553d --- /dev/null +++ b/dlls/winmm/midimap/midimap.c @@ -0,0 +1,284 @@ +/* -*- tab-width: 8; c-basic-offset: 4 -*- */ +/* + * Wine Midi mapper driver + * + * Copyright 1999 Eric Pouech + */ + +#include "winuser.h" +#include "driver.h" +#include "mmddk.h" +#include "debugtools.h" + +DEFAULT_DEBUG_CHANNEL(msacm) + +typedef struct tagMIDIMAPDATA { + HMIDI hMidi; +} MIDIMAPDATA; + +/*======================================================================* + * MIDI OUT part * + *======================================================================*/ + +static DWORD modOpen(LPDWORD lpdwUser, LPMIDIOPENDESC lpDesc, DWORD dwFlags) +{ + UINT nd = midiOutGetNumDevs(); + UINT i; + MIDIMAPDATA* mom = HeapAlloc(GetProcessHeap(), 0, sizeof(MIDIMAPDATA)); + + TRACE("(%p %p %08lx\n", lpdwUser, lpDesc, dwFlags); + + for (i = 0; i < nd; i++) { + if (midiOutOpen(&mom->hMidi, i, lpDesc->dwCallback, + lpDesc->dwInstance, dwFlags) == MMSYSERR_NOERROR) { + lpDesc->hMidi = mom->hMidi; + *lpdwUser = (DWORD)mom; + return MMSYSERR_NOERROR; + } + } + HeapFree(GetProcessHeap(), 0, mom); + return MMSYSERR_ALLOCATED; +} + +static DWORD modClose(MIDIMAPDATA* mom) +{ + DWORD ret = midiOutClose(mom->hMidi); + if (ret == MMSYSERR_NOERROR) + HeapFree(GetProcessHeap(), 0, mom); + return ret; +} + +static DWORD modLongData(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2) +{ + return midiOutLongMsg(mom->hMidi, lpMidiHdr, dwParam2); +} + +static DWORD modData(MIDIMAPDATA* mom, DWORD dwParam) +{ + return midiOutShortMsg(mom->hMidi, dwParam); +} + +static DWORD modPrepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2) +{ + return midiOutPrepareHeader(mom->hMidi, lpMidiHdr, dwParam2); +} + +static DWORD modUnprepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2) +{ + return midiOutUnprepareHeader(mom->hMidi, lpMidiHdr, dwParam2); +} + +static DWORD modGetDevCaps(MIDIMAPDATA* mom, LPMIDIOUTCAPSA lpMidiCaps, DWORD dwParam2) +{ + return midiOutGetDevCapsA(mom->hMidi, lpMidiCaps, dwParam2); +} + +static DWORD modGetVolume(MIDIMAPDATA* mom, LPDWORD lpVol) +{ + return midiOutGetVolume(mom->hMidi, lpVol); +} + +static DWORD modSetVolume(MIDIMAPDATA* mom, DWORD vol) +{ + return midiOutSetVolume(mom->hMidi, vol); +} + +static DWORD modReset(MIDIMAPDATA* mom) +{ + return midiOutReset(mom->hMidi); +} + +/************************************************************************** + * MIDIMAP_modMessage [sample driver] + */ +DWORD WINAPI MIDIMAP_modMessage(UINT wDevID, UINT wMsg, DWORD dwUser, + DWORD dwParam1, DWORD dwParam2) +{ + TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n", + wDevID, wMsg, dwUser, dwParam1, dwParam2); + + switch (wMsg) { + case DRVM_INIT: + case DRVM_EXIT: + case DRVM_ENABLE: + case DRVM_DISABLE: + /* FIXME: Pretend this is supported */ + return 0; + + case MODM_OPEN: return modOpen ((LPDWORD)dwUser, (LPMIDIOPENDESC)dwParam1,dwParam2); + case MODM_CLOSE: return modClose ((MIDIMAPDATA*)dwUser); + + case MODM_DATA: return modData ((MIDIMAPDATA*)dwUser, dwParam1); + case MODM_LONGDATA: return modLongData ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2); + case MODM_PREPARE: return modPrepare ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2); + case MODM_UNPREPARE: return modUnprepare ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2); + + case MODM_GETDEVCAPS: return modGetDevCaps ((MIDIMAPDATA*)dwUser, (LPMIDIOUTCAPSA)dwParam1,dwParam2); + case MODM_GETNUMDEVS: return 1; + case MODM_GETVOLUME: return modGetVolume ((MIDIMAPDATA*)dwUser, (LPDWORD)dwParam1); + case MODM_SETVOLUME: return modSetVolume ((MIDIMAPDATA*)dwUser, dwParam1); + case MODM_RESET: return modReset ((MIDIMAPDATA*)dwUser); + default: + FIXME("unknown message %d!\n", wMsg); + } + return MMSYSERR_NOTSUPPORTED; +} + +/*======================================================================* + * MIDI IN part * + *======================================================================*/ + +static DWORD midOpen(LPDWORD lpdwUser, LPMIDIOPENDESC lpDesc, DWORD dwFlags) +{ + UINT nd = midiInGetNumDevs(); + UINT i; + MIDIMAPDATA* wim = HeapAlloc(GetProcessHeap(), 0, sizeof(MIDIMAPDATA)); + + TRACE("(%p %p %08lx\n", lpdwUser, lpDesc, dwFlags); + + for (i = 0; i < nd; i++) { + if (midiInOpen(&wim->hMidi, i, lpDesc->dwCallback, + lpDesc->dwInstance, dwFlags) == MMSYSERR_NOERROR) { + lpDesc->hMidi = wim->hMidi; + *lpdwUser = (DWORD)wim; + return MMSYSERR_NOERROR; + } + } + HeapFree(GetProcessHeap(), 0, wim); + return MMSYSERR_ALLOCATED; +} + +static DWORD midClose(MIDIMAPDATA* wim) +{ + DWORD ret = midiInClose(wim->hMidi); + if (ret == MMSYSERR_NOERROR) + HeapFree(GetProcessHeap(), 0, wim); + return ret; +} + +static DWORD midAddBuffer(MIDIMAPDATA* wim, LPMIDIHDR lpMidiHdr, DWORD dwParam2) +{ + return midiInAddBuffer(wim->hMidi, lpMidiHdr, dwParam2); +} + +static DWORD midPrepare(MIDIMAPDATA* wim, LPMIDIHDR lpMidiHdr, DWORD dwParam2) +{ + return midiInPrepareHeader(wim->hMidi, lpMidiHdr, dwParam2); +} + +static DWORD midUnprepare(MIDIMAPDATA* wim, LPMIDIHDR lpMidiHdr, DWORD dwParam2) +{ + return midiInUnprepareHeader(wim->hMidi, lpMidiHdr, dwParam2); +} + +static DWORD midGetDevCaps(MIDIMAPDATA* wim, LPMIDIINCAPSA lpMidiCaps, DWORD dwParam2) +{ + return midiInGetDevCapsA(wim->hMidi, lpMidiCaps, dwParam2); +} + +static DWORD midStop(MIDIMAPDATA* wim) +{ + return midiInStop(wim->hMidi); +} + +static DWORD midStart(MIDIMAPDATA* wim) +{ + return midiInStart(wim->hMidi); +} + +static DWORD midReset(MIDIMAPDATA* wim) +{ + return midiInReset(wim->hMidi); +} + +/************************************************************************** + * MIDIMAP_midMessage [sample driver] + */ +DWORD WINAPI MIDIMAP_midMessage(WORD wDevID, WORD wMsg, DWORD dwUser, + DWORD dwParam1, DWORD dwParam2) +{ + TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n", + wDevID, wMsg, dwUser, dwParam1, dwParam2); + + switch (wMsg) { + case DRVM_INIT: + case DRVM_EXIT: + case DRVM_ENABLE: + case DRVM_DISABLE: + /* FIXME: Pretend this is supported */ + return 0; + + case MIDM_OPEN: return midOpen ((LPDWORD)dwUser, (LPMIDIOPENDESC)dwParam1, dwParam2); + case MIDM_CLOSE: return midClose ((MIDIMAPDATA*)dwUser); + + case MIDM_ADDBUFFER: return midAddBuffer ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2); + case MIDM_PREPARE: return midPrepare ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2); + case MIDM_UNPREPARE: return midUnprepare ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2); + case MIDM_GETDEVCAPS: return midGetDevCaps ((MIDIMAPDATA*)dwUser, (LPMIDIINCAPSA)dwParam1, dwParam2); + case MIDM_GETNUMDEVS: return 1; + case MIDM_RESET: return midReset ((MIDIMAPDATA*)dwUser); + case MIDM_START: return midStart ((MIDIMAPDATA*)dwUser); + case MIDM_STOP: return midStop ((MIDIMAPDATA*)dwUser); + default: + FIXME("unknown message %u!\n", wMsg); + } + return MMSYSERR_NOTSUPPORTED; +} + +/*======================================================================* + * Driver part * + *======================================================================*/ + +static struct WINE_MIDIMAP* oss = NULL; + +/************************************************************************** + * MIDIMAP_drvOpen [internal] + */ +static DWORD MIDIMAP_drvOpen(LPSTR str) +{ + if (oss) + return 0; + + /* I know, this is ugly, but who cares... */ + oss = (struct WINE_MIDIMAP*)1; + return 1; +} + +/************************************************************************** + * MIDIMAP_drvClose [internal] + */ +static DWORD MIDIMAP_drvClose(DWORD dwDevID) +{ + if (oss) { + oss = NULL; + return 1; + } + return 0; +} + +/************************************************************************** + * MIDIMAP_DriverProc [internal] + */ +LONG CALLBACK MIDIMAP_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg, + DWORD dwParam1, DWORD dwParam2) +{ +/* EPP TRACE("(%08lX, %04X, %08lX, %08lX, %08lX)\n", */ +/* EPP dwDevID, hDriv, wMsg, dwParam1, dwParam2); */ + + switch(wMsg) { + case DRV_LOAD: return 1; + case DRV_FREE: return 1; + case DRV_OPEN: return MIDIMAP_drvOpen((LPSTR)dwParam1); + case DRV_CLOSE: return MIDIMAP_drvClose(dwDevID); + case DRV_ENABLE: return 1; + case DRV_DISABLE: return 1; + case DRV_QUERYCONFIGURE: return 1; + case DRV_CONFIGURE: MessageBoxA(0, "MIDIMAP MultiMedia Driver !", "OSS Driver", MB_OK); return 1; + case DRV_INSTALL: return DRVCNF_RESTART; + case DRV_REMOVE: return DRVCNF_RESTART; + default: + return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2); + } +} + + diff --git a/dlls/winmm/midimap/midimap.spec b/dlls/winmm/midimap/midimap.spec new file mode 100644 index 00000000000..22c52533261 --- /dev/null +++ b/dlls/winmm/midimap/midimap.spec @@ -0,0 +1,7 @@ +name midimap +file midimap.drv +type win32 + + 1 stdcall DriverProc(long long long long long) MIDIMAP_DriverProc + 2 stdcall midMessage(long long long long long) MIDIMAP_midMessage + 3 stdcall modMessage(long long long long long) MIDIMAP_modMessage diff --git a/dlls/winmm/wavemap/.cvsignore b/dlls/winmm/wavemap/.cvsignore new file mode 100644 index 00000000000..313661889f4 --- /dev/null +++ b/dlls/winmm/wavemap/.cvsignore @@ -0,0 +1,2 @@ +Makefile +msacm.spec.c diff --git a/dlls/winmm/wavemap/Makefile.in b/dlls/winmm/wavemap/Makefile.in new file mode 100644 index 00000000000..7b356982760 --- /dev/null +++ b/dlls/winmm/wavemap/Makefile.in @@ -0,0 +1,21 @@ +DEFS = @DLLFLAGS@ -D__WINE__ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = msacm.drv + +SPEC_SRCS = \ + msacm.spec + +C_SRCS = \ + wavemap.c + +all: $(MODULE).o + +@MAKE_RULES@ + +call32.s: $(BUILD) + $(BUILD) @BUILDFLAGS@ -o $@ -call32 + +### Dependencies: diff --git a/dlls/winmm/wavemap/msacm.spec b/dlls/winmm/wavemap/msacm.spec new file mode 100644 index 00000000000..19fbf328fec --- /dev/null +++ b/dlls/winmm/wavemap/msacm.spec @@ -0,0 +1,7 @@ +name msacmmap +file msacm.drv +type win32 + + 1 stdcall DriverProc(long long long long long) WAVEMAP_DriverProc + 2 stdcall widMessage(long long long long long) WAVEMAP_widMessage + 3 stdcall wodMessage(long long long long long) WAVEMAP_wodMessage diff --git a/dlls/winmm/wavemap/wavemap.c b/dlls/winmm/wavemap/wavemap.c new file mode 100644 index 00000000000..9dbcf06a96f --- /dev/null +++ b/dlls/winmm/wavemap/wavemap.c @@ -0,0 +1,501 @@ +/* -*- tab-width: 8; c-basic-offset: 4 -*- */ +/* + * Wine Wave mapper driver + * + * Copyright 1999 Eric Pouech + */ + +/* TODOs + * + implement wavein as waveout has been implemented + * + better protection against evilish dwUser parameters + * + use asynchronous ACM conversion + */ + +#include "winuser.h" +#include "driver.h" +#include "mmddk.h" +#include "msacm.h" +#include "debugtools.h" + +DEFAULT_DEBUG_CHANNEL(msacm) + +typedef struct tagWAVEMAPDATA { + HWAVE hWave; + HACMSTREAM hAcmStream; + /* needed data to filter callbacks. Only needed when hAcmStream is not 0 */ + DWORD dwCallback; + DWORD dwClientInstance; + DWORD dwFlags; + MMRESULT (WINAPI *acmStreamOpen)(LPHACMSTREAM, HACMDRIVER, LPWAVEFORMATEX, LPWAVEFORMATEX, LPWAVEFILTER, DWORD, DWORD, DWORD); + MMRESULT (WINAPI *acmStreamClose)(HACMSTREAM, DWORD); + MMRESULT (WINAPI *acmStreamSize)(HACMSTREAM, DWORD, LPDWORD, DWORD); + MMRESULT (WINAPI *acmStreamConvert)(HACMSTREAM, PACMSTREAMHEADER, DWORD); + MMRESULT (WINAPI *acmStreamPrepareHeader)(HACMSTREAM, PACMSTREAMHEADER, DWORD); + MMRESULT (WINAPI *acmStreamUnprepareHeader)(HACMSTREAM, PACMSTREAMHEADER, DWORD); +} WAVEMAPDATA; + +/*======================================================================* + * WAVE OUT part * + *======================================================================*/ + +static void CALLBACK WAVEMAP_DstCallback(HDRVR hDev, UINT uMsg, DWORD dwInstance, + DWORD dwParam1, DWORD dwParam2) +{ + WAVEMAPDATA* wom = (WAVEMAPDATA*)dwInstance; + + TRACE("(0x%x %u %ld %ld %ld);\n", hDev, uMsg, dwInstance, dwParam1, dwParam2); + + switch (uMsg) { + case WOM_OPEN: + case WOM_CLOSE: + /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */ + break; + case WOM_DONE: + { + LPWAVEHDR lpWaveHdrDst = (LPWAVEHDR)dwParam1; + PACMSTREAMHEADER ash = (PACMSTREAMHEADER)((LPSTR)lpWaveHdrDst - sizeof(ACMSTREAMHEADER)); + LPWAVEHDR lpWaveHdrSrc = (LPWAVEHDR)ash->dwUser; + + lpWaveHdrSrc->dwFlags &= ~WHDR_INQUEUE; + lpWaveHdrSrc->dwFlags |= WHDR_DONE; + dwParam1 = (DWORD)lpWaveHdrSrc; + } + break; + default: + ERR("Unknown msg %u\n", uMsg); + } + + DriverCallback(wom->dwCallback, wom->dwFlags, hDev, uMsg, + wom->dwClientInstance, dwParam1, dwParam2); +} + +static DWORD wodOpenHelper(WAVEMAPDATA* wom, UINT idx, + LPWAVEOPENDESC lpDesc, LPWAVEFORMATEX lpwfx, + DWORD dwFlags) +{ + DWORD ret; + + /* destination is always PCM, so the formulas below apply */ + lpwfx->nBlockAlign = (lpwfx->nChannels * lpwfx->wBitsPerSample) / 8; + lpwfx->nAvgBytesPerSec = lpwfx->nSamplesPerSec * lpwfx->nBlockAlign; + ret = wom->acmStreamOpen(&wom->hAcmStream, 0, lpDesc->lpFormat, lpwfx, NULL, 0L, 0L, 0L); + if (ret != MMSYSERR_NOERROR) + return ret; + return waveOutOpen(&wom->hWave, idx, lpwfx, (DWORD)WAVEMAP_DstCallback, + (DWORD)wom, (dwFlags & CALLBACK_TYPEMASK) | CALLBACK_FUNCTION); +} + +static DWORD wodOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags) +{ + UINT nd = waveOutGetNumDevs(); + UINT i; + WAVEMAPDATA* wom = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEMAPDATA)); + WAVEFORMATEX wfx; + + TRACE("(%p %p %08lx\n", lpdwUser, lpDesc, dwFlags); + + if (!wom) + return MMSYSERR_NOMEM; + + for (i = 0; i < nd; i++) { + /* if no ACM stuff is involved, no need to handle callbacks at this + * level, this will be done transparently + */ + if (waveOutOpen(&wom->hWave, i, lpDesc->lpFormat, lpDesc->dwCallback, + lpDesc->dwInstance, dwFlags) == MMSYSERR_NOERROR) { + wom->hAcmStream = 0; + goto found; + } + } + + /* temporary hack until real builtin dll loading is available */ + do { + HMODULE hModule = LoadLibraryA("msacm32.dll"); + + wom->acmStreamOpen = (void*)GetProcAddress(hModule, "acmStreamOpen"); + wom->acmStreamClose = (void*)GetProcAddress(hModule, "acmStreamClose"); + wom->acmStreamSize = (void*)GetProcAddress(hModule, "acmStreamSize"); + wom->acmStreamConvert = (void*)GetProcAddress(hModule, "acmStreamConvert"); + wom->acmStreamPrepareHeader = (void*)GetProcAddress(hModule, "acmStreamPrepareHeader"); + wom->acmStreamUnprepareHeader = (void*)GetProcAddress(hModule, "acmStreamUnprepareHeader"); + } while (0); + + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.cbSize = 0; /* normally, this field is not used for PCM format, just in case */ + /* try some ACM stuff */ + + wom->dwCallback = lpDesc->dwCallback; + wom->dwFlags = dwFlags; + wom->dwClientInstance = lpDesc->dwInstance; + +#define TRY(sps,bps) wfx.nSamplesPerSec = (sps); wfx.wBitsPerSample = (bps); \ + if (wodOpenHelper(wom, i, lpDesc, &wfx, dwFlags) == MMSYSERR_NOERROR) goto found; + + for (i = 0; i < nd; i++) { + /* first try with same stereo/mono option as source */ + wfx.nChannels = lpDesc->lpFormat->nChannels; + TRY(44100, 8); + TRY(22050, 8); + TRY(11025, 8); + + /* 2^3 => 1, 1^3 => 2, so if stereo, try mono (and the other way around) */ + wfx.nChannels ^= 3; + TRY(44100, 8); + TRY(22050, 8); + TRY(11025, 8); + } +#undef TRY + + HeapFree(GetProcessHeap(), 0, wom); + return MMSYSERR_ALLOCATED; +found: + lpDesc->hWave = wom->hWave; + *lpdwUser = (DWORD)wom; + return MMSYSERR_NOERROR; +} + +static DWORD wodClose(WAVEMAPDATA* wom) +{ + DWORD ret = waveOutClose(wom->hWave); + + if (ret == MMSYSERR_NOERROR) { + if (wom->hAcmStream) { + ret = wom->acmStreamClose(wom->hAcmStream, 0); + } + if (ret == MMSYSERR_NOERROR) { + HeapFree(GetProcessHeap(), 0, wom); + } + } + return ret; +} + +static DWORD wodWrite(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwParam2) +{ + PACMSTREAMHEADER ash; + LPWAVEHDR lpWaveHdrDst; + + if (!wom->hAcmStream) { + return waveOutWrite(wom->hWave, lpWaveHdrSrc, dwParam2); + } + + lpWaveHdrSrc->dwFlags |= WHDR_INQUEUE; + ash = (PACMSTREAMHEADER)lpWaveHdrSrc->reserved; + if (wom->acmStreamConvert(wom->hAcmStream, ash, 0L) != MMSYSERR_NOERROR) + return MMSYSERR_ERROR; + + lpWaveHdrDst = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER)); + lpWaveHdrDst->dwBufferLength = ash->cbDstLengthUsed; + return waveOutWrite(wom->hWave, lpWaveHdrDst, sizeof(*lpWaveHdrDst)); +} + +static DWORD wodPrepare(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwParam2) +{ + PACMSTREAMHEADER ash; + DWORD size; + DWORD dwRet; + LPWAVEHDR lpWaveHdrDst; + + if (!wom->hAcmStream) { + return waveOutPrepareHeader(wom->hWave, lpWaveHdrSrc, dwParam2); + } + if (wom->acmStreamSize(wom->hAcmStream, lpWaveHdrSrc->dwBufferLength, &size, ACM_STREAMSIZEF_SOURCE) != MMSYSERR_NOERROR) + return MMSYSERR_ERROR; + + ash = HeapAlloc(GetProcessHeap(), 0, sizeof(ACMSTREAMHEADER) + sizeof(WAVEHDR) + size); + if (ash == NULL) + return MMSYSERR_NOMEM; + + ash->cbStruct = sizeof(*ash); + ash->fdwStatus = 0L; + ash->dwUser = (DWORD)lpWaveHdrSrc; + ash->pbSrc = lpWaveHdrSrc->lpData; + ash->cbSrcLength = lpWaveHdrSrc->dwBufferLength; + /* ash->cbSrcLengthUsed */ + ash->dwSrcUser = lpWaveHdrSrc->dwUser; /* FIXME ? */ + ash->pbDst = (LPSTR)ash + sizeof(ACMSTREAMHEADER) + sizeof(WAVEHDR); + ash->cbDstLength = size; + /* ash->cbDstLengthUsed */ + ash->dwDstUser = 0; /* FIXME ? */ + dwRet = wom->acmStreamPrepareHeader(wom->hAcmStream, ash, 0L); + if (dwRet != MMSYSERR_NOERROR) + goto errCleanUp; + + lpWaveHdrDst = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER)); + lpWaveHdrDst->lpData = ash->pbDst; + lpWaveHdrDst->dwBufferLength = size; /* conversion is not done yet */ + lpWaveHdrDst->dwFlags = 0; + lpWaveHdrDst->dwLoops = 0; + dwRet = waveOutPrepareHeader(wom->hWave, lpWaveHdrDst, sizeof(*lpWaveHdrDst)); + if (dwRet != MMSYSERR_NOERROR) + goto errCleanUp; + + lpWaveHdrSrc->reserved = (DWORD)ash; + lpWaveHdrSrc->dwFlags = WHDR_PREPARED; + TRACE("=> (0)\n"); + return MMSYSERR_NOERROR; +errCleanUp: + TRACE("=> (%ld)\n", dwRet); + HeapFree(GetProcessHeap(), 0, ash); + return dwRet; +} + +static DWORD wodUnprepare(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwParam2) +{ + PACMSTREAMHEADER ash; + LPWAVEHDR lpWaveHdrDst; + DWORD dwRet1, dwRet2; + + if (!wom->hAcmStream) { + return waveOutUnprepareHeader(wom->hWave, lpWaveHdrSrc, dwParam2); + } + ash = (PACMSTREAMHEADER)lpWaveHdrSrc->reserved; + dwRet1 = wom->acmStreamUnprepareHeader(wom->hAcmStream, ash, 0L); + + lpWaveHdrDst = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER)); + dwRet2 = waveOutUnprepareHeader(wom->hWave, lpWaveHdrDst, sizeof(*lpWaveHdrDst)); + + HeapFree(GetProcessHeap(), 0, ash); + + lpWaveHdrSrc->dwFlags &= ~WHDR_PREPARED; + return (dwRet1 == MMSYSERR_NOERROR) ? dwRet2 : dwRet1; +} + +static DWORD wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2) +{ + return waveOutGetPosition(wom->hWave, lpTime, dwParam2); +} + +static DWORD wodGetDevCaps(WAVEMAPDATA* wom, LPWAVEOUTCAPSA lpWaveCaps, DWORD dwParam2) +{ + return waveOutGetDevCapsA(wom->hWave, lpWaveCaps, dwParam2); +} + +static DWORD wodGetVolume(WAVEMAPDATA* wom, LPDWORD lpVol) +{ + return waveOutGetVolume(wom->hWave, lpVol); +} + +static DWORD wodSetVolume(WAVEMAPDATA* wom, DWORD vol) +{ + return waveOutSetVolume(wom->hWave, vol); +} + +static DWORD wodPause(WAVEMAPDATA* wom) +{ + return waveOutPause(wom->hWave); +} + +static DWORD wodRestart(WAVEMAPDATA* wom) +{ + return waveOutRestart(wom->hWave); +} + +static DWORD wodReset(WAVEMAPDATA* wom) +{ + return waveOutReset(wom->hWave); +} + +/************************************************************************** + * WAVEMAP_wodMessage [sample driver] + */ +DWORD WINAPI WAVEMAP_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser, + DWORD dwParam1, DWORD dwParam2) +{ + TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n", + wDevID, wMsg, dwUser, dwParam1, dwParam2); + + switch (wMsg) { + case DRVM_INIT: + case DRVM_EXIT: + case DRVM_ENABLE: + case DRVM_DISABLE: + /* FIXME: Pretend this is supported */ + return 0; + case WODM_OPEN: return wodOpen ((LPDWORD)dwUser, (LPWAVEOPENDESC)dwParam1,dwParam2); + case WODM_CLOSE: return wodClose ((WAVEMAPDATA*)dwUser); + case WODM_WRITE: return wodWrite ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2); + case WODM_PAUSE: return wodPause ((WAVEMAPDATA*)dwUser); + case WODM_GETPOS: return wodGetPosition ((WAVEMAPDATA*)dwUser, (LPMMTIME)dwParam1, dwParam2); + case WODM_BREAKLOOP: return MMSYSERR_NOTSUPPORTED; + case WODM_PREPARE: return wodPrepare ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2); + case WODM_UNPREPARE: return wodUnprepare ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2); + case WODM_GETDEVCAPS: return wodGetDevCaps ((WAVEMAPDATA*)dwUser, (LPWAVEOUTCAPSA)dwParam1,dwParam2); + case WODM_GETNUMDEVS: return 1; + case WODM_GETPITCH: return MMSYSERR_NOTSUPPORTED; + case WODM_SETPITCH: return MMSYSERR_NOTSUPPORTED; + case WODM_GETPLAYBACKRATE: return MMSYSERR_NOTSUPPORTED; + case WODM_SETPLAYBACKRATE: return MMSYSERR_NOTSUPPORTED; + case WODM_GETVOLUME: return wodGetVolume ((WAVEMAPDATA*)dwUser, (LPDWORD)dwParam1); + case WODM_SETVOLUME: return wodSetVolume ((WAVEMAPDATA*)dwUser, dwParam1); + case WODM_RESTART: return wodRestart ((WAVEMAPDATA*)dwUser); + case WODM_RESET: return wodReset ((WAVEMAPDATA*)dwUser); + default: + FIXME("unknown message %d!\n", wMsg); + } + return MMSYSERR_NOTSUPPORTED; +} + +/*======================================================================* + * WAVE IN part * + *======================================================================*/ + +static DWORD widOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags) +{ + UINT nd = waveInGetNumDevs(); + UINT i; + WAVEMAPDATA* wim = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEMAPDATA)); + + TRACE("(%p %p %08lx\n", lpdwUser, lpDesc, dwFlags); + + for (i = 0; i < nd; i++) { + if (waveInOpen(&wim->hWave, i, lpDesc->lpFormat, lpDesc->dwCallback, + lpDesc->dwInstance, dwFlags) == MMSYSERR_NOERROR) { + lpDesc->hWave = wim->hWave; + *lpdwUser = (DWORD)wim; + return MMSYSERR_NOERROR; + } + } + HeapFree(GetProcessHeap(), 0, wim); + return MMSYSERR_ALLOCATED; +} + +static DWORD widClose(WAVEMAPDATA* wim) +{ + DWORD ret = waveInClose(wim->hWave); + if (ret == MMSYSERR_NOERROR) + HeapFree(GetProcessHeap(), 0, wim); + return ret; +} + +static DWORD widAddBuffer(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdr, DWORD dwParam2) +{ + return waveInAddBuffer(wim->hWave, lpWaveHdr, dwParam2); +} + +static DWORD widPrepare(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdr, DWORD dwParam2) +{ + return waveInPrepareHeader(wim->hWave, lpWaveHdr, dwParam2); +} + +static DWORD widUnprepare(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdr, DWORD dwParam2) +{ + return waveInUnprepareHeader(wim->hWave, lpWaveHdr, dwParam2); +} + +static DWORD widGetPosition(WAVEMAPDATA* wim, LPMMTIME lpTime, DWORD dwParam2) +{ + return waveInGetPosition(wim->hWave, lpTime, dwParam2); +} + +static DWORD widGetDevCaps(WAVEMAPDATA* wim, LPWAVEINCAPSA lpWaveCaps, DWORD dwParam2) +{ + return waveInGetDevCapsA(wim->hWave, lpWaveCaps, dwParam2); +} + +static DWORD widStop(WAVEMAPDATA* wim) +{ + return waveInStop(wim->hWave); +} + +static DWORD widStart(WAVEMAPDATA* wim) +{ + return waveInStart(wim->hWave); +} + +static DWORD widReset(WAVEMAPDATA* wim) +{ + return waveInReset(wim->hWave); +} + +/************************************************************************** + * WAVEMAP_widMessage [sample driver] + */ +DWORD WINAPI WAVEMAP_widMessage(WORD wDevID, WORD wMsg, DWORD dwUser, + DWORD dwParam1, DWORD dwParam2) +{ + TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n", + wDevID, wMsg, dwUser, dwParam1, dwParam2); + + switch (wMsg) { + case DRVM_INIT: + case DRVM_EXIT: + case DRVM_ENABLE: + case DRVM_DISABLE: + /* FIXME: Pretend this is supported */ + return 0; + + case WIDM_OPEN: return widOpen ((LPDWORD)dwUser, (LPWAVEOPENDESC)dwParam1, dwParam2); + case WIDM_CLOSE: return widClose ((WAVEMAPDATA*)dwUser); + + case WIDM_ADDBUFFER: return widAddBuffer ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2); + case WIDM_PREPARE: return widPrepare ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2); + case WIDM_UNPREPARE: return widUnprepare ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2); + case WIDM_GETDEVCAPS: return widGetDevCaps ((WAVEMAPDATA*)dwUser, (LPWAVEINCAPSA)dwParam1, dwParam2); + case WIDM_GETNUMDEVS: return 1; + case WIDM_GETPOS: return widGetPosition ((WAVEMAPDATA*)dwUser, (LPMMTIME)dwParam1, dwParam2); + case WIDM_RESET: return widReset ((WAVEMAPDATA*)dwUser); + case WIDM_START: return widStart ((WAVEMAPDATA*)dwUser); + case WIDM_STOP: return widStop ((WAVEMAPDATA*)dwUser); + default: + FIXME("unknown message %u!\n", wMsg); + } + return MMSYSERR_NOTSUPPORTED; +} + +/*======================================================================* + * Driver part * + *======================================================================*/ + +static struct WINE_WAVEMAP* oss = NULL; + +/************************************************************************** + * WAVEMAP_drvOpen [internal] + */ +static DWORD WAVEMAP_drvOpen(LPSTR str) +{ + if (oss) + return 0; + + /* I know, this is ugly, but who cares... */ + oss = (struct WINE_WAVEMAP*)1; + return 1; +} + +/************************************************************************** + * WAVEMAP_drvClose [internal] + */ +static DWORD WAVEMAP_drvClose(DWORD dwDevID) +{ + if (oss) { + oss = NULL; + return 1; + } + return 0; +} + +/************************************************************************** + * WAVEMAP_DriverProc [internal] + */ +LONG CALLBACK WAVEMAP_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg, + DWORD dwParam1, DWORD dwParam2) +{ +/* EPP TRACE("(%08lX, %04X, %08lX, %08lX, %08lX)\n", */ +/* EPP dwDevID, hDriv, wMsg, dwParam1, dwParam2); */ + + switch(wMsg) { + case DRV_LOAD: return 1; + case DRV_FREE: return 1; + case DRV_OPEN: return WAVEMAP_drvOpen((LPSTR)dwParam1); + case DRV_CLOSE: return WAVEMAP_drvClose(dwDevID); + case DRV_ENABLE: return 1; + case DRV_DISABLE: return 1; + case DRV_QUERYCONFIGURE: return 1; + case DRV_CONFIGURE: MessageBoxA(0, "WAVEMAP MultiMedia Driver !", "OSS Driver", MB_OK); return 1; + case DRV_INSTALL: return DRVCNF_RESTART; + case DRV_REMOVE: return DRVCNF_RESTART; + default: + return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2); + } +} + + diff --git a/loader/loadorder.c b/loader/loadorder.c index 489548538b8..a340c8ba2da 100644 --- a/loader/loadorder.c +++ b/loader/loadorder.c @@ -51,6 +51,7 @@ static struct tagDllOverride { {"mcicda.drv, mciseq.drv", "builtin, native"}, {"mciwave.drv", "builtin, native"}, {"mciavi.drv, mcianim.drv", "native, builtin"}, + {"msacm.drv, midimap.drv", "builtin, native"}, {"w32skrnl", "builtin"}, {"wnaspi32,wow32", "builtin"}, {"system,display,wprocs ", "builtin"}, diff --git a/relay32/builtin32.c b/relay32/builtin32.c index 450df451a08..92c8df18a86 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -70,7 +70,9 @@ extern const BUILTIN32_DESCRIPTOR MCIAVI_Descriptor; extern const BUILTIN32_DESCRIPTOR MCICDA_Descriptor; extern const BUILTIN32_DESCRIPTOR MCISEQ_Descriptor; extern const BUILTIN32_DESCRIPTOR MCIWAVE_Descriptor; +extern const BUILTIN32_DESCRIPTOR MIDIMAP_Descriptor; extern const BUILTIN32_DESCRIPTOR MSACM32_Descriptor; +extern const BUILTIN32_DESCRIPTOR MSACMMAP_Descriptor; extern const BUILTIN32_DESCRIPTOR MSNET32_Descriptor; extern const BUILTIN32_DESCRIPTOR MSVFW32_Descriptor; extern const BUILTIN32_DESCRIPTOR NTDLL_Descriptor; @@ -123,8 +125,10 @@ static BUILTIN32_DLL BuiltinDLLs[] = { &MCICDA_Descriptor, 0, 0, NULL }, { &MCISEQ_Descriptor, 0, 0, NULL }, { &MCIWAVE_Descriptor, 0, 0, NULL }, + { &MIDIMAP_Descriptor, 0, 0, NULL }, { &MPR_Descriptor, 0, 0, NULL }, { &MSACM32_Descriptor, BI32_DANGER, 0, NULL }, + { &MSACMMAP_Descriptor, 0, 0, NULL }, { &MSNET32_Descriptor, 0, 0, NULL }, { &MSVFW32_Descriptor, 0, 0, NULL }, { &NTDLL_Descriptor, 0, 0, NULL }, diff --git a/wine.ini b/wine.ini index 98d153cd327..6f55056c0d3 100644 --- a/wine.ini +++ b/wine.ini @@ -91,6 +91,7 @@ msvideo, msvfw32 = builtin, native mcicda.drv, mciseq.drv = builtin, native mciwave.drv = builtin, native mciavi.drv, mcianim.drv = native, builtin +msacm.drv, midimap.drv = builtin, native w32skrnl = builtin wnaspi32, wow32 = builtin system, display, wprocs = builtin -- GitLab