/* Convenience routine for getting the path of a device and opening it. */ MMRESULT OpenNt4KernelSoundDevice( IN PSOUND_DEVICE SoundDevice, IN BOOLEAN ReadOnly, OUT PHANDLE Handle) { PWSTR Path; MMRESULT Result; VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) ); VALIDATE_MMSYS_PARAMETER( Handle ); Result = GetSoundDeviceIdentifier(SoundDevice, (PVOID*) &Path); if ( ! MMSUCCESS(Result) ) { SND_ERR(L"Unable to get sound device path"); return TranslateInternalMmResult(Result); } SND_ASSERT( Path ); return OpenKernelSoundDeviceByName(Path, ReadOnly, Handle); }
MMRESULT WdmAudSetWaveDeviceFormatByLegacy( IN PSOUND_DEVICE_INSTANCE Instance, IN DWORD DeviceId, IN PWAVEFORMATEX WaveFormat, IN DWORD WaveFormatSize) { MMRESULT Result; PSOUND_DEVICE SoundDevice; PVOID Identifier; WDMAUD_DEVICE_INFO DeviceInfo; MMDEVICE_TYPE DeviceType; Result = GetSoundDeviceFromInstance(Instance, &SoundDevice); if ( ! MMSUCCESS(Result) ) { return TranslateInternalMmResult(Result); } Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier); if ( ! MMSUCCESS(Result) ) { return TranslateInternalMmResult(Result); } if (Instance->Handle != NULL) { /* device is already open */ return MMSYSERR_NOERROR; } Result = GetSoundDeviceType(SoundDevice, &DeviceType); SND_ASSERT( Result == MMSYSERR_NOERROR ); ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); DeviceInfo.DeviceType = DeviceType; DeviceInfo.DeviceIndex = DeviceId; DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); //WaveFormat->cbSize; DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag; #ifdef USERMODE_MIXER DeviceInfo.u.WaveFormatEx.nChannels = 2; DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 44100; DeviceInfo.u.WaveFormatEx.nBlockAlign = 4; DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 176400; DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16; #else DeviceInfo.u.WaveFormatEx.nChannels = WaveFormat->nChannels; DeviceInfo.u.WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec; DeviceInfo.u.WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign; DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec; DeviceInfo.u.WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels); #endif Result = SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_OPEN_WDMAUD, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); if ( ! MMSUCCESS(Result) ) { return TranslateInternalMmResult(Result); } if (WaveFormatSize >= sizeof(WAVEFORMAT)) { /* Store format */ Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag; Instance->WaveFormatEx.nChannels = WaveFormat->nChannels; Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec; Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign; Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec; } /* store details */ Instance->WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); Instance->WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels); /* Store sound device handle instance handle */ Instance->Handle = (PVOID)DeviceInfo.hDevice; /* Now determine framing requirements */ Result = SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_GETFRAMESIZE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); if ( MMSUCCESS(Result) ) { if (DeviceInfo.u.FrameSize) { Instance->FrameSize = DeviceInfo.u.FrameSize * 2; Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize; SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount); } } else { // use a default of 100 buffers Instance->BufferCount = 100; } /* Now acquire resources */ DeviceInfo.u.State = KSSTATE_ACQUIRE; SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); /* pause the pin */ DeviceInfo.u.State = KSSTATE_PAUSE; SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); /* start the pin */ DeviceInfo.u.State = KSSTATE_RUN; SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); return MMSYSERR_NOERROR; }