├── ASIO SDK └── dummy.txt ├── Driver ├── asiouac2.cpp ├── asiouac2.def ├── asiouac2.h ├── asiouac2.sln ├── asiouac2.vcproj └── wintimer.cpp ├── DriverPackages ├── 7ZDP_LZMA.sfx ├── 7zDP_LZMA.cfg ├── Audio-Widget.inf ├── Instructions.txt ├── amd64 │ ├── WdfCoInstaller01009.dll │ ├── libusb0.dll │ ├── libusbK.dll │ └── libusbK.sys ├── dpinst.xml ├── dpinst32.exe ├── dpinst64.exe ├── dpscat.exe ├── re-pack-files.cmd └── x86 │ ├── WdfCoInstaller01009.dll │ ├── libusb0_x86.dll │ ├── libusbK.sys │ └── libusbK_x86.dll ├── Installer ├── ASIO.bmp ├── ASIO.gif ├── audiowidget.iss ├── license.txt ├── test.ini └── usb_driver │ └── Audio-Widget.inf ├── LICENSE-bsd.txt ├── WidgetControl ├── WidgetControl.sln └── WidgetControl │ ├── Program.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ └── Settings.Designer.cs │ ├── WidgetControl.Designer.cs │ ├── WidgetControl.cs │ ├── WidgetControl.csproj │ ├── WidgetControl.resx │ ├── app.config │ ├── bin │ └── Release │ │ └── test.ini │ └── libusbK.cs ├── WidgetTest ├── WidgetTest.sln ├── WidgetTest.vcproj └── widgettest.cpp ├── dump2wav ├── Debug │ └── BuildLog.htm ├── ReadMe.txt ├── dump2wav.cpp ├── dump2wav.sln ├── dump2wav.vcproj ├── stdafx.cpp ├── stdafx.h ├── targetver.h └── use_case.txt ├── libusbK-dev-kit └── dummy.txt ├── readme.txt └── uaclib ├── ReadMe.txt ├── USBAudioDevice.cpp ├── USBAudioDevice.h ├── UsbDevice.cpp ├── UsbDevice.h ├── audiotask.cpp ├── audiotask.h ├── descriptors.cpp ├── descriptors.h ├── targetver.h ├── tlist.h ├── uaclib.sln ├── uaclib.vcproj └── usb_audio.h /ASIO SDK/dummy.txt: -------------------------------------------------------------------------------- 1 | Please put in this dir ASIO SDK -------------------------------------------------------------------------------- /Driver/asiouac2.def: -------------------------------------------------------------------------------- 1 | LIBRARY ASIOUAC2 2 | DESCRIPTION 'ASIO USB Audio Class 2 Driver' 3 | PROTMODE 4 | EXPORTS 5 | DllMain 6 | DllGetClassObject 7 | DllCanUnloadNow 8 | DllRegisterServer 9 | DllUnregisterServer 10 | -------------------------------------------------------------------------------- /Driver/asiouac2.h: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | // Based on samples from ASIO SDK 16 | /* 17 | Steinberg Audio Stream I/O API 18 | (c) 1999, Steinberg Soft- und Hardware GmbH 19 | */ 20 | 21 | 22 | #ifndef _asiosmpl_ 23 | #define _asiosmpl_ 24 | 25 | #include "asiosys.h" 26 | 27 | #define DRIVER_VERSION 0x00000002L 28 | 29 | enum 30 | { 31 | USBAudioClassUnknown = 0, 32 | USBAudioClass1, 33 | USBAudioClass2 34 | }; 35 | 36 | 37 | 38 | #if WINDOWS 39 | 40 | #include "rpc.h" 41 | #include "rpcndr.h" 42 | #ifndef COM_NO_WINDOWS_H 43 | #include 44 | #include "ole2.h" 45 | #endif 46 | 47 | #include "combase.h" 48 | #include "iasiodrv.h" 49 | #include "USBAudioDevice.h" 50 | 51 | 52 | class AsioUAC2 : public IASIO, public CUnknown 53 | { 54 | public: 55 | AsioUAC2(LPUNKNOWN pUnk, HRESULT *phr); 56 | ~AsioUAC2(); 57 | 58 | DECLARE_IUNKNOWN 59 | //STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \ 60 | // return GetOwner()->QueryInterface(riid,ppv); \ 61 | //}; \ 62 | //STDMETHODIMP_(ULONG) AddRef() { \ 63 | // return GetOwner()->AddRef(); \ 64 | //}; \ 65 | //STDMETHODIMP_(ULONG) Release() { \ 66 | // return GetOwner()->Release(); \ 67 | //}; 68 | 69 | // Factory method 70 | static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); 71 | // IUnknown 72 | virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject); 73 | #else 74 | 75 | #include "asiodrvr.h" 76 | 77 | //--------------------------------------------------------------------------------------------- 78 | class AsioUAC2 : public AsioDriver 79 | { 80 | public: 81 | AsioUAC2 (); 82 | ~AsioUAC2 (); 83 | #endif 84 | 85 | ASIOBool init (void* sysRef); 86 | void getDriverName (char *name); // max 32 bytes incl. terminating zero 87 | long getDriverVersion (); 88 | void getErrorMessage (char *string); // max 128 bytes incl. 89 | 90 | ASIOError start (); 91 | ASIOError stop (); 92 | 93 | ASIOError getChannels (long *numInputChannels, long *numOutputChannels); 94 | ASIOError getLatencies (long *inputLatency, long *outputLatency); 95 | ASIOError getBufferSize (long *minSize, long *maxSize, 96 | long *preferredSize, long *granularity); 97 | 98 | ASIOError canSampleRate (ASIOSampleRate sampleRate); 99 | ASIOError getSampleRate (ASIOSampleRate *sampleRate); 100 | ASIOError setSampleRate (ASIOSampleRate sampleRate); 101 | ASIOError getClockSources (ASIOClockSource *clocks, long *numSources); 102 | ASIOError setClockSource (long index); 103 | 104 | ASIOError getSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp); 105 | ASIOError getChannelInfo (ASIOChannelInfo *info); 106 | 107 | ASIOError createBuffers (ASIOBufferInfo *bufferInfos, long numChannels, 108 | long bufferSize, ASIOCallbacks *callbacks); 109 | ASIOError disposeBuffers (); 110 | 111 | ASIOError controlPanel (); 112 | ASIOError future (long selector, void *opt); 113 | ASIOError outputReady (); 114 | 115 | void DeviceNotify(int reason); 116 | 117 | void bufferSwitch (); 118 | long getMilliSeconds () {return milliSeconds;} 119 | 120 | template void FillInputData(UCHAR *buffer, int& len); 121 | template void FillOutputData(UCHAR *buffer, int& len); 122 | 123 | static void sFillOutputData3(void* context, UCHAR *buffer, int& len); 124 | static void sFillInputData3(void* context, UCHAR *buffer, int& len); 125 | static void sFillOutputData4(void* context, UCHAR *buffer, int& len); 126 | static void sFillInputData4(void* context, UCHAR *buffer, int& len); 127 | 128 | static void sDeviceNotify(void* context, int reason); 129 | 130 | private: 131 | friend void myTimer(); 132 | 133 | bool inputOpen (); 134 | void inputClose (); 135 | void input (); 136 | 137 | bool outputOpen (); 138 | void outputClose (); 139 | void output (); 140 | 141 | #ifdef EMULATION_HARDWARE 142 | void timerOn (); 143 | void timerOff (); 144 | #endif 145 | void bufferSwitchX (); 146 | 147 | double samplePosition; 148 | #ifdef EMULATION_HARDWARE 149 | public: 150 | #endif 151 | double sampleRate; 152 | #ifdef EMULATION_HARDWARE 153 | private: 154 | #endif 155 | ASIOCallbacks *callbacks; 156 | ASIOTime asioTime; 157 | ASIOTimeStamp theSystemTime; 158 | 159 | int m_NumInputs; 160 | int m_NumOutputs; 161 | int m_inputSampleSize; 162 | int m_outputSampleSize; 163 | char **inputBuffers; 164 | char **outputBuffers; 165 | long *inMap; 166 | long *outMap; 167 | 168 | long blockFrames; 169 | long inputLatency; 170 | long outputLatency; 171 | long activeInputs; 172 | long activeOutputs; 173 | long toggle; 174 | long milliSeconds; 175 | bool active, started; 176 | bool timeInfoMode, tcRead; 177 | char errorMessage[128]; 178 | 179 | private: 180 | int USBAudioClass; 181 | 182 | USBAudioDevice *m_device; 183 | 184 | ASIOError StartDevice(); 185 | ASIOError StopDevice(); 186 | int currentOutBufferPosition; 187 | int currentInBufferPosition; 188 | 189 | volatile bool m_StopInProgress; 190 | HANDLE m_AsioSyncEvent; 191 | HANDLE m_BufferSwitchEvent; 192 | }; 193 | 194 | #endif 195 | 196 | -------------------------------------------------------------------------------- /Driver/asiouac2.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual C++ Express 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asiouac2", "asiouac2.vcproj", "{F47BECCA-9313-4A58-BD05-49A835D017D5}" 5 | ProjectSection(ProjectDependencies) = postProject 6 | {6964BC9D-1940-424C-9273-921F7C60D72A} = {6964BC9D-1940-424C-9273-921F7C60D72A} 7 | EndProjectSection 8 | EndProject 9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uaclib", "..\uaclib\uaclib.vcproj", "{6964BC9D-1940-424C-9273-921F7C60D72A}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Win32 = Debug|Win32 14 | Release with Trace|Win32 = Release with Trace|Win32 15 | Release|Win32 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {F47BECCA-9313-4A58-BD05-49A835D017D5}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {F47BECCA-9313-4A58-BD05-49A835D017D5}.Debug|Win32.Build.0 = Debug|Win32 20 | {F47BECCA-9313-4A58-BD05-49A835D017D5}.Release with Trace|Win32.ActiveCfg = Release with Trace|Win32 21 | {F47BECCA-9313-4A58-BD05-49A835D017D5}.Release with Trace|Win32.Build.0 = Release with Trace|Win32 22 | {F47BECCA-9313-4A58-BD05-49A835D017D5}.Release|Win32.ActiveCfg = Release|Win32 23 | {F47BECCA-9313-4A58-BD05-49A835D017D5}.Release|Win32.Build.0 = Release|Win32 24 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Debug|Win32.Build.0 = Debug|Win32 26 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Release with Trace|Win32.ActiveCfg = Release with Trace|Win32 27 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Release with Trace|Win32.Build.0 = Release with Trace|Win32 28 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Release|Win32.ActiveCfg = Release|Win32 29 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Release|Win32.Build.0 = Release|Win32 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /Driver/asiouac2.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 27 | 30 | 33 | 36 | 39 | 48 | 64 | 67 | 72 | 75 | 91 | 94 | 97 | 100 | 105 | 108 | 111 | 114 | 115 | 124 | 127 | 130 | 133 | 136 | 145 | 161 | 164 | 169 | 172 | 187 | 190 | 193 | 196 | 201 | 204 | 207 | 210 | 211 | 220 | 223 | 226 | 229 | 232 | 241 | 257 | 260 | 265 | 268 | 283 | 286 | 289 | 292 | 297 | 300 | 303 | 306 | 307 | 308 | 309 | 310 | 311 | 315 | 318 | 321 | 326 | 327 | 330 | 335 | 336 | 339 | 344 | 345 | 346 | 349 | 350 | 353 | 356 | 361 | 362 | 365 | 370 | 371 | 374 | 379 | 380 | 381 | 384 | 387 | 392 | 393 | 396 | 401 | 402 | 405 | 410 | 411 | 412 | 415 | 418 | 423 | 424 | 427 | 432 | 433 | 436 | 441 | 442 | 443 | 446 | 449 | 454 | 455 | 458 | 463 | 464 | 467 | 472 | 473 | 474 | 475 | 479 | 482 | 483 | 486 | 487 | 490 | 491 | 494 | 495 | 498 | 499 | 502 | 503 | 504 | 508 | 509 | 510 | 511 | 512 | 513 | -------------------------------------------------------------------------------- /Driver/wintimer.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | // Based on samples from ASIO SDK 16 | /* 17 | Steinberg Audio Stream I/O API 18 | (c) 1999, Steinberg Soft- und Hardware GmbH 19 | */ 20 | 21 | #include 22 | #include "asiouac2.h" 23 | 24 | #ifdef EMULATION_HARDWARE 25 | extern void debugPrintf(const char *szFormat, ...); 26 | static DWORD __stdcall ASIOThread (void *param); 27 | static HANDLE ASIOThreadHandle = 0; 28 | static bool done = false; 29 | 30 | AsioUAC2* theDriver = 0; 31 | #endif 32 | 33 | const double twoRaisedTo32 = 4294967296.; 34 | 35 | 36 | //------------------------------------------------------------------------------------------ 37 | void getNanoSeconds (ASIOTimeStamp* ts) 38 | { 39 | double nanoSeconds = (double)((unsigned long)timeGetTime ()) * 1000000.; 40 | ts->hi = (unsigned long)(nanoSeconds / twoRaisedTo32); 41 | ts->lo = (unsigned long)(nanoSeconds - (ts->hi * twoRaisedTo32)); 42 | } 43 | 44 | #ifdef EMULATION_HARDWARE 45 | //------------------------------------------------------------------------------------------ 46 | void AsioUAC2::timerOn () 47 | { 48 | theDriver = this; 49 | DWORD asioId; 50 | done = false; 51 | ASIOThreadHandle = CreateThread (0, 0, &ASIOThread, 0, 0, &asioId); 52 | } 53 | 54 | //------------------------------------------------------------------------------------------ 55 | void AsioUAC2::timerOff () 56 | { 57 | done = true; 58 | if (ASIOThreadHandle) 59 | WaitForSingleObject(ASIOThreadHandle, 1000); 60 | ASIOThreadHandle = 0; 61 | } 62 | 63 | //------------------------------------------------------------------------------------------ 64 | static DWORD __stdcall ASIOThread (void *param) 65 | { 66 | #ifdef _ENABLE_TRACE 67 | debugPrintf("ASIOUAC: Start ASIOThread!, theDriver = %X, MilliSeconds = %d", theDriver, theDriver->getMilliSeconds ()); 68 | #endif 69 | int i = 0; 70 | do 71 | { 72 | if (theDriver) 73 | { 74 | theDriver->bufferSwitch (); 75 | Sleep (theDriver->getMilliSeconds ()); 76 | } 77 | else 78 | { 79 | double a = 1000. / theDriver->sampleRate; 80 | Sleep ((long)(a * (double)kBlockFrames)); 81 | 82 | } 83 | } while (!done); 84 | #ifdef _ENABLE_TRACE 85 | debugPrintf("ASIOUAC: Stop ASIOThread!"); 86 | #endif 87 | return 0; 88 | } 89 | #endif -------------------------------------------------------------------------------- /DriverPackages/7ZDP_LZMA.sfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/7ZDP_LZMA.sfx -------------------------------------------------------------------------------- /DriverPackages/7zDP_LZMA.cfg: -------------------------------------------------------------------------------- 1 | ;!@Install@!UTF-8! 2 | RunProgram="dpscat.exe" 3 | RunProgram="x86:dpinst32.exe" 4 | RunProgram="x64:dpinst64.exe" 5 | GUIMode="2" 6 | ;!@InstallEnd@! -------------------------------------------------------------------------------- /DriverPackages/Audio-Widget.inf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/Audio-Widget.inf -------------------------------------------------------------------------------- /DriverPackages/Instructions.txt: -------------------------------------------------------------------------------- 1 | /* Auto-generated By libusbK InfWizard 2 | * 3 | * DEVICE DRIVER CLIENT INSTALLER By Travis Lee Robinson (libusbdotnet@gmail.com) 4 | * 5 | * Summary: 6 | * - libusbK client installers combine proven LZMA sfx technology with a professional driver installation tool 7 | * creating a tightly packed and feature rich solution for end-user driver installations. 8 | * 9 | * FACTS: 10 | * - Packaged in a modified LZMA sfx module. See: http://7zsfx.info/en. This module is highly configurable 11 | * with installer-like options. 12 | * - Uses dpinst.exe, by Microsoft. Dpinst.exe is a robust multi-language driver installation utility. This 13 | * utility has a set of configurable wizard screens to ease end-user installations. Features also include: 14 | * - Install multiple .inf files at once, each can contain multiple devices with multiple hardware 15 | * identifiers. 16 | * - Uninstall via add/remove programs. (removes from driver-store) 17 | * - Silent/wizardless operation modes. 18 | * - Simplistic xml-based configuration. (dpinst.xml) 19 | * - Customizable EULA. 20 | * - For a complete list of dpinst.exe features see: 21 | * http://msdn.microsoft.com/en-us/library/windows/hardware/ff553383%28v=vs.85%29.aspx 22 | * 23 | * ORDER OF OPERATIONS (InstallDriver.exe - default config): 24 | * -# End-user launches InstallDriver.exe. If not already running with elevated permssions, the user will 25 | * immediately be prompted with a UAC warning: 26 | * http://msdn.microsoft.com/en-us/library/windows/desktop/aa511445.aspx If you do not sign 27 | * InstallDriver.exe with a code signing certificate, the UAC prompt will display "Unknown Name" and 28 | * "Unknown Publisher" in the message box. Purchasing a cheap code signing certificate will allow you to 29 | * set these values. 30 | * -# SFX module:Extracts driver setup files to a temporary folder. 31 | * -# SFX module:Runs dpscat.exe. This utility creates self signed catalog files from .inf files and the 32 | * binaries they reference. These signed catalog files prevent windows from prompting the user with an 33 | * unverified publisher warning: http://www.codeproject.com/KB/system/wiisensor/wiisensor10.png 34 | * -# SFX module:Runs dpinst.exe. Device drivers are pre-installed. If the device has not been connected it 35 | * will be available for use upon first connection. All devices known to windows matching your hardware IDs 36 | * will be flagged for re-install. If the device is currently connected, drivers are immediately installed, 37 | * the device is retarted and available immediately. 38 | * -# SFX module:On wizard exit, removes the temporary extraction folder. 39 | * 40 | * ORDER OF OPERATIONS (re-pack-files.cmd - default config): 41 | * -# The following files are compressed into a normal LZMA .7z file. 42 | * - All ".inf" files in the current folder 43 | * - All files and folders starting with "dpinst" in the current folder. 44 | * - All files matching "dpscat.*" in the current folder. 45 | * - All files and folders in the x86, amd64, and data sub-folders. (recursive) 46 | * -# The SFX module, SFX config file and .7z file are merged together using a binary copy. 47 | * eg: COPY /B sfx_module+sfx_config+files.7z installer.exe 48 | * 49 | * \note Run the "re-pack-files.cmd" batch file after modifying any part of the package. 50 | * 51 | * CUSTOMIZATION: 52 | * - Customizing the SFX Module: 53 | * - SFX customization is done in the "7zDP_LZMA.cfg" file. 54 | * - See http://7zsfx.info/en/ 55 | * - Customizing the driver installation: 56 | * - dpinst.exe customization is done in the "dpinst.xml" file. 57 | * - See http://msdn.microsoft.com/en-us/library/windows/hardware/ff553383%28v=vs.85%29.aspx 58 | * - Other customization: 59 | * - .inf file can be hand modified as needed. 60 | * - Files can be added or removed as needed. 61 | * - Icon and resource text can be changed with a standard resource editor such as ResourcHacker: 62 | * http://www.angusj.com/resourcehacker/ 63 | * 64 | */ 65 | -------------------------------------------------------------------------------- /DriverPackages/amd64/WdfCoInstaller01009.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/amd64/WdfCoInstaller01009.dll -------------------------------------------------------------------------------- /DriverPackages/amd64/libusb0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/amd64/libusb0.dll -------------------------------------------------------------------------------- /DriverPackages/amd64/libusbK.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/amd64/libusbK.dll -------------------------------------------------------------------------------- /DriverPackages/amd64/libusbK.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/amd64/libusbK.sys -------------------------------------------------------------------------------- /DriverPackages/dpinst.xml: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 17 | 1 18 | 1 19 | 20 | -------------------------------------------------------------------------------- /DriverPackages/dpinst32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/dpinst32.exe -------------------------------------------------------------------------------- /DriverPackages/dpinst64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/dpinst64.exe -------------------------------------------------------------------------------- /DriverPackages/dpscat.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/dpscat.exe -------------------------------------------------------------------------------- /DriverPackages/re-pack-files.cmd: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION 3 | 4 | SET FILES_TO_PACK=*.inf dpinst* dpscat.* .\data* .\x86* .\amd64* 5 | SET SFX_MODULE=7zDP_LZMA.sfx 6 | SET SFX_MODULE_CFG=7zDP_LZMA.cfg 7 | SET INSTALL_DRIVER_EXE=InstallDriver.exe 8 | SET DRIVER_FILES_7Z=_DriverFiles.7z 9 | SET 7Z_SWITCHES=-air0 -mx 10 | 11 | SET CMD_EXIT_CODE=0 12 | 13 | IF EXIST "!7ZA_EXE!" (SET 7Z_RUN="!7ZA_EXE!") ELSE CALL :Find7Zip 7z.exe 7za.exe 7zan.exe 14 | IF !7Z_RUN! EQU "" ( 15 | ECHO 7Zip is required to re-pack this installer. 16 | ECHO 1] Download and install 7Zip. http://www.7-zip.org/ 17 | ECHO 2] Add the bin folder to the PATH environment variable. 18 | ECHO "Control Panel->System->Advanced->Environment Variables..." 19 | SET CMD_EXIT_CODE=1 20 | GOTO Error 21 | ) 22 | 23 | IF EXIST "!INSTALL_DRIVER_EXE!" DEL /Q "!INSTALL_DRIVER_EXE!" 24 | IF NOT "!ERRORLEVEL!" EQU "0" ( 25 | ECHO Access denied or file in-use "!INSTALL_DRIVER_EXE!" 26 | SET CMD_EXIT_CODE=2 27 | GOTO Error 28 | ) 29 | 30 | IF EXIST "!DRIVER_FILES_7Z!" DEL /Q "!DRIVER_FILES_7Z!" 31 | IF NOT "!ERRORLEVEL!" EQU "0" ( 32 | ECHO Access denied or file in-use "!DRIVER_FILES_7Z!" 33 | SET CMD_EXIT_CODE=3 34 | GOTO Error 35 | ) 36 | 37 | !7Z_RUN! a "!DRIVER_FILES_7Z!" !FILES_TO_PACK! !7Z_SWITCHES! 38 | IF NOT "!ERRORLEVEL!" EQU "0" ( 39 | ECHO Failed re-packing. Check your 7Zip installation at 40 | ECHO !7Z_RUN! 41 | SET CMD_EXIT_CODE=4 42 | GOTO Error 43 | ) 44 | 45 | COPY /B "!SFX_MODULE!"+"!SFX_MODULE_CFG!"+"!DRIVER_FILES_7Z!" "!INSTALL_DRIVER_EXE!" 46 | 47 | ECHO. 48 | ECHO Done. 49 | ECHO "!INSTALL_DRIVER_EXE!" re-packed! 50 | GOTO :EOF 51 | 52 | :Find7Zip 53 | SET 7Z_RUN="%~$PATH:1" 54 | IF NOT !7Z_RUN! EQU "" ( 55 | ECHO 7Zip found at: !7Z_RUN! 56 | SET 7Z_RUN="%~1" 57 | GOTO :EOF 58 | ) 59 | SHIFT /1 60 | IF "%~1" EQU "" GOTO :EOF 61 | GOTO Find7Zip 62 | GOTO :EOF 63 | 64 | :Error 65 | IF NOT DEFINED NO_REPACK_ERROR_WAIT PAUSE 66 | EXIT %CMD_EXIT_CODE% 67 | GOTO :EOF -------------------------------------------------------------------------------- /DriverPackages/x86/WdfCoInstaller01009.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/x86/WdfCoInstaller01009.dll -------------------------------------------------------------------------------- /DriverPackages/x86/libusb0_x86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/x86/libusb0_x86.dll -------------------------------------------------------------------------------- /DriverPackages/x86/libusbK.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/x86/libusbK.sys -------------------------------------------------------------------------------- /DriverPackages/x86/libusbK_x86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/DriverPackages/x86/libusbK_x86.dll -------------------------------------------------------------------------------- /Installer/ASIO.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/Installer/ASIO.bmp -------------------------------------------------------------------------------- /Installer/ASIO.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/Installer/ASIO.gif -------------------------------------------------------------------------------- /Installer/audiowidget.iss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/Installer/audiowidget.iss -------------------------------------------------------------------------------- /Installer/license.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------------------------- 2 | ASIO driver for open hardware device Audio-Widget 3 | -------------------------------------------------------------------------------------------------- 4 | 5 | THIS SOFTWARE IS PROVIDED "AS IS". IN NO EVENT SHALL I, THE AUTHOR, BE LIABLE FOR ANY KIND OF LOSS OR DAMAGE ARISING OUT OF THE USE, ABUSE OR THE INABILITY TO USE THIS SOFTWRAE, NEITHER SHALL CO-AUTHORS AND CONTRIBUTORS. USE IT AT YOUR OWN RISK! 6 | 7 | THIS SOFTWARE COMES WITHOUT ANY KIND OF WARRANTY, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 8 | 9 | THIS SOFTWARE IS FREEWARE. NON- EXCLUSIVE PERMISSION TO USE THIS SOFTWARE IN ITS UNMODIFIED FORM HEREBY GRANTED. 'USE' SHALL BE DEFINED AS THE UTILISATION OF THIS SOFTWARE FOR ITS INTENDED END USER PURPOSE ONLY. 10 | 11 | YOU MAY FURTHER REDISTRIBUTE ONLY VERBATIM COPIES OF THIS SOFTWARE WITH THE FOLLOWING RESTRICTIONS: 12 | 13 | 1.) THE SOLE SOURCE OF PROFIT TO BE MADE (IF ANY) - INCLUDING PROFIT INTENTED TO BE MADE - FROM THIS SOFTWARE SHALL BE THE SERVICE OF ITS REDISTRIBUTION ONLY. THIS SPECIFICALLY PROHIBITS PLACING SOFTWARE ON ANY MEDIA SOLD TOGETHER WITH AUDIO HARD- AND SOFTWARE, OR SIMILAR PRODUCTS TO WHICH THIS SOFTWARE WOULD ADD SUBSTANTIAL MARKET VALUE. 14 | 2.) EXCEPTIONS TO 1. REQUIRE WRITTEN CONSENT FROM THE AUTHOR. 15 | 16 | IF YOU DO NOT AGREE WITH THESE TERMS OR IF YOUR JURISTDICTION DOES NOT ALLOW THE EXCLUSION OF WARRANTY AND LIABILITY AS STATED ABOVE YOU ARE NOT ALLOWED TO USE THIS SOFTWARE AT ALL. 17 | 18 | THIS SOFTWARE IS COPYRIGHT(c)2012, NIKOLAY KOVBASA, ALL RIGHTS RESERVED. 19 | 20 | ASIO is a trademark and software of Steinberg Media Technologies GmbH -------------------------------------------------------------------------------- /Installer/test.ini: -------------------------------------------------------------------------------- 1 | ;; Useage: "WidgetControl.exe test.ini" 2 | ;; See firmware source file features.h, #define FEATURE_VALUE_NAMES 3 | ;; for a list of available options 4 | BoardType=usbi2s 5 | ImageType=uac2_audio 6 | InType=normal 7 | OutType=normal 8 | AdcType=none 9 | DacType=generic 10 | LcdType=none 11 | LogType=none 12 | FilterType=fir 13 | QuirkType=quirk_linux 14 | NeedReset=0 15 | -------------------------------------------------------------------------------- /Installer/usb_driver/Audio-Widget.inf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/Installer/usb_driver/Audio-Widget.inf -------------------------------------------------------------------------------- /LICENSE-bsd.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Nikolay Kovbasa 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the Nikolay Kovbasa nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL NIKOLAY KOVBASA BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /WidgetControl/WidgetControl.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WidgetControl", "WidgetControl\WidgetControl.csproj", "{8D90372D-EA3B-4435-89EE-C61CA7DF742A}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {8D90372D-EA3B-4435-89EE-C61CA7DF742A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {8D90372D-EA3B-4435-89EE-C61CA7DF742A}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {8D90372D-EA3B-4435-89EE-C61CA7DF742A}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {8D90372D-EA3B-4435-89EE-C61CA7DF742A}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/Program.cs: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | // Widget control utility 16 | // 17 | 18 | using System; 19 | using System.Collections.Generic; 20 | using System.Windows.Forms; 21 | 22 | namespace WidgetControl 23 | { 24 | static class Program 25 | { 26 | /// 27 | /// Главная точка входа для приложения. 28 | /// 29 | [STAThread] 30 | static void Main(string[] args) 31 | { 32 | if (args.Length != 0) 33 | { 34 | WidgetControl widCtrl = new WidgetControl(); 35 | if (!widCtrl.InitializeDevice()) 36 | { 37 | MessageBox.Show(widCtrl.GetInfo(), "Error!"); 38 | return; 39 | } 40 | if (!widCtrl.SetFeatureFromFile(args[0])) 41 | { 42 | MessageBox.Show(widCtrl.GetInfo(), "Error!"); 43 | } 44 | MessageBox.Show("Success", "Information"); 45 | } 46 | else 47 | { 48 | Application.EnableVisualStyles(); 49 | Application.SetCompatibleTextRenderingDefault(false); 50 | Application.Run(new WidgetControl()); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Управление общими сведениями о сборке осуществляется с помощью 6 | // набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения, 7 | // связанные со сборкой. 8 | [assembly: AssemblyTitle("WidgetControl")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WidgetControl")] 13 | [assembly: AssemblyCopyright("Copyright © 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Параметр ComVisible со значением FALSE делает типы в сборке невидимыми 18 | // для COM-компонентов. Если требуется обратиться к типу в этой сборке через 19 | // COM, задайте атрибуту ComVisible значение TRUE для этого типа. 20 | [assembly: ComVisible(false)] 21 | 22 | // Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM 23 | [assembly: Guid("348005be-81bb-4bdb-b6db-0fdf867579e1")] 24 | 25 | // Сведения о версии сборки состоят из следующих четырех значений: 26 | // 27 | // Основной номер версии 28 | // Дополнительный номер версии 29 | // Номер построения 30 | // Редакция 31 | // 32 | // Можно задать все значения или принять номер построения и номер редакции по умолчанию, 33 | // используя "*", как показано ниже: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Этот код создан программным средством. 4 | // Версия среды выполнения: 2.0.50727.4927 5 | // 6 | // Изменения в этом файле могут привести к неправильному поведению и будут утрачены, если 7 | // код создан повторно. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WidgetControl.Properties 12 | { 13 | 14 | 15 | /// 16 | /// Класс ресурсов со строгим типом для поиска локализованных строк и пр. 17 | /// 18 | // Этот класс был автоматически создан при помощи StronglyTypedResourceBuilder 19 | // класс с помощью таких средств, как ResGen или Visual Studio. 20 | // Для добавления или удаления члена измените файл .ResX, а затем перезапустите ResGen 21 | // с параметром /str или заново постройте свой VS-проект. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Возврат кэшированного экземпляра ResourceManager, используемого этим классом. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WidgetControl.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Переопределяет свойство CurrentUICulture текущего потока для всех 56 | /// подстановки ресурсов с помощью этого класса ресурсов со строгим типом. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:2.0.50727.4927 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WidgetControl.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/WidgetControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace WidgetControl 2 | { 3 | partial class WidgetControl 4 | { 5 | /// 6 | /// Требуется переменная конструктора. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Освободить все используемые ресурсы. 12 | /// 13 | /// истинно, если управляемый ресурс должен быть удален; иначе ложно. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (deviceList != null) 17 | deviceList.Free(); 18 | deviceList = null; 19 | if (usb != null) 20 | usb.Free(); 21 | usb = null; 22 | 23 | if (disposing && (components != null)) 24 | { 25 | components.Dispose(); 26 | } 27 | base.Dispose(disposing); 28 | } 29 | 30 | #region Код, автоматически созданный конструктором форм Windows 31 | 32 | /// 33 | /// Обязательный метод для поддержки конструктора - не изменяйте 34 | /// содержимое данного метода при помощи редактора кода. 35 | /// 36 | private void InitializeComponent() 37 | { 38 | this.components = new System.ComponentModel.Container(); 39 | this.DeviceInfo = new System.Windows.Forms.TextBox(); 40 | this.comboBox1 = new System.Windows.Forms.ComboBox(); 41 | this.label1 = new System.Windows.Forms.Label(); 42 | this.comboBox2 = new System.Windows.Forms.ComboBox(); 43 | this.label2 = new System.Windows.Forms.Label(); 44 | this.comboBox3 = new System.Windows.Forms.ComboBox(); 45 | this.label3 = new System.Windows.Forms.Label(); 46 | this.comboBox4 = new System.Windows.Forms.ComboBox(); 47 | this.label4 = new System.Windows.Forms.Label(); 48 | this.comboBox5 = new System.Windows.Forms.ComboBox(); 49 | this.label5 = new System.Windows.Forms.Label(); 50 | this.comboBox6 = new System.Windows.Forms.ComboBox(); 51 | this.label6 = new System.Windows.Forms.Label(); 52 | this.comboBox7 = new System.Windows.Forms.ComboBox(); 53 | this.label7 = new System.Windows.Forms.Label(); 54 | this.comboBox8 = new System.Windows.Forms.ComboBox(); 55 | this.label8 = new System.Windows.Forms.Label(); 56 | this.comboBox9 = new System.Windows.Forms.ComboBox(); 57 | this.label9 = new System.Windows.Forms.Label(); 58 | this.button1 = new System.Windows.Forms.Button(); 59 | this.button2 = new System.Windows.Forms.Button(); 60 | this.button3 = new System.Windows.Forms.Button(); 61 | this.button4 = new System.Windows.Forms.Button(); 62 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); 63 | this.label10 = new System.Windows.Forms.Label(); 64 | this.comboBox10 = new System.Windows.Forms.ComboBox(); 65 | this.SuspendLayout(); 66 | // 67 | // DeviceInfo 68 | // 69 | this.DeviceInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 70 | | System.Windows.Forms.AnchorStyles.Left) 71 | | System.Windows.Forms.AnchorStyles.Right))); 72 | this.DeviceInfo.Location = new System.Drawing.Point(12, 12); 73 | this.DeviceInfo.Multiline = true; 74 | this.DeviceInfo.Name = "DeviceInfo"; 75 | this.DeviceInfo.ReadOnly = true; 76 | this.DeviceInfo.Size = new System.Drawing.Size(470, 162); 77 | this.DeviceInfo.TabIndex = 0; 78 | // 79 | // comboBox1 80 | // 81 | this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 82 | this.comboBox1.FormattingEnabled = true; 83 | this.comboBox1.Location = new System.Drawing.Point(12, 208); 84 | this.comboBox1.Name = "comboBox1"; 85 | this.comboBox1.Size = new System.Drawing.Size(127, 21); 86 | this.comboBox1.TabIndex = 1; 87 | this.comboBox1.Tag = "0"; 88 | // 89 | // label1 90 | // 91 | this.label1.AutoSize = true; 92 | this.label1.Location = new System.Drawing.Point(12, 192); 93 | this.label1.Name = "label1"; 94 | this.label1.Size = new System.Drawing.Size(62, 13); 95 | this.label1.TabIndex = 2; 96 | this.label1.Text = "Board Type"; 97 | // 98 | // comboBox2 99 | // 100 | this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 101 | this.comboBox2.FormattingEnabled = true; 102 | this.comboBox2.Location = new System.Drawing.Point(145, 208); 103 | this.comboBox2.Name = "comboBox2"; 104 | this.comboBox2.Size = new System.Drawing.Size(127, 21); 105 | this.comboBox2.TabIndex = 1; 106 | this.comboBox2.Tag = "1"; 107 | // 108 | // label2 109 | // 110 | this.label2.AutoSize = true; 111 | this.label2.Location = new System.Drawing.Point(145, 192); 112 | this.label2.Name = "label2"; 113 | this.label2.Size = new System.Drawing.Size(63, 13); 114 | this.label2.TabIndex = 2; 115 | this.label2.Text = "Image Type"; 116 | // 117 | // comboBox3 118 | // 119 | this.comboBox3.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 120 | this.comboBox3.FormattingEnabled = true; 121 | this.comboBox3.Location = new System.Drawing.Point(278, 208); 122 | this.comboBox3.Name = "comboBox3"; 123 | this.comboBox3.Size = new System.Drawing.Size(127, 21); 124 | this.comboBox3.TabIndex = 1; 125 | this.comboBox3.Tag = "2"; 126 | // 127 | // label3 128 | // 129 | this.label3.AutoSize = true; 130 | this.label3.Location = new System.Drawing.Point(278, 192); 131 | this.label3.Name = "label3"; 132 | this.label3.Size = new System.Drawing.Size(45, 13); 133 | this.label3.TabIndex = 2; 134 | this.label3.Text = "IN Type"; 135 | // 136 | // comboBox4 137 | // 138 | this.comboBox4.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 139 | this.comboBox4.FormattingEnabled = true; 140 | this.comboBox4.Location = new System.Drawing.Point(411, 208); 141 | this.comboBox4.Name = "comboBox4"; 142 | this.comboBox4.Size = new System.Drawing.Size(127, 21); 143 | this.comboBox4.TabIndex = 1; 144 | this.comboBox4.Tag = "3"; 145 | // 146 | // label4 147 | // 148 | this.label4.AutoSize = true; 149 | this.label4.Location = new System.Drawing.Point(411, 192); 150 | this.label4.Name = "label4"; 151 | this.label4.Size = new System.Drawing.Size(57, 13); 152 | this.label4.TabIndex = 2; 153 | this.label4.Text = "OUT Type"; 154 | // 155 | // comboBox5 156 | // 157 | this.comboBox5.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 158 | this.comboBox5.FormattingEnabled = true; 159 | this.comboBox5.Location = new System.Drawing.Point(12, 256); 160 | this.comboBox5.Name = "comboBox5"; 161 | this.comboBox5.Size = new System.Drawing.Size(127, 21); 162 | this.comboBox5.TabIndex = 1; 163 | this.comboBox5.Tag = "4"; 164 | // 165 | // label5 166 | // 167 | this.label5.AutoSize = true; 168 | this.label5.Location = new System.Drawing.Point(12, 240); 169 | this.label5.Name = "label5"; 170 | this.label5.Size = new System.Drawing.Size(56, 13); 171 | this.label5.TabIndex = 2; 172 | this.label5.Text = "ADC Type"; 173 | // 174 | // comboBox6 175 | // 176 | this.comboBox6.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 177 | this.comboBox6.FormattingEnabled = true; 178 | this.comboBox6.Location = new System.Drawing.Point(145, 256); 179 | this.comboBox6.Name = "comboBox6"; 180 | this.comboBox6.Size = new System.Drawing.Size(127, 21); 181 | this.comboBox6.TabIndex = 1; 182 | this.comboBox6.Tag = "5"; 183 | this.comboBox6.SelectedIndexChanged += new System.EventHandler(this.comboBox6_SelectedIndexChanged); 184 | // 185 | // label6 186 | // 187 | this.label6.AutoSize = true; 188 | this.label6.Location = new System.Drawing.Point(145, 240); 189 | this.label6.Name = "label6"; 190 | this.label6.Size = new System.Drawing.Size(56, 13); 191 | this.label6.TabIndex = 2; 192 | this.label6.Text = "DAC Type"; 193 | // 194 | // comboBox7 195 | // 196 | this.comboBox7.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 197 | this.comboBox7.FormattingEnabled = true; 198 | this.comboBox7.Location = new System.Drawing.Point(278, 256); 199 | this.comboBox7.Name = "comboBox7"; 200 | this.comboBox7.Size = new System.Drawing.Size(127, 21); 201 | this.comboBox7.TabIndex = 1; 202 | this.comboBox7.Tag = "6"; 203 | // 204 | // label7 205 | // 206 | this.label7.AutoSize = true; 207 | this.label7.Location = new System.Drawing.Point(278, 240); 208 | this.label7.Name = "label7"; 209 | this.label7.Size = new System.Drawing.Size(55, 13); 210 | this.label7.TabIndex = 2; 211 | this.label7.Text = "LCD Type"; 212 | // 213 | // comboBox8 214 | // 215 | this.comboBox8.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 216 | this.comboBox8.FormattingEnabled = true; 217 | this.comboBox8.Location = new System.Drawing.Point(411, 256); 218 | this.comboBox8.Name = "comboBox8"; 219 | this.comboBox8.Size = new System.Drawing.Size(127, 21); 220 | this.comboBox8.TabIndex = 1; 221 | this.comboBox8.Tag = "7"; 222 | // 223 | // label8 224 | // 225 | this.label8.AutoSize = true; 226 | this.label8.Location = new System.Drawing.Point(411, 240); 227 | this.label8.Name = "label8"; 228 | this.label8.Size = new System.Drawing.Size(52, 13); 229 | this.label8.TabIndex = 2; 230 | this.label8.Text = "Log Type"; 231 | // 232 | // comboBox9 233 | // 234 | this.comboBox9.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 235 | this.comboBox9.FormattingEnabled = true; 236 | this.comboBox9.Location = new System.Drawing.Point(12, 306); 237 | this.comboBox9.Name = "comboBox9"; 238 | this.comboBox9.Size = new System.Drawing.Size(127, 21); 239 | this.comboBox9.TabIndex = 1; 240 | this.comboBox9.Tag = "8"; 241 | // 242 | // label9 243 | // 244 | this.label9.AutoSize = true; 245 | this.label9.Location = new System.Drawing.Point(12, 290); 246 | this.label9.Name = "label9"; 247 | this.label9.Size = new System.Drawing.Size(56, 13); 248 | this.label9.TabIndex = 2; 249 | this.label9.Text = "Filter Type"; 250 | // 251 | // button1 252 | // 253 | this.button1.Location = new System.Drawing.Point(511, 12); 254 | this.button1.Name = "button1"; 255 | this.button1.Size = new System.Drawing.Size(75, 23); 256 | this.button1.TabIndex = 3; 257 | this.button1.Text = "Save"; 258 | this.toolTip1.SetToolTip(this.button1, "Save new value to device"); 259 | this.button1.UseVisualStyleBackColor = true; 260 | this.button1.Click += new System.EventHandler(this.OnSave); 261 | // 262 | // button2 263 | // 264 | this.button2.Location = new System.Drawing.Point(511, 41); 265 | this.button2.Name = "button2"; 266 | this.button2.Size = new System.Drawing.Size(75, 23); 267 | this.button2.TabIndex = 3; 268 | this.button2.Text = "Refresh"; 269 | this.toolTip1.SetToolTip(this.button2, "Read value from device"); 270 | this.button2.UseVisualStyleBackColor = true; 271 | this.button2.Click += new System.EventHandler(this.OnRefresh); 272 | // 273 | // button3 274 | // 275 | this.button3.Location = new System.Drawing.Point(511, 91); 276 | this.button3.Name = "button3"; 277 | this.button3.Size = new System.Drawing.Size(75, 23); 278 | this.button3.TabIndex = 4; 279 | this.button3.Text = "Reset"; 280 | this.toolTip1.SetToolTip(this.button3, "Reset USB device"); 281 | this.button3.UseVisualStyleBackColor = true; 282 | this.button3.Click += new System.EventHandler(this.OnReset); 283 | // 284 | // button4 285 | // 286 | this.button4.Location = new System.Drawing.Point(511, 120); 287 | this.button4.Name = "button4"; 288 | this.button4.Size = new System.Drawing.Size(75, 23); 289 | this.button4.TabIndex = 4; 290 | this.button4.Text = "Fact.Reset"; 291 | this.toolTip1.SetToolTip(this.button4, "Factory reset"); 292 | this.button4.UseVisualStyleBackColor = true; 293 | this.button4.Click += new System.EventHandler(this.OnFactReset); 294 | // 295 | // label10 296 | // 297 | this.label10.AutoSize = true; 298 | this.label10.Location = new System.Drawing.Point(145, 290); 299 | this.label10.Name = "label10"; 300 | this.label10.Size = new System.Drawing.Size(37, 13); 301 | this.label10.TabIndex = 6; 302 | this.label10.Text = "Quirks"; 303 | this.label10.Click += new System.EventHandler(this.label10_Click); 304 | // 305 | // comboBox10 306 | // 307 | this.comboBox10.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 308 | this.comboBox10.FormattingEnabled = true; 309 | this.comboBox10.Location = new System.Drawing.Point(145, 306); 310 | this.comboBox10.Name = "comboBox10"; 311 | this.comboBox10.Size = new System.Drawing.Size(127, 21); 312 | this.comboBox10.TabIndex = 5; 313 | this.comboBox10.Tag = "9"; 314 | // 315 | // WidgetControl 316 | // 317 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 318 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 319 | this.ClientSize = new System.Drawing.Size(598, 339); 320 | this.Controls.Add(this.label10); 321 | this.Controls.Add(this.comboBox10); 322 | this.Controls.Add(this.button4); 323 | this.Controls.Add(this.button3); 324 | this.Controls.Add(this.button2); 325 | this.Controls.Add(this.button1); 326 | this.Controls.Add(this.label9); 327 | this.Controls.Add(this.label8); 328 | this.Controls.Add(this.label7); 329 | this.Controls.Add(this.label6); 330 | this.Controls.Add(this.label5); 331 | this.Controls.Add(this.label4); 332 | this.Controls.Add(this.label3); 333 | this.Controls.Add(this.label2); 334 | this.Controls.Add(this.label1); 335 | this.Controls.Add(this.comboBox1); 336 | this.Controls.Add(this.comboBox2); 337 | this.Controls.Add(this.comboBox3); 338 | this.Controls.Add(this.comboBox4); 339 | this.Controls.Add(this.comboBox5); 340 | this.Controls.Add(this.comboBox6); 341 | this.Controls.Add(this.comboBox7); 342 | this.Controls.Add(this.comboBox8); 343 | this.Controls.Add(this.comboBox9); 344 | this.Controls.Add(this.DeviceInfo); 345 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 346 | this.Name = "WidgetControl"; 347 | this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; 348 | this.Text = "WidgetControl"; 349 | this.ResumeLayout(false); 350 | this.PerformLayout(); 351 | 352 | } 353 | 354 | #endregion 355 | 356 | private System.Windows.Forms.TextBox DeviceInfo; 357 | private System.Windows.Forms.ComboBox comboBox1; 358 | private System.Windows.Forms.Label label1; 359 | private System.Windows.Forms.ComboBox comboBox2; 360 | private System.Windows.Forms.Label label2; 361 | private System.Windows.Forms.ComboBox comboBox3; 362 | private System.Windows.Forms.Label label3; 363 | private System.Windows.Forms.ComboBox comboBox4; 364 | private System.Windows.Forms.Label label4; 365 | private System.Windows.Forms.ComboBox comboBox5; 366 | private System.Windows.Forms.Label label5; 367 | private System.Windows.Forms.ComboBox comboBox6; 368 | private System.Windows.Forms.Label label6; 369 | private System.Windows.Forms.ComboBox comboBox7; 370 | private System.Windows.Forms.Label label7; 371 | private System.Windows.Forms.ComboBox comboBox8; 372 | private System.Windows.Forms.Label label8; 373 | private System.Windows.Forms.ComboBox comboBox9; 374 | private System.Windows.Forms.Label label9; 375 | private System.Windows.Forms.Button button1; 376 | private System.Windows.Forms.Button button2; 377 | private System.Windows.Forms.Button button3; 378 | private System.Windows.Forms.ToolTip toolTip1; 379 | private System.Windows.Forms.Button button4; 380 | private System.Windows.Forms.Label label10; 381 | private System.Windows.Forms.ComboBox comboBox10; 382 | } 383 | } 384 | 385 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/WidgetControl.cs: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | // Widget control utility 16 | // Based on code Widget Control 17 | // by Alex Lee, 9V1AL & Loftur Jonasson, TF3LJ 18 | 19 | using System; 20 | using System.Collections; 21 | using System.ComponentModel; 22 | using System.Data; 23 | using System.Drawing; 24 | using System.Text; 25 | using System.Windows.Forms; 26 | using System.Runtime.InteropServices; 27 | using System.IO; 28 | 29 | using libusbK; 30 | 31 | namespace WidgetControl 32 | { 33 | public partial class WidgetControl : Form 34 | { 35 | private const int vendorid1 = 0x16c0; 36 | private const int vendorid2 = 0xfffe; 37 | private const int productid1 = 0x05dc; 38 | private const int productid2 = 0x03e8; 39 | private const int productid3 = 0x0007; 40 | private const int productid4 = 0x03e9; 41 | private const int interfaceNumber = 0; 42 | // BSB 20120928 Lowercase from usb_descriptors.h 43 | private const int audio_vendor_id = 0x16d0; 44 | private const int audio_product_id_1 = 0x0761; // SDR-WIDGET UAC1 PID 45 | private const int audio_product_id_2 = 0x0762; // SDR-WIDGET UAC2 PID 46 | private const int audio_product_id_3 = 0x0763; // USB9023 UAC1 PID 47 | private const int audio_product_id_4 = 0x0764; // USB9023 UAC2 PID 48 | private const int audio_product_id_5 = 0x0765; // USB5102 UAC1 PID 49 | private const int audio_product_id_6 = 0x0766; // USB5102 UAC2 PID 50 | private const int audio_product_id_7 = 0x0767; // USB8741 UAC1 PID 51 | private const int audio_product_id_8 = 0x0768; // USB8741 UAC2 PID 52 | private const int audio_product_id_9 = 0x075C; // AB-1.x UAC1 PID 53 | private const int audio_product_id_10 = 0x075D; // AB-1.x UAC2 PID 54 | private const int audio_product_id_11 = 0x075E; // QNKTC future use UAC1 PID 55 | private const int audio_product_id_12 = 0x075F; // QNKTC future use UAC2 PID 56 | private const int audio_product_id_13 = 0x098b; // AMB UAC1 PID 57 | private const int audio_product_id_14 = 0x098c; // AMB UAC2 PID 58 | 59 | LstK deviceList = null; 60 | UsbK usb = null; 61 | 62 | Hashtable feature_value_dict = new Hashtable(); 63 | Hashtable feature_value_lookup_dict = new Hashtable(); 64 | 65 | uint LengthTransferred; 66 | const uint globalBufferLength = 256; 67 | byte[] globalBuffer = new byte[256]; 68 | 69 | public WidgetControl() 70 | { 71 | InitializeComponent(); 72 | InitializeDevice(); 73 | //SetFeatureFromFile("test.ini"); 74 | } 75 | 76 | USB_DEVICE_DESCRIPTOR ByteToDeviceDescriptor (byte[] packet) 77 | { 78 | GCHandle pinnedPacket = GCHandle.Alloc(packet, GCHandleType.Pinned); 79 | USB_DEVICE_DESCRIPTOR descriptor = (USB_DEVICE_DESCRIPTOR)Marshal.PtrToStructure( 80 | pinnedPacket.AddrOfPinnedObject(), 81 | typeof(USB_DEVICE_DESCRIPTOR)); 82 | pinnedPacket.Free(); 83 | return descriptor; 84 | } 85 | 86 | USB_CONFIGURATION_DESCRIPTOR ByteToConfigDescriptor(byte[] packet) 87 | { 88 | GCHandle pinnedPacket = GCHandle.Alloc(packet, GCHandleType.Pinned); 89 | USB_CONFIGURATION_DESCRIPTOR descriptor = (USB_CONFIGURATION_DESCRIPTOR)Marshal.PtrToStructure( 90 | pinnedPacket.AddrOfPinnedObject(), 91 | typeof(USB_CONFIGURATION_DESCRIPTOR)); 92 | pinnedPacket.Free(); 93 | return descriptor; 94 | } 95 | 96 | string GetStringDescriptor(byte index) 97 | { 98 | usb.GetDescriptor((byte)USB_DESCRIPTOR_TYPE.STRING, index, 0, 99 | globalBuffer, globalBufferLength, out LengthTransferred); 100 | 101 | string s2 = System.Text.Encoding.Unicode.GetString(globalBuffer, 0, (int)LengthTransferred); 102 | if (s2.Length > 0) 103 | return s2.Substring(1, s2.Length - 1); 104 | return string.Empty; 105 | } 106 | 107 | public bool InitializeDevice() 108 | { 109 | if (deviceList != null) 110 | deviceList.Free(); 111 | deviceList = null; 112 | if (usb != null) 113 | usb.Free(); 114 | usb = null; 115 | 116 | feature_value_dict.Clear(); 117 | feature_value_lookup_dict.Clear(); 118 | 119 | foreach (Control ctrl in this.Controls) 120 | { 121 | if (ctrl is ComboBox) 122 | { 123 | ComboBox box = (ComboBox)ctrl; 124 | box.Items.Clear(); 125 | } 126 | } 127 | 128 | deviceList = new LstK(KLST_FLAG.NONE); 129 | KLST_DEVINFO_HANDLE deviceInfo; 130 | 131 | DeviceInfo.Text = ""; 132 | bool success = false; 133 | deviceList.MoveReset(); 134 | while (deviceList.MoveNext(out deviceInfo)) 135 | { 136 | if ( // BSB 20120928 revised test 137 | // (deviceInfo.Common.Vid == vendorid1 || deviceInfo.Common.Vid == vendorid2) && 138 | // (deviceInfo.Common.Pid == productid1 || deviceInfo.Common.Pid == productid2 || deviceInfo.Common.Pid == productid3 || deviceInfo.Common.Pid == productid4) && 139 | // deviceInfo.DeviceInterfaceGUID.ToUpper() == "{D49AB938-53BA-498A-A848-8E2780A4A75F}" 140 | (deviceInfo.DeviceInterfaceGUID.ToUpper() == "{D49AB938-53BA-498A-A848-8E2780A4A75F}") && 141 | ( 142 | ( 143 | (deviceInfo.Common.Vid == vendorid1 || deviceInfo.Common.Vid == vendorid2) && 144 | (deviceInfo.Common.Pid == productid1 || deviceInfo.Common.Pid == productid2 || deviceInfo.Common.Pid == productid3 || deviceInfo.Common.Pid == productid4) 145 | ) || 146 | ( 147 | (deviceInfo.Common.Vid == audio_vendor_id) && 148 | ( 149 | (deviceInfo.Common.Pid == audio_product_id_1) || 150 | (deviceInfo.Common.Pid == audio_product_id_2) || 151 | (deviceInfo.Common.Pid == audio_product_id_3) || 152 | (deviceInfo.Common.Pid == audio_product_id_4) || 153 | (deviceInfo.Common.Pid == audio_product_id_5) || 154 | (deviceInfo.Common.Pid == audio_product_id_6) || 155 | (deviceInfo.Common.Pid == audio_product_id_7) || 156 | (deviceInfo.Common.Pid == audio_product_id_8) || 157 | (deviceInfo.Common.Pid == audio_product_id_9) || 158 | (deviceInfo.Common.Pid == audio_product_id_10) || 159 | (deviceInfo.Common.Pid == audio_product_id_11) || 160 | (deviceInfo.Common.Pid == audio_product_id_12) || 161 | (deviceInfo.Common.Pid == audio_product_id_13) || 162 | (deviceInfo.Common.Pid == audio_product_id_14) 163 | ) 164 | ) 165 | ) 166 | ) 167 | { 168 | if (deviceInfo.Connected) 169 | { 170 | success = true; 171 | break; 172 | } 173 | } 174 | } 175 | if (!success) 176 | { 177 | DeviceInfo.Text += String.Format("Audio-Widget device not found!\r\n"); 178 | if (deviceList != null) 179 | deviceList.Free(); 180 | deviceList = null; 181 | return false; 182 | } 183 | usb = new UsbK(deviceInfo); 184 | DeviceInfo.Text += String.Format("Opening usb device OK\r\n"); 185 | 186 | usb.GetDescriptor((byte)USB_DESCRIPTOR_TYPE.DEVICE, 0, 0, 187 | globalBuffer, globalBufferLength, out LengthTransferred); 188 | 189 | USB_DEVICE_DESCRIPTOR deviceDescriptor = ByteToDeviceDescriptor(globalBuffer); 190 | 191 | usb.GetDescriptor((byte)USB_DESCRIPTOR_TYPE.CONFIGURATION, 0, 0, 192 | globalBuffer, globalBufferLength, out LengthTransferred); 193 | USB_CONFIGURATION_DESCRIPTOR configurationDescriptor = ByteToConfigDescriptor(globalBuffer); 194 | 195 | string product = GetStringDescriptor(deviceDescriptor.iProduct); 196 | string manufacturer = GetStringDescriptor(deviceDescriptor.iManufacturer); 197 | string serial = GetStringDescriptor(deviceDescriptor.iSerialNumber); 198 | 199 | DeviceInfo.Text += String.Format("Device: VID=0x{0:X04}/PID=0x{1:X04}\r\n", deviceDescriptor.idVendor, deviceDescriptor.idProduct); 200 | DeviceInfo.Text += String.Format("Product: {0}\r\n", product); 201 | DeviceInfo.Text += String.Format("Manufacturer: {0}\r\n", manufacturer); 202 | DeviceInfo.Text += String.Format("Serial number: {0}\r\n", serial); 203 | 204 | success = SendUsbControl(interfaceNumber, (byte)BMREQUEST_DIR.DEVICE_TO_HOST, (byte)BMREQUEST_TYPE.VENDOR, 205 | (byte)BMREQUEST_RECIPIENT.DEVICE, 0x71, 4, 1, 206 | globalBuffer, globalBufferLength, out LengthTransferred); 207 | 208 | 209 | ushort max_feature_value_index = globalBuffer[0]; 210 | ushort feature_index = 0; 211 | ComboBox control = null; 212 | 213 | for (ushort i = 0; i < max_feature_value_index; i++) 214 | { 215 | success = SendUsbControl(interfaceNumber, (byte)BMREQUEST_DIR.DEVICE_TO_HOST, (byte)BMREQUEST_TYPE.VENDOR, 216 | (byte)BMREQUEST_RECIPIENT.DEVICE, 0x71, 8, i, 217 | globalBuffer, globalBufferLength, out LengthTransferred); 218 | if (globalBuffer[0] == 63) 219 | break; 220 | 221 | string output_str = ""; 222 | for (int s = (int)LengthTransferred - 1; s >= 0; s--) 223 | output_str += (char)globalBuffer[s]; 224 | 225 | if (output_str == "end") 226 | { 227 | feature_index++; 228 | control = null; 229 | } 230 | else 231 | { 232 | if (control == null) 233 | control = FindFeatureControl(feature_index); 234 | 235 | if (control != null) 236 | { 237 | control.Items.Add(output_str); 238 | feature_value_dict[(int)i] = output_str; 239 | feature_value_lookup_dict[feature_index.ToString() + output_str] = (int)i; 240 | } 241 | } 242 | 243 | if (i > 100) 244 | break; 245 | } 246 | foreach (Control ctrl in this.Controls) 247 | { 248 | if (ctrl is ComboBox) 249 | { 250 | int index = Convert.ToInt32(ctrl.Tag); 251 | ComboBox box = (ComboBox)ctrl; 252 | 253 | success = SendUsbControl(interfaceNumber, (byte)BMREQUEST_DIR.DEVICE_TO_HOST, (byte)BMREQUEST_TYPE.VENDOR, 254 | (byte)BMREQUEST_RECIPIENT.DEVICE, 0x71, 4, (byte)(2 + index), 255 | globalBuffer, globalBufferLength, out LengthTransferred); 256 | int feature_value_index = (int)globalBuffer[0]; 257 | if (feature_value_dict.ContainsKey(feature_value_index)) 258 | { 259 | string text = feature_value_dict[feature_value_index].ToString(); 260 | box.SelectedIndex = box.Items.IndexOf(text); 261 | } 262 | } 263 | } 264 | return true; 265 | } 266 | 267 | public string GetInfo() 268 | { 269 | return DeviceInfo.Text; 270 | } 271 | 272 | ComboBox FindFeatureControl(int ind) 273 | { 274 | foreach(Control ctrl in this.Controls) 275 | { 276 | if (ctrl is ComboBox && Convert.ToInt32(ctrl.Tag) == ind) 277 | return (ComboBox)ctrl; 278 | } 279 | return null; 280 | } 281 | 282 | bool SendUsbControl(byte interfaceNum, 283 | byte dir, byte type, byte recipient, byte request, ushort value, ushort index, 284 | byte[] Buffer, uint BufferLength, out uint LengthTransferred) 285 | { 286 | bool retVal = false; 287 | WINUSB_SETUP_PACKET packet; 288 | packet.RequestType = (byte)((dir << 7) | (type << 5) | (recipient)); 289 | packet.Request = request; 290 | packet.Value = value; 291 | packet.Index = index; 292 | packet.Length = 0; 293 | LengthTransferred = 0; 294 | if (usb.ClaimInterface(interfaceNum, false)) 295 | { 296 | if (usb.ControlTransfer(packet, Buffer, BufferLength, out LengthTransferred, IntPtr.Zero)) 297 | retVal = true; 298 | 299 | usb.ReleaseInterface(interfaceNum, false); 300 | } 301 | return retVal; 302 | } 303 | 304 | void RefreshValues() 305 | { 306 | InitializeDevice(); 307 | } 308 | 309 | public bool SetFeatureFromFile(string fileName) 310 | { 311 | bool needReset = false; 312 | bool retValue; 313 | try 314 | { 315 | if (!File.Exists(fileName)) 316 | { 317 | DeviceInfo.Text = String.Format("{0} does not exist.", fileName); 318 | return false; 319 | } 320 | using (StreamReader sr = File.OpenText(fileName)) 321 | { 322 | String input; 323 | int i = 0; 324 | while ((input = sr.ReadLine()) != null) 325 | { 326 | //format line feature=value 327 | input = input.TrimStart().TrimEnd(); 328 | if (input.StartsWith(";") || string.IsNullOrEmpty(input)) 329 | continue; 330 | string[] str = input.Split(new char[] {'='}); 331 | if (str.Length != 2) 332 | { 333 | DeviceInfo.Text = String.Format("Error in line {0}, string {1}", i, input); 334 | return false; 335 | } 336 | string feature = str[0]; 337 | string value = str[1]; 338 | 339 | // if (feature.ToUpper() == "NEEDRESET" && value == "1") 340 | if (feature.ToUpper() == "NEEDRESET") // Continue on "needreset=0" in .ini file. BSB 20120413 341 | { 342 | if (value == "1") 343 | needReset = true; 344 | continue; 345 | } 346 | 347 | int featureIndex = GetFeatureIndex(feature); 348 | if (featureIndex == -1) 349 | { 350 | DeviceInfo.Text = String.Format("Feature {0} not found in possible features", feature); 351 | return false; 352 | } 353 | ComboBox cbox = FindFeatureControl(featureIndex); 354 | if (cbox == null) 355 | { 356 | DeviceInfo.Text = String.Format("Feature {0} not found in device", feature); 357 | return false; 358 | } 359 | bool isFound = false; 360 | for (int ci = 0; ci < cbox.Items.Count; ci++) 361 | { 362 | if (cbox.Items[ci].ToString().ToUpper() == value.ToUpper()) 363 | { 364 | cbox.SelectedIndex = ci; 365 | isFound = true; 366 | break; 367 | } 368 | } 369 | if (!isFound) 370 | { 371 | DeviceInfo.Text = String.Format("Feature value {0} for feature {1} not found in device", value, feature); 372 | return false; 373 | } 374 | //Console.WriteLine("The end of the stream has been reached."); 375 | i++; 376 | } 377 | } 378 | retValue = true; 379 | } 380 | catch(Exception e) 381 | { 382 | DeviceInfo.Text = e.Message; 383 | return false; 384 | } 385 | 386 | retValue &= Save(); 387 | if (needReset) 388 | ResetDevice(); 389 | 390 | return retValue; 391 | } 392 | 393 | private void OnSave(object sender, EventArgs e) 394 | { 395 | Save(); 396 | } 397 | 398 | private bool Save() 399 | { 400 | bool success = true; 401 | foreach (Control ctrl in this.Controls) 402 | { 403 | if (ctrl is ComboBox) 404 | { 405 | int feature = Convert.ToInt32(ctrl.Tag); 406 | ComboBox box = (ComboBox)ctrl; 407 | string index = feature.ToString() + box.Text; 408 | if (feature_value_lookup_dict.ContainsKey(index)) 409 | { 410 | int feature_value_index = (int)feature_value_lookup_dict[index]; 411 | 412 | success &= SendUsbControl(interfaceNumber, (byte)BMREQUEST_DIR.DEVICE_TO_HOST, (byte)BMREQUEST_TYPE.VENDOR, 413 | (byte)BMREQUEST_RECIPIENT.DEVICE, 0x71, 3, (ushort)(2 + feature + feature_value_index * 256), 414 | globalBuffer, globalBufferLength, out LengthTransferred); 415 | } 416 | } 417 | } 418 | return success; 419 | } 420 | 421 | private void OnRefresh(object sender, EventArgs e) 422 | { 423 | InitializeDevice(); 424 | } 425 | 426 | private void OnReset(object sender, EventArgs e) 427 | { 428 | ResetDevice(); 429 | System.Threading.Thread.Sleep(5000); 430 | InitializeDevice(); 431 | } 432 | 433 | private bool ResetDevice() 434 | { 435 | return SendUsbControl(interfaceNumber, (byte)BMREQUEST_DIR.DEVICE_TO_HOST, (byte)BMREQUEST_TYPE.VENDOR, 436 | (byte)BMREQUEST_RECIPIENT.DEVICE, 0x0F, 0, 0, 437 | globalBuffer, globalBufferLength, out LengthTransferred); 438 | } 439 | 440 | private void OnFactReset(object sender, EventArgs e) 441 | { 442 | bool success = SendUsbControl(interfaceNumber, (byte)BMREQUEST_DIR.DEVICE_TO_HOST, (byte)BMREQUEST_TYPE.VENDOR, 443 | (byte)BMREQUEST_RECIPIENT.DEVICE, 0x41, 0xFF, 0, 444 | globalBuffer, globalBufferLength, out LengthTransferred); 445 | System.Threading.Thread.Sleep(5); 446 | InitializeDevice(); 447 | } 448 | 449 | struct FeatureDescriptor 450 | { 451 | public int index; 452 | public string name; 453 | public FeatureDescriptor(int _index, string _name) 454 | { 455 | index = _index; 456 | name = _name; 457 | } 458 | }; 459 | 460 | static FeatureDescriptor[] features = new FeatureDescriptor[] 461 | { 462 | new FeatureDescriptor(0, "BoardType"), 463 | new FeatureDescriptor(1, "ImageType"), 464 | new FeatureDescriptor(2, "InType"), 465 | new FeatureDescriptor(3, "OutType"), 466 | new FeatureDescriptor(4, "AdcType"), 467 | new FeatureDescriptor(5, "DacType"), 468 | new FeatureDescriptor(6, "LcdType"), 469 | new FeatureDescriptor(7, "LogType"), 470 | new FeatureDescriptor(8, "FilterType"), 471 | new FeatureDescriptor(9, "QuirkType"), 472 | }; 473 | 474 | static int GetFeatureIndex(string name) 475 | { 476 | foreach (FeatureDescriptor feature in features) 477 | { 478 | if (name.ToUpper() == feature.name.ToUpper()) 479 | return feature.index; 480 | } 481 | return -1; 482 | } 483 | 484 | private void comboBox6_SelectedIndexChanged(object sender, EventArgs e) 485 | { 486 | 487 | } 488 | 489 | private void label10_Click(object sender, EventArgs e) 490 | { 491 | 492 | } 493 | } 494 | } 495 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/WidgetControl.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {8D90372D-EA3B-4435-89EE-C61CA7DF742A} 9 | WinExe 10 | Properties 11 | WidgetControl 12 | WidgetControl 13 | v2.0 14 | 512 15 | 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Form 46 | 47 | 48 | WidgetControl.cs 49 | 50 | 51 | 52 | 53 | 54 | WidgetControl.cs 55 | Designer 56 | 57 | 58 | ResXFileCodeGenerator 59 | Resources.Designer.cs 60 | Designer 61 | 62 | 63 | True 64 | Resources.resx 65 | 66 | 67 | 68 | SettingsSingleFileGenerator 69 | Settings.Designer.cs 70 | 71 | 72 | True 73 | Settings.settings 74 | True 75 | 76 | 77 | 78 | 85 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/WidgetControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 17, 17 125 | 126 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /WidgetControl/WidgetControl/bin/Release/test.ini: -------------------------------------------------------------------------------- 1 | ;; Useage: "WidgetControl.exe test.ini" 2 | ;; See firmware source file features.h, #define FEATURE_VALUE_NAMES 3 | ;; for a list of available options 4 | BoardType=usbi2s 5 | ImageType=uac2_audio 6 | InType=normal 7 | OutType=normal 8 | AdcType=none 9 | DacType=generic 10 | LcdType=none 11 | LogType=none 12 | FilterType=fir 13 | QuirkType=quirk_linux 14 | NeedReset=0 15 | -------------------------------------------------------------------------------- /WidgetTest/WidgetTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual C++ Express 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WidgetTest", "WidgetTest.vcproj", "{FF52CB06-75F7-4B69-B1BC-79CF7D09618C}" 5 | ProjectSection(ProjectDependencies) = postProject 6 | {6964BC9D-1940-424C-9273-921F7C60D72A} = {6964BC9D-1940-424C-9273-921F7C60D72A} 7 | EndProjectSection 8 | EndProject 9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uaclib", "..\uaclib\uaclib.vcproj", "{6964BC9D-1940-424C-9273-921F7C60D72A}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Win32 = Debug|Win32 14 | Release with Trace|Win32 = Release with Trace|Win32 15 | Release|Win32 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {FF52CB06-75F7-4B69-B1BC-79CF7D09618C}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {FF52CB06-75F7-4B69-B1BC-79CF7D09618C}.Debug|Win32.Build.0 = Debug|Win32 20 | {FF52CB06-75F7-4B69-B1BC-79CF7D09618C}.Release with Trace|Win32.ActiveCfg = Release with Trace|Win32 21 | {FF52CB06-75F7-4B69-B1BC-79CF7D09618C}.Release with Trace|Win32.Build.0 = Release with Trace|Win32 22 | {FF52CB06-75F7-4B69-B1BC-79CF7D09618C}.Release|Win32.ActiveCfg = Release|Win32 23 | {FF52CB06-75F7-4B69-B1BC-79CF7D09618C}.Release|Win32.Build.0 = Release|Win32 24 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Debug|Win32.Build.0 = Debug|Win32 26 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Release with Trace|Win32.ActiveCfg = Release with Trace|Win32 27 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Release with Trace|Win32.Build.0 = Release with Trace|Win32 28 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Release|Win32.ActiveCfg = Release|Win32 29 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Release|Win32.Build.0 = Release|Win32 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /WidgetTest/WidgetTest.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/WidgetTest/WidgetTest.vcproj -------------------------------------------------------------------------------- /WidgetTest/widgettest.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | 16 | #define _CRTDBG_MAP_ALLOC 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "USBAudioDevice.h" 23 | #include "tlist.h" 24 | 25 | #ifdef _ENABLE_TRACE 26 | 27 | void debugPrintf(const char *szFormat, ...) 28 | { 29 | char str[4096]; 30 | va_list argptr; 31 | va_start(argptr, szFormat); 32 | vsprintf_s(str, szFormat, argptr); 33 | va_end(argptr); 34 | 35 | printf(str); 36 | OutputDebugString(str); 37 | } 38 | #endif 39 | 40 | 41 | struct AudioSample4 42 | { 43 | int left; 44 | int right; 45 | }; 46 | 47 | struct ThreeByteSample 48 | { 49 | UCHAR sample[3]; 50 | ThreeByteSample(int val = 0) 51 | { 52 | UCHAR *ptrVal = (UCHAR *)&val; 53 | sample[0] = *(ptrVal); 54 | sample[1] = *(ptrVal+1); 55 | sample[2] = *(ptrVal+2); 56 | } 57 | 58 | operator int()const 59 | { 60 | return (sample[0] << 0) + (sample[1] << 8) + (sample[2] << 16); 61 | } 62 | }; 63 | 64 | struct AudioSample3 65 | { 66 | ThreeByteSample left; 67 | ThreeByteSample right; 68 | }; 69 | 70 | AudioSample4 dummybuffer[48]; 71 | DWORD globalReadBuffer = 0; 72 | DWORD globalPacketCounter = 0; 73 | 74 | void FillBuffer(bool zoom) 75 | { 76 | memset(dummybuffer, 0, 48*sizeof(AudioSample4)); 77 | for(int i = 0; i < 48; i++) 78 | { 79 | //dummybuffer[i].left = (int)(0x1FFFFF*sin(2.0*3.14159265358979323846*(double)i/48.)); 80 | dummybuffer[i].left = (int)(0x1FFFFF*sin(2.0*3.14159265358979323846*(double)i/48.)); 81 | dummybuffer[i].right = dummybuffer[i].left; 82 | 83 | if(zoom) 84 | { 85 | dummybuffer[i].left = dummybuffer[i].left << 8; 86 | dummybuffer[i].right = dummybuffer[i].right << 8; 87 | } 88 | } 89 | } 90 | 91 | void FillData4(void* context, UCHAR *buffer, int& len) 92 | { 93 | AudioSample4 *sampleBuff = (AudioSample4 *)buffer; 94 | int sampleLength = len / sizeof(AudioSample4); 95 | 96 | for(int i = 0; i < sampleLength; i++) 97 | { 98 | sampleBuff[i].left = dummybuffer[globalReadBuffer].left; 99 | sampleBuff[i].right = dummybuffer[globalReadBuffer].right; 100 | globalReadBuffer++; 101 | if(globalReadBuffer >= 48) 102 | globalReadBuffer = 0; 103 | } 104 | globalPacketCounter++; 105 | if(globalPacketCounter > 0xFF) 106 | globalPacketCounter = 0; 107 | } 108 | 109 | void FillData3(void* context, UCHAR *buffer, int& len) 110 | { 111 | AudioSample3 *sampleBuff = (AudioSample3 *)buffer; 112 | int sampleLength = len / sizeof(AudioSample3); 113 | 114 | for(int i = 0; i < sampleLength; i++) 115 | { 116 | sampleBuff[i].left = dummybuffer[globalReadBuffer].left; 117 | sampleBuff[i].right = dummybuffer[globalReadBuffer].right; 118 | globalReadBuffer++; 119 | if(globalReadBuffer >= 48) 120 | globalReadBuffer = 0; 121 | } 122 | globalPacketCounter++; 123 | if(globalPacketCounter > 0xFF) 124 | globalPacketCounter = 0; 125 | } 126 | 127 | 128 | // Parse a wav file header and return file parameters 129 | // See https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ 130 | int parsewavheader (FILE* wavfile, int* NumChannels, int* SampleRate, int* BytesPerSample, long* NumSamples) { 131 | #define WAVHEADER_L 44 // Length of standard wav file header 132 | #define IG 0xAB // A byte which doesn't occur elsewhere in header 133 | 134 | unsigned char wavheader[WAVHEADER_L] = { // Required header contents 135 | 'R', 'I', 'F', 'F', // Chunk ID 136 | IG, IG, IG, IG, // ChunkSize, 36 + bytes of audio data 137 | 'W', 'A', 'V', 'E', // Format 138 | 'f', 'm', 't', 0x20, // Subchunk1ID 139 | 0x10, 0x00, 0x00, 0x00, // Subchunk1Size, 16 for PCM 140 | 0x01, 0x00, // AudioFormat, 1 for PCM 141 | IG, IG, // NumChannels, extract number, only accept 2 142 | IG, IG, IG, IG, // SampleRate 143 | IG, IG, IG, IG, // ByteRate = SampleRate * NumChannels * BitsPerSample / 8 144 | IG, IG, // BlockAlign = NumChannels * BitsPerSample / 8 145 | IG, IG, // BitsPerSample 146 | 'd', 'a', 't', 'a', // Subchunk2ID 147 | IG, IG, IG, IG}; // SubChunk2Size 148 | 149 | unsigned char readwavheader[WAVHEADER_L]; 150 | 151 | rewind (wavfile); // Make sure to read header from beginning of file! 152 | 153 | // Extract wav file header and do initial error checking 154 | int n = fread (readwavheader, 1, WAVHEADER_L, wavfile); // Try to read 44 header bytes 155 | 156 | if (n != WAVHEADER_L) { 157 | printf ("ERROR: Could not read %d bytes wav file header\n", WAVHEADER_L); 158 | return 0; 159 | } 160 | 161 | // Compare wavfile to default header, ignoring all bytes set to IG 162 | n=0; 163 | while ( ( (readwavheader[n] == wavheader[n]) || (wavheader[n] == IG) ) && (n < WAVHEADER_L) ) n++; 164 | 165 | if (n != WAVHEADER_L) { 166 | printf ("ERROR: wav file header error at position %d\n", n); 167 | return 0; 168 | } 169 | 170 | // Extract wav file parameters 171 | int ChunkSize = (readwavheader[4]) + (readwavheader[5]<<8) + (readwavheader[6]<<16) + (readwavheader[7]<<24); 172 | *NumChannels = (readwavheader[22]) + (readwavheader[23]<<8); 173 | *SampleRate = (readwavheader[24]) + (readwavheader[25]<<8) + (readwavheader[26]<<16) + (readwavheader[27]<<24); 174 | int ByteRate = (readwavheader[28]) + (readwavheader[29]<<8) + (readwavheader[30]<<16) + (readwavheader[31]<<24); 175 | int BlockAlign = (readwavheader[32]) + (readwavheader[33]<<8); 176 | int BitsPerSample = (readwavheader[34]) + (readwavheader[35]<<8); 177 | *BytesPerSample = BitsPerSample >> 3; 178 | int SubChunk2Size = (readwavheader[40]) + (readwavheader[41]<<8) + (readwavheader[42]<<16) + (readwavheader[43]<<24); 179 | *NumSamples = SubChunk2Size / *BytesPerSample / *NumChannels; 180 | double Duration = *NumSamples; Duration /= *SampleRate; 181 | 182 | // Print parameters 183 | printf ("ChunkSize = %d\n", ChunkSize); 184 | printf ("NumChannels = %d\n", *NumChannels); 185 | printf ("SampleRate = %d\n", *SampleRate); 186 | printf ("ByteRate = %d\n", ByteRate); 187 | printf ("BlockAlign = %d\n", BlockAlign); 188 | printf ("BytesPerSample = %d\n", *BytesPerSample); // Bytes per MONO sample, *2 for stereo 189 | printf ("SubChunk2Size = %d\n", SubChunk2Size); 190 | printf ("NumSamples = %d\n", *NumSamples); 191 | printf ("Duration = %4.3fs\n", Duration); 192 | 193 | // Full error checking 194 | n = 1; // Assuming a clean return. But report all found errors before returning 195 | 196 | if (SubChunk2Size + 36 != ChunkSize) { 197 | printf ("ERROR: SubChunk2Size, ChunkSize mismatch %d+36 != %d\n", SubChunk2Size, ChunkSize); 198 | n = 0; 199 | } 200 | 201 | if (*NumChannels != 2) { 202 | printf ("ERROR: Only 2-channel wav is accepted, not the detected %d-channel.\n", *NumChannels); 203 | n = 0; 204 | } 205 | 206 | if ( (*SampleRate != 44100) && (*SampleRate != 48000) && 207 | (*SampleRate != 88200) && (*SampleRate != 96000) && 208 | (*SampleRate != 176400) && (*SampleRate != 192000) ) { 209 | printf ("ERROR: Only 44.1/48/88.2/96/176.4/192ksps accepted, not the detected %d.\n", *SampleRate); 210 | n = 0 ; 211 | } 212 | 213 | if (ByteRate != *SampleRate * *NumChannels * *BytesPerSample) { 214 | printf ("ERROR: Mismatch between ByteRate, SampleRate, NumChannels, BitsPerSample\n"); 215 | n = 0; 216 | } 217 | 218 | if (BlockAlign != *NumChannels * *BytesPerSample) { 219 | printf ("ERROR: Mismatch between BlockAlign, NumChannels, BitsPerSample\n"); 220 | n = 0; 221 | } 222 | 223 | if ( (*BytesPerSample != 2) && (*BytesPerSample != 3) && (*BytesPerSample != 4) ) { 224 | printf ("ERROR: Only 2/3/4 bytes per mono sample accepted, not the detected %d.\n", *BytesPerSample); 225 | n = 0; 226 | } 227 | 228 | return n; 229 | } 230 | 231 | 232 | // Fill 3L, 3R bytes from wavfile 233 | long fillwavbuffer3 (AudioSample3* wavbuffer, FILE* wavfile, int* BytesPerSample, long* NumSamples) { 234 | unsigned char temp[8]; // Temporary variable for reading a stereo sample from the wavfile 235 | long readsamples = 0; 236 | 237 | if (*BytesPerSample == 2) { 238 | for (long n=0; n<*NumSamples; n++) { 239 | if (fread(temp, 1, 4, wavfile) == 4) { // 16 bits -> 24 bits stereo 240 | wavbuffer[n].left = (temp[0]<<8) + (temp[1]<<16); 241 | wavbuffer[n].right = (temp[2]<<8) + (temp[3]<<16); 242 | readsamples++; 243 | } 244 | else { 245 | printf ("a\n"); 246 | return readsamples; // Cut the process short if read fails 247 | } 248 | } 249 | } 250 | 251 | else if (*BytesPerSample == 3) { 252 | for (long n=0; n<*NumSamples; n++) { 253 | if (fread(temp, 1, 6, wavfile) == 6) { // 24 bits -> 24 bits stereo. Can we do simple copy? 254 | wavbuffer[n].left = (temp[0]) + (temp[1]<<8) + (temp[2]<<16); 255 | wavbuffer[n].right = (temp[3]) + (temp[4]<<8) + (temp[5]<<16); 256 | readsamples++; 257 | } 258 | else { 259 | printf ("b\n"); 260 | return readsamples; // Cut the process short if read fails 261 | } 262 | } 263 | } 264 | 265 | else if (*BytesPerSample == 4) { 266 | for (long n=0; n<*NumSamples; n++) { 267 | if (fread(temp, 1, 8, wavfile) == 8) { // 32 bits -> 24 bits stereo. FIX: add dither! 268 | wavbuffer[n].left = (temp[1]) + (temp[2]<<8) + (temp[3]<<16); 269 | wavbuffer[n].right = (temp[5]) + (temp[6]<<8) + (temp[7]<<16); 270 | readsamples++; 271 | } 272 | else { 273 | printf ("c\n"); 274 | return readsamples; // Cut the process short if read fails 275 | } 276 | } 277 | } 278 | 279 | return readsamples; 280 | } 281 | 282 | 283 | // Fill 3L, 3R bytes from wavfile 284 | long fillwavbuffer4 (AudioSample4* wavbuffer, FILE* wavfile, int* BytesPerSample, long* NumSamples) { 285 | unsigned char temp[8]; // Temporary variable for reading a stereo sample from the wavfile 286 | long readsamples = 0; 287 | int m = 0; 288 | 289 | if (*BytesPerSample == 2) { 290 | for (long n=0; n<*NumSamples; n++) { 291 | m = fread(temp, 1, 4, wavfile); 292 | if (m == 4) { // 16 bits -> 32 bits stereo 293 | wavbuffer[n].left = (temp[0]<<16) + (temp[1]<<24); 294 | wavbuffer[n].right = (temp[2]<<16) + (temp[3]<<24); 295 | readsamples++; 296 | } 297 | else { 298 | printf ("d %d, %d, %d", n, readsamples, m); 299 | return readsamples; // Cut the process short if read fails 300 | } 301 | } 302 | } 303 | 304 | else if (*BytesPerSample == 3) { 305 | for (long n=0; n<*NumSamples; n++) { 306 | if (fread(temp, 1, 6, wavfile) == 6) { // 24 bits -> 32 bits stereo. 307 | wavbuffer[n].left = (temp[0]<<8) + (temp[1]<<16) + (temp[2]<<24); 308 | wavbuffer[n].right = (temp[3]<<8) + (temp[4]<<16) + (temp[5]<<24); 309 | readsamples++; 310 | } 311 | else { 312 | printf ("e\n"); 313 | return readsamples; // Cut the process short if read fails 314 | } 315 | } 316 | } 317 | 318 | else if (*BytesPerSample == 4) { 319 | for (long n=0; n<*NumSamples; n++) { 320 | if (fread(temp, 1, 8, wavfile) == 8) { // 32 bits -> 32 bits stereo. Can we do simple copy? 321 | wavbuffer[n].left = (temp[0]) + (temp[1]<<8) + (temp[2]<<16) + (temp[3]<<24); 322 | wavbuffer[n].right = (temp[4]) + (temp[5]<<8) + (temp[6]<<16) + (temp[7]<<24); 323 | readsamples++; 324 | } 325 | else { 326 | printf ("f\n"); 327 | return readsamples; // Cut the process short if read fails 328 | } 329 | } 330 | } 331 | 332 | return readsamples; 333 | } 334 | 335 | 336 | int main(int argc, char* argv[]) { 337 | 338 | int freq; 339 | int mode; // BSB 20121007 0:signal generator 1:wav file player 340 | 341 | if (argc == 1) { // No arguments 342 | freq = 48000; // Default sampling frequency 343 | mode = 0; // Run as signal generator 344 | } 345 | 346 | else if (argc == 2) { // One argument, may it be a valid audio frequency? 347 | freq = atoi(argv[1]); 348 | if ( (freq == 44100) || (freq == 48000) || (freq == 88200) || (freq == 96000) || (freq == 176400) || (freq == 192000) ) 349 | mode = 0; // Run as signal generator 350 | else 351 | mode = 1; // Run as wav file player 352 | } 353 | 354 | else // >1 argument, run as wav file player 355 | mode = 1; // Run as wav file player 356 | 357 | if (mode == 0) { // signal generator 358 | printf("Running as signal generator.\n"); 359 | 360 | // First check for valid playback device 361 | USBAudioDevice device(true); 362 | if (!device.InitDevice()) { 363 | printf ("ERROR: UAC2 Audio device not found\n"); 364 | // offline return -1; 365 | } 366 | 367 | if(device.GetDACSubslotSize() == 3) { 368 | FillBuffer(false); 369 | device.SetDACCallback(FillData3, NULL); 370 | } 371 | else if(device.GetDACSubslotSize() == 4) { 372 | FillBuffer(true); 373 | device.SetDACCallback(FillData4, NULL); 374 | } 375 | device.SetSampleRate(freq); 376 | device.Start(); 377 | printf("Press any key to stop...\n"); 378 | _getch(); 379 | device.Stop(); 380 | } 381 | 382 | else if (mode == 1) { // wav file player 383 | AudioSample3 * wavbuffer3; // Memory pointers for wav file data access, make global! 384 | AudioSample4 * wavbuffer4; 385 | 386 | int NumChannels = 0; 387 | int SampleRate = 0; 388 | int BytesPerSample = 0; 389 | long NumSamples = 0; 390 | long ReadSamples = 0; 391 | FILE * wavfile; 392 | int SubSlotSize = 0; 393 | 394 | printf("Running as wav file player.\n"); 395 | 396 | // First check for valid playback device 397 | USBAudioDevice device(true); 398 | if (!device.InitDevice()) { 399 | printf ("ERROR: UAC2 Audio device not found\n"); 400 | // offline return -1; 401 | } 402 | 403 | // Open files 404 | for (int n=1; n 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 26 | 29 | 32 | 35 | 38 | 41 | 52 | 55 | 58 | 61 | 68 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 90 | 98 | 101 | 104 | 107 | 110 | 113 | 124 | 127 | 130 | 133 | 142 | 145 | 148 | 151 | 154 | 157 | 160 | 163 | 164 | 165 | 166 | 167 | 168 | 173 | 176 | 177 | 180 | 183 | 187 | 188 | 191 | 195 | 196 | 197 | 198 | 203 | 206 | 207 | 210 | 211 | 212 | 217 | 218 | 221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /dump2wav/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // dump2wav.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /dump2wav/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | 17 | // TODO: reference additional headers your program requires here 18 | -------------------------------------------------------------------------------- /dump2wav/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // The following macros define the minimum required platform. The minimum required platform 4 | // is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run 5 | // your application. The macros work by enabling all features available on platform versions up to and 6 | // including the version specified. 7 | 8 | // Modify the following defines if you have to target a platform prior to the ones specified below. 9 | // Refer to MSDN for the latest info on corresponding values for different platforms. 10 | #ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. 11 | #define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /dump2wav/use_case.txt: -------------------------------------------------------------------------------- 1 | dump2wav 44 c:\dac_dump.bin c:\tag01.wav 2 | 3 | Replace "44" with "48", "88", "96", "176" or "192" to set sample rate of tag01.wav 4 | -------------------------------------------------------------------------------- /libusbK-dev-kit/dummy.txt: -------------------------------------------------------------------------------- 1 | Please put in this dir LibUsbK -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | Win-Widget project 2 | ------------------ 3 | Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | 5 | Contents 6 | Driver - simple ASIO driver for Widgets (needed ASIO SDK 2.2 and LibUsbK library) 7 | WidgetTest - simple test application for playing "beep" on Widget (LibUsbK library) -------------------------------------------------------------------------------- /uaclib/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/uaclib/ReadMe.txt -------------------------------------------------------------------------------- /uaclib/USBAudioDevice.h: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | /* 16 | This code based on samples from library LibUsbK by Travis Robinson 17 | */ 18 | /* 19 | # Copyright (c) 2011 Travis Robinson 20 | # All rights reserved. 21 | # 22 | # Redistribution and use in source and binary forms, with or without 23 | # modification, are permitted provided that the following conditions are met: 24 | # 25 | # * Redistributions of source code must retain the above copyright 26 | # notice, this list of conditions and the following disclaimer. 27 | # 28 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 29 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 31 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TRAVIS LEE ROBINSON 32 | # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 38 | # THE POSSIBILITY OF SUCH DAMAGE. 39 | # 40 | */ 41 | 42 | 43 | #pragma once 44 | #ifndef __USBAUDIO_DEVICE_H__ 45 | #define __USBAUDIO_DEVICE_H__ 46 | 47 | #include "usbdevice.h" 48 | #include "audiotask.h" 49 | #include "tlist.h" 50 | #include "descriptors.h" 51 | 52 | 53 | typedef void (*NotifyCallback)(void* context, int reason); 54 | 55 | typedef TList USBACInterfaceList; 56 | typedef TList USBASInterfaceList; 57 | 58 | class USBAudioDevice : public USBDevice 59 | { 60 | //IAD 61 | //USB_INTERFACE_ASSOCIATION_DESCRIPTOR m_iad; 62 | 63 | USBACInterfaceList m_acInterfaceList; 64 | USBASInterfaceList m_asInterfaceList; 65 | 66 | void FreeDeviceInternal(); 67 | void InitDescriptors(); 68 | 69 | int m_audioClass; 70 | bool m_useInput; 71 | 72 | USBAudioStreamingEndpoint* m_dacEndpoint; 73 | USBAudioStreamingEndpoint* m_adcEndpoint; 74 | USBAudioStreamingEndpoint* m_fbEndpoint; 75 | 76 | NotifyCallback m_notifyCallback; 77 | void* m_notifyCallbackContext; 78 | protected: 79 | virtual void FreeDevice(); 80 | 81 | virtual bool ParseDescriptorInternal(USB_DESCRIPTOR_HEADER* uDescriptor); 82 | 83 | bool SetSampleRateInternal(int freq); 84 | 85 | USBAudioClockSource* FindClockSource(int freq); 86 | bool CheckSampleRate(USBAudioClockSource* clocksrc, int freq); 87 | int GetSampleRateInternal(int interfaceNum, int clockID); 88 | 89 | USBAudioInTerminal* FindInTerminal(int id); 90 | USBAudioFeatureUnit* FindFeatureUnit(int id); 91 | USBAudioOutTerminal* FindOutTerminal(int id); 92 | 93 | public: 94 | USBAudioDevice(bool useInput); 95 | virtual ~USBAudioDevice(); 96 | virtual bool InitDevice(); 97 | 98 | bool CanSampleRate(int freq); 99 | bool SetSampleRate(int freq); 100 | int GetCurrentSampleRate(); 101 | 102 | int GetInputChannelNumber(); 103 | int GetOutputChannelNumber(); 104 | 105 | bool Start(); 106 | bool Stop(); 107 | 108 | void SetDACCallback(FillDataCallback readDataCb, void* context); 109 | void SetADCCallback(FillDataCallback writeDataCb, void* context); 110 | void SetNotifyCallback(NotifyCallback notifyCallback, void* notifyCallbackContext) 111 | { 112 | m_notifyCallback = notifyCallback; 113 | m_notifyCallbackContext = notifyCallbackContext; 114 | } 115 | 116 | int GetDACSubslotSize() 117 | { 118 | return m_dacEndpoint ? m_dacEndpoint->m_interface->m_formatDescriptor.bSubslotSize : 0; 119 | } 120 | int GetADCSubslotSize() 121 | { 122 | return m_adcEndpoint ? m_adcEndpoint->m_interface->m_formatDescriptor.bSubslotSize : 0; 123 | } 124 | int GetDACBitResolution() 125 | { 126 | return m_dacEndpoint ? m_dacEndpoint->m_interface->m_formatDescriptor.bBitResolution : 0; 127 | } 128 | int GetADCBitResolution() 129 | { 130 | return m_adcEndpoint ? m_adcEndpoint->m_interface->m_formatDescriptor.bBitResolution : 0; 131 | } 132 | int GetAudioClass() 133 | { 134 | return m_audioClass; 135 | } 136 | void Notify(int reason) 137 | { 138 | if(m_notifyCallback) 139 | m_notifyCallback(m_notifyCallbackContext, reason); 140 | } 141 | private: 142 | USBAudioInterface* m_lastParsedInterface; 143 | USBEndpoint* m_lastParsedEndpoint; 144 | 145 | FeedbackInfo m_fbInfo; 146 | AudioDAC* m_dac; 147 | AudioADC* m_adc; 148 | AudioFeedback* m_feedback; 149 | 150 | bool m_isStarted; 151 | }; 152 | 153 | #endif //__USBAUDIO_DEVICE_H__ 154 | -------------------------------------------------------------------------------- /uaclib/UsbDevice.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | 16 | #include "UsbDevice.h" 17 | 18 | 19 | union DESCRIPTORS_UNION 20 | { 21 | BYTE* Bytes; 22 | USB_DESCRIPTOR_HEADER* Common; 23 | USB_CONFIGURATION_DESCRIPTOR* Config; 24 | USB_INTERFACE_DESCRIPTOR* Interface; 25 | USB_ENDPOINT_DESCRIPTOR* Endpoint; 26 | }; 27 | 28 | /* 29 | struct DeviceID 30 | { 31 | USHORT vid; 32 | USHORT pid; 33 | }; 34 | 35 | DeviceID deviceID[] = { 36 | {0x16C0, 0x03E8}, 37 | {0x16C0, 0x05dc} 38 | }; 39 | 40 | int deviceIDNum = sizeof(deviceID)/sizeof(DeviceID); 41 | */ 42 | 43 | #define _DeviceInterfaceGUID "{09e4c63c-ce0f-168c-1862-06410a764a35}" 44 | 45 | USBDevice::USBDevice() : m_usbDeviceHandle(NULL), m_deviceInfo(NULL), m_errorCode(ERROR_SUCCESS), m_deviceSpeed(HighSpeed), m_deviceMutex(NULL), m_deviceIsConnected(FALSE) 46 | { 47 | InitDescriptors(); 48 | #ifdef _ENABLE_TRACE 49 | debugPrintf("ASIOUAC: USBDevice()\n"); 50 | #endif 51 | } 52 | 53 | USBDevice::~USBDevice() 54 | { 55 | FreeDevice(); 56 | #ifdef _ENABLE_TRACE 57 | debugPrintf("ASIOUAC: ~USBDevice()\n"); 58 | #endif 59 | if(m_deviceMutex) 60 | CloseHandle(m_deviceMutex); 61 | } 62 | 63 | void USBDevice::FreeDevice() 64 | { 65 | // Close the device handle 66 | // if handle is invalid (NULL), has no effect 67 | UsbK_Free(m_usbDeviceHandle); 68 | } 69 | 70 | void USBDevice::InitDescriptors() 71 | { 72 | memset(&m_deviceDescriptor, 0, sizeof(USB_DEVICE_DESCRIPTOR)); 73 | memset(&m_configDescriptor, 0, sizeof(USB_CONFIGURATION_DESCRIPTOR)); 74 | m_errorCode = ERROR_SUCCESS; 75 | } 76 | 77 | bool USBDevice::ParseDescriptors(BYTE *configDescr, DWORD length) 78 | { 79 | DWORD remaining = length; 80 | 81 | DESCRIPTORS_UNION curDescrPtr; 82 | USB_INTERFACE_DESCRIPTOR* interfaceDescriptor = NULL; 83 | USB_ENDPOINT_DESCRIPTOR* endpointDescriptor = NULL; 84 | 85 | while(remaining > 0) 86 | { 87 | curDescrPtr.Bytes = configDescr; 88 | UCHAR curLen = curDescrPtr.Common->bLength; 89 | if(curDescrPtr.Common->bDescriptorType == USB_DESCRIPTOR_TYPE_CONFIGURATION) 90 | memcpy(&m_configDescriptor, curDescrPtr.Config, sizeof(USB_CONFIGURATION_DESCRIPTOR)); 91 | else 92 | ParseDescriptorInternal(curDescrPtr.Common); 93 | remaining -= curLen; 94 | configDescr += curLen; 95 | } 96 | 97 | return TRUE; 98 | } 99 | 100 | bool USBDevice::SendUsbControl(int dir, int type, int recipient, int request, int value, int index, 101 | unsigned char *buff, int size, PUINT lengthTransferred) 102 | { 103 | bool retVal = FALSE; 104 | WINUSB_SETUP_PACKET packet; 105 | KUSB_SETUP_PACKET* defPkt = (KUSB_SETUP_PACKET*)&packet; 106 | 107 | memset(&packet, 0, sizeof(packet)); 108 | defPkt->BmRequest.Dir = dir; 109 | defPkt->BmRequest.Type = type; 110 | defPkt->BmRequest.Recipient = recipient; 111 | defPkt->Request = request; 112 | defPkt->Value = value; 113 | defPkt->Index = index; 114 | defPkt->Length = 0; 115 | 116 | *lengthTransferred = 0; 117 | if(UsbK_ControlTransfer(m_usbDeviceHandle, packet, buff, size, lengthTransferred, NULL)) 118 | return TRUE; 119 | m_errorCode = GetLastErrorInternal(); 120 | #ifdef _ENABLE_TRACE 121 | debugPrintf("ASIOUAC: UsbK_ControlTransfer failed. ErrorCode: %08Xh\n", m_errorCode); 122 | #endif 123 | return FALSE; 124 | } 125 | 126 | KUSB_HANDLE USBDevice::FindDevice() 127 | { 128 | KLST_HANDLE DeviceList = NULL; 129 | KUSB_HANDLE handle = NULL; 130 | 131 | m_deviceInfo = NULL; 132 | KLST_DEVINFO_HANDLE tmpDeviceInfo = NULL; 133 | 134 | UINT deviceCount = 0; 135 | m_errorCode = ERROR_SUCCESS; 136 | 137 | // Get the device list 138 | if (!LstK_Init(&DeviceList, KLST_FLAG_NONE)) 139 | { 140 | #ifdef _ENABLE_TRACE 141 | debugPrintf("ASIOUAC: Error initializing device list.\n"); 142 | #endif 143 | return NULL; 144 | } 145 | 146 | LstK_Count(DeviceList, &deviceCount); 147 | if (!deviceCount) 148 | { 149 | #ifdef _ENABLE_TRACE 150 | debugPrintf("ASIOUAC: No devices in device list.\n"); 151 | #endif 152 | SetLastError(ERROR_DEVICE_NOT_CONNECTED); 153 | // If LstK_Init returns TRUE, the list must be freed. 154 | LstK_Free(DeviceList); 155 | return NULL; 156 | } 157 | 158 | #ifdef _ENABLE_TRACE 159 | debugPrintf("ASIOUAC: Looking for device with DeviceInterfaceGUID %s\n", _T(_DeviceInterfaceGUID)); 160 | #endif 161 | LstK_MoveReset(DeviceList); 162 | // 163 | // 164 | // Call LstK_MoveNext after a LstK_MoveReset to advance to the first 165 | // element. 166 | while(LstK_MoveNext(DeviceList, &tmpDeviceInfo) 167 | && m_deviceInfo == NULL) 168 | { 169 | if(!_stricmp(tmpDeviceInfo->DeviceInterfaceGUID, _DeviceInterfaceGUID) && tmpDeviceInfo->Connected) 170 | { 171 | m_deviceInfo = tmpDeviceInfo; 172 | break; 173 | } 174 | } 175 | 176 | if (!m_deviceInfo) 177 | { 178 | #ifdef _ENABLE_TRACE 179 | debugPrintf("ASIOUAC: Device not found.\n"); 180 | #endif 181 | // If LstK_Init returns TRUE, the list must be freed. 182 | LstK_Free(DeviceList); 183 | return NULL; 184 | } 185 | 186 | // Initialize the device with the "dynamic" Open function 187 | if (!UsbK_Init(&handle, m_deviceInfo)) 188 | { 189 | m_deviceInfo = NULL; 190 | handle = NULL; 191 | m_errorCode = GetLastErrorInternal(); 192 | #ifdef _ENABLE_TRACE 193 | debugPrintf("ASIOUAC: UsbK_Init failed. ErrorCode: %08Xh\n", m_errorCode); 194 | #endif 195 | } 196 | 197 | LstK_Free(DeviceList); 198 | return handle; 199 | } 200 | 201 | bool USBDevice::InitDevice() 202 | { 203 | BYTE configDescriptorBuffer[4096]; 204 | UINT lengthTransferred; 205 | 206 | m_deviceMutex = CreateMutex(NULL, FALSE, "Global\\ASIOUAC2"); 207 | if(GetLastErrorInternal() == ERROR_ALREADY_EXISTS) 208 | { 209 | #ifdef _ENABLE_TRACE 210 | debugPrintf("ASIOUAC: Can't start device! Device already used!\n"); 211 | #endif 212 | if(m_deviceMutex) 213 | { 214 | CloseHandle(m_deviceMutex); 215 | m_deviceMutex = NULL; 216 | m_errorCode = ERROR_BUSY; 217 | } 218 | return FALSE; 219 | } 220 | 221 | FreeDevice(); 222 | InitDescriptors(); 223 | 224 | m_usbDeviceHandle = FindDevice(); 225 | if(m_usbDeviceHandle == NULL) 226 | return FALSE; 227 | 228 | lengthTransferred = sizeof(configDescriptorBuffer); 229 | if(!UsbK_QueryDeviceInformation( m_usbDeviceHandle, DEVICE_SPEED, &lengthTransferred, configDescriptorBuffer)) 230 | { 231 | m_errorCode = GetLastErrorInternal(); 232 | #ifdef _ENABLE_TRACE 233 | debugPrintf("ASIOUAC: UsbK_QueryDeviceInformation failed. ErrorCode: %08Xh\n", m_errorCode); 234 | #endif 235 | UsbK_Free(m_usbDeviceHandle); 236 | m_usbDeviceHandle = NULL; 237 | return FALSE; 238 | } 239 | m_deviceSpeed = (int)configDescriptorBuffer[0]; 240 | #ifdef _ENABLE_TRACE 241 | if(m_deviceSpeed == HighSpeed) 242 | debugPrintf("ASIOUAC: Device speed: high\n"); 243 | else 244 | debugPrintf("ASIOUAC: Device speed: low/full\n"); 245 | #endif 246 | if(!UsbK_GetDescriptor(m_usbDeviceHandle, USB_DESCRIPTOR_TYPE_DEVICE, 0, 0, configDescriptorBuffer, sizeof(configDescriptorBuffer), &lengthTransferred)) 247 | { 248 | m_errorCode = GetLastErrorInternal(); 249 | #ifdef _ENABLE_TRACE 250 | debugPrintf("ASIOUAC: Get device descriptor failed. ErrorCode: %08Xh\n", m_errorCode); 251 | #endif 252 | UsbK_Free(m_usbDeviceHandle); 253 | m_usbDeviceHandle = NULL; 254 | return FALSE; 255 | } 256 | memcpy(&m_deviceDescriptor, configDescriptorBuffer, sizeof(USB_DEVICE_DESCRIPTOR)); 257 | 258 | if(SendUsbControl(BMREQUEST_DIR_DEVICE_TO_HOST, BMREQUEST_TYPE_STANDARD, BMREQUEST_RECIPIENT_DEVICE, 259 | USB_REQUEST_GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_CONFIGURATION << 8), 0, 260 | configDescriptorBuffer, sizeof(configDescriptorBuffer), &lengthTransferred)) 261 | { 262 | ParseDescriptors(configDescriptorBuffer, lengthTransferred); 263 | m_deviceIsConnected = TRUE; 264 | return m_usbDeviceHandle != NULL; 265 | } 266 | else 267 | { 268 | m_errorCode = GetLastErrorInternal(); 269 | #ifdef _ENABLE_TRACE 270 | debugPrintf("ASIOUAC: Get config descriptor failed. ErrorCode: %08Xh\n", m_errorCode); 271 | #endif 272 | UsbK_Free(m_usbDeviceHandle); 273 | m_usbDeviceHandle = NULL; 274 | return FALSE; 275 | } 276 | } 277 | 278 | -------------------------------------------------------------------------------- /uaclib/UsbDevice.h: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | #pragma once 16 | #ifndef __USB_DEVICE_H__ 17 | #define __USB_DEVICE_H__ 18 | 19 | #include "targetver.h" 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include "usb_audio.h" 26 | 27 | #ifdef _ENABLE_TRACE 28 | extern void debugPrintf(const _TCHAR *szFormat, ...); 29 | #endif 30 | 31 | 32 | // common part of all types of USB descriptors 33 | struct USB_DESCRIPTOR_HEADER 34 | { 35 | //! Size of this descriptor (in bytes) 36 | UCHAR bLength; 37 | //! Descriptor type 38 | UCHAR bDescriptorType; 39 | //! Descriptor type 40 | UCHAR bDescriptorSubType; 41 | }; 42 | 43 | 44 | 45 | //Common USB device data and functions 46 | class USBDevice 47 | { 48 | // 49 | USB_DEVICE_DESCRIPTOR m_deviceDescriptor; 50 | // 51 | USB_CONFIGURATION_DESCRIPTOR m_configDescriptor; 52 | // 53 | KUSB_HANDLE m_usbDeviceHandle; 54 | 55 | KLST_DEVINFO_HANDLE m_deviceInfo; 56 | 57 | 58 | //device speed LowSpeed=0x01, FullSpeed=0x02, HighSpeed=0x03 59 | int m_deviceSpeed; 60 | HANDLE m_deviceMutex; 61 | 62 | 63 | KUSB_HANDLE FindDevice(); 64 | bool ParseDescriptors(BYTE *configDescr, DWORD length); 65 | void InitDescriptors(); 66 | 67 | bool m_deviceIsConnected; 68 | protected: 69 | DWORD m_errorCode; 70 | 71 | virtual void FreeDevice(); 72 | 73 | bool SendUsbControl(int dir, int type, int recipient, int request, int value, int index, 74 | unsigned char *buff, int size, PUINT lengthTransferred); 75 | 76 | virtual bool ParseDescriptorInternal(USB_DESCRIPTOR_HEADER* uDescriptor) = 0; 77 | 78 | bool IsConnected() { return m_deviceInfo != NULL && m_deviceIsConnected; } 79 | 80 | void CheckError(int currentError) 81 | { 82 | if(currentError != ERROR_IO_PENDING && currentError != ERROR_SUCCESS) 83 | { 84 | #ifdef _ENABLE_TRACE 85 | debugPrintf("ASIOUAC: Found critical error with ErrorCode: %08Xh\n", currentError); 86 | #endif 87 | m_deviceIsConnected = FALSE; 88 | } 89 | } 90 | 91 | int GetLastErrorInternal() 92 | { 93 | int lastError = GetLastError(); 94 | CheckError(lastError); 95 | return lastError; 96 | } 97 | public: 98 | USBDevice(); 99 | virtual ~USBDevice(); 100 | virtual bool InitDevice(); 101 | 102 | virtual bool IsValidDevice() { return m_usbDeviceHandle != NULL; } 103 | 104 | DWORD GetErrorCode() 105 | { 106 | return m_errorCode; 107 | } 108 | 109 | void ClearErrorCode() 110 | { 111 | m_errorCode = ERROR_SUCCESS; 112 | } 113 | 114 | bool OvlInit(KOVL_POOL_HANDLE* PoolHandle, LONG MaxOverlappedCount) 115 | { 116 | if(OvlK_Init(PoolHandle, m_usbDeviceHandle, MaxOverlappedCount, KOVL_POOL_FLAG_NONE)) 117 | return TRUE; 118 | m_errorCode = GetLastErrorInternal(); 119 | #ifdef _ENABLE_TRACE 120 | debugPrintf("ASIOUAC: OvlK_Init failed. ErrorCode: %08Xh\n", m_errorCode); 121 | #endif 122 | return FALSE; 123 | } 124 | 125 | bool OvlAcquire(KOVL_HANDLE* OverlappedK, KOVL_POOL_HANDLE PoolHandle) 126 | { 127 | if(OvlK_Acquire(OverlappedK, PoolHandle)) 128 | return TRUE; 129 | m_errorCode = GetLastErrorInternal(); 130 | #ifdef _ENABLE_TRACE 131 | debugPrintf("ASIOUAC: OvlK_Acquire failed. ErrorCode: %08Xh\n", m_errorCode); 132 | #endif 133 | return FALSE; 134 | } 135 | 136 | bool OvlWait(KOVL_HANDLE OverlappedK, LONG TimeoutMS, KOVL_WAIT_FLAG WaitFlags, PUINT TransferredLength) 137 | { 138 | if(OvlK_Wait(OverlappedK, TimeoutMS, WaitFlags, TransferredLength)) 139 | return TRUE; 140 | m_errorCode = GetLastErrorInternal(); 141 | #ifdef _ENABLE_TRACE 142 | debugPrintf("ASIOUAC: OvlK_Wait failed. ErrorCode: %08Xh\n", m_errorCode); 143 | #endif 144 | return FALSE; 145 | } 146 | 147 | bool OvlWaitOrCancel(KOVL_HANDLE OverlappedK, LONG TimeoutMS, PUINT TransferredLength) 148 | { 149 | if(OvlK_WaitOrCancel(OverlappedK, TimeoutMS, TransferredLength)) 150 | return TRUE; 151 | if(TimeoutMS != 0) // we are just cancel request, no errors report 152 | { 153 | m_errorCode = GetLastErrorInternal(); 154 | #ifdef _ENABLE_TRACE 155 | debugPrintf("ASIOUAC: OvlK_WaitOrCancel failed. ErrorCode: %08Xh\n", m_errorCode); 156 | #endif 157 | } 158 | return FALSE; 159 | } 160 | 161 | bool OvlRelease(KOVL_HANDLE OverlappedK) 162 | { 163 | if(OvlK_Release(OverlappedK)) 164 | return TRUE; 165 | m_errorCode = GetLastErrorInternal(); 166 | #ifdef _ENABLE_TRACE 167 | debugPrintf("ASIOUAC: OvlK_Release failed. ErrorCode: %08Xh\n", m_errorCode); 168 | #endif 169 | return FALSE; 170 | } 171 | 172 | bool OvlReUse(KOVL_HANDLE OverlappedK) 173 | { 174 | if(OvlK_ReUse(OverlappedK)) 175 | return TRUE; 176 | m_errorCode = GetLastErrorInternal(); 177 | #ifdef _ENABLE_TRACE 178 | debugPrintf("ASIOUAC: OvlK_ReUse failed. ErrorCode: %08Xh\n", m_errorCode); 179 | #endif 180 | return FALSE; 181 | } 182 | 183 | 184 | bool UsbResetPipe(UCHAR PipeId) 185 | { 186 | if(UsbK_ResetPipe(m_usbDeviceHandle, PipeId)) 187 | return TRUE; 188 | m_errorCode = GetLastErrorInternal(); 189 | #ifdef _ENABLE_TRACE 190 | debugPrintf("ASIOUAC: UsbK_ResetPipe failed. ErrorCode: %08Xh\n", m_errorCode); 191 | #endif 192 | return FALSE; 193 | } 194 | 195 | bool UsbAbortPipe(UCHAR PipeId) 196 | { 197 | if(UsbK_AbortPipe(m_usbDeviceHandle, PipeId)) 198 | return TRUE; 199 | m_errorCode = GetLastErrorInternal(); 200 | #ifdef _ENABLE_TRACE 201 | debugPrintf("ASIOUAC: UsbK_AbortPipe failed. ErrorCode: %08Xh\n", m_errorCode); 202 | #endif 203 | return FALSE; 204 | } 205 | 206 | bool UsbIsoWritePipe(UCHAR PipeID, PUCHAR Buffer, ULONG BufferLength, LPOVERLAPPED Overlapped, PKISO_CONTEXT IsoContext) 207 | { 208 | DWORD lastError; 209 | if(UsbK_IsoWritePipe (m_usbDeviceHandle, PipeID, Buffer, BufferLength, Overlapped, IsoContext) || 210 | ERROR_IO_PENDING == (lastError = GetLastErrorInternal())) 211 | return TRUE; 212 | m_errorCode = lastError; 213 | #ifdef _ENABLE_TRACE 214 | debugPrintf("ASIOUAC: UsbK_IsoWritePipe failed. ErrorCode: %08Xh\n", m_errorCode); 215 | #endif 216 | return FALSE; 217 | } 218 | 219 | bool UsbIsoReadPipe (UCHAR PipeID, PUCHAR Buffer, ULONG BufferLength, LPOVERLAPPED Overlapped, PKISO_CONTEXT IsoContext) 220 | { 221 | DWORD lastError; 222 | if(UsbK_IsoReadPipe (m_usbDeviceHandle, PipeID, Buffer, BufferLength, Overlapped, IsoContext) || 223 | ERROR_IO_PENDING == (lastError = GetLastErrorInternal())) 224 | return TRUE; 225 | m_errorCode = lastError; 226 | #ifdef _ENABLE_TRACE 227 | debugPrintf("ASIOUAC: UsbK_IsoReadPipe failed. ErrorCode: %08Xh\n", m_errorCode); 228 | #endif 229 | return FALSE; 230 | } 231 | 232 | bool UsbSetPipePolicy(UCHAR PipeID, ULONG PolicyType, ULONG ValueLength, PVOID Value) 233 | { 234 | if(UsbK_SetPipePolicy(m_usbDeviceHandle, PipeID, PolicyType, ValueLength, Value)) 235 | return TRUE; 236 | 237 | return FALSE; 238 | } 239 | 240 | bool UsbClaimInterface(UCHAR Number) 241 | { 242 | if(UsbK_ClaimInterface (m_usbDeviceHandle, Number, FALSE)) 243 | return TRUE; 244 | m_errorCode = GetLastErrorInternal(); 245 | #ifdef _ENABLE_TRACE 246 | debugPrintf("ASIOUAC: UsbK_ClaimInterface %d failed. ErrorCode: %08Xh\n", Number, m_errorCode); 247 | #endif 248 | return FALSE; 249 | } 250 | 251 | bool UsbSetAltInterface(UCHAR Number, UCHAR AltSettingNumber) 252 | { 253 | if(UsbK_SetAltInterface(m_usbDeviceHandle, Number, FALSE, AltSettingNumber)) 254 | return TRUE; 255 | m_errorCode = GetLastErrorInternal(); 256 | #ifdef _ENABLE_TRACE 257 | debugPrintf("ASIOUAC: UsbK_SetAltInterface %d (alt %d) failed. ErrorCode: %08Xh\n", Number, AltSettingNumber, m_errorCode); 258 | #endif 259 | return FALSE; 260 | } 261 | 262 | bool UsbReleaseInterface(UCHAR Number) 263 | { 264 | if(UsbK_ReleaseInterface (m_usbDeviceHandle, Number, FALSE)) 265 | return TRUE; 266 | m_errorCode = GetLastErrorInternal(); 267 | #ifdef _ENABLE_TRACE 268 | debugPrintf("ASIOUAC: UsbK_ReleaseInterface %d failed. ErrorCode: %08Xh\n", Number, m_errorCode); 269 | #endif 270 | return FALSE; 271 | } 272 | 273 | }; 274 | 275 | 276 | #endif //__USB_DEVICE_H__ 277 | -------------------------------------------------------------------------------- /uaclib/audiotask.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | 16 | #include "USBAudioDevice.h" 17 | #include "audiotask.h" 18 | 19 | 20 | #define NEXT_INDEX(x) ((x + 1) % (sizeof(m_isoBuffers) / sizeof(ISOBuffer))) 21 | 22 | #define MAX_OVL_ERROR_COUNT 3 23 | #define OVL_WAIT_TIMEOUT 100 24 | 25 | 26 | bool AudioTask::BeforeStart() 27 | { 28 | if(m_DataBufferSize == 0 || m_packetPerTransfer == 0 || m_packetSize == 0) 29 | { 30 | #ifdef _ENABLE_TRACE 31 | debugPrintf("ASIOUAC: %s. Can't start AudioTask thread: unknown sample freq\n", TaskName()); 32 | #endif 33 | return FALSE; 34 | } 35 | if(!m_isoBuffers[0].DataBuffer) 36 | { 37 | #ifdef _ENABLE_TRACE 38 | debugPrintf("ASIOUAC: %s. Can't start AudioTask thread: buffers not allocated\n", TaskName()); 39 | #endif 40 | return FALSE; 41 | } 42 | 43 | m_SubmittedCount = 0; 44 | m_CompletedCount = 0; 45 | m_FrameNumber = 0; 46 | m_LastStartFrame = 0; 47 | m_isoTransferErrorCount = 0; 48 | 49 | bool r = m_device->OvlInit(&m_OvlPool, MAX_OUTSTANDING_TRANSFERS); 50 | if(!r) 51 | { 52 | #ifdef _ENABLE_TRACE 53 | debugPrintf("ASIOUAC: %s. Can't start AudioTask thread: OvlK_Init failed\n", TaskName()); 54 | #endif 55 | return FALSE; 56 | } 57 | for(int i = 0; i < sizeof(m_isoBuffers) / sizeof(ISOBuffer); i++) 58 | { 59 | ISOBuffer* bufferEL = m_isoBuffers + i; 60 | memset(bufferEL->DataBuffer, 0xAA, m_DataBufferSize); 61 | //memset(bufferEL->DataBuffer, 0, m_DataBufferSize); 62 | IsoK_SetPackets(bufferEL->IsoContext, m_packetSize); 63 | bufferEL->IsoPackets = bufferEL->IsoContext->IsoPackets; 64 | m_device->OvlAcquire(&bufferEL->OvlHandle, m_OvlPool); 65 | } 66 | m_outstandingIndex = 0; 67 | m_completedIndex = 0; 68 | 69 | // Reset the pipe. 70 | r = m_device->UsbResetPipe((UCHAR)m_pipeId); 71 | 72 | BeforeStartInternal(); 73 | m_isStarted = TRUE; 74 | #ifdef _ENABLE_TRACE 75 | debugPrintf("ASIOUAC: %s. Before start thread is OK\n", TaskName()); 76 | m_sampleNumbers = 0; 77 | m_tickCount = 0; 78 | #endif 79 | return TRUE; 80 | } 81 | 82 | bool AudioTask::AfterStop() 83 | { 84 | if(!m_isStarted) 85 | return TRUE; 86 | 87 | m_device->UsbAbortPipe((UCHAR)m_pipeId); 88 | 89 | //index of last buffer in queue 90 | m_outstandingIndex; 91 | //index of last received buffer 92 | m_completedIndex; 93 | 94 | // Cancel all transfers left outstanding. 95 | #ifdef _ENABLE_TRACE 96 | debugPrintf("ASIOUAC: %s. Cancel outstanding transfers\n", TaskName()); 97 | #endif 98 | while(m_completedIndex != m_outstandingIndex) 99 | { 100 | ISOBuffer* nextBufferEL = m_isoBuffers + m_completedIndex; 101 | UINT transferred; 102 | m_device->OvlWaitOrCancel(nextBufferEL->OvlHandle, 0, &transferred); 103 | m_completedIndex = NEXT_INDEX(m_completedIndex); 104 | } 105 | m_device->ClearErrorCode(); 106 | for(int i = 0; i < sizeof(m_isoBuffers) / sizeof(ISOBuffer); i++) 107 | { 108 | // Free the iso buffer resources. 109 | ISOBuffer* bufferEL = m_isoBuffers + i; 110 | m_device->OvlRelease(bufferEL->OvlHandle); 111 | } 112 | // Free the overlapped pool. 113 | OvlK_Free(m_OvlPool); 114 | m_isStarted = FALSE; 115 | AfterStopInternal(); 116 | #ifdef _ENABLE_TRACE 117 | debugPrintf("ASIOUAC: %s. After stop thread is OK\n", TaskName()); 118 | #endif 119 | 120 | return TRUE; 121 | } 122 | 123 | bool AudioTask::FreeBuffers() 124 | { 125 | // Free the iso buffer resources. 126 | if(m_isoBuffers[0].DataBuffer != NULL) 127 | for(int i = 0; i < sizeof(m_isoBuffers) / sizeof(ISOBuffer); i++) 128 | { 129 | ISOBuffer* nextBufferEL = m_isoBuffers + i; 130 | IsoK_Free(nextBufferEL->IsoContext); 131 | nextBufferEL->IsoContext = NULL; 132 | delete nextBufferEL->DataBuffer; 133 | nextBufferEL->DataBuffer = NULL; 134 | } 135 | m_outstandingIndex = 0; 136 | m_completedIndex = 0; 137 | #ifdef _ENABLE_TRACE 138 | debugPrintf("ASIOUAC: %s. Free buffers is OK\n", TaskName()); 139 | #endif 140 | return TRUE; 141 | } 142 | 143 | bool AudioTask::AllocBuffers() 144 | { 145 | if(m_packetPerTransfer == 0 || m_packetSize == 0) 146 | { 147 | #ifdef _ENABLE_TRACE 148 | debugPrintf("ASIOUAC: %s. Can't start AllocBuffers: unknown sample freq\n", TaskName()); 149 | #endif 150 | return FALSE; 151 | } 152 | m_DataBufferSize = m_packetPerTransfer * m_packetSize; 153 | 154 | for (int i = 0; i < sizeof(m_isoBuffers) / sizeof(ISOBuffer); i++) 155 | { 156 | ISOBuffer* bufferEL = m_isoBuffers + i; 157 | bufferEL->DataBuffer = new UCHAR[m_DataBufferSize]; 158 | memset(bufferEL->DataBuffer, 0xAA, m_DataBufferSize); 159 | //memset(bufferEL->DataBuffer, 0, m_DataBufferSize); 160 | IsoK_Init(&bufferEL->IsoContext, m_packetPerTransfer, 0); 161 | IsoK_SetPackets(bufferEL->IsoContext, m_packetSize); 162 | } 163 | 164 | #ifdef _ENABLE_TRACE 165 | debugPrintf("ASIOUAC: %s. AllocBuffers OK\n", TaskName()); 166 | #endif 167 | return TRUE; 168 | } 169 | 170 | bool AudioTask::Work(volatile TaskState& taskState) 171 | { 172 | ISOBuffer* nextXfer; 173 | UINT transferred; 174 | int dataLength = 0; 175 | 176 | m_buffersGuard.Enter(); 177 | while(taskState == TaskStarted && NEXT_INDEX(m_outstandingIndex) != m_completedIndex && m_device->GetErrorCode() == ERROR_SUCCESS) 178 | { 179 | nextXfer = m_isoBuffers + m_outstandingIndex; 180 | dataLength = FillBuffer(nextXfer); 181 | m_outstandingIndex = NEXT_INDEX(m_outstandingIndex); 182 | m_device->OvlReUse(nextXfer->OvlHandle); 183 | SetNextFrameNumber(nextXfer); 184 | 185 | RWBuffer(nextXfer, dataLength); 186 | } 187 | 188 | //find next waiting buffer in queue 189 | nextXfer = m_isoBuffers + m_completedIndex; 190 | if (!nextXfer || taskState != TaskStarted) 191 | { 192 | #ifdef _ENABLE_TRACE 193 | debugPrintf("ASIOUAC: %s. No more packets!\n", TaskName()); 194 | #endif 195 | return TRUE; 196 | } 197 | 198 | if(!m_device->OvlWait(nextXfer->OvlHandle, OVL_WAIT_TIMEOUT, KOVL_WAIT_FLAG_NONE, &transferred)) 199 | // if(!m_device->OvlWaitOrCancel(nextXfer->OvlHandle, OVL_WAIT_TIMEOUT, &transferred)) 200 | { 201 | int deviceErrorCode = m_device->GetErrorCode(); 202 | #ifdef _ENABLE_TRACE 203 | debugPrintf("ASIOUAC: %s OvlK_Wait failed. ErrorCode: %08Xh\n", TaskName(), deviceErrorCode); 204 | #endif 205 | m_isoTransferErrorCount++; 206 | if(//deviceErrorCode == ERROR_GEN_FAILURE || 207 | m_isoTransferErrorCount >= MAX_OVL_ERROR_COUNT) 208 | { 209 | #ifdef _ENABLE_TRACE 210 | debugPrintf("ASIOUAC: Notify to device about error\n"); //report to device error 211 | #endif 212 | m_device->Notify(0); 213 | return FALSE; 214 | } 215 | else 216 | m_device->ClearErrorCode(); 217 | } 218 | else 219 | { 220 | ProcessBuffer(nextXfer); 221 | m_isoTransferErrorCount = 0; //reset error count 222 | } 223 | 224 | IsoXferComplete(nextXfer, transferred); 225 | #ifdef _ENABLE_TRACE 226 | CalcStatistics(transferred); 227 | #endif 228 | m_completedIndex = NEXT_INDEX(m_completedIndex); 229 | m_buffersGuard.Leave(); 230 | 231 | return TRUE; 232 | } 233 | 234 | 235 | 236 | bool AudioDACTask::BeforeStartInternal() 237 | { 238 | UCHAR policyValue = 1; 239 | if(m_feedbackInfo) 240 | { 241 | m_feedbackInfo->ClearStatistics(); 242 | #ifdef _ENABLE_TRACE 243 | debugPrintf("ASIOUAC: %s. Clear feedback statistics\n", TaskName()); 244 | #endif 245 | m_feedbackInfo->SetIntervalValue((float)(8 / (1 << (m_interval - 1)))); 246 | // m_feedbackInfo->SetValue(0); 247 | m_feedbackInfo->SetDefaultValue(m_defaultPacketSize); 248 | } 249 | #ifdef _ENABLE_TRACE 250 | m_sampleNumbers = 0; 251 | m_tickCount = 0; 252 | #endif 253 | return m_device->UsbSetPipePolicy((UCHAR)m_pipeId, ISO_ALWAYS_START_ASAP, 1, &policyValue) && 254 | m_device->UsbSetPipePolicy((UCHAR)m_pipeId, RESET_PIPE_ON_RESUME, 1, &policyValue); //experimental 255 | } 256 | 257 | bool AudioDACTask::AfterStopInternal() 258 | { 259 | #ifdef _ENABLE_TRACE 260 | if(m_feedbackInfo) 261 | debugPrintf("ASIOUAC: %s. Maximum feedback value (%f), minimum feedback value (%f)\n", TaskName(), m_feedbackInfo->GetMaxValue(), m_feedbackInfo->GetMinValue()); 262 | #endif 263 | return TRUE; 264 | } 265 | 266 | int AudioDACTask::FillBuffer(ISOBuffer* nextXfer) 267 | { 268 | float raw_cur_feedback = m_feedbackInfo == NULL || m_feedbackInfo->GetValue() == 0.0f 269 | ? m_defaultPacketSize 270 | : m_feedbackInfo->GetValue(); //value in stereo samples in one second // BSB: or in one milisecond?? 271 | 272 | int maxSamplesInPacket = m_packetSize / m_channelNumber / m_sampleSize; //max stereo samples in one packet 273 | if(raw_cur_feedback > (float)(maxSamplesInPacket)) 274 | { 275 | #ifdef _ENABLE_TRACE 276 | debugPrintf("ASIOUAC: %s. Feedback value (%f) larger than the maximum packet size\n", TaskName(), raw_cur_feedback); 277 | #endif 278 | raw_cur_feedback = (float)maxSamplesInPacket; 279 | } 280 | int dataLength = 0; 281 | if(raw_cur_feedback > 0) 282 | { 283 | //raw_cur_feedback = m_defaultPacketSize; 284 | //in one second we have 8 / (1 << (m_interval - 1)) packets 285 | //one packet must contain samples number = [cur_feedback * (1 << (m_interval - 1)) / 8] 286 | float cur_feedback = raw_cur_feedback; //number stereo samples in one packet 287 | int icur_feedback = (int)(cur_feedback + 0.5f); // BSB: added +0.5f to get round() function. (int)(f) === floor(f), f>=0 288 | int nextOffSet = 0; 289 | static float addSample = 0; // BSB: added static. 290 | float frac = cur_feedback - icur_feedback; 291 | if(raw_cur_feedback == (float)maxSamplesInPacket) 292 | { 293 | frac = 0.f; 294 | addSample = 0; 295 | } 296 | icur_feedback *= m_channelNumber * m_sampleSize; 297 | for (int packetIndex = 0; packetIndex < nextXfer->IsoContext->NumberOfPackets; packetIndex++) 298 | { 299 | nextXfer->IsoContext->IsoPackets[packetIndex].Offset = nextOffSet; 300 | nextOffSet += icur_feedback; 301 | addSample += frac; 302 | if(addSample > 0.5f) // 1.f) 303 | { 304 | nextOffSet += m_channelNumber * m_sampleSize; //append additional stereo sample 305 | addSample -= 1.f; 306 | } 307 | else if(addSample < -0.5f) // -1.f) // BSB: Added negative case 308 | { 309 | nextOffSet -= m_channelNumber * m_sampleSize; //append additional stereo sample 310 | addSample += 1.f; 311 | } 312 | nextXfer->IsoContext->IsoPackets[packetIndex].Length = nextOffSet - nextXfer->IsoContext->IsoPackets[packetIndex].Offset; 313 | } 314 | dataLength = (int)nextOffSet; 315 | 316 | if(m_readDataCb) 317 | m_readDataCb(m_readDataCbContext, nextXfer->DataBuffer, dataLength); 318 | 319 | #ifdef _ENABLE_TRACE 320 | //You can dump data for analise like this 321 | if(m_dumpFile) { 322 | char packetstart[] = {'*', '*', 0x00, 0x80, 'P', 'a', 'c', 'k', 'e', 't', ' ', 's', 't', 'a', 'r', 't'}; // BSB added packet identifier 323 | fwrite(packetstart, 1, 16, m_dumpFile); // "**", L: negative 16-bit fullscalle, "Packet start" 324 | fwrite(nextXfer->DataBuffer, 1, dataLength, m_dumpFile); 325 | } 326 | #endif 327 | 328 | #ifdef _ENABLE_TRACE 329 | // debugPrintf("ASIOUAC: %s. Transfer: feedback val = %.1f, send %.1f samples, transfer length=%d\n", TaskName(), raw_cur_feedback, (float)dataLength/8.f, dataLength); 330 | #endif 331 | } 332 | else 333 | { 334 | //default transfer length 335 | dataLength = (int)(m_defaultPacketSize * m_packetPerTransfer); 336 | memset(nextXfer->DataBuffer, 0, dataLength); 337 | } 338 | return dataLength; 339 | } 340 | 341 | bool AudioDACTask::RWBuffer(ISOBuffer* nextXfer, int len) 342 | { 343 | if(!m_device->UsbIsoWritePipe(m_pipeId, nextXfer->DataBuffer, len, (LPOVERLAPPED)nextXfer->OvlHandle, nextXfer->IsoContext)) 344 | { 345 | #ifdef _ENABLE_TRACE 346 | debugPrintf("ASIOUAC: %s. IsoWritePipe failed. ErrorCode: %08Xh\n", TaskName(), m_device->GetErrorCode()); 347 | #endif 348 | return FALSE; 349 | } 350 | return TRUE; 351 | } 352 | 353 | void AudioDACTask::ProcessBuffer(ISOBuffer* buffer) 354 | { 355 | } 356 | 357 | #ifdef _ENABLE_TRACE 358 | void AudioDACTask::CalcStatistics(int sampleNumbers) 359 | { 360 | if(m_tickCount == 0) 361 | { 362 | m_tickCount = GetTickCount(); 363 | m_sampleNumbers = 0; 364 | } 365 | else 366 | { 367 | DWORD curTick = GetTickCount(); 368 | m_sampleNumbers += sampleNumbers / m_channelNumber / m_sampleSize; 369 | if(curTick - m_tickCount > 1000) 370 | { 371 | if(m_feedbackInfo == NULL) 372 | debugPrintf("ASIOUAC: %s. Current sample freq: %f\n", TaskName(), (float)m_sampleNumbers / (float)(curTick - m_tickCount) * 1000.f); 373 | else 374 | debugPrintf("ASIOUAC: %s. Current sample freq: %f (interval %d), by fb=%f\n", TaskName(), (float)m_sampleNumbers / (float)(curTick - m_tickCount) * 1000.f, curTick - m_tickCount, m_feedbackInfo->GetFreqValue()); 375 | m_sampleNumbers = 0; 376 | m_tickCount = curTick; 377 | } 378 | } 379 | } 380 | #endif 381 | 382 | bool AudioADCTask::BeforeStartInternal() 383 | { 384 | if(m_feedbackInfo != NULL) 385 | //m_feedbackInfo->SetValue(0); 386 | m_feedbackInfo->SetDefaultValue(m_defaultPacketSize); 387 | //return TRUE; 388 | #ifdef _ENABLE_TRACE 389 | m_sampleNumbers = 0; 390 | m_tickCount = 0; 391 | #endif 392 | 393 | UCHAR policyValue = 1; 394 | return m_device->UsbSetPipePolicy((UCHAR)m_pipeId, ISO_ALWAYS_START_ASAP, 1, &policyValue); 395 | } 396 | 397 | bool AudioADCTask::AfterStopInternal() 398 | { 399 | return TRUE; 400 | } 401 | 402 | int AudioADCTask::FillBuffer(ISOBuffer* nextXfer) 403 | { 404 | return m_packetPerTransfer * m_packetSize; 405 | } 406 | 407 | bool AudioADCTask::RWBuffer(ISOBuffer* nextXfer, int len) 408 | { 409 | if(!m_device->UsbIsoReadPipe(m_pipeId, nextXfer->DataBuffer, len, (LPOVERLAPPED)nextXfer->OvlHandle, nextXfer->IsoContext)) 410 | { 411 | #ifdef _ENABLE_TRACE 412 | debugPrintf("ASIOUAC: %s. IsoReadPipe (ADC) failed. ErrorCode: %08Xh\n", TaskName(), m_device->GetErrorCode()); 413 | #endif 414 | return FALSE; 415 | } 416 | return TRUE; 417 | } 418 | 419 | #define PACK_ADC_BUFFER 420 | 421 | void AudioADCTask::ProcessBuffer(ISOBuffer* buffer) 422 | { 423 | int packetLength = 0; 424 | int recLength = 0; 425 | for(int i = 0; i < buffer->IsoContext->NumberOfPackets; i++) 426 | { 427 | packetLength = buffer->IsoContext->IsoPackets[i].Length; 428 | #ifdef PACK_ADC_BUFFER 429 | memcpy(buffer->DataBuffer + recLength, buffer->DataBuffer + buffer->IsoPackets[i].Offset, packetLength); 430 | recLength += packetLength; 431 | #else 432 | recLength += packetLength; 433 | if(m_writeDataCb && packetLength > 0) 434 | m_writeDataCb(m_writeDataCbContext, buffer->DataBuffer + buffer->IsoPackets[i].Offset, packetLength); 435 | #endif 436 | } 437 | #ifdef PACK_ADC_BUFFER 438 | if(m_writeDataCb) 439 | m_writeDataCb(m_writeDataCbContext, buffer->DataBuffer, recLength); 440 | #endif 441 | if(m_feedbackInfo) 442 | { 443 | /* 444 | int div = buffer->IsoContext->NumberOfPackets * m_channelNumber * m_sampleSize * (1 << (m_interval - 1)) / 8; 445 | int d1 = recLength / div; 446 | int d2 = recLength % div; 447 | m_feedbackInfo->SetValue((d1 << 14) + d2); 448 | */ 449 | int div = buffer->IsoContext->NumberOfPackets * m_channelNumber * m_sampleSize; 450 | int d1 = recLength / div; 451 | int d2 = recLength % div; 452 | m_feedbackInfo->SetValue((d1 << 16) + d2); 453 | } 454 | } 455 | 456 | 457 | #ifdef _ENABLE_TRACE 458 | void AudioADCTask::CalcStatistics(int sampleNumbers) 459 | { 460 | } 461 | #endif 462 | 463 | 464 | int AudioFeedbackTask::FillBuffer(ISOBuffer* nextXfer) 465 | { 466 | return m_packetPerTransfer * m_packetSize; 467 | } 468 | 469 | bool AudioFeedbackTask::RWBuffer(ISOBuffer* nextXfer, int len) 470 | { 471 | if(!m_device->UsbIsoReadPipe(m_pipeId, nextXfer->DataBuffer, len, (LPOVERLAPPED)nextXfer->OvlHandle, nextXfer->IsoContext)) 472 | { 473 | #ifdef _ENABLE_TRACE 474 | debugPrintf("ASIOUAC: %s. IsoReadPipe (feedback) failed. ErrorCode: %08Xh\n", TaskName(), m_device->GetErrorCode()); 475 | #endif 476 | return FALSE; 477 | } 478 | return TRUE; 479 | } 480 | 481 | void AudioFeedbackTask::ProcessBuffer(ISOBuffer* nextXfer) 482 | { 483 | if(m_feedbackInfo == NULL) 484 | return; 485 | KISO_PACKET isoPacket = nextXfer->IsoPackets[nextXfer->IsoContext->NumberOfPackets - 1]; 486 | //TODO: isoPacket.Length may be 3 or 4 487 | if (isoPacket.Length > 1) 488 | { 489 | int feedback = *((int*)(nextXfer->DataBuffer + isoPacket.Offset)); 490 | m_feedbackInfo->SetValue(feedback); 491 | } 492 | } 493 | 494 | 495 | bool AudioFeedbackTask::BeforeStartInternal() 496 | { 497 | //if(m_feedbackInfo != NULL) 498 | // m_feedbackInfo->SetValue(0); 499 | return TRUE; 500 | } 501 | 502 | bool AudioFeedbackTask::AfterStopInternal() 503 | { 504 | return TRUE; 505 | } 506 | -------------------------------------------------------------------------------- /uaclib/audiotask.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/uaclib/audiotask.h -------------------------------------------------------------------------------- /uaclib/descriptors.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | 16 | #include "descriptors.h" 17 | 18 | USBAudioInterface::USBAudioInterface(USB_INTERFACE_DESCRIPTOR* iface) 19 | { 20 | memcpy(&m_interface, iface, sizeof(USB_INTERFACE_DESCRIPTOR)); 21 | } 22 | 23 | USBAudioClockSource::USBAudioClockSource(usb_clock_source_descriptor* clockSource, USBAudioControlInterface* iface) : m_interface(iface) 24 | { 25 | memcpy(&m_clockSource, clockSource, sizeof(usb_clock_source_descriptor)); 26 | } 27 | 28 | USBAudioInTerminal::USBAudioInTerminal(usb_in_ter_descriptor_2* inTerminal, USBAudioControlInterface* iface) : m_interface(iface) 29 | { 30 | memcpy(&m_inTerminal, inTerminal, sizeof(usb_in_ter_descriptor_2)); 31 | } 32 | 33 | USBAudioOutTerminal::USBAudioOutTerminal(usb_out_ter_descriptor_2* outTerminal, USBAudioControlInterface* iface) : m_interface(iface) 34 | { 35 | memcpy(&m_outTerminal, outTerminal, sizeof(usb_out_ter_descriptor_2)); 36 | } 37 | 38 | USBAudioFeatureUnit::USBAudioFeatureUnit(usb_feature_unit_descriptor_2* featureUnit, USBAudioControlInterface* iface) : m_interface(iface) 39 | { 40 | memcpy(&m_featureUnit, featureUnit, sizeof(usb_feature_unit_descriptor_2)); 41 | } 42 | 43 | USBEndpoint::USBEndpoint(USB_ENDPOINT_DESCRIPTOR* descriptor) 44 | { 45 | memcpy(&m_descriptor, descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR)); 46 | } 47 | 48 | 49 | USBAudioStreamingEndpoint::USBAudioStreamingEndpoint(USB_ENDPOINT_DESCRIPTOR* descriptor, USBAudioStreamingInterface* iface) : USBEndpoint(descriptor), m_interface(iface) 50 | { 51 | memset(&m_asDescriptor, 0, sizeof(usb_endpoint_audio_specific_2)); 52 | } 53 | 54 | bool USBAudioStreamingEndpoint::SetCSDescriptor(USB_DESCRIPTOR_HEADER *csDescriptor) 55 | { 56 | if(csDescriptor->bDescriptorSubType == GENERAL_SUB_TYPE && csDescriptor->bLength == sizeof(usb_endpoint_audio_specific_2)) 57 | { 58 | memcpy(&m_asDescriptor, csDescriptor, sizeof(usb_endpoint_audio_specific_2)); 59 | #ifdef _ENABLE_TRACE 60 | debugPrintf("ASIOUAC: Found CS descriptor for endpoint 0x%X, audio streaming interface 0x%X\n", m_descriptor.bEndpointAddress, m_interface->Descriptor().bInterfaceNumber); 61 | #endif 62 | return TRUE; 63 | } 64 | return FALSE; 65 | } 66 | 67 | USBAudioControlInterface::USBAudioControlInterface(USB_INTERFACE_DESCRIPTOR* iface) : USBAudioInterface(iface) 68 | { 69 | memset(&m_acDescriptor, 0, sizeof(usb_ac_interface_descriptor_2)); 70 | } 71 | 72 | bool USBAudioControlInterface::SetCSDescriptor(USB_DESCRIPTOR_HEADER *csDescriptor) 73 | { 74 | switch(csDescriptor->bDescriptorSubType) 75 | { 76 | case HEADER_SUB_TYPE: 77 | memcpy(&m_acDescriptor, csDescriptor, sizeof(usb_ac_interface_descriptor_2)); 78 | #ifdef _ENABLE_TRACE 79 | debugPrintf("ASIOUAC: Found CS descriptor (subtype 0x%X) for audio control interface 0x%X\n", m_interface.bInterfaceSubClass, m_interface.bInterfaceNumber); 80 | #endif 81 | return TRUE; 82 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_CLOCK_SOURCE: 83 | AddClockSource((usb_clock_source_descriptor*)csDescriptor); 84 | #ifdef _ENABLE_TRACE 85 | debugPrintf("ASIOUAC: Found clock source 0x%X in interface 0x%X\n", m_clockSourceList.Last()->m_clockSource.bClockID, m_interface.bInterfaceNumber); 86 | #endif 87 | return TRUE; 88 | 89 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_INPUT_TERMINAL: 90 | AddInTerminal((usb_in_ter_descriptor_2*)csDescriptor); 91 | #ifdef _ENABLE_TRACE 92 | debugPrintf("ASIOUAC: Found in terminal 0x%X in interface 0x%X\n", m_inTerminalList.Last()->m_inTerminal.bTerminalID, m_interface.bInterfaceNumber); 93 | #endif 94 | return TRUE; 95 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_OUTPUT_TERMINAL: 96 | AddOutTerminal((usb_out_ter_descriptor_2*)csDescriptor); 97 | #ifdef _ENABLE_TRACE 98 | debugPrintf("ASIOUAC: Found out terminal 0x%X in interface 0x%X\n", m_outTerminalList.Last()->m_outTerminal.bTerminalID, m_interface.bInterfaceNumber); 99 | #endif 100 | return TRUE; 101 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_FEATURE_UNIT: 102 | AddFeatureUnit((usb_feature_unit_descriptor_2*) csDescriptor); 103 | #ifdef _ENABLE_TRACE 104 | debugPrintf("ASIOUAC: Found feature unit 0x%X in interface 0x%X\n", m_featureUnitList.Last()->m_featureUnit.bUnitID, m_interface.bInterfaceNumber); 105 | #endif 106 | return TRUE; 107 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_MIXER_UNIT: 108 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_SELECTOR_UNIT: 109 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_EFFECT_UNIT: 110 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_PROCESSING_UNIT: 111 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_EXTENSION_UNIT: 112 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_CLOCK_SELECTOR: 113 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_CLOCK_MULTIPLIER: 114 | case DESCRIPTOR_SUBTYPE_AUDIO_AC_SAMPLE_RATE_CONVERTE: 115 | return FALSE; 116 | } 117 | return FALSE; 118 | } 119 | 120 | bool USBAudioControlInterface::AddClockSource(usb_clock_source_descriptor* clockSource) 121 | { 122 | USBAudioClockSource *clkSrc = new USBAudioClockSource(clockSource, this); 123 | return m_clockSourceList.Add(clkSrc); 124 | } 125 | 126 | bool USBAudioControlInterface::AddInTerminal(usb_in_ter_descriptor_2* inTerminal) 127 | { 128 | USBAudioInTerminal *inTerm = new USBAudioInTerminal(inTerminal, this); 129 | return m_inTerminalList.Add(inTerm); 130 | } 131 | 132 | bool USBAudioControlInterface::AddOutTerminal(usb_out_ter_descriptor_2* outTerminal) 133 | { 134 | USBAudioOutTerminal *outTerm = new USBAudioOutTerminal(outTerminal, this); 135 | return m_outTerminalList.Add(outTerm); 136 | } 137 | 138 | bool USBAudioControlInterface::AddFeatureUnit(usb_feature_unit_descriptor_2* featureUnit) 139 | { 140 | USBAudioFeatureUnit *featUnit = new USBAudioFeatureUnit(featureUnit, this); 141 | return m_featureUnitList.Add(featUnit); 142 | } 143 | 144 | USBEndpoint* USBAudioControlInterface::CreateEndpoint(USB_ENDPOINT_DESCRIPTOR* descriptor) 145 | { 146 | return NULL; 147 | } 148 | 149 | 150 | 151 | USBAudioStreamingInterface::USBAudioStreamingInterface(USB_INTERFACE_DESCRIPTOR* iface) : USBAudioInterface(iface) 152 | { 153 | memset(&m_asgDescriptor, 0, sizeof(usb_as_g_interface_descriptor_2)); 154 | memset(&m_formatDescriptor, 0, sizeof(usb_format_type_2)); 155 | } 156 | 157 | bool USBAudioStreamingInterface::SetCSDescriptor(USB_DESCRIPTOR_HEADER* csDescriptor) 158 | { 159 | switch(csDescriptor->bDescriptorSubType) 160 | { 161 | case HEADER_SUB_TYPE: 162 | memcpy(&m_asgDescriptor, csDescriptor, sizeof(usb_as_g_interface_descriptor_2)); 163 | #ifdef _ENABLE_TRACE 164 | debugPrintf("ASIOUAC: Found CS descriptor (subtype 0x%X) for audio streaming interface 0x%X\n", m_interface.bInterfaceSubClass, m_interface.bInterfaceNumber); 165 | #endif 166 | return TRUE; 167 | case FORMAT_SUB_TYPE: 168 | memcpy(&m_formatDescriptor, csDescriptor, sizeof(usb_format_type_2)); 169 | #ifdef _ENABLE_TRACE 170 | debugPrintf("ASIOUAC: Found format type descriptor for audio streaming interface 0x%X\n", m_interface.bInterfaceNumber); 171 | #endif 172 | return TRUE; 173 | } 174 | return FALSE; 175 | } 176 | 177 | USBEndpoint* USBAudioStreamingInterface::CreateEndpoint(USB_ENDPOINT_DESCRIPTOR* descriptor) 178 | { 179 | USBAudioStreamingEndpoint *ep = new USBAudioStreamingEndpoint(descriptor, this); 180 | #ifdef _ENABLE_TRACE 181 | debugPrintf("ASIOUAC: Found endpoint 0x%X for audio streaming interface 0x%X\n", ep->m_descriptor.bEndpointAddress, m_interface.bInterfaceNumber); 182 | #endif 183 | m_endpointsList.Add(ep); 184 | return ep; 185 | } -------------------------------------------------------------------------------- /uaclib/descriptors.h: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | #pragma once 16 | #ifndef __DESCRIPTORS_H__ 17 | #define __DESCRIPTORS_H__ 18 | 19 | #include "targetver.h" 20 | #include 21 | #include 22 | 23 | #include 24 | #include "usbdevice.h" 25 | #include "tlist.h" 26 | 27 | 28 | 29 | class USBAudioDevice; 30 | class USBEndpoint; 31 | class USBAudioStreamingInterface; 32 | class USBAudioControlInterface; 33 | 34 | class USBAudioInterface 35 | { 36 | protected: 37 | USB_INTERFACE_DESCRIPTOR m_interface; 38 | public: 39 | USBAudioInterface(USB_INTERFACE_DESCRIPTOR* iface); 40 | ~USBAudioInterface() {} 41 | virtual bool SetCSDescriptor(USB_DESCRIPTOR_HEADER *csDescriptor) = 0; 42 | virtual USBEndpoint* CreateEndpoint(USB_ENDPOINT_DESCRIPTOR* descriptor) = 0; 43 | const USB_INTERFACE_DESCRIPTOR& Descriptor() { return m_interface; } 44 | 45 | friend class USBAudioDevice; 46 | }; 47 | 48 | class USBAudioClockSource : public TElement> 49 | { 50 | protected: 51 | usb_clock_source_descriptor m_clockSource; // Clock source 52 | USBAudioControlInterface* m_interface; 53 | public: 54 | USBAudioClockSource(usb_clock_source_descriptor* clockSource, USBAudioControlInterface* iface); 55 | ~USBAudioClockSource() {} 56 | void Destroy() 57 | { delete this; } 58 | friend class USBAudioDevice; 59 | friend class USBAudioControlInterface; 60 | }; 61 | 62 | class USBAudioInTerminal : public TElement> 63 | { 64 | protected: 65 | usb_in_ter_descriptor_2 m_inTerminal; 66 | USBAudioControlInterface* m_interface; 67 | public: 68 | USBAudioInTerminal(usb_in_ter_descriptor_2* inTerminal, USBAudioControlInterface* iface); 69 | ~USBAudioInTerminal() {} 70 | void Destroy() 71 | { delete this; } 72 | friend class USBAudioDevice; 73 | friend class USBAudioControlInterface; 74 | }; 75 | 76 | class USBAudioOutTerminal : public TElement> 77 | { 78 | protected: 79 | usb_out_ter_descriptor_2 m_outTerminal; 80 | USBAudioControlInterface* m_interface; 81 | public: 82 | USBAudioOutTerminal(usb_out_ter_descriptor_2* outTerminal, USBAudioControlInterface* iface); 83 | ~USBAudioOutTerminal() {} 84 | void Destroy() 85 | { delete this; } 86 | friend class USBAudioDevice; 87 | friend class USBAudioControlInterface; 88 | }; 89 | 90 | 91 | class USBAudioFeatureUnit : public TElement> 92 | { 93 | protected: 94 | usb_feature_unit_descriptor_2 m_featureUnit; 95 | USBAudioControlInterface* m_interface; 96 | public: 97 | USBAudioFeatureUnit(usb_feature_unit_descriptor_2* featureUnit, USBAudioControlInterface* iface); 98 | ~USBAudioFeatureUnit() {} 99 | void Destroy() 100 | { delete this; } 101 | friend class USBAudioDevice; 102 | friend class USBAudioControlInterface; 103 | }; 104 | 105 | class USBEndpoint 106 | { 107 | protected: 108 | USB_ENDPOINT_DESCRIPTOR m_descriptor; 109 | public: 110 | USBEndpoint(USB_ENDPOINT_DESCRIPTOR* descriptor); 111 | ~USBEndpoint() {} 112 | virtual bool SetCSDescriptor(USB_DESCRIPTOR_HEADER *csDescriptor) = 0; 113 | friend class USBAudioDevice; 114 | friend class USBAudioControlInterface; 115 | friend class USBAudioStreamingInterface; 116 | }; 117 | 118 | class USBAudioStreamingEndpoint : public USBEndpoint, public TElement> 119 | { 120 | protected: 121 | usb_endpoint_audio_specific_2 m_asDescriptor; 122 | USBAudioStreamingInterface* m_interface; 123 | public: 124 | USBAudioStreamingEndpoint(USB_ENDPOINT_DESCRIPTOR* descriptor, USBAudioStreamingInterface* iface); 125 | ~USBAudioStreamingEndpoint() {} 126 | void Destroy() 127 | { delete this; } 128 | virtual bool SetCSDescriptor(USB_DESCRIPTOR_HEADER *csDescriptor); 129 | friend class USBAudioDevice; 130 | friend class USBAudioControlInterface; 131 | friend class USBAudioStreamingInterface; 132 | }; 133 | 134 | class USBAudioControlInterface : public USBAudioInterface, public TElement> 135 | { 136 | protected: 137 | usb_ac_interface_descriptor_2 m_acDescriptor; 138 | TList m_clockSourceList; 139 | TList m_inTerminalList; 140 | TList m_featureUnitList; 141 | TList m_outTerminalList; 142 | public: 143 | USBAudioControlInterface(USB_INTERFACE_DESCRIPTOR* iface); 144 | ~USBAudioControlInterface() {} 145 | void Destroy() 146 | { delete this; } 147 | 148 | virtual bool SetCSDescriptor(USB_DESCRIPTOR_HEADER *csDescriptor); 149 | bool AddClockSource(usb_clock_source_descriptor* clockSource); 150 | bool AddInTerminal(usb_in_ter_descriptor_2* inTerminal); 151 | bool AddOutTerminal(usb_out_ter_descriptor_2* outTerminal); 152 | bool AddFeatureUnit(usb_feature_unit_descriptor_2* featureUnit); 153 | USBEndpoint* CreateEndpoint(USB_ENDPOINT_DESCRIPTOR* descriptor); 154 | 155 | friend class USBAudioDevice; 156 | }; 157 | 158 | class USBAudioStreamingInterface : public USBAudioInterface, public TElement> 159 | { 160 | protected: 161 | usb_as_g_interface_descriptor_2 m_asgDescriptor; 162 | usb_format_type_2 m_formatDescriptor; 163 | TList m_endpointsList; 164 | 165 | public: 166 | USBAudioStreamingInterface(USB_INTERFACE_DESCRIPTOR* iface); 167 | ~USBAudioStreamingInterface() {} 168 | 169 | void Destroy() 170 | { delete this; } 171 | 172 | virtual bool SetCSDescriptor(USB_DESCRIPTOR_HEADER* csDescriptor); 173 | virtual USBEndpoint* CreateEndpoint(USB_ENDPOINT_DESCRIPTOR* descriptor); 174 | 175 | friend class USBAudioDevice; 176 | }; 177 | 178 | 179 | #endif //__DESCRIPTORS_H__ 180 | -------------------------------------------------------------------------------- /uaclib/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/uaclib/targetver.h -------------------------------------------------------------------------------- /uaclib/tlist.h: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | 16 | #ifndef __TLIST_T__ 17 | #define __TLIST_T__ 18 | 19 | 20 | template class TElement 21 | { 22 | protected: 23 | element* m_prev; 24 | element* m_next; 25 | list* m_list; 26 | 27 | public: 28 | TElement() : m_prev(NULL), m_next(NULL), m_list(NULL) 29 | { 30 | } 31 | virtual ~TElement() {} 32 | virtual void Destroy() = 0; 33 | 34 | friend typename list; 35 | }; 36 | 37 | 38 | class DummyLocker 39 | { 40 | public: 41 | DummyLocker() {} 42 | void Init() {} 43 | void Lock() {} 44 | void Unlock() {} 45 | }; 46 | 47 | 48 | template class TList 49 | { 50 | private: 51 | element * m_first; 52 | element * m_last; 53 | long m_numElements; 54 | lockobj m_lock; 55 | 56 | public: 57 | TList() : m_first(NULL), m_last(NULL), m_numElements(0) 58 | { 59 | m_lock.Init(); 60 | } 61 | 62 | ~TList() 63 | { 64 | Clear(); 65 | } 66 | 67 | long Count() 68 | { return m_numElements; } 69 | 70 | element* First() 71 | { return m_first; } 72 | 73 | element* Last() 74 | { return m_last; } 75 | 76 | element* Next(element* elem) 77 | { 78 | if(!IsContains(elem)) 79 | return NULL; 80 | return elem->m_next; 81 | } 82 | 83 | element* Prev(element* elem) 84 | { 85 | if(!IsContains(elem)) 86 | return NULL; 87 | return elem->m_prev(); 88 | } 89 | 90 | void Clear() 91 | { 92 | element* curElem = m_first; 93 | while(curElem) 94 | { 95 | element* nextElem = curElem->m_next; 96 | curElem->Destroy(); 97 | curElem = nextElem; 98 | } 99 | m_first = m_last = NULL; 100 | m_numElements = 0; 101 | } 102 | 103 | void LockList() 104 | { 105 | m_lock.Lock(); 106 | } 107 | 108 | void UnlockList() 109 | { 110 | m_lock.Unlock(); 111 | } 112 | 113 | bool IsContains(element* elem) 114 | { 115 | element* curElem = m_first; 116 | while(curElem) 117 | { 118 | if(elem == curElem) 119 | return TRUE; 120 | curElem = curElem->m_next; 121 | } 122 | return FALSE; 123 | } 124 | 125 | bool IsEmpty() 126 | { 127 | return m_numElements == 0; 128 | } 129 | 130 | bool Add(element* elem) 131 | { 132 | if(IsContains(elem)) 133 | return FALSE; 134 | elem->m_next = elem->m_prev = NULL; 135 | elem->m_list = this; 136 | if(m_last) 137 | { 138 | m_last->m_next = elem; 139 | elem->m_prev = m_last; 140 | m_last = elem; 141 | } 142 | else 143 | { 144 | m_first = m_last = elem; 145 | } 146 | m_numElements++; 147 | return TRUE; 148 | } 149 | 150 | bool Del(element* elem) 151 | { 152 | if(!IsContains(elem)) 153 | return FALSE; 154 | 155 | if (elem->m_prev) { elem->m_prev->m_next = elem->m_next; } 156 | if (elem->m_next) 157 | elem->m_next->m_prev = elem->m_prev; 158 | 159 | if (elem == m_first) 160 | m_first = elem->m_next; 161 | 162 | if (elem == m_last) 163 | m_last=elem->m_prev; 164 | 165 | elem->m_next = NULL; 166 | elem->m_prev = NULL; 167 | elem->m_list = NULL; 168 | m_numElements--; 169 | return TRUE; 170 | } 171 | }; 172 | 173 | 174 | 175 | #endif //__TLIST_T__ -------------------------------------------------------------------------------- /uaclib/uaclib.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual C++ Express 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uaclib", "uaclib.vcproj", "{6964BC9D-1940-424C-9273-921F7C60D72A}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Debug|Win32.Build.0 = Debug|Win32 14 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Release|Win32.ActiveCfg = Release|Win32 15 | {6964BC9D-1940-424C-9273-921F7C60D72A}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /uaclib/uaclib.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikkov/Win-Widget/2069c72269ed371bd7907bde2c4911b005a2a7a6/uaclib/uaclib.vcproj -------------------------------------------------------------------------------- /uaclib/usb_audio.h: -------------------------------------------------------------------------------- 1 | /*! 2 | # 3 | # Win-Widget. Windows related software for Audio-Widget/SDR-Widget (http://code.google.com/p/sdr-widget/) 4 | # Copyright (C) 2012 Nikolay Kovbasa 5 | # 6 | # Permission to copy, use, modify, sell and distribute this software 7 | # is granted provided this copyright notice appears in all copies. 8 | # This software is provided "as is" without express or implied 9 | # warranty, and with no claim as to its suitability for any purpose. 10 | # 11 | #---------------------------------------------------------------------------- 12 | # Contact: nikkov@gmail.com 13 | #---------------------------------------------------------------------------- 14 | */ 15 | 16 | // USB Audio defines 17 | 18 | #ifndef USB_AUDIO_DEF 19 | #define USB_AUDIO_DEF 20 | 21 | #define U8 unsigned char 22 | #define U16 unsigned short 23 | #define U32 unsigned __int32 24 | 25 | //_____ M A C R O S ____________________________________________________________ 26 | #define CS_INTERFACE 0x24 27 | #define CS_ENDPOINT 0x25 28 | #define GENERAL_SUB_TYPE 0x01 29 | #define FORMAT_SUB_TYPE 0x02 30 | #define HEADER_SUB_TYPE 0x01 31 | #define MIXER_UNIT_SUB_TYPE 0x04 32 | #define FEATURE_UNIT_SUB_TYPE 0x06 33 | #define INPUT_TERMINAL_SUB_TYPE 0x02 34 | #define OUTPUT_TERMINAL_SUB_TYPE 0x03 35 | 36 | /*! \name Audio specific definitions (Class, subclass and protocol) 37 | */ 38 | //! @{ 39 | #define AUDIO_CLASS 0x01 40 | #define AUDIOCONTROL_SUBCLASS 0x01 41 | #define AUDIOSTREAMING_SUBCLASS 0x02 42 | #define MIDISTREAMING_SUBCLASS 0x03 43 | //! @} 44 | 45 | 46 | //! \name Audio Interface Subclass Code pp. A.5 47 | //! @{ 48 | #define AUDIO_INTERFACE_SUBCLASS_UNDEFINED 0x00 49 | #define AUDIO_INTERFACE_SUBCLASS_AUDIOCONTROL 0x01 50 | #define AUDIO_INTERFACE_SUBCLASS_AUDIOSTREAMING 0x02 51 | #define AUDIO_INTERFACE_SUBCLASS_MIDISTREAMING 0x03 52 | //! @} 53 | 54 | //! \name Audio Interface Protocol Code pp. A.6 55 | //! @{ 56 | #define AUDIO_INTERFACE_PROTOCOL_UNDEFINED 0x00 57 | #define AUDIO_INTERFACE_IP_VERSION_02_00 0x20 58 | #define IP_VERSION_02_00 AUDIO_INTERFACE_IP_VERSION_02_00 59 | //! @} 60 | 61 | //! \name Audio Class-Specific AC Interface Descriptor Subtypes pp. A.9 62 | //! @{ 63 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_UNDEFINED 0x00 64 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_HEADER 0x01 65 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_INPUT_TERMINAL 0x02 66 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_OUTPUT_TERMINAL 0x03 67 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_MIXER_UNIT 0x04 68 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_SELECTOR_UNIT 0x05 69 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_FEATURE_UNIT 0x06 70 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_EFFECT_UNIT 0x07 71 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_PROCESSING_UNIT 0x08 72 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_EXTENSION_UNIT 0x09 73 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_CLOCK_SOURCE 0x0A 74 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_CLOCK_SELECTOR 0x0B 75 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_CLOCK_MULTIPLIER 0x0C 76 | #define DESCRIPTOR_SUBTYPE_AUDIO_AC_SAMPLE_RATE_CONVERTE 0x0D 77 | //! @} 78 | 79 | 80 | //! \name Audio Class-Specific Request Code pp. A.14 81 | //! @{ 82 | #define AUDIO_CS_REQUEST_UNDEFINED 0x00 83 | #define AUDIO_CS_REQUEST_CUR 0x01 84 | #define AUDIO_CS_REQUEST_RANGE 0x02 85 | #define AUDIO_CS_REQUEST_MEM 0x03 86 | 87 | 88 | //! \name AudioStreaming Interface Control Selectors pp. A.17.11 89 | //! @{ 90 | #define AUDIO_AS_UNDEFINED 0x00 91 | #define AUDIO_AS_ACT_ALT_SETTINGS 0x01 92 | #define AUDIO_AS_VAL_ALT_SETTINGS 0x02 93 | #define AUDIO_AS_AUDIO_DATA_FORMAT 0x03 94 | //! @} 95 | 96 | //! \name Clock Source Control Selectors pp. A17.1 97 | //! @{ 98 | #define AUDIO_CS_UNDEFINED 0x00 99 | #define AUDIO_CS_CONTROL_SAM_FREQ 0x01 100 | #define AUDIO_CS_CONTROL_CLOCK_VALID 0x02 101 | //! @} 102 | 103 | 104 | /* ensure byte-packed structures */ 105 | #include 106 | 107 | struct usb_ac_interface_descriptor_2 108 | { 109 | U8 bLength; /* Size of this descriptor in bytes */ 110 | U8 bDescriptorType; /* CS_INTERFACE descriptor type */ 111 | U8 bDescritorSubtype; /* HEADER subtype */ 112 | U16 bcdADC; /* Revision of class spec */ 113 | U8 bCategory; /* Primary use of this function */ 114 | U16 wTotalLength; /* Total size of class specific descriptor */ 115 | U8 bmControls; /* Latency Control Bitmap */ 116 | }; 117 | 118 | //! USB Standard AS interface Descriptor pp 4.9.1 119 | struct usb_as_interface_descriptor 120 | { 121 | U8 bLength; /* Size of this descriptor in bytes */ 122 | U8 bDescriptorType; /* INTERFACE descriptor type */ 123 | U8 bInterfaceNumber; /* Number of the interface (0 based) */ 124 | U8 bAlternateSetting; 125 | U8 bNumEndpoints; /* Number of endpoints in this interface */ 126 | U8 bInterfaceClass; /* AUDIO Interface class code */ 127 | U8 bInterfaceSubclass; /* AUDIO_STREAMING Interface subclass code */ 128 | U8 bInterfaceProtocol; /* IP_VERSION_02_00 Interface protocol code */ 129 | U8 iInterface; /* String descriptor of this Interface */ 130 | }; 131 | 132 | //! USB Class-Specific AS general interface descriptor pp 4.9.2 133 | struct usb_as_g_interface_descriptor_2 134 | { 135 | U8 bLength; /* Size of this descriptor in bytes */ 136 | U8 bDescriptorType; /* CS_INTERFACE descriptor type */ 137 | U8 bDescriptorSubType; /* AS_GENERAL subtype */ 138 | U8 bTerminalLink; /* Terminal ID to which this interface is connected */ 139 | U8 bmControls; /* Bitmap of controls */ 140 | U8 bFormatType; /* Format type the interface is using */ 141 | U32 bmFormats; /* Bitmap of Formats this interface supports */ 142 | U8 bNrChannels; /* Number of Physical channels in this interface cluster */ 143 | U32 bmChannelConfig; /* Bitmap of spatial locations of the physical channels */ 144 | U8 iChannelNames; /* String descriptor of the first physical channel */ 145 | }; 146 | 147 | 148 | struct usb_clock_source_descriptor 149 | { 150 | U8 bLength; /* Size of this descriptor in bytes */ 151 | U8 bDescriptorType; /* CS_INTERFACE descriptor type */ 152 | U8 bDescritorSubtype; /* CLOCK_SOURCE subtype */ 153 | U8 bClockID; /* Clock Source ID */ 154 | U8 bmAttributes; /* Clock Type Bitmap */ 155 | U8 bmControls; /* Clock control bitmap */ 156 | U8 bAssocTerminal; /* Terminal ID associated with this source */ 157 | U8 iClockSource; /* String descriptor of this clock source */ 158 | }; 159 | 160 | //! USB INPUT Terminal Descriptor pp 4.7.2.4 161 | struct usb_in_ter_descriptor_2 162 | { 163 | U8 bLength; /* Size of this descriptor in bytes */ 164 | U8 bDescriptorType; /* CS_INTERFACE descriptor type */ 165 | U8 bDescriptorSubType; /* INPUT_TERMINAL subtype */ 166 | U8 bTerminalID; /* Input Terminal ID */ 167 | U16 wTerminalType; /* Terminal type */ 168 | U8 bAssocTerminal; /* Output terminal this input is associated with */ 169 | U8 bCSourceID; /* ID of Clock entity to which this terminal is connected */ 170 | U8 bNrChannels; /* Number of Logical output channels */ 171 | U32 bmChannelConfig; /* Spatial location of logical channels */ 172 | U8 iChannelNames; /* String descriptor of first logical channel */ 173 | U16 bmControls; /* Paired Bitmap of controls */ 174 | U8 iTerminal; /* String descriptor of this Input Terminal */ 175 | }; 176 | 177 | 178 | //! USB OUTPUT Terminal Descriptor pp 4.7.2.5 179 | struct usb_out_ter_descriptor_2 180 | { 181 | U8 bLength; /* Size of this descriptor in bytes */ 182 | U8 bDescriptorType; /* CS_INTERFACE descriptor type */ 183 | U8 bDescriptorSubType; /* OUTPUT_TERMINAL subtype */ 184 | U8 bTerminalID; /* Output Terminal ID */ 185 | U16 wTerminalType; /* Terminal type */ 186 | U8 bAssocTerminal; /* Input Terminal this output is associated with */ 187 | U8 bSourceID; /* ID of the Unit or Terminal to which this teminal is connected to */ 188 | U8 bCSourceID; /* ID od the Clock Entity to which this terminal is connected */ 189 | U16 bmControls; /* Paired Bitmap of controls */ 190 | U8 iTerminal; /* String descriptor of this Output Terminal */ 191 | }; 192 | 193 | //! USB Audio Feature Unit descriptor pp 4.7.2.8 194 | struct usb_feature_unit_descriptor_2 195 | { 196 | U8 bLength; /* Size of this descriptor in bytes */ 197 | U8 bDescriptorType; /* CS_INTERFACE descriptor type */ 198 | U8 bDescriptorSubType; /* FEATURE_UNIT subtype */ 199 | U8 bUnitID; /* Feature unit ID */ 200 | U8 bSourceID; /* ID of the Unit or Terminal to which this teminal is connected to */ 201 | U32 bmaControls; /* Master Channel 0*/ 202 | U32 bmaControls_1; // Channel 1 203 | U32 bmaControls_2; // Channel 2 204 | U8 iFeature; /* String Descriptor of this Feature Unit */ 205 | }; 206 | 207 | //! Class-Specific Audio Format Type descriptor pp 4.9.3 -> 2.3.1.6 Type I Format 208 | struct usb_format_type_2 209 | { 210 | U8 bLength; /* Size of this descriptor in bytes */ 211 | U8 bDescriptorType; /* CS_INTERFACE descriptor type */ 212 | U8 bDescriptorSubType; /* FORMAT_TYPE subtype */ 213 | U8 bFormatType; /* Format Type this streaming interface is using */ 214 | U8 bSubslotSize; /* Number of bytes in one audio subslot */ 215 | U8 bBitResolution; /* Number of bits used from the available bits in the subslot */ 216 | }; 217 | 218 | 219 | //! Usb Standard AS Isochronous Audio Data Endpoint Descriptors pp 4.10.1.1 220 | struct usb_endpoint_audio_descriptor_2 221 | { 222 | U8 bLength; /* Size of this descriptor in bytes */ 223 | U8 bDescriptorType; /* CS_ENDPOINT descriptor type */ 224 | U8 bEndpointAddress; /* Address of the endpoint */ 225 | U8 bmAttributes; /* Endpoint's attributes */ 226 | U16 wMaxPacketSize; /* Maximum packet size for this EP */ 227 | U8 bInterval; /* Interval for polling EP in ms */ 228 | }; 229 | 230 | //! Usb Class_Specific AS Isochronous Audio Data Endpoint Descriptors pp 4.10.1.2 231 | struct usb_endpoint_audio_specific_2 232 | { 233 | U8 bLength; /* Size of this descriptor in bytes */ 234 | U8 bDescriptorType; /* CS_ENDPOINT descriptor type*/ 235 | U8 bDescriptorSubType; /* EP_GENERAL subtype */ 236 | U8 bmAttributes; /* Bitmap of attributes 8 */ 237 | U8 bmControls; /* Paired bitmap of controls */ 238 | U8 bLockDelayUnits; /* units for wLockDelay */ 239 | U16 wLockDelay; /* time to lock endpoint */ 240 | }; 241 | 242 | struct sample_rate_triplets 243 | { 244 | int min_freq; 245 | int max_freq; 246 | int res_freq; 247 | }; 248 | 249 | #endif --------------------------------------------------------------------------------