/*********************************************************************** * MSACM_RegisterAllDrivers() */ void MSACM_RegisterAllDrivers(void) { static const WCHAR msacm32[] = {'m','s','a','c','m','3','2','.','d','l','l','\0'}; static const WCHAR msacmW[] = {'M','S','A','C','M','.'}; static const WCHAR drv32[] = {'d','r','i','v','e','r','s','3','2','\0'}; static const WCHAR sys[] = {'s','y','s','t','e','m','.','i','n','i','\0'}; static const WCHAR drvkey[] = {'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', 'W','i','n','d','o','w','s',' ','N','T','\\', 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 'D','r','i','v','e','r','s','3','2','\0'}; DWORD i, cnt, bufLen, lRet, type; WCHAR buf[2048], valname[64], *name, *s; FILETIME lastWrite; HKEY hKey; /* FIXME: What if the user edits system.ini while the program is running? * Does Windows handle that? */ if (MSACM_pFirstACMDriverID) return; lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drvkey, 0, KEY_QUERY_VALUE, &hKey); if (lRet == ERROR_SUCCESS) { RegQueryInfoKeyW( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0); for (i = 0; i < cnt; i++) { bufLen = sizeof(buf) / sizeof(buf[0]); lRet = RegEnumKeyExW(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite); if (lRet != ERROR_SUCCESS) continue; if (strncmpiW(buf, msacmW, sizeof(msacmW)/sizeof(msacmW[0]))) continue; if (!(name = strchrW(buf, '='))) continue; *name = 0; MSACM_RegisterDriver(buf, name + 1, 0); } i = 0; cnt = sizeof(valname) / sizeof(*valname); bufLen = sizeof(buf); while(RegEnumValueW(hKey, i, valname, &cnt, 0, &type, (BYTE*)buf, &bufLen) == ERROR_SUCCESS){ if(!strncmpiW(valname, msacmW, sizeof(msacmW) / sizeof(*msacmW))) MSACM_RegisterDriver(valname, buf, 0); ++i; } RegCloseKey( hKey ); } if (GetPrivateProfileSectionW(drv32, buf, sizeof(buf)/sizeof(buf[0]), sys)) { for(s = buf; *s; s += strlenW(s) + 1) { if (strncmpiW(s, msacmW, sizeof(msacmW)/sizeof(msacmW[0]))) continue; if (!(name = strchrW(s, '='))) continue; *name = 0; MSACM_RegisterDriver(s, name + 1, 0); *name = '='; } } MSACM_ReorderDriversByPriority(); MSACM_RegisterDriver(msacm32, msacm32, 0); }
/*********************************************************************** * MSACM_RegisterDriverFromRegistry() */ PWINE_ACMDRIVERID MSACM_RegisterDriverFromRegistry(LPCWSTR pszRegEntry) { static const WCHAR msacmW[] = {'M','S','A','C','M','.'}; static const WCHAR drvkey[] = {'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', 'W','i','n','d','o','w','s',' ','N','T','\\', 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 'D','r','i','v','e','r','s','3','2','\0'}; WCHAR buf[2048]; DWORD bufLen, lRet; HKEY hKey; PWINE_ACMDRIVERID padid = NULL; /* The requested registry entry must have the format msacm.XXXXX in order to be recognized in any future sessions of msacm */ if (0 == strncmpiW(buf, msacmW, sizeof(msacmW)/sizeof(WCHAR))) { lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drvkey, 0, KEY_QUERY_VALUE, &hKey); if (lRet != ERROR_SUCCESS) { WARN("unable to open registry key - 0x%08x\n", lRet); } else { bufLen = sizeof(buf); lRet = RegQueryValueExW(hKey, pszRegEntry, NULL, NULL, (LPBYTE)buf, &bufLen); if (lRet != ERROR_SUCCESS) { WARN("unable to query requested subkey %s - 0x%08x\n", debugstr_w(pszRegEntry), lRet); } else { MSACM_RegisterDriver(pszRegEntry, buf, 0); } RegCloseKey( hKey ); } } return padid; }
/*********************************************************************** * acmDriverAddA (MSACM32.2) */ MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd) { if (!phadid) return MMSYSERR_INVALPARAM; /* Check if any unknown flags */ if (fdwAdd & ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND| ACM_DRIVERADDF_GLOBAL)) return MMSYSERR_INVALFLAG; /* Check if any incompatible flags */ if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND)) return MMSYSERR_INVALFLAG; /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a * LoadDriver on it, to be sure we can call SendDriverMessage on the * hDrvr handle. */ *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule); /* FIXME: lParam, dwPriority and fdwAdd ignored */ return MMSYSERR_NOERROR; }
/*********************************************************************** * MSACM_RegisterAllDrivers() */ 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? */ if (MSACM_pFirstACMDriverID) return; /* FIXME: Does not work! How do I determine the section length? */ dwBufferLength = 1024; /* EPP GetPrivateProfileSectionA("drivers32", NULL, 0, "system.ini"); */ pszBuffer = (LPSTR) HeapAlloc(MSACM_hHeap, 0, dwBufferLength); if (GetPrivateProfileSectionA("drivers32", pszBuffer, dwBufferLength, "system.ini")) { char* s = pszBuffer; while (*s) { if (!strncasecmp("MSACM.", s, 6)) { char *s2 = s; while (*s2 != '\0' && *s2 != '=') s2++; if (*s2) { *s2 = '\0'; MSACM_RegisterDriver(s, s2 + 1, 0); *s2 = '='; } } s += strlen(s) + 1; /* Either next char or \0 */ } } HeapFree(MSACM_hHeap, 0, pszBuffer); MSACM_RegisterDriver("msacm32.dll", "msacm32.dll", 0); }
static int preinit(sh_audio_t *sh_audio) { HRESULT ret; WAVEFORMATEX *in_fmt = sh_audio->wf; DWORD srcsize = 0; acm_context_t *priv; priv = malloc(sizeof(acm_context_t)); if (!priv) return 0; sh_audio->context = priv; mp_msg(MSGT_WIN32, MSGL_V, "======= Win32 (ACM) AUDIO Codec init =======\n"); // priv->handle = NULL; priv->o_wf = malloc(sizeof(*priv->o_wf)); if (!priv->o_wf) { mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_ACMiniterror); return 0; } priv->o_wf->nChannels = in_fmt->nChannels; priv->o_wf->nSamplesPerSec = in_fmt->nSamplesPerSec; priv->o_wf->nAvgBytesPerSec = 2*in_fmt->nSamplesPerSec*in_fmt->nChannels; priv->o_wf->wFormatTag = WAVE_FORMAT_PCM; priv->o_wf->nBlockAlign = 2*in_fmt->nChannels; priv->o_wf->wBitsPerSample = 16; // priv->o_wf->wBitsPerSample = inf_fmt->wBitsPerSample; priv->o_wf->cbSize = 0; if ( mp_msg_test(MSGT_DECAUDIO,MSGL_V) ) { mp_msg(MSGT_DECAUDIO, MSGL_V, "Input format:\n"); print_wave_header(in_fmt, MSGL_V); mp_msg(MSGT_DECAUDIO, MSGL_V, "Output format:\n"); print_wave_header(priv->o_wf, MSGL_V); } MSACM_RegisterDriver((const char *)sh_audio->codec->dll, in_fmt->wFormatTag, 0); ret = acmStreamOpen(&priv->handle, (HACMDRIVER)NULL, in_fmt, priv->o_wf, NULL, 0, 0, 0); if (ret) { if (ret == ACMERR_NOTPOSSIBLE) mp_msg(MSGT_WIN32, MSGL_ERR, "ACM_Decoder: Unappropriate audio format\n"); else mp_msg(MSGT_WIN32, MSGL_ERR, "ACM_Decoder: acmStreamOpen error: %d\n", (int)ret); mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_ACMiniterror); return 0; } mp_msg(MSGT_WIN32, MSGL_V, "Audio codec opened OK! ;-)\n"); acmStreamSize(priv->handle, in_fmt->nBlockAlign, &srcsize, ACM_STREAMSIZEF_SOURCE); //if ( mp_msg_test(MSGT_DECAUDIO,MSGL_V) ) printf("Audio ACM output buffer min. size: %ld (reported by codec)\n", srcsize); srcsize *= 2; //if (srcsize < MAX_OUTBURST) srcsize = MAX_OUTBURST; if (!srcsize) { mp_msg(MSGT_WIN32, MSGL_WARN, "Warning! ACM codec reports srcsize=0\n"); srcsize = 16384; } // limit srcsize to 4-16kb //while(srcsize && srcsize<4096) srcsize*=2; //while(srcsize>16384) srcsize/=2; sh_audio->audio_out_minsize=srcsize; // audio output min. size mp_msg(MSGT_WIN32,MSGL_V,"Audio ACM output buffer min. size: %ld\n",srcsize); acmStreamSize(priv->handle, srcsize, &srcsize, ACM_STREAMSIZEF_DESTINATION); // if(srcsize<in_fmt->nBlockAlign) srcsize=in_fmt->nBlockAlign; if (!srcsize) { mp_msg(MSGT_WIN32, MSGL_WARN, "Warning! ACM codec reports srcsize=0\n"); srcsize = 2*in_fmt->nBlockAlign; } mp_msg(MSGT_WIN32,MSGL_V,"Audio ACM input buffer min. size: %ld\n",srcsize); sh_audio->audio_in_minsize=2*srcsize; // audio input min. size sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; sh_audio->channels=priv->o_wf->nChannels; sh_audio->samplerate=priv->o_wf->nSamplesPerSec; sh_audio->samplesize=2; mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Win32/ACM audio codec init OK!\n"); return 1; }
/*********************************************************************** * acmDriverAddW (MSACM32.@) * */ MMRESULT WINAPI acmDriverAddW(PHACMDRIVERID phadid, HINSTANCE hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd) { PWINE_ACMLOCALDRIVER pLocalDrv = NULL; TRACE("(%p, %p, %08lx, %08x, %08x)\n", phadid, hinstModule, lParam, dwPriority, fdwAdd); if (!phadid) { WARN("invalid parameter\n"); return MMSYSERR_INVALPARAM; } /* Check if any unknown flags */ if (fdwAdd & ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND| ACM_DRIVERADDF_GLOBAL)) { WARN("invalid flag\n"); return MMSYSERR_INVALFLAG; } /* Check if any incompatible flags */ if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND)) { WARN("invalid flag\n"); return MMSYSERR_INVALFLAG; } switch (fdwAdd & ACM_DRIVERADDF_TYPEMASK) { case ACM_DRIVERADDF_NAME: /* hInstModule (unused) lParam name of value in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32 dwPriority (unused, set to 0) */ *phadid = (HACMDRIVERID) MSACM_RegisterDriverFromRegistry((LPCWSTR)lParam); if (!*phadid) { ERR("Unable to register driver via ACM_DRIVERADDF_NAME\n"); return MMSYSERR_INVALPARAM; } break; case ACM_DRIVERADDF_FUNCTION: /* hInstModule Handle of module which contains driver entry proc lParam Driver function address dwPriority (unused, set to 0) */ fdwAdd &= ~ACM_DRIVERADDF_TYPEMASK; /* FIXME: fdwAdd ignored */ /* Application-supplied acmDriverProc's are placed at the top of the priority unless fdwAdd indicates ACM_DRIVERADDF_GLOBAL */ pLocalDrv = MSACM_RegisterLocalDriver(hinstModule, (DRIVERPROC)lParam); *phadid = pLocalDrv ? (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, pLocalDrv) : NULL; if (!*phadid) { ERR("Unable to register driver via ACM_DRIVERADDF_FUNCTION\n"); return MMSYSERR_INVALPARAM; } break; case ACM_DRIVERADDF_NOTIFYHWND: /* hInstModule (unused) lParam Handle of notification window dwPriority Window message to send for notification broadcasts */ *phadid = (HACMDRIVERID) MSACM_RegisterNotificationWindow((HWND)lParam, dwPriority); if (!*phadid) { ERR("Unable to register driver via ACM_DRIVERADDF_NOTIFYHWND\n"); return MMSYSERR_INVALPARAM; } break; default: ERR("invalid flag value 0x%08x for fdwAdd\n", fdwAdd & ACM_DRIVERADDF_TYPEMASK); return MMSYSERR_INVALFLAG; } MSACM_BroadcastNotification(); return MMSYSERR_NOERROR; }