Added PCM converter internal driver.
A few driver handling fixes.
This commit is contained in:
parent
bd8ede1bac
commit
140d8cd909
|
@ -14,6 +14,7 @@ C_SRCS = \
|
|||
internal.c \
|
||||
msacm32_main.c \
|
||||
msacm_main.c \
|
||||
pcmconverter.c \
|
||||
stream.c
|
||||
|
||||
RC_SRCS = \
|
||||
|
|
|
@ -76,27 +76,32 @@ MMRESULT WINAPI acmDriverAddW(PHACMDRIVERID phadid, HINSTANCE hinstModule,
|
|||
*/
|
||||
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 @@ MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpe
|
|||
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 @@ MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpe
|
|||
|
||||
/* FIXME: Create a WINE_ACMDRIVER32 */
|
||||
*phad = (HACMDRIVER)pad;
|
||||
|
||||
TRACE("'%s' => %08lx\n", padid->pszDriverAlias, (DWORD)pad);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -484,7 +484,7 @@ MMRESULT WINAPI acmFormatEnumW(HACMDRIVER had, PACMFORMATDETAILSW pafd,
|
|||
|
||||
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;
|
||||
|
|
|
@ -42,8 +42,8 @@ PWINE_ACMDRIVERID MSACM_RegisterDriver(LPSTR pszDriverAlias, LPSTR pszFileName,
|
|||
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 @@ void MSACM_RegisterAllDrivers(void)
|
|||
{
|
||||
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 @@ void MSACM_RegisterAllDrivers(void)
|
|||
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 @@ void MSACM_RegisterAllDrivers(void)
|
|||
}
|
||||
|
||||
HeapFree(MSACM_hHeap, 0, pszBuffer);
|
||||
|
||||
MSACM_RegisterDriver("msacm32.dll", "msacm32.dll", 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -51,3 +51,6 @@ import kernel32.dll
|
|||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -285,7 +285,6 @@ typedef struct _WINE_ACMDRIVER
|
|||
{
|
||||
WINE_ACMOBJ obj;
|
||||
HDRVR hDrvr;
|
||||
DRIVERPROC pfnDriverProc;
|
||||
PWINE_ACMDRIVER pNextACMDriver;
|
||||
} WINE_ACMDRIVER;
|
||||
|
||||
|
@ -328,6 +327,10 @@ extern MMRESULT MSACM_Message(HACMDRIVER, UINT, LPARAM, LPARAM);
|
|||
/* 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
|
||||
|
|
Loading…
Reference in New Issue