bool USBAudioDevice::SetSampleRateInternal(int freq) { UINT lengthTransferred = 0; bool retValue = FALSE; USBAudioClockSource* clockSource = FindClockSource(freq); if(!clockSource) { #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Not found clock source for sample rate %d\n", freq); #endif return FALSE; } if(UsbClaimInterface(clockSource->m_interface->Descriptor().bInterfaceNumber)) { retValue = SendUsbControl(BMREQUEST_DIR_HOST_TO_DEVICE, BMREQUEST_TYPE_CLASS, BMREQUEST_RECIPIENT_INTERFACE, AUDIO_CS_REQUEST_CUR, AUDIO_CS_CONTROL_SAM_FREQ << 8, (clockSource->m_clockSource.bClockID << 8) + clockSource->m_interface->Descriptor().bInterfaceNumber, (unsigned char*)&freq, sizeof(freq), &lengthTransferred); if(!retValue) { m_errorCode = GetLastErrorInternal(); #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Set samplerate %d failed. ErrorCode: %08Xh\n", freq, m_errorCode); #endif } else if(lengthTransferred != 4) { #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Set samplerate %d failed. Wrong transfer length\n", freq); #endif retValue = FALSE; } UsbReleaseInterface(clockSource->m_interface->Descriptor().bInterfaceNumber); } else { m_errorCode = GetLastErrorInternal(); #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Claim interface %d failed. ErrorCode: %08Xh\n", clockSource->m_interface->Descriptor().bInterfaceNumber, m_errorCode); #endif } return retValue; }
int USBAudioDevice::GetSampleRateInternal(int interfaceNum, int clockID) { UINT lengthTransferred = 0; int freq = 0; if(UsbClaimInterface(interfaceNum)) { if(!SendUsbControl( BMREQUEST_DIR_DEVICE_TO_HOST, BMREQUEST_TYPE_CLASS, BMREQUEST_RECIPIENT_INTERFACE, AUDIO_CS_REQUEST_CUR, AUDIO_CS_CONTROL_SAM_FREQ << 8, (clockID << 8) + interfaceNum, (unsigned char*)&freq, sizeof(freq), &lengthTransferred)) { freq = 0; m_errorCode = GetLastErrorInternal(); #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Get samplerate %d failed. ErrorCode: %08Xh\n", freq, m_errorCode); #endif } else if(lengthTransferred != 4) { #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Get samplerate %d failed. Wrong transfer length\n", freq); #endif freq = 0; } UsbReleaseInterface(interfaceNum); } else { m_errorCode = GetLastErrorInternal(); #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Claim interface %d failed. ErrorCode: %08Xh\n", interfaceNum, m_errorCode); #endif } return freq; }
bool USBAudioDevice::CheckSampleRate(USBAudioClockSource* clocksrc, int newfreq) { unsigned char buff[64]; UINT lengthTransferred = 0; bool retVal = FALSE; if(UsbClaimInterface(clocksrc->m_interface->Descriptor().bInterfaceNumber)) { bool retValue = SendUsbControl(BMREQUEST_DIR_DEVICE_TO_HOST, BMREQUEST_TYPE_CLASS, BMREQUEST_RECIPIENT_INTERFACE, AUDIO_CS_REQUEST_RANGE, AUDIO_CS_CONTROL_SAM_FREQ << 8, (clocksrc->m_clockSource.bClockID << 8) + clocksrc->m_interface->Descriptor().bInterfaceNumber, buff, sizeof(buff), &lengthTransferred); if(!retValue) { m_errorCode = GetLastErrorInternal(); #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Enumerate samplerate failed. ErrorCode: %08Xh\n", m_errorCode); #endif } else if(lengthTransferred <= 2) { #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Enumerate samplerate failed. Wrong transfer length\n"); #endif retValue = FALSE; } unsigned short length = *((unsigned short*)buff); struct sample_rate_triplets *triplets = (sample_rate_triplets *)(buff + 2); #ifdef _ENABLE_TRACE //debugPrintf("ASIOUAC: Enumerate samplerate OK\n"); #endif for(int i = 0; i < length; i++) { if(triplets[i].res_freq == 0) { if(newfreq == triplets[i].min_freq) retVal = TRUE; } else for(int freq = triplets[i].min_freq; freq <= triplets[i].max_freq; freq += triplets[i].res_freq) { #ifdef _ENABLE_TRACE //debugPrintf("ASIOUAC: Supported freq: %d\n", freq); #endif if(newfreq == freq) retVal = TRUE; } } UsbReleaseInterface(clocksrc->m_interface->Descriptor().bInterfaceNumber); #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Sample freq: %d %s\n", newfreq, retVal ? "is supported" : "isn't supported"); #endif } else { m_errorCode = GetLastErrorInternal(); #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Claim interface %d failed. ErrorCode: %08Xh\n", clocksrc->m_interface->Descriptor().bInterfaceNumber, m_errorCode); #endif } return retVal; }
bool USBDevice::InitDevice() { BYTE configDescriptorBuffer[4096]; ULONG lengthTransferred; m_deviceMutex = CreateMutex(NULL, FALSE, "Global\\ASIOUAC2"); if(GetLastError() == ERROR_ALREADY_EXISTS) { #ifdef _DEBUG debugPrintf("ASIOUAC: Can't start device! Device already used!\n"); #endif if(m_deviceMutex) { CloseHandle(m_deviceMutex); m_deviceMutex = NULL; m_errorCode = ERROR_BUSY; } return FALSE; } FreeDevice(); InitDescriptors(); m_usbDeviceHandle = FindDevice(); if(m_usbDeviceHandle == NULL) return FALSE; lengthTransferred = sizeof(configDescriptorBuffer); if(!UsbK_QueryDeviceInformation( m_usbDeviceHandle, DEVICE_SPEED, &lengthTransferred, configDescriptorBuffer)) { m_errorCode = GetLastError(); #ifdef _DEBUG debugPrintf("ASIOUAC: UsbK_QueryDeviceInformation failed. ErrorCode: %08Xh\n", m_errorCode); #endif UsbK_Free(m_usbDeviceHandle); m_usbDeviceHandle = NULL; return FALSE; } m_deviceSpeed = (int)configDescriptorBuffer[0]; #ifdef _DEBUG if(m_deviceSpeed == HighSpeed) debugPrintf("ASIOUAC: Device speed: high\n"); else debugPrintf("ASIOUAC: Device speed: low/full\n"); #endif if(!UsbK_GetDescriptor(m_usbDeviceHandle, USB_DESCRIPTOR_TYPE_DEVICE, 0, 0, configDescriptorBuffer, sizeof(configDescriptorBuffer), &lengthTransferred)) { m_errorCode = GetLastError(); #ifdef _DEBUG debugPrintf("ASIOUAC: Get device descriptor failed. ErrorCode: %08Xh\n", m_errorCode); #endif UsbK_Free(m_usbDeviceHandle); m_usbDeviceHandle = NULL; return FALSE; } memcpy(&m_deviceDescriptor, configDescriptorBuffer, sizeof(USB_DEVICE_DESCRIPTOR)); if(SendUsbControl(BMREQUEST_DIR_DEVICE_TO_HOST, BMREQUEST_TYPE_STANDARD, BMREQUEST_RECIPIENT_DEVICE, USB_REQUEST_GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_CONFIGURATION << 8), 0, configDescriptorBuffer, sizeof(configDescriptorBuffer), &lengthTransferred)) { ParseDescriptors(configDescriptorBuffer, lengthTransferred); return m_usbDeviceHandle != NULL; } else { m_errorCode = GetLastError(); #ifdef _DEBUG debugPrintf("ASIOUAC: Get config descriptor failed. ErrorCode: %08Xh\n", m_errorCode); #endif UsbK_Free(m_usbDeviceHandle); m_usbDeviceHandle = NULL; return FALSE; } }