Category Archives: Source - Page 2

Utility Clearance: GPS Location/Coordinate Converter

This tool came up as a result of mess around GPS coordinate formatting and variety of popular formats and notations. Some use latitude and longitude degrees, some prefer degrees and minutes with fractional part. this does not take into account choices for datum and file formats.

For instance, both Google Maps and Yandex Maps accept latitude and longitude as ll= URL parameter with the value of latitude and longitude in degrees, however Google uses latitude coming first, while Yandex prefers the opposite.

Recently, a rally road book contained the following formatting of track points:

Having to put a stop to the madness, this utility comes up as a handy assistant to convert and format GPS coordinates into reasonable presentation and separators.

The utility runs on background and monitors clipboard, and once it recognizes one of the following:

  • GPS Point in Degrees
  • GPS Point in Degrees and Minutes
  • GPS Point in Degrees, Minutes and Seconds
  • Google Maps URL
  • Yandex Maps URL

it flashes and updates its UI providing the choices of track point formatting:

The utility is trying hard to accept various separators and formats, just one thing is important to keep in mind: if you are using minutes without seconds, the fractional part of minutes should be separated by decimal point (.).

The utility also responds to hotkeys Ctrl+Shift+F1, Ctrl+Shift+F2 etc. and copies the formatted point location back into clipboard so that one could quickly re-format editable text in another application through clipboard updates. Alternatively, it is possible to click the formatted value and place it into clipboard.

The utility also provides clickable hyperlinks to open Google Maps and Yandex Maps into the point of interest.

A binary [Win32] and partial Visual C++ .NET 2010 partial source code are available from SVN.

Note: you might need to run the tool “As Administrator” elevating UAC privileges in Vista/7 operating systems.

Bonus links on the topic:

Sample: Simultaneous Audio Playback via Waveform Audio (waveOut) API

The minimalistic sample demonstrates support of [deprecated] Waveform Audio API for multiple playback streams.

Depending on command line parameters, the application starts threads to open audio hardware using separate waveOutOpen call and stream one or more generated sine waves:

  • 1,000 Hz sine wave as 22,050 Hz, Mono, 16-bit PCM (command line parameter “a”)
  • 5,000 Hz sine wave as 32,000 Hz, Mono, 16-bit PCM (command line parameter “b”)
  • 15,000 Hz sine wave as 44,100 Hz, Mono, 16-bit PCM (command line parameter “c”)
Check(waveOutOpen(&hWaveOut, WAVE_MAPPER, &WaveFormatEx, NULL, NULL, CALLBACK_NULL));
ATLASSERT(hWaveOut);
WAVEHDR* pWaveHeader;
HGLOBAL hWaveHeader = (WAVEHDR*) GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof *pWaveHeader + WaveFormatEx.nAvgBytesPerSec * 10);
pWaveHeader = (WAVEHDR*) GlobalLock(hWaveHeader);
ATLENSURE_THROW(pWaveHeader, E_OUTOFMEMORY);
pWaveHeader->lpData = (LPSTR) (BYTE*) (pWaveHeader + 1);
pWaveHeader->dwBufferLength = WaveFormatEx.nAvgBytesPerSec * 10;
//pWaveHeader->dwUser = 
pWaveHeader->dwFlags = 0;
pWaveHeader->dwLoops = 0;
#pragma region Generate Actual Data
{
    SHORT* pnData = (SHORT*) pWaveHeader->lpData;
    SIZE_T nDataCount = pWaveHeader->dwBufferLength / sizeof *pnData;
    for(SIZE_T nIndex = 0; nIndex < nDataCount; nIndex++)
    pnData[nIndex] = (SHORT) (32000 * sin(1.0 * nIndex / WaveFormatEx.nSamplesPerSec * nFrequency * 2 * M_PI));
}
#pragma endregion 
Check(waveOutPrepareHeader(hWaveOut, pWaveHeader, sizeof *pWaveHeader));
Check(waveOutWrite(hWaveOut, pWaveHeader, sizeof *pWaveHeader));
GlobalUnlock(hWaveHeader);

The operating system is supposed to mix the waves, which can be easily perceived taking place. It is possible to run the application with multiple waveforms within a process, e.g. “abc” command line parameter, and/or start multiple instances of the application.

A binary [Win32] and partial Visual C++ .NET 2010 source code are available from SVN.

Utility Clearance: Enumerate Audio ‘MMDevice’s

The utility and code does straightforward enumeration of MMDevices (Vista+, check MSDN for MMDevice API availability), which correspond to MMDevice API, WASAPI, Core Audio API. The code itself is straightforward, with a ready to use binary to quickly lookup data of interest:

The data is detailed well and in Excel-friendly format (via Copy/Paste):

The code also automatically looks up for named Windows SDK constants, such as PKEY_Device_FriendlyName:

    Identifier    {0.0.1.00000000}.{4c1a7642-3f91-43e5-8fcf-b4b1e803d3f9}
    State    DEVICE_STATE_DISABLED    0x02
    Properties:
        {B3F8FA53-0004-438E-9003-51A46E139BFC}, 15    16 bytes of BLOB, DA 07 03 00 02 00 09 00 0E 00 39 00 16 00 C5 02    65
        PKEY_Device_DeviceDesc    Stereo Mix    31
        {B3F8FA53-0004-438E-9003-51A46E139BFC}, 6    Realtek High Definition Audio    31
        {B3F8FA53-0004-438E-9003-51A46E139BFC}, 2    {1}.HDAUDIO\FUNC_01&VEN_10EC&DEV_0888&SUBSYS_80860034&REV_1002\4&37D44F2F&0&0201    31
        {83DA6326-97A6-4088-9453-A1923F573B29}, 3    oem29.inf:AzaliaManufacturerID.NTamd64.6.0:IntcAzAudModel:6.0.1.5964:hdaudio\func_01&ven_10ec&dev_0888    31
        PKEY_Device_BaseContainerId    {00000000-0000-0000-FFFF-FFFFFFFFFFFF}    72
        PKEY_Device_ContainerId    {00000000-0000-0000-FFFF-FFFFFFFFFFFF}    72
        PKEY_Device_EnumeratorName    HDAUDIO    31
        PKEY_AudioEndpoint_FormFactor    10    19
        PKEY_AudioEndpoint_JackSubType    {DFF21FE1-F70F-11D0-B917-00A0C9223196}    31
        PKEY_DeviceClass_IconPath    %windir%\system32\mmres.dll,-3018    31
        {840B8171-B0AD-410F-8581-CCCC0382CFEF}, 0    316 bytes of BLOB, 01 00 00 00 38 01 00 00 ... 00 00 00 00    65
        PKEY_AudioEndpoint_Association    {00000000-0000-0000-0000-000000000000}    31
        PKEY_AudioEndpoint_Supports_EventDriven_Mode    1    19
        {24DBB0FC-9311-4B3D-9CF0-18FF155639D4}, 3    0    11
        {24DBB0FC-9311-4B3D-9CF0-18FF155639D4}, 4    -1    11
        {9A82A7DB-3EBB-41B4-83BA-18B7311718FC}, 1    65536    19
        {233164C8-1B2C-4C7D-BC68-B671687A2567}, 1    {2}.\\?\hdaudio#func_01&ven_10ec&dev_0888&subsys_80860034&rev_1002#4&37d44f2f&0&0201#{6994ad04-93ef-11d0-a3cc-00a0c9223196}\rtstereomixwave    31
        {5A9125B7-F367-4924-ACE2-0803A4A3A471}, 0    1610612916    19
        {B3F8FA53-0004-438E-9003-51A46E139BFC}, 0    3    19
        PKEY_Device_FriendlyName    Stereo Mix (Realtek High Definition Audio)    31
        PKEY_DeviceInterface_FriendlyName    Realtek High Definition Audio    31
        PKEY_AudioEndpoint_GUID    {4C1A7642-3F91-43E5-8FCF-B4B1E803D3F9}    31

A binary [Win32, x64] and partial Visual C++ .NET 2010 source code are available from SVN.

See also:

Utility Clearance: Generate PCM .WAV File

GeneratePcmWavFile tool is generating PCM .WAV files with requested parameters, silent or with a sine wave data. The utility uses WavDest SDK Sample as a multiplexer, so it is expected to be available.

It is possible to define the following audio data parameters:

  • sampling frequency, number of samples per second, such as 44100 or 48000
  • number of channels; the utility does not constrain this to be stereo or 5.1, it will be able to create 64 or 128 channel audio data as well
  • 8 or 16 bit audio samples
    • 16-bit PCM only: sine wave signal parameters, frequency in Hz and amplitude/loudness relative to full scale, that is 0 dB is maximal loudness, and an argument of 23 will result in -23 dB loud audio (such as -23 dbFS, also see EBU R128 Specification, the signal depending on frequency may be used a reference source for normalized -23 LUFS audio)
  • file duration in seconds
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\>GeneratePcmWavFile.exe
Syntax: GeneratePcmWavFile <options> <output-path>
  /s:N: Sampling Rate N, Hz
  /c:N: Channel Count N
  /b:N: Sample Bit Count N, 8 or 16
  /t:N: Length N, seconds
  /f:N: Sine Signal Frequency N, Hz
  /l:N: Sine Signal Loudness N, dB below full scale
  /n:N: Noise Signal Loudness N, dB below full scale

A binary [Win32] and partial Visual C++ .NET 2010 source code are available from SVN.

UPDATE: An extra /n parameter lets the application add random noise within provided loudness parameter.

Utility Clearance: Artificial CPU Load

The LoadCpu tool creates one or more threads to waste CPU cycles and emulate slower environment, such as for testing and troubleshooting. There has been a great deal of similar tools out there, and this one in particular is convenient/special as it takes process affinity mask as a parameter.

That is, /a:NN defines affinity mask, e.g. 5 for 1st and 3rd CPU (two threads), and /r:MM defines [roughly] CPU load time in percent.

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\>loadcpu /a:5 /r:25
System Affinity Mask: 0xff
Process Affinity Mask: 0x05
Rate: 25%

A binary [Win32] and partial Visual C++ .NET 2010 source code are available from SVN.

ATLENSURE_SUCCEEDED double failure

A colleague pointed out that code snippet in previous post is misusing ATL’s ATLENSURE_SUCCEEDED macro making it [possibly] evaluate its argument twice in case of failure, that is evaluating into failure HRESULT code. As it is defined like this:

#define ATLENSURE_SUCCEEDED(hr) ATLENSURE_THROW(SUCCEEDED(hr), hr)

It does things in a straightforward way, for a code line

ATLENSURE_SUCCEEDED(pFilterGraph.CoCreateInstance(CLSID_FilterGraph));

It is doing “let’s CoCreateInstance the thing and if it fails, let’s CoCreateInstance it again to find out error code”. Disassembly shows this clearly:

This is exactly another spin of the story previously happened with HRESULT_FROM_WIN32 macro and possibly a number of others. With it being originally a macro, SDK offered an option to override the definition by pre-defining INLINE_HRESULT_FROM_WIN32. This way a user might be explicitly requesting a safer definition while still leaving legacy code live with macro. See more detailed story on this in Matthew’s blog.

A tricky thing is that with successful execution the problem does not come up. In case of failure, it depends on the functions called, some with just repeat the error code, some will return a different code on second run, some might create less desired and expected consequences. So you can find yourself having written quite some code before you even suspect a problem.

Having identified the issue, there are a few solutions.

1. First of all, the original ATLENSURE_SUCCEEDED macro can still be used, provided that you don’t put expressions as arguments.

This is going to do just fine:

const HRESULT nCoCreateInstanceResult = pFilterGraph.CoCreateInstance(CLSID_FilterGraph);
ATLENSURE_SUCCEEDED(nCoCreateInstanceResult);

2. Second straightforward way is to replace the original ATL definition in ATL code (boo, woodenly)

3. As ATL code is checking for the macros to be already defined, and skipping its own definition in such case, it is possible to inject a safer private definition before including ATL headers (which would typically need one to do the define in stdafx.h):

#define ATLENSURE_SUCCEEDED(x){ const HRESULT nResult =(x); ATLENSURE_THROW(SUCCEEDED(nResult), nResult); }

#include <atlbase.h>
#include <atlstr.h>

Pre-evaluating the argument into local variable is going to resolve the original multi-evaluation problem.

4. There might be a new inline function defined on top of the original macro, which will be used instead and which is free from the problem:

inline VOID ATLENSURE_INLINE_SUCCEEDED(HRESULT nResult)
{
    ATLENSURE_SUCCEEDED(nResult);
}

Either way, the correct code compiles into single argument evaluation and throws an exception with failure code immediately:

Also, vote for the suggestion on Microsoft Connect. The issue is marked as fixed in future version of Visual Studio.

Utility Clearance: Automatic Snapshots

Automatic Snapshots runs as a background application monitors clipboard. Should a new image be copied there, the utility automatically writes the image into a file. The process does not require any user interaction and is completely automatic so that – per Mike Westen‘s request – user could quickly and easily create snapshots of a multitude of windows (Alt+Print Screen) or full screen images (Print Screen) using standard hotkeys.

Features:

  • Automatic PNG compression (can be disabled via registry and enable BMP mode)
  • Reduction of color depth to create smaller PNG files
  • Asynchronous processing, the compression and file writes are on background thread to not slow foreground application
  • Application window flashes on application bar while busy and indicates the status via window caption
  • Application appends current foreground window caption to the image file name

A binary [Win32, x64] and Visual C++ .NET 2010 source code are available from SVN.