Настройки ввода PortAcapture ComboBox < /p>
Когда 2 -канал выбирается из ComboBox, в Naudio c# приложение I может видеть mmdevice.audioclient.mixformat.Channels == 2 ComboBox, в приложении Naudio C# я вижу mmdevice.audioclient.mixformat.channels == 8. < /p>
Интересно, какие кодовые окна выполняют, когда я выбираю индекс в combobox, который в конечном итоге влияет на mmdevice.audioclient.mixformat.Channels? Тот же или аналогичный код (возможно, он находится в C ++) из моей программы, когда Windows выполняет.
Код: Выделить всё
#define _WIN32_WINNT 0x0A00
#define INITGUID
#include
#include
#include
#include // PKEY_AudioEngine_DeviceFormat
#include // InitPropVariantFromBuffer
#include
#include
#include
#include
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")
#pragma comment(lib, "uuid.lib")
#pragma comment(lib, "propsys.lib")
#pragma comment(lib, "mmdevapi.lib")
// Simple HRESULT check helper
//#define CHECK(hr, msg) do { if (FAILED(hr)) { wprintf(L"%s (hr=0x%08X)\n", L##msg, hr); goto Cleanup; } } while(0)
#define CHECK(hr, msg) do { if (FAILED(hr)) { wprintf(L"%s (hr=0x%08X)\n", L##msg, hr); } } while(0)
// replace the "get default endpoint" part with this helper and use it
static HRESULT FindCaptureEndpointByNameSubstring(
LPCWSTR needle, IMMDevice * *outDevice, IMMDeviceEnumerator * enumr)
{
/*
*outDevice = nullptr;
IMMDeviceCollection* coll = nullptr;
HRESULT hr = enumr->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE, &coll);
if (FAILED(hr))
return hr;
UINT count = 0;
coll->GetCount(&count);
for (UINT i = 0; i < count; ++i) {
IMMDevice* dev = nullptr;
IPropertyStore* ps = nullptr;
PROPVARIANT vname; PropVariantInit(&vname);
if (SUCCEEDED(coll->Item(i, &dev)) &&
SUCCEEDED(dev->OpenPropertyStore(STGM_READ, &ps)) &&
SUCCEEDED(ps->GetValue(PKEY_Device_FriendlyName, &vname)) &&
vname.vt == VT_LPWSTR && wcsstr(vname.pwszVal, needle) != nullptr)
{
wprintf(L"Selected: %s\n", vname.pwszVal);
*outDevice = dev; // transfer
if (ps) ps->Release();
PropVariantClear(&vname);
coll->Release();
return S_OK;
}
if (ps) ps->Release();
PropVariantClear(&vname);
if (dev) dev->Release();
}
coll->Release();
*/
return E_FAIL;
}
// Build a packed-24b WAVEFORMATEXTENSIBLE for N channels at sampleRate.
static WAVEFORMATEXTENSIBLE MakePcm24WfxExt(WORD channels, DWORD sampleRate)
{
WAVEFORMATEXTENSIBLE wfxe = {};
//WAVEFORMATEX& wfxe = wfx.Format;
ZeroMemory(&wfxe, sizeof(wfxe));
wfxe.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfxe.Format.nChannels = channels;
wfxe.Format.nSamplesPerSec = sampleRate;
wfxe.Format.wBitsPerSample = 24; // packed 24-bit PCM
wfxe.Samples.wValidBitsPerSample = 24;
wfxe.Format.nBlockAlign = (channels * 24) / 8; // ch * 3 bytes
wfxe.Format.nAvgBytesPerSec = wfxe.Format.nBlockAlign * sampleRate;
wfxe.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
//wfxe.dwChannelMask = mask; // try multiple masks
wfxe.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
return wfxe;
}
static void PrintMixFormat(IMMDevice* endpoint)
{
IAudioClient* ac = nullptr;
WAVEFORMATEX* mix = nullptr;
HRESULT hr = endpoint->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, (void**)&ac);
if (SUCCEEDED(hr))
hr = ac->GetMixFormat(&mix);
if (SUCCEEDED(hr))
{
WORD ch = mix->nChannels;
WORD bps = mix->wBitsPerSample;
DWORD sr = mix->nSamplesPerSec;
wprintf(L"Current shared-mode mix format: %u channels, %u-bit, %lu Hz\n", ch, bps, sr);
}
else
{
wprintf(L"Failed to read mix format (hr=0x%08X)\n", hr);
}
if (mix) CoTaskMemFree(mix);
if (ac) ac->Release();
}
static void PrintDeviceFriendlyName()
{
int a = 0;
a++;
return;
//IPropertyStore* pProps = nullptr;
//PROPVARIANT varName;
//PropVariantInit(&varName);
//HRESULT hr = pDevice->OpenPropertyStore(STGM_READ, &pProps);
//if (SUCCEEDED(hr))
//{
// hr = pProps->GetValue(PKEY_Device_FriendlyName, &varName);
// if (SUCCEEDED(hr))
// {
// wprintf(L"Device Friendly Name: %s\n", varName.pwszVal);
// PropVariantClear(&varName);
// }
// pProps->Release();
//}
//else
//{
// wprintf(L"Failed to open property store (hr=0x%08X)\n", hr);
//}
}
int wmain()
{
HRESULT hr = S_OK;
IMMDeviceEnumerator* enumr = nullptr;
IMMDevice* endpoint = nullptr;
IPropertyStore* store = nullptr;
wprintf(L"=== Portacapture X8 Endpoint Default Format Setter (shared mode) ===\n");
// 1) Init COM and get the default capture endpoint
hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
CHECK(hr, "CoInitializeEx failed");
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator), (void**)&enumr);
CHECK(hr, "Create MMDeviceEnumerator failed");
if (true)
{
// Default capture device, console role
hr = enumr->GetDefaultAudioEndpoint(eCapture, eConsole, &endpoint);
CHECK(hr, "GetDefaultAudioEndpoint(eCapture) failed");
//PrintDeviceFriendlyName();
IPropertyStore* pProps = nullptr;
PROPVARIANT varName;
PropVariantInit(&varName);
HRESULT hr = endpoint->OpenPropertyStore(STGM_READ, &pProps);
if (SUCCEEDED(hr))
{
hr = pProps->GetValue(PKEY_Device_FriendlyName, &varName);
if (SUCCEEDED(hr))
{
wprintf(L"Device Friendly Name: %s\n", varName.pwszVal);
PropVariantClear(&varName);
}
pProps->Release();
}
else
{
wprintf(L"Failed to open property store (hr=0x%08X)\n", hr);
}
}
else
{
// Ask the user what to look for
wprintf(L"Type part of the device name (e.g., Portacapture): ");
wchar_t needle[128] = {};
_wscanf_s_l(L"%127ls", _get_current_locale(), needle, (unsigned)_countof(needle));
hr = FindCaptureEndpointByNameSubstring(needle, &endpoint, enumr);
CHECK(hr, "Could not find a matching capture endpoint (is it active?)");
wprintf(L"Got requested capture endpoint.\n");
PrintMixFormat(endpoint);
}
wprintf(L"Got default capture endpoint.\n");
PrintMixFormat(endpoint);
// 2) Open its property store for read/write
hr = endpoint->OpenPropertyStore(STGM_READWRITE, &store);
CHECK(hr, "OpenPropertyStore(STGM_READWRITE) failed");
// 3) Ask user for target channels / sample rate
int chChoice = 0;
int srChoice = 0;
wprintf(L"\nChoose channel count [2 or 8]: ");
if (wscanf_s(L"%d", &chChoice) != 1 || (chChoice != 2 && chChoice != 8)) {
wprintf(L"Invalid choice.\n");
//goto Cleanup;
}
wprintf(L"Choose sample rate [44100 | 48000 | 96000]: ");
if (wscanf_s(L"%d", &srChoice) != 1 || (srChoice != 44100 && srChoice != 48000 && srChoice != 96000)) {
wprintf(L"Invalid sample rate.\n");
//goto Cleanup;
}
// 4) Build a WAVEFORMATEXTENSIBLE blob (packed 24-bit PCM)
WAVEFORMATEXTENSIBLE wfx = MakePcm24WfxExt((WORD)chChoice, (DWORD)srChoice);
const UINT32 blobSize = sizeof(WAVEFORMATEXTENSIBLE); // for extensible we commit full struct
PROPVARIANT var; PropVariantInit(&var);
hr = InitPropVariantFromBuffer(&wfx, blobSize, &var); // VT_BLOB
CHECK(hr, "InitPropVariantFromBuffer failed");
// After building PROPVARIANT var from your WAVEFORMATEXTENSIBLE
hr = store->SetValue(PKEY_AudioEngine_DeviceFormat, var);
CHECK(hr, "SetValue(DeviceFormat) failed");
// Some drivers honor OEMFormat on reconfigure; setting both is safe.
hr = store->SetValue(PKEY_AudioEngine_OEMFormat, var); // SetValue(PKEY_AudioEndpoint_PhysicalSpeakers, spk);
//PropVariantClear(&spk);
hr = store->Commit();
CHECK(hr, "PropertyStore Commit failed");
// after store->Commit()
PROPVARIANT got; PropVariantInit(&got);
store->GetValue(PKEY_AudioEngine_DeviceFormat, &got);
if (got.vt == VT_BLOB && got.blob.cbSize >= sizeof(WAVEFORMATEX)) {
auto ex = reinterpret_cast(got.blob.pBlobData);
wprintf(L"PropertyStore now has: %u ch, %u-bit, %lu Hz\n",
ex->nChannels, ex->wBitsPerSample, ex->nSamplesPerSec);
}
PropVariantClear(&got);
wprintf(L"\nWrote shared-mode default format: %d ch, 24-bit, %d Hz. (PKEY_AudioEngine_DeviceFormat)\n", chChoice, srChoice);
wprintf(L"Windows Audio Engine will use this as the endpoint's shared mix format.\n");
// 6) Read back via IAudioClient::GetMixFormat to show the effect.
wprintf(L"\nRe-querying IAudioClient::GetMixFormat...\n");
PrintMixFormat(endpoint);
//Cleanup:
// if (store) { PropVariantClear(&var); store->Release(); }
// if (endpoint) endpoint->Release();
// if (enumr) enumr->Release();
// CoUninitialize();
// wprintf(L"\nDone.\n");
// return FAILED(hr) ? 1 : 0;
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... n-mmdevice
Мобильная версия