1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
110
111
112
113
114
115
116
117
118
119
120
121
|
#pragma once
#define ReturnIfFailed(x) { HRESULT hr = (x); if (FAILED(hr)) return hr; }
#define ReturnIfNotEquals(r, x) { HRESULT hr = (x); if (hr != r) return hr; }
namespace SaneAudioRenderer
{
// One second in 100ns units.
const int64_t OneSecond = 10000000;
// One millisecond in 100ns units.
const int64_t OneMillisecond = OneSecond / 1000;
typedef std::shared_ptr<const std::wstring> SharedString;
typedef std::shared_ptr<const WAVEFORMATEX> SharedWaveFormat;
inline void ThrowIfFailed(HRESULT result)
{
if (FAILED(result))
throw result;
}
inline int64_t GetPerformanceFrequency()
{
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
return frequency.QuadPart;
}
inline int64_t GetPerformanceCounter()
{
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return counter.QuadPart;
}
struct AlignedFreeDeleter
{
void operator()(void* p)
{
_aligned_free(p);
}
};
struct CoTaskMemFreeDeleter
{
void operator()(void* p)
{
CoTaskMemFree(p);
}
};
class CoInitializeHelper final
{
public:
explicit CoInitializeHelper(DWORD appartment) : m_initialized(SUCCEEDED(CoInitializeEx(nullptr, appartment))) {}
CoInitializeHelper(const CoInitializeHelper&) = delete;
CoInitializeHelper& operator=(const CoInitializeHelper&) = delete;
~CoInitializeHelper() { if (m_initialized) CoUninitialize(); }
bool Initialized() const { return m_initialized; }
private:
const bool m_initialized;
};
class TimePeriodHelper final
{
public:
explicit TimePeriodHelper(UINT period) : m_period(period) { timeBeginPeriod(m_period); }
TimePeriodHelper(const TimePeriodHelper&) = delete;
TimePeriodHelper& operator=(const TimePeriodHelper&) = delete;
~TimePeriodHelper() { timeEndPeriod(m_period); }
private:
const UINT m_period;
};
inline std::wstring GetHexString(uint32_t number)
{
std::array<wchar_t, 11> temp;
return swprintf(temp.data(), temp.size(), L"0x%X", number) > 0 ? temp.data() : L"";
}
inline SharedWaveFormat CopyWaveFormat(const WAVEFORMATEX& format)
{
size_t size = sizeof(WAVEFORMATEX) + format.cbSize;
void* pBuffer = _aligned_malloc(size, 4);
if (!pBuffer) throw std::bad_alloc();
memcpy(pBuffer, &format, size);
return SharedWaveFormat(reinterpret_cast<WAVEFORMATEX*>(pBuffer), AlignedFreeDeleter());
}
namespace
{
void DebugOutForward(std::wostringstream&) {}
template <typename T0, typename... T>
void DebugOutForward(std::wostringstream& stream, T0&& arg0, T&&... args)
{
stream << " " << arg0;
DebugOutForward(stream, std::forward<T>(args)...);
}
}
template <typename... T>
inline void DebugOut(T&&... args)
{
#ifndef NDEBUG
try
{
std::wostringstream stream;
stream << "sanear:";
DebugOutForward(stream, std::forward<T>(args)...);
stream << "\n";
OutputDebugString(stream.str().c_str());
}
catch (...)
{
OutputDebugString(L"sanear: caught exception while formatting debug message");
}
#endif
}
}
|