Added PCM converter internal driver.
A few driver handling fixes.
diff --git a/dlls/msacm/Makefile.in b/dlls/msacm/Makefile.in
index f1478f1..06eca80 100644
--- a/dlls/msacm/Makefile.in
+++ b/dlls/msacm/Makefile.in
@@ -14,6 +14,7 @@
internal.c \
msacm32_main.c \
msacm_main.c \
+ pcmconverter.c \
stream.c
RC_SRCS = \
diff --git a/dlls/msacm/driver.c b/dlls/msacm/driver.c
index abca669..112f033 100644
--- a/dlls/msacm/driver.c
+++ b/dlls/msacm/driver.c
@@ -76,27 +76,32 @@
*/
MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
{
- PWINE_ACMDRIVER p;
- PWINE_ACMDRIVER* tp;
-
+ PWINE_ACMDRIVER pad;
+ PWINE_ACMDRIVERID padid;
+ PWINE_ACMDRIVER* tpad;
+
if (fdwClose)
return MMSYSERR_INVALFLAG;
- p = MSACM_GetDriver(had);
- if (!p)
+ pad = MSACM_GetDriver(had);
+ if (!pad)
return MMSYSERR_INVALHANDLE;
- for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
- if (*tp == p) {
- *tp = (*tp)->pNextACMDriver;
+ padid = pad->obj.pACMDriverID;
+
+ /* remove driver from list */
+ for (tpad = &(padid->pACMDriverList); *tpad; *tpad = (*tpad)->pNextACMDriver) {
+ if (*tpad == pad) {
+ *tpad = (*tpad)->pNextACMDriver;
break;
}
}
- if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
- CloseDriver(p->hDrvr, 0, 0);
+ /* close driver if it has been opened */
+ if (pad->hDrvr && !padid->hInstModule)
+ CloseDriver(pad->hDrvr, 0, 0);
- HeapFree(MSACM_hHeap, 0, p);
+ HeapFree(MSACM_hHeap, 0, pad);
return MMSYSERR_NOERROR;
}
@@ -232,30 +237,25 @@
if (!phad)
return MMSYSERR_INVALPARAM;
+ if (fdwOpen)
+ return MMSYSERR_INVALFLAG;
+
padid = MSACM_GetDriverID(hadid);
if (!padid)
return MMSYSERR_INVALHANDLE;
- if (fdwOpen)
- return MMSYSERR_INVALFLAG;
-
pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
if (!pad) return MMSYSERR_NOMEM;
pad->obj.dwType = WINE_ACMOBJ_DRIVER;
pad->obj.pACMDriverID = padid;
- if (!padid->hInstModule)
- pad->hDrvr = OpenDriverA(padid->pszDriverAlias, "drivers32", 0);
- else
- pad->hDrvr = padid->hInstModule;
-
+ if (!(pad->hDrvr = padid->hInstModule) && padid->pszDriverAlias)
+ pad->hDrvr = OpenDriverA(padid->pszDriverAlias, NULL, 0);
if (!pad->hDrvr) {
HeapFree(MSACM_hHeap, 0, pad);
return MMSYSERR_ERROR;
}
-
- pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
/* insert new pad at beg of list */
pad->pNextACMDriver = padid->pACMDriverList;
@@ -263,7 +263,7 @@
/* FIXME: Create a WINE_ACMDRIVER32 */
*phad = (HACMDRIVER)pad;
-
+ TRACE("'%s' => %08lx\n", padid->pszDriverAlias, (DWORD)pad);
return MMSYSERR_NOERROR;
}
diff --git a/dlls/msacm/format.c b/dlls/msacm/format.c
index 8d28e47..b1fe666 100644
--- a/dlls/msacm/format.c
+++ b/dlls/msacm/format.c
@@ -484,7 +484,7 @@
if (fdwEnum & (ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST|
ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT))
- FIXME("Unsupported fdwEnum values\n");
+ FIXME("Unsupported fdwEnum values %08lx\n", fdwEnum);
if (had) {
HACMDRIVERID hadid;
diff --git a/dlls/msacm/internal.c b/dlls/msacm/internal.c
index e9d2bd3..293513c 100644
--- a/dlls/msacm/internal.c
+++ b/dlls/msacm/internal.c
@@ -42,8 +42,8 @@
padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
padid->obj.dwType = WINE_ACMOBJ_DRIVERID;
padid->obj.pACMDriverID = padid;
- padid->pszDriverAlias = HEAP_strdupA(MSACM_hHeap, 0, pszDriverAlias);
- padid->pszFileName = HEAP_strdupA(MSACM_hHeap, 0, pszFileName);
+ padid->pszDriverAlias = pszDriverAlias ? HEAP_strdupA(MSACM_hHeap, 0, pszDriverAlias) : NULL;
+ padid->pszFileName = pszFileName ? HEAP_strdupA(MSACM_hHeap, 0, pszFileName) : NULL;
padid->hInstModule = hinstModule;
padid->bEnabled = TRUE;
padid->pACMDriverList = NULL;
@@ -65,7 +65,7 @@
{
LPSTR pszBuffer;
DWORD dwBufferLength;
-
+
/* FIXME
* What if the user edits system.ini while the program is running?
* Does Windows handle that?
@@ -85,8 +85,9 @@
char *s2 = s;
while (*s2 != '\0' && *s2 != '=') s2++;
if (*s2) {
- *s2++ = '\0';
- MSACM_RegisterDriver(s, s2, 0);
+ *s2 = '\0';
+ MSACM_RegisterDriver(s, s2 + 1, 0);
+ *s2 = '=';
}
}
s += strlen(s) + 1; /* Either next char or \0 */
@@ -94,6 +95,8 @@
}
HeapFree(MSACM_hHeap, 0, pszBuffer);
+
+ MSACM_RegisterDriver("msacm32.dll", "msacm32.dll", 0);
}
/***********************************************************************
diff --git a/dlls/msacm/msacm32.spec b/dlls/msacm/msacm32.spec
index b3cc6bd..13e297c 100644
--- a/dlls/msacm/msacm32.spec
+++ b/dlls/msacm/msacm32.spec
@@ -51,3 +51,6 @@
42 stdcall acmStreamReset(long long) acmStreamReset
43 stdcall acmStreamSize(long long ptr long) acmStreamSize
44 stdcall acmStreamUnprepareHeader(long ptr long) acmStreamUnprepareHeader
+
+# this is wine only
+@ stdcall DriverProc(long long long long long) PCM_DriverProc
diff --git a/dlls/msacm/pcmconverter.c b/dlls/msacm/pcmconverter.c
new file mode 100644
index 0000000..1184f19
--- /dev/null
+++ b/dlls/msacm/pcmconverter.c
@@ -0,0 +1,450 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
+/*
+ * MSACM32 library
+ *
+ * Copyright 2000 Eric Pouech
+ */
+
+#include <assert.h>
+#include "wine/winestring.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "msacm.h"
+#include "msacmdrv.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(msacm);
+
+static DWORD PCM_drvOpen(LPCSTR str)
+{
+ return 1;
+}
+
+static DWORD PCM_drvClose(DWORD dwDevID)
+{
+ return 1;
+}
+
+static struct {
+ int nChannels;
+ int nBits;
+ int rate;
+} PCM_Formats[] = {
+ {1, 8, 8000},
+ {2, 8, 8000},
+ {1, 16, 8000},
+ {2, 16, 8000},
+ {1, 8, 11025},
+ {2, 8, 11025},
+ {1, 16, 11025},
+ {2, 16, 11025},
+ {1, 8, 22050},
+ {2, 8, 22050},
+ {1, 16, 22050},
+ {2, 16, 22050},
+ {1, 8, 44100},
+ {2, 8, 44100},
+ {1, 16, 44100},
+ {2, 16, 44100},
+};
+
+#define NUM_PCM_FORMATS (sizeof(PCM_Formats) / sizeof(PCM_Formats[0]))
+
+static DWORD PCM_GetFormatIndex(LPWAVEFORMATEX wfx)
+{
+ int i;
+
+ for (i = 0; i < NUM_PCM_FORMATS; i++) {
+ if (wfx->nChannels == PCM_Formats[i].nChannels &&
+ wfx->nSamplesPerSec == PCM_Formats[i].rate &&
+ wfx->wBitsPerSample == PCM_Formats[i].nBits)
+ return i;
+ }
+ return 0xFFFFFFFF;
+}
+
+static LRESULT PCM_DriverDetails(PACMDRIVERDETAILSW add)
+{
+ add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
+ add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
+ add->wMid = 0xFF;
+ add->wPid = 0x00;
+ add->vdwACM = 0x01000000;
+ add->vdwDriver = 0x01000000;
+ add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CONVERTER;
+ add->cFormatTags = 1;
+ add->cFilterTags = 0;
+ add->hicon = (HICON)0;
+ lstrcpyAtoW(add->szShortName, "WINE-PCM");
+ lstrcpyAtoW(add->szLongName, "Wine PCM converter");
+ lstrcpyAtoW(add->szCopyright, "Brought to you by the Wine team...");
+ lstrcpyAtoW(add->szLicensing, "Refer to LICENSE file");
+ add->szFeatures[0] = 0;
+
+ return MMSYSERR_NOERROR;
+}
+
+static LRESULT PCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
+{
+ switch (dwQuery) {
+ case ACM_FORMATTAGDETAILSF_INDEX:
+ if (aftd->dwFormatTagIndex != 0) return ACMERR_NOTPOSSIBLE;
+ break;
+ case ACM_FORMATTAGDETAILSF_FORMATTAG:
+ if (aftd->dwFormatTag != WAVE_FORMAT_PCM) return ACMERR_NOTPOSSIBLE;
+ break;
+ case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
+ if (aftd->dwFormatTag != WAVE_FORMAT_UNKNOWN && aftd->dwFormatTag != WAVE_FORMAT_UNKNOWN)
+ return ACMERR_NOTPOSSIBLE;
+ break;
+ default:
+ WARN("Unsupported query %08lx\n", dwQuery);
+ return MMSYSERR_NOTSUPPORTED;
+ }
+
+ aftd->dwFormatTagIndex = 0;
+ aftd->dwFormatTag = WAVE_FORMAT_PCM;
+ aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
+ aftd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CONVERTER;
+ aftd->cStandardFormats = NUM_PCM_FORMATS;
+ aftd->szFormatTag[0] = 0;
+
+ return MMSYSERR_NOERROR;
+}
+
+static LRESULT PCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
+{
+ switch (dwQuery) {
+ case ACM_FORMATDETAILSF_FORMAT:
+ afd->dwFormatIndex = PCM_GetFormatIndex(afd->pwfx);
+ if (afd->dwFormatIndex == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
+ break;
+ case ACM_FORMATDETAILSF_INDEX:
+ assert(afd->dwFormatIndex < NUM_PCM_FORMATS);
+ afd->pwfx->wFormatTag = WAVE_FORMAT_PCM;
+ afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;
+ afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;
+ afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;
+ /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible
+ afd->pwfx->cbSize = 0;
+ */
+ afd->pwfx->nBlockAlign = (afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;
+ afd->pwfx->nAvgBytesPerSec = afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
+ break;
+ default:
+ WARN("Unsupported query %08lx\n", dwQuery);
+ return MMSYSERR_NOTSUPPORTED;
+ }
+
+ afd->dwFormatTag = WAVE_FORMAT_PCM;
+ afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CONVERTER;
+ afd->szFormat[0] = 0; /* let MSACM format this for us... */
+
+ return MMSYSERR_NOERROR;
+}
+
+static LRESULT PCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
+{
+ FIXME("(%p);\n", adfs);
+ return MMSYSERR_NOTSUPPORTED;
+}
+
+static LRESULT PCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
+{
+ assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
+
+ if (PCM_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
+ PCM_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
+ return ACMERR_NOTPOSSIBLE;
+ return MMSYSERR_NOERROR;
+}
+
+static LRESULT PCM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
+{
+ return MMSYSERR_NOERROR;
+}
+
+static inline DWORD PCM_round(DWORD a, DWORD b, DWORD c)
+{
+ assert(a && b && c);
+ /* to be sure, always return an entire number of c... */
+ return (a * b + c - 1) / c;
+}
+
+static LRESULT PCM_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss)
+{
+ switch (adss->fdwSize) {
+ case ACM_STREAMSIZEF_DESTINATION:
+ /* cbDstLength => cbSrcLength */
+ adss->cbSrcLength = PCM_round(adss->cbDstLength, adsi->pwfxSrc->nAvgBytesPerSec, adsi->pwfxDst->nAvgBytesPerSec);
+ break;
+ case ACM_STREAMSIZEF_SOURCE:
+ /* cbSrcLength => cbDstLength */
+ adss->cbDstLength = PCM_round(adss->cbSrcLength, adsi->pwfxDst->nAvgBytesPerSec, adsi->pwfxSrc->nAvgBytesPerSec);
+ break;
+ default:
+ WARN("Unsupported query %08lx\n", adss->fdwSize);
+ return MMSYSERR_NOTSUPPORTED;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/*
+ parameters :
+ 8 bit unsigned vs 16 bit signed (-32 / +32k ???)
+ mono vs stereo
+ sampling rate (8.0, 11.025, 22.05, 44.1 kHz)
+*/
+
+static void cvtMS88K(const unsigned char* src, int ns, unsigned char* dst)
+{
+ while (ns--) {
+ *dst++ = *src;
+ *dst++ = *src++;
+ }
+}
+
+static void cvtMS816K(const unsigned char* src, int ns, short* dst)
+{
+ int v;
+
+ while (ns--) {
+ v = ((short)(*src++) ^ 0x80) * 256;
+ *dst++ = LOBYTE(v);
+ *dst++ = HIBYTE(v);
+ *dst++ = LOBYTE(v);
+ *dst++ = HIBYTE(v);
+ }
+}
+
+static void cvtMS168K(const short* src, int ns, unsigned char* dst)
+{
+ unsigned char v;
+
+ while (ns--) {
+ v = HIBYTE(*src++) ^ 0x80;
+ *dst++ = v;
+ *dst++ = v;
+ }
+}
+
+static void cvtMS1616K(const short* src, int ns, short* dst)
+{
+ while (ns--) {
+ *dst++ = *src;
+ *dst++ = *src++;
+ }
+}
+
+static void cvtSM88K(const unsigned char* src, int ns, unsigned char* dst)
+{
+ while (ns--) {
+ *dst++ = (src[0] + src[1]) / 2;
+ src += 2;
+ }
+}
+
+static void cvtSM816K(const unsigned char* src, int ns, short* dst)
+{
+ int v;
+
+ while (ns--) {
+ v = (((short)(src[0]) ^ 0x80) * 256 + ((short)(src[1]) ^ 0x80) * 256) / 2;
+ src += 2;
+ *dst++ = LOBYTE(v);
+ *dst++ = HIBYTE(v);
+ }
+}
+
+static void cvtSM168K(const short* src, int ns, unsigned char* dst)
+{
+ unsigned char v;
+
+ while (ns--) {
+ v = ((HIBYTE(src[0]) ^ 0x80) + (HIBYTE(src[1]) ^ 0x80)) / 2;
+ src += 2;
+ *dst++ = v;
+ }
+}
+
+static void cvtSM1616K(const short* src, int ns, short* dst)
+{
+ while (ns--) {
+ *dst++ = (src[0] + src[1]) / 2;
+ src += 2;
+ }
+}
+
+static void cvtMM816K(const unsigned char* src, int ns, short* dst)
+{
+ int v;
+
+ while (ns--) {
+ v = ((short)(*src++) ^ 0x80) * 256;
+ *dst++ = LOBYTE(v);
+ *dst++ = HIBYTE(v);
+ }
+}
+
+static void cvtSS816K(const unsigned char* src, int ns, short* dst)
+{
+ int v;
+
+ while (ns--) {
+ v = ((short)(*src++) ^ 0x80) * 256;
+ *dst++ = LOBYTE(v);
+ *dst++ = HIBYTE(v);
+ v = ((short)(*src++) ^ 0x80) * 256;
+ *dst++ = LOBYTE(v);
+ *dst++ = HIBYTE(v);
+ }
+}
+
+static void cvtMM168K(const short* src, int ns, unsigned char* dst)
+{
+ while (ns--) {
+ *dst++ = HIBYTE(*src++) ^ 0x80;
+ }
+}
+
+static void cvtSS168K(const short* src, int ns, unsigned char* dst)
+{
+ while (ns--) {
+ *dst++ = HIBYTE(*src++) ^ 0x80;
+ *dst++ = HIBYTE(*src++) ^ 0x80;
+ }
+}
+
+static LRESULT PCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
+{
+ /* do the job */
+ if (adsi->pwfxSrc->nSamplesPerSec == adsi->pwfxDst->nSamplesPerSec) {
+ /* easy case */
+ if (adsi->pwfxSrc->wBitsPerSample == adsi->pwfxDst->wBitsPerSample &&
+ adsi->pwfxSrc->nChannels == adsi->pwfxDst->nChannels) {
+ memcpy(adsh->pbDst, adsh->pbSrc, adsh->cbSrcLength);
+ } else if (adsi->pwfxSrc->wBitsPerSample == 8 &&
+ adsi->pwfxDst->wBitsPerSample == 8) {
+ if (adsi->pwfxSrc->nChannels == 1 &&
+ adsi->pwfxDst->nChannels == 2)
+ cvtMS88K(adsh->pbSrc, adsh->cbSrcLength, adsh->pbDst);
+ else if (adsi->pwfxSrc->nChannels == 2 &&
+ adsi->pwfxDst->nChannels == 1)
+ cvtSM88K(adsh->pbSrc, adsh->cbSrcLength / 2, adsh->pbDst);
+ } else if (adsi->pwfxSrc->wBitsPerSample == 8 &&
+ adsi->pwfxDst->wBitsPerSample == 16) {
+ if (adsi->pwfxSrc->nChannels == 1 &&
+ adsi->pwfxDst->nChannels == 1)
+ cvtMM816K(adsh->pbSrc, adsh->cbSrcLength, (short*)adsh->pbDst);
+ else if (adsi->pwfxSrc->nChannels == 1 &&
+ adsi->pwfxDst->nChannels == 2)
+ cvtMS816K(adsh->pbSrc, adsh->cbSrcLength, (short*)adsh->pbDst);
+ else if (adsi->pwfxSrc->nChannels == 2 &&
+ adsi->pwfxDst->nChannels == 1)
+ cvtSM816K(adsh->pbSrc, adsh->cbSrcLength / 2, (short*)adsh->pbDst);
+ else if (adsi->pwfxSrc->nChannels == 2 &&
+ adsi->pwfxDst->nChannels == 2)
+ cvtSS816K(adsh->pbSrc, adsh->cbSrcLength / 2, (short*)adsh->pbDst);
+ } else if (adsi->pwfxSrc->wBitsPerSample == 16 &&
+ adsi->pwfxDst->wBitsPerSample == 8) {
+ if (adsi->pwfxSrc->nChannels == 1 &&
+ adsi->pwfxDst->nChannels == 1)
+ cvtMM168K((short*)adsh->pbSrc, adsh->cbSrcLength / 2, adsh->pbDst);
+ else if (adsi->pwfxSrc->nChannels == 1 &&
+ adsi->pwfxDst->nChannels == 2)
+ cvtMS168K((short*)adsh->pbSrc, adsh->cbSrcLength / 2, adsh->pbDst);
+ else if (adsi->pwfxSrc->nChannels == 2 &&
+ adsi->pwfxDst->nChannels == 1)
+ cvtSM168K((short*)adsh->pbSrc, adsh->cbSrcLength / 4, adsh->pbDst);
+ else if (adsi->pwfxSrc->nChannels == 2 &&
+ adsi->pwfxDst->nChannels == 2)
+ cvtSS168K((short*)adsh->pbSrc, adsh->cbSrcLength / 4, adsh->pbDst);
+ } else if (adsi->pwfxSrc->wBitsPerSample == 16 &&
+ adsi->pwfxDst->wBitsPerSample == 16) {
+ if (adsi->pwfxSrc->nChannels == 1 &&
+ adsi->pwfxDst->nChannels == 2)
+ cvtMS1616K((short*)adsh->pbSrc, adsh->cbSrcLength / 2, (short*)adsh->pbDst);
+ else if (adsi->pwfxSrc->nChannels == 2 &&
+ adsi->pwfxDst->nChannels == 1)
+ cvtSM1616K((short*)adsh->pbSrc, adsh->cbSrcLength / 4, (short*)adsh->pbDst);
+ } else FIXME("NIY\n");
+ /* FIXME: rounding shall be taken care off... */
+ adsh->cbSrcLengthUsed = adsh->cbSrcLength;
+ adsh->cbDstLengthUsed = (adsh->cbSrcLength * adsi->pwfxDst->nBlockAlign) / adsi->pwfxSrc->nBlockAlign;
+
+ } else {
+ FIXME("NIY\n");
+ return MMSYSERR_NOTSUPPORTED;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+ * PCM_DriverProc [exported]
+ */
+LRESULT CALLBACK PCM_DriverProc(DWORD dwDevID, HDRVR hDriv, UINT wMsg,
+ LPARAM dwParam1, LPARAM dwParam2)
+{
+ TRACE("(%08lx %08lx %u %08lx %08lx);\n",
+ dwDevID, (DWORD)hDriv, wMsg, dwParam1, dwParam2);
+
+ switch (wMsg) {
+ case DRV_LOAD: return 1;
+ case DRV_FREE: return 1;
+ case DRV_OPEN: return PCM_drvOpen((LPSTR)dwParam1);
+ case DRV_CLOSE: return PCM_drvClose(dwDevID);
+ case DRV_ENABLE: return 1;
+ case DRV_DISABLE: return 1;
+ case DRV_QUERYCONFIGURE: return 1;
+ case DRV_CONFIGURE: MessageBoxA(0, "MSACM PCM filter !", "Wine Driver", MB_OK); return 1;
+ case DRV_INSTALL: return DRVCNF_RESTART;
+ case DRV_REMOVE: return DRVCNF_RESTART;
+
+ case ACMDM_DRIVER_NOTIFY:
+ /* no caching from other ACM drivers is done so far */
+ return MMSYSERR_NOERROR;
+
+ case ACMDM_DRIVER_DETAILS:
+ return PCM_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
+
+ case ACMDM_FORMATTAG_DETAILS:
+ return PCM_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
+
+ case ACMDM_FORMAT_DETAILS:
+ return PCM_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
+
+ case ACMDM_FORMAT_SUGGEST:
+ return PCM_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
+
+ case ACMDM_STREAM_OPEN:
+ return PCM_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
+
+ case ACMDM_STREAM_CLOSE:
+ return PCM_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
+
+ case ACMDM_STREAM_SIZE:
+ return PCM_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
+
+ case ACMDM_STREAM_CONVERT:
+ return PCM_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2);
+
+ case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
+ case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
+ /* this converter is not a hardware driver */
+ case ACMDM_FILTERTAG_DETAILS:
+ case ACMDM_FILTER_DETAILS:
+ /* this converter is not a filter */
+ case ACMDM_STREAM_RESET:
+ /* only needed for asynchronous driver... we aren't, so just say it */
+ case ACMDM_STREAM_PREPARE:
+ case ACMDM_STREAM_UNPREPARE:
+ /* nothing special to do here... so don't do anything */
+ return MMSYSERR_NOTSUPPORTED;
+
+ default:
+ return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
+ }
+ return 0;
+}
diff --git a/dlls/msacm/wineacm.h b/dlls/msacm/wineacm.h
index 4356cc6..3595abf 100644
--- a/dlls/msacm/wineacm.h
+++ b/dlls/msacm/wineacm.h
@@ -285,7 +285,6 @@
{
WINE_ACMOBJ obj;
HDRVR hDrvr;
- DRIVERPROC pfnDriverProc;
PWINE_ACMDRIVER pNextACMDriver;
} WINE_ACMDRIVER;
@@ -328,6 +327,10 @@
/* From msacm32.c */
extern HINSTANCE MSACM_hInstance32;
+/* From pcmcnvtr.c */
+LRESULT CALLBACK PCM_DriverProc(DWORD dwDevID, HDRVR hDriv, UINT wMsg,
+ LPARAM dwParam1, LPARAM dwParam2);
+
/* Dialog box templates */
#define DLG_ACMFORMATCHOOSE_ID 70
#define IDD_ACMFORMATCHOOSE_BTN_HELP 9