static void check_count(UINT uMetric) { DWORD dwMetric; MMRESULT rc; /* try invalid result pointer */ rc = acmMetrics(NULL, uMetric, 0); ok(rc == MMSYSERR_INVALPARAM, "acmMetrics(NULL, %s, 0): rc = 0x%08x, should be 0x%08x\n", get_metric(uMetric), rc, MMSYSERR_INVALPARAM); /* try invalid handle */ rc = acmMetrics((HACMOBJ)1, uMetric, &dwMetric); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(1, %s, %p): rc = 0x%08x, should be 0x%08x\n", get_metric(uMetric), &dwMetric, rc, MMSYSERR_INVALHANDLE); /* try invalid result pointer and handle */ rc = acmMetrics((HACMOBJ)1, uMetric, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(1, %s, 0): rc = 0x%08x, should be 0x%08x\n", get_metric(uMetric), rc, MMSYSERR_INVALHANDLE); /* try valid parameters */ rc = acmMetrics(NULL, uMetric, &dwMetric); ok(rc == MMSYSERR_NOERROR, "acmMetrics() failed: rc = 0x%08x\n", rc); if (rc == MMSYSERR_NOERROR && winetest_interactive) trace("%s: %u\n", get_metric(uMetric), dwMetric); }
void AllocLocalCompressFormat() { if (pwfxLocal) { //Do nothing....already allocated } else { MMRESULT mmresult = acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &cbwfxLocal); if (MMSYSERR_NOERROR != mmresult) { CString msgstr; msgstr.Format("Metrics failed mmresult=%u!", mmresult); ::MessageBox(NULL,msgstr,"Note", MB_OK | MB_ICONEXCLAMATION); return ; } if (cbwfxLocal < cbwfx) cbwfxLocal = cbwfx; pwfxLocal = (LPWAVEFORMATEX)GlobalAllocPtr(GHND, cbwfxLocal); if (NULL == pwfxLocal) { CString msgstr; msgstr.Format("GlobalAllocPtr(%lu) failed!", cbwfxLocal); ::MessageBox(NULL,msgstr,"Note", MB_OK | MB_ICONEXCLAMATION); return ; } } }
MMRESULT16 WINAPI acmMetrics16( HACMOBJ16 hao, UINT16 uMetric, LPVOID pMetric) { FIXME("(0x%04x, %d, %p): semi-stub\n", hao, uMetric, pMetric); if(!hao) return acmMetrics(0, uMetric, pMetric); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return MMSYSERR_ERROR; }
// Choose an audio capture format using ACM void CAudioGrabber::ChooseAudioFormat() { DWORD dwSize; LPWAVEFORMATEX lpwfx; AM_MEDIA_TYPE *pmt; // There's no point if we can't set a new format if(pASC == NULL) return; // What's the largest format size around? acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize); HRESULT hr = pASC->GetFormat(&pmt); if(hr != NOERROR) return; lpwfx = (LPWAVEFORMATEX)pmt->pbFormat; dwSize = (DWORD) (max(dwSize, lpwfx->cbSize + sizeof(WAVEFORMATEX))); // !!! This doesn't really map to the supported formats of the filter. // We should be using a property page based on IAMStreamConfig lpwfx = (LPWAVEFORMATEX)GlobalAllocPtr(GHND, dwSize); if(lpwfx) { CopyMemory(lpwfx, pmt->pbFormat, pmt->cbFormat); lpwfx->nChannels = 1; lpwfx->nSamplesPerSec = 44100; lpwfx->wBitsPerSample = 16; lpwfx->nBlockAlign = lpwfx->nChannels * lpwfx->wBitsPerSample / 8; lpwfx->nAvgBytesPerSec = lpwfx->nChannels * lpwfx->nSamplesPerSec * lpwfx->wBitsPerSample / 8; //lpwfx->wFormatTag = 0x0161; ((CMediaType *)pmt)->SetFormat((LPBYTE)lpwfx, lpwfx->cbSize + sizeof(WAVEFORMATEX)); pASC->SetFormat(pmt); // Filter will reconnect GlobalFreePtr(lpwfx) ; } DeleteMediaType(pmt); }
static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid, DWORD_PTR dwInstance, DWORD fdwSupport) { MMRESULT rc; ACMDRIVERDETAILSA dd; HACMDRIVER had; DWORD dwDriverPriority; DWORD dwDriverSupport; if (winetest_interactive) { trace("id: %p\n", hadid); trace(" Supports:\n"); if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_ASYNC) trace(" async conversions\n"); if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) trace(" different format conversions\n"); if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER) trace(" same format conversions\n"); if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER) trace(" filtering\n"); } /* try an invalid pointer */ rc = acmDriverDetailsA(hadid, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmDriverDetailsA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try an invalid structure size */ ZeroMemory(&dd, sizeof(dd)); rc = acmDriverDetailsA(hadid, &dd, 0); ok(rc == MMSYSERR_INVALPARAM, "acmDriverDetailsA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* MSDN says this should fail but it doesn't in practice */ dd.cbStruct = 4; rc = acmDriverDetailsA(hadid, &dd, 0); ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NOTSUPPORTED, "acmDriverDetailsA(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* try an invalid handle */ dd.cbStruct = sizeof(dd); rc = acmDriverDetailsA((HACMDRIVERID)1, &dd, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverDetailsA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try an invalid handle and pointer */ rc = acmDriverDetailsA((HACMDRIVERID)1, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmDriverDetailsA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try invalid details */ rc = acmDriverDetailsA(hadid, &dd, -1); ok(rc == MMSYSERR_INVALFLAG, "acmDriverDetailsA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALFLAG); /* try valid parameters */ rc = acmDriverDetailsA(hadid, &dd, 0); ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NOTSUPPORTED, "acmDriverDetailsA(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* cbStruct should contain size of returned data (at most sizeof(dd)) TODO: should it be *exactly* sizeof(dd), as tested here? */ if (rc == MMSYSERR_NOERROR) { static const struct { const char *shortname; WORD mid; WORD pid; WORD pid_alt; } *iter, expected_ids[] = { { "Microsoft IMA ADPCM", MM_MICROSOFT, MM_MSFT_ACM_IMAADPCM }, { "MS-ADPCM", MM_MICROSOFT, MM_MSFT_ACM_MSADPCM }, { "Microsoft CCITT G.711", MM_MICROSOFT, MM_MSFT_ACM_G711}, { "MPEG Layer-3 Codec", MM_FRAUNHOFER_IIS, MM_FHGIIS_MPEGLAYER3_DECODE, MM_FHGIIS_MPEGLAYER3_PROFESSIONAL }, { "MS-PCM", MM_MICROSOFT, MM_MSFT_ACM_PCM }, { 0 } }; ok(dd.cbStruct == sizeof(dd), "acmDriverDetailsA(): cbStruct = %08x\n", dd.cbStruct); for (iter = expected_ids; iter->shortname; ++iter) { if (!strcmp(iter->shortname, dd.szShortName)) { /* try alternative product id on mismatch */ if (iter->pid_alt && iter->pid != dd.wPid) ok(iter->mid == dd.wMid && iter->pid_alt == dd.wPid, "Got wrong manufacturer (0x%x vs 0x%x) or product (0x%x vs 0x%x)\n", dd.wMid, iter->mid, dd.wPid, iter->pid_alt); else ok(iter->mid == dd.wMid && iter->pid == dd.wPid, "Got wrong manufacturer (0x%x vs 0x%x) or product (0x%x vs 0x%x)\n", dd.wMid, iter->mid, dd.wPid, iter->pid); } } } if (rc == MMSYSERR_NOERROR && winetest_interactive) { trace(" Short name: %s\n", dd.szShortName); trace(" Long name: %s\n", dd.szLongName); trace(" Copyright: %s\n", dd.szCopyright); trace(" Licensing: %s\n", dd.szLicensing); trace(" Features: %s\n", dd.szFeatures); trace(" Supports %u formats\n", dd.cFormatTags); trace(" Supports %u filter formats\n", dd.cFilterTags); trace(" Mid: 0x%x\n", dd.wMid); trace(" Pid: 0x%x\n", dd.wPid); } /* try bad pointer */ rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, 0); ok(rc == MMSYSERR_INVALPARAM, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, &dwDriverPriority); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try bad pointer and handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try valid parameters */ rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, &dwDriverSupport); ok(rc == MMSYSERR_NOERROR, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* try bad pointer */ rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, 0); ok(rc == MMSYSERR_INVALPARAM, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try bad pointer and handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try valid parameters */ rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport); ok(rc == MMSYSERR_NOERROR, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* try invalid pointer */ rc = acmDriverOpen(0, hadid, 0); ok(rc == MMSYSERR_INVALPARAM, "acmDriverOpen(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try invalid handle */ rc = acmDriverOpen(&had, (HACMDRIVERID)1, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverOpen(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try invalid open */ rc = acmDriverOpen(&had, hadid, -1); ok(rc == MMSYSERR_INVALFLAG, "acmDriverOpen(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALFLAG); /* try valid parameters */ rc = acmDriverOpen(&had, hadid, 0); ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NODRIVER, "acmDriverOpen(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); if (rc == MMSYSERR_NOERROR) { DWORD dwSize; HACMDRIVERID hid; /* try bad pointer */ rc = acmDriverID((HACMOBJ)had, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmDriverID(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad handle */ rc = acmDriverID((HACMOBJ)1, &hid, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverID(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try bad handle and pointer */ rc = acmDriverID((HACMOBJ)1, 0, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverID(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try bad flag */ rc = acmDriverID((HACMOBJ)had, &hid, 1); ok(rc == MMSYSERR_INVALFLAG, "acmDriverID(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALFLAG); /* try valid parameters */ rc = acmDriverID((HACMOBJ)had, &hid, 0); ok(rc == MMSYSERR_NOERROR, "acmDriverID(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); ok(hid == hadid, "acmDriverID() returned ID %p doesn't equal %p\n", hid, hadid); /* try bad pointer */ rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, 0); ok(rc == MMSYSERR_INVALPARAM, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try bad pointer and handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try valid parameters */ rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize); ok(rc == MMSYSERR_NOERROR, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); if (rc == MMSYSERR_NOERROR) { ACMFORMATDETAILSA fd; WAVEFORMATEX * pwfx; ACMFORMATTAGDETAILSA aftd; /* try bad pointer */ rc = acmFormatEnumA(had, 0, FormatEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatEnumA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad structure size */ ZeroMemory(&fd, sizeof(fd)); rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatEnumA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); fd.cbStruct = sizeof(fd) - 1; rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatEnumA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); if (dwSize < sizeof(WAVEFORMATEX)) dwSize = sizeof(WAVEFORMATEX); pwfx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); pwfx->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX); pwfx->wFormatTag = WAVE_FORMAT_UNKNOWN; fd.cbStruct = sizeof(fd); fd.pwfx = pwfx; fd.cbwfx = dwSize; fd.dwFormatTag = WAVE_FORMAT_UNKNOWN; /* try valid parameters */ rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0); ok(rc == MMSYSERR_NOERROR, "acmFormatEnumA(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* try bad pointer */ rc = acmFormatTagEnumA(had, 0, FormatTagEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatTagEnumA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad structure size */ ZeroMemory(&aftd, sizeof(aftd)); rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatTagEnumA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); aftd.cbStruct = sizeof(aftd) - 1; rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatTagEnumA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); aftd.cbStruct = sizeof(aftd); aftd.dwFormatTag = WAVE_FORMAT_UNKNOWN; /* try bad flag */ rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 1); ok(rc == MMSYSERR_INVALFLAG, "acmFormatTagEnumA(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALFLAG); /* try valid parameters */ rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 0); ok(rc == MMSYSERR_NOERROR, "acmFormatTagEnumA(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); HeapFree(GetProcessHeap(), 0, pwfx); /* try invalid handle */ rc = acmDriverClose((HACMDRIVER)1, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverClose(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try invalid flag */ rc = acmDriverClose(had, 1); ok(rc == MMSYSERR_INVALFLAG, "acmDriverClose(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALFLAG); /* try valid parameters */ rc = acmDriverClose(had, 0); ok(rc == MMSYSERR_NOERROR, "acmDriverClose(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* try closing again */ rc = acmDriverClose(had, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverClose(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); } } return TRUE; }
static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid, DWORD_PTR dwInstance, DWORD fdwSupport) { MMRESULT rc; ACMDRIVERDETAILS dd; HACMDRIVER had; DWORD dwDriverPriority; DWORD dwDriverSupport; if (winetest_interactive) { trace("id: %p\n", hadid); trace(" Supports:\n"); if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_ASYNC) trace(" async conversions\n"); if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) trace(" different format conversions\n"); if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER) trace(" same format conversions\n"); if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER) trace(" filtering\n"); } /* try an invalid pointer */ rc = acmDriverDetails(hadid, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmDriverDetails(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try an invalid structure size */ ZeroMemory(&dd, sizeof(dd)); rc = acmDriverDetails(hadid, &dd, 0); ok(rc == MMSYSERR_INVALPARAM, "acmDriverDetails(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* MSDN says this should fail but it doesn't in practice */ dd.cbStruct = 4; rc = acmDriverDetails(hadid, &dd, 0); ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NOTSUPPORTED, "acmDriverDetails(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* try an invalid handle */ dd.cbStruct = sizeof(dd); rc = acmDriverDetails((HACMDRIVERID)1, &dd, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverDetails(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try an invalid handle and pointer */ rc = acmDriverDetails((HACMDRIVERID)1, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmDriverDetails(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try invalid details */ rc = acmDriverDetails(hadid, &dd, -1); ok(rc == MMSYSERR_INVALFLAG, "acmDriverDetails(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALFLAG); /* try valid parameters */ rc = acmDriverDetails(hadid, &dd, 0); ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NOTSUPPORTED, "acmDriverDetails(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* cbStruct should contain size of returned data (at most sizeof(dd)) TODO: should it be *exactly* sizeof(dd), as tested here? */ if (rc == MMSYSERR_NOERROR) { ok(dd.cbStruct == sizeof(dd), "acmDriverDetails(): cbStruct = %08x\n", dd.cbStruct); } if (rc == MMSYSERR_NOERROR && winetest_interactive) { trace(" Short name: %s\n", dd.szShortName); trace(" Long name: %s\n", dd.szLongName); trace(" Copyright: %s\n", dd.szCopyright); trace(" Licensing: %s\n", dd.szLicensing); trace(" Features: %s\n", dd.szFeatures); trace(" Supports %u formats\n", dd.cFormatTags); trace(" Supports %u filter formats\n", dd.cFilterTags); } /* try bad pointer */ rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, 0); ok(rc == MMSYSERR_INVALPARAM, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, &dwDriverPriority); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try bad pointer and handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try valid parameters */ rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, &dwDriverSupport); ok(rc == MMSYSERR_NOERROR, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* try bad pointer */ rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, 0); ok(rc == MMSYSERR_INVALPARAM, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try bad pointer and handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try valid parameters */ rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport); ok(rc == MMSYSERR_NOERROR, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* try invalid pointer */ rc = acmDriverOpen(0, hadid, 0); ok(rc == MMSYSERR_INVALPARAM, "acmDriverOpen(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try invalid handle */ rc = acmDriverOpen(&had, (HACMDRIVERID)1, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverOpen(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try invalid open */ rc = acmDriverOpen(&had, hadid, -1); ok(rc == MMSYSERR_INVALFLAG, "acmDriverOpen(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALFLAG); /* try valid parameters */ rc = acmDriverOpen(&had, hadid, 0); ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NODRIVER, "acmDriverOpen(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); if (rc == MMSYSERR_NOERROR) { DWORD dwSize; HACMDRIVERID hid; /* try bad pointer */ rc = acmDriverID((HACMOBJ)had, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmDriverID(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad handle */ rc = acmDriverID((HACMOBJ)1, &hid, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverID(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try bad handle and pointer */ rc = acmDriverID((HACMOBJ)1, 0, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverID(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try bad flag */ rc = acmDriverID((HACMOBJ)had, &hid, 1); ok(rc == MMSYSERR_INVALFLAG, "acmDriverID(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALFLAG); /* try valid parameters */ rc = acmDriverID((HACMOBJ)had, &hid, 0); ok(rc == MMSYSERR_NOERROR, "acmDriverID(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); ok(hid == hadid, "acmDriverID() returned ID %p doesn't equal %p\n", hid, hadid); /* try bad pointer */ rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, 0); ok(rc == MMSYSERR_INVALPARAM, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try bad pointer and handle */ rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try valid parameters */ rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize); ok(rc == MMSYSERR_NOERROR, "acmMetrics(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); if (rc == MMSYSERR_NOERROR) { ACMFORMATDETAILS fd; WAVEFORMATEX * pwfx; ACMFORMATTAGDETAILS aftd; /* try bad pointer */ rc = acmFormatEnum(had, 0, FormatEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatEnum(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad structure size */ ZeroMemory(&fd, sizeof(fd)); rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatEnum(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); fd.cbStruct = sizeof(fd) - 1; rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatEnum(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); if (dwSize < sizeof(WAVEFORMATEX)) dwSize = sizeof(WAVEFORMATEX); pwfx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); pwfx->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX); pwfx->wFormatTag = WAVE_FORMAT_UNKNOWN; fd.cbStruct = sizeof(fd); fd.pwfx = pwfx; fd.cbwfx = dwSize; fd.dwFormatTag = WAVE_FORMAT_UNKNOWN; /* try valid parameters */ rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0); ok(rc == MMSYSERR_NOERROR, "acmFormatEnum(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* try bad pointer */ rc = acmFormatTagEnum(had, 0, FormatTagEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatTagEnum(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); /* try bad structure size */ ZeroMemory(&aftd, sizeof(aftd)); rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatTagEnum(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); aftd.cbStruct = sizeof(aftd) - 1; rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0); ok(rc == MMSYSERR_INVALPARAM, "acmFormatTagEnum(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALPARAM); aftd.cbStruct = sizeof(aftd); aftd.dwFormatTag = WAVE_FORMAT_UNKNOWN; /* try bad flag */ rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 1); ok(rc == MMSYSERR_INVALFLAG, "acmFormatTagEnum(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALFLAG); /* try valid parameters */ rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0); ok(rc == MMSYSERR_NOERROR, "acmFormatTagEnum(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); HeapFree(GetProcessHeap(), 0, pwfx); /* try invalid handle */ rc = acmDriverClose((HACMDRIVER)1, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverClose(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); /* try invalid flag */ rc = acmDriverClose(had, 1); ok(rc == MMSYSERR_INVALFLAG, "acmDriverClose(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALFLAG); /* try valid parameters */ rc = acmDriverClose(had, 0); ok(rc == MMSYSERR_NOERROR, "acmDriverClose(): rc = %08x, should be %08x\n", rc, MMSYSERR_NOERROR); /* try closing again */ rc = acmDriverClose(had, 0); ok(rc == MMSYSERR_INVALHANDLE, "acmDriverClose(): rc = %08x, should be %08x\n", rc, MMSYSERR_INVALHANDLE); } } return TRUE; }
// // GetMediaType // HRESULT CSynthStream::GetMediaType(CMediaType *pmt) { CheckPointer(pmt,E_POINTER); // The caller must hold the state lock because this function // calls get_OutputFormat() and GetPCMFormatStructure(). // The function assumes that the state of the m_Synth // object does not change between the two calls. The // m_Synth object's state will not change if the // state lock is held. ASSERT(CritCheckIn(m_pParent->pStateLock())); WAVEFORMATEX *pwfex; SYNTH_OUTPUT_FORMAT ofCurrent; HRESULT hr = m_Synth->get_OutputFormat( &ofCurrent ); if(FAILED(hr)) { return hr; } if(SYNTH_OF_PCM == ofCurrent) { pwfex = (WAVEFORMATEX *) pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX)); if(NULL == pwfex) { return E_OUTOFMEMORY; } m_Synth->GetPCMFormatStructure(pwfex); } else if(SYNTH_OF_MS_ADPCM == ofCurrent) { DWORD dwMaxWAVEFORMATEXSize; MMRESULT mmr = acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, (void*)&dwMaxWAVEFORMATEXSize); // acmMetrics() returns 0 if no errors occur. if(0 != mmr) { return E_FAIL; } pwfex = (WAVEFORMATEX *) pmt->AllocFormatBuffer(dwMaxWAVEFORMATEXSize); if(NULL == pwfex) { return E_OUTOFMEMORY; } WAVEFORMATEX wfexSourceFormat; m_Synth->GetPCMFormatStructure(&wfexSourceFormat); ZeroMemory(pwfex, dwMaxWAVEFORMATEXSize); pwfex->wFormatTag = WAVE_FORMAT_ADPCM; pwfex->cbSize = (USHORT)(dwMaxWAVEFORMATEXSize - sizeof(WAVEFORMATEX)); pwfex->nChannels = wfexSourceFormat.nChannels; pwfex->nSamplesPerSec = wfexSourceFormat.nSamplesPerSec; mmr = acmFormatSuggest(NULL, &wfexSourceFormat, pwfex, dwMaxWAVEFORMATEXSize, ACM_FORMATSUGGESTF_WFORMATTAG | ACM_FORMATSUGGESTF_NSAMPLESPERSEC | ACM_FORMATSUGGESTF_NCHANNELS); // acmFormatSuggest() returns 0 if no errors occur. if(0 != mmr) { return E_FAIL; } } else { return E_UNEXPECTED; } return CreateAudioMediaType(pwfex, pmt, FALSE); }
bool VDAudioCodecW32::Init(const WAVEFORMATEX *pSrcFormat, const WAVEFORMATEX *pDstFormat, bool isCompression, const char *pDriverShortNameHint, bool throwOnError) { Shutdown(); SafeCopyWaveFormat(mSrcFormat, (const VDWaveFormat *)pSrcFormat); if (pDstFormat) SafeCopyWaveFormat(mDstFormat, (const VDWaveFormat *)pDstFormat); // enumerate IDs for all installed codecs ACMDriverList driverList(pDriverShortNameHint); // try one driver at a time MMRESULT res = 0; for(ACMDriverList::const_iterator it(driverList.begin()), itEnd(driverList.end()); it != itEnd; ++it) { const HACMDRIVERID driverId = *it; // open driver HACMDRIVER hDriver = NULL; if (acmDriverOpen(&hDriver, *it, 0)) continue; if (!pDstFormat) { VDASSERT(!isCompression); DWORD dwDstFormatSize = 0; VDVERIFY(!acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, (LPVOID)&dwDstFormatSize)); if (dwDstFormatSize < sizeof(WAVEFORMATEX)) dwDstFormatSize = sizeof(WAVEFORMATEX); mDstFormat.resize(dwDstFormatSize); memset(mDstFormat.data(), 0, dwDstFormatSize); mDstFormat->mTag = WAVE_FORMAT_PCM; if (acmFormatSuggest(hDriver, (WAVEFORMATEX *)pSrcFormat, (WAVEFORMATEX *)mDstFormat.data(), dwDstFormatSize, ACM_FORMATSUGGESTF_WFORMATTAG)) { acmDriverClose(hDriver, NULL); continue; } // sanitize the destination format a bit if (mDstFormat->mSampleBits != 8 && mDstFormat->mSampleBits != 16) mDstFormat->mSampleBits = 16; if (mDstFormat->mChannels != 1 && mDstFormat->mChannels !=2) mDstFormat->mChannels = 2; mDstFormat->mBlockSize = (uint16)((mDstFormat->mSampleBits >> 3) * mDstFormat->mChannels); mDstFormat->mDataRate = mDstFormat->mBlockSize * mDstFormat->mSamplingRate; mDstFormat->mExtraSize = 0; mDstFormat.resize(sizeof(WAVEFORMATEX)); } // open conversion stream res = acmStreamOpen(&mhStream, hDriver, (WAVEFORMATEX *)pSrcFormat, (WAVEFORMATEX *)mDstFormat.data(), NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME); if (!res) { mhDriver = hDriver; break; } // Aud-X accepts PCM/6ch but not WAVE_FORMAT_EXTENSIBLE/PCM/6ch. Argh. We attempt to work // around this by trying a PCM version if WFE doesn't work. if (isCompression) { // Need to put this somewhere. struct WaveFormatExtensibleW32 { WAVEFORMATEX mFormat; union { uint16 mBitDepth; uint16 mSamplesPerBlock; // may be zero, according to MSDN }; uint32 mChannelMask; GUID mGuid; }; static const GUID local_KSDATAFORMAT_SUBTYPE_PCM={ // so we don't have to bring in ksmedia.h WAVE_FORMAT_PCM, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }; if (pSrcFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE && pSrcFormat->cbSize >= sizeof(WaveFormatExtensibleW32) - sizeof(WAVEFORMATEX)) { const WaveFormatExtensibleW32& wfexex = *(const WaveFormatExtensibleW32 *)pSrcFormat; if (wfexex.mGuid == local_KSDATAFORMAT_SUBTYPE_PCM) { // Rewrite the format to be straight PCM and try again. vdstructex<VDWaveFormat> srcFormat2(mSrcFormat.data(), sizeof(VDWaveFormat)); srcFormat2->mExtraSize = 0; srcFormat2->mTag = WAVE_FORMAT_PCM; MMRESULT res2 = acmStreamOpen(&mhStream, hDriver, (WAVEFORMATEX *)srcFormat2.data(), (WAVEFORMATEX *)mDstFormat.data(), NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME); if (!res2) { res = res2; mSrcFormat = srcFormat2; pSrcFormat = (WAVEFORMATEX *)mSrcFormat.data(); mhDriver = hDriver; break; } } } } acmDriverClose(hDriver, 0); }