webrtcvad 0.1.0 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/ext/webrtcvad/extconf.rb +29 -0
  3. data/ext/webrtcvad/webrtc/common_audio/signal_processing/division_operations.c +141 -0
  4. data/ext/webrtcvad/webrtc/common_audio/signal_processing/dot_product_with_scale.h +40 -0
  5. data/ext/webrtcvad/webrtc/common_audio/signal_processing/energy.c +39 -0
  6. data/ext/webrtcvad/webrtc/common_audio/signal_processing/get_scaling_square.c +46 -0
  7. data/ext/webrtcvad/webrtc/common_audio/signal_processing/include/signal_processing_library.h +1605 -0
  8. data/ext/webrtcvad/webrtc/common_audio/signal_processing/include/spl_inl.h +153 -0
  9. data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_48khz.c +186 -0
  10. data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_by_2_internal.c +689 -0
  11. data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_by_2_internal.h +60 -0
  12. data/ext/webrtcvad/webrtc/common_audio/signal_processing/resample_fractional.c +239 -0
  13. data/ext/webrtcvad/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.c +77 -0
  14. data/ext/webrtcvad/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h +29 -0
  15. data/ext/webrtcvad/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor_mips.c +207 -0
  16. data/ext/webrtcvad/webrtc/common_audio/vad/include/webrtc_vad.h +87 -0
  17. data/ext/webrtcvad/webrtc/common_audio/vad/vad_core.c +685 -0
  18. data/ext/webrtcvad/webrtc/common_audio/vad/vad_core.h +114 -0
  19. data/ext/webrtcvad/webrtc/common_audio/vad/vad_filterbank.c +329 -0
  20. data/ext/webrtcvad/webrtc/common_audio/vad/vad_filterbank.h +45 -0
  21. data/ext/webrtcvad/webrtc/common_audio/vad/vad_gmm.c +82 -0
  22. data/ext/webrtcvad/webrtc/common_audio/vad/vad_gmm.h +39 -0
  23. data/ext/webrtcvad/webrtc/common_audio/vad/vad_sp.c +176 -0
  24. data/ext/webrtcvad/webrtc/common_audio/vad/vad_sp.h +54 -0
  25. data/ext/webrtcvad/webrtc/common_audio/vad/webrtc_vad.c +114 -0
  26. data/ext/webrtcvad/webrtc/rtc_base/checks.cc +207 -0
  27. data/ext/webrtcvad/webrtc/rtc_base/checks.h +400 -0
  28. data/ext/webrtcvad/webrtc/rtc_base/compile_assert_c.h +25 -0
  29. data/ext/webrtcvad/webrtc/rtc_base/numerics/safe_compare.h +176 -0
  30. data/ext/webrtcvad/webrtc/rtc_base/sanitizer.h +144 -0
  31. data/ext/webrtcvad/webrtc/rtc_base/system/inline.h +31 -0
  32. data/ext/webrtcvad/webrtc/rtc_base/system/rtc_export.h +43 -0
  33. data/ext/webrtcvad/webrtc/rtc_base/type_traits.h +140 -0
  34. data/ext/webrtcvad/webrtcvad.c +112 -0
  35. metadata +37 -3
@@ -0,0 +1,207 @@
1
+ /*
2
+ * Copyright 2006 The WebRTC Project Authors. All rights reserved.
3
+ *
4
+ * Use of this source code is governed by a BSD-style license
5
+ * that can be found in the LICENSE file in the root of the source
6
+ * tree. An additional intellectual property rights grant can be found
7
+ * in the file PATENTS. All contributing project authors may
8
+ * be found in the AUTHORS file in the root of the source tree.
9
+ */
10
+
11
+ // Most of this was borrowed (with minor modifications) from V8's and Chromium's
12
+ // src/base/logging.cc.
13
+
14
+ #include <cstdarg>
15
+ #include <cstdio>
16
+ #include <cstdlib>
17
+
18
+ #if defined(WEBRTC_ANDROID)
19
+ #define RTC_LOG_TAG_ANDROID "rtc"
20
+ #include <android/log.h> // NOLINT
21
+ #endif
22
+
23
+ #if defined(WEBRTC_WIN)
24
+ #include <windows.h>
25
+ #endif
26
+
27
+ #if defined(WEBRTC_WIN)
28
+ #define LAST_SYSTEM_ERROR (::GetLastError())
29
+ #elif defined(__native_client__) && __native_client__
30
+ #define LAST_SYSTEM_ERROR (0)
31
+ #elif defined(WEBRTC_POSIX)
32
+ #include <errno.h>
33
+ #define LAST_SYSTEM_ERROR (errno)
34
+ #endif // WEBRTC_WIN
35
+
36
+ #include "rtc_base/checks.h"
37
+
38
+ namespace {
39
+ #if defined(__GNUC__)
40
+ __attribute__((__format__(__printf__, 2, 3)))
41
+ #endif
42
+ void AppendFormat(std::string* s, const char* fmt, ...) {
43
+ va_list args, copy;
44
+ va_start(args, fmt);
45
+ va_copy(copy, args);
46
+ const int predicted_length = std::vsnprintf(nullptr, 0, fmt, copy);
47
+ va_end(copy);
48
+
49
+ if (predicted_length > 0) {
50
+ const size_t size = s->size();
51
+ s->resize(size + predicted_length);
52
+ // Pass "+ 1" to vsnprintf to include space for the '\0'.
53
+ std::vsnprintf(&((*s)[size]), predicted_length + 1, fmt, args);
54
+ }
55
+ va_end(args);
56
+ }
57
+ } // namespace
58
+
59
+ namespace rtc {
60
+ namespace webrtc_checks_impl {
61
+
62
+ #if RTC_CHECK_MSG_ENABLED
63
+ // Reads one argument from args, appends it to s and advances fmt.
64
+ // Returns true iff an argument was sucessfully parsed.
65
+ bool ParseArg(va_list* args, const CheckArgType** fmt, std::string* s) {
66
+ if (**fmt == CheckArgType::kEnd)
67
+ return false;
68
+
69
+ switch (**fmt) {
70
+ case CheckArgType::kInt:
71
+ AppendFormat(s, "%d", va_arg(*args, int));
72
+ break;
73
+ case CheckArgType::kLong:
74
+ AppendFormat(s, "%ld", va_arg(*args, long));
75
+ break;
76
+ case CheckArgType::kLongLong:
77
+ AppendFormat(s, "%lld", va_arg(*args, long long));
78
+ break;
79
+ case CheckArgType::kUInt:
80
+ AppendFormat(s, "%u", va_arg(*args, unsigned));
81
+ break;
82
+ case CheckArgType::kULong:
83
+ AppendFormat(s, "%lu", va_arg(*args, unsigned long));
84
+ break;
85
+ case CheckArgType::kULongLong:
86
+ AppendFormat(s, "%llu", va_arg(*args, unsigned long long));
87
+ break;
88
+ case CheckArgType::kDouble:
89
+ AppendFormat(s, "%g", va_arg(*args, double));
90
+ break;
91
+ case CheckArgType::kLongDouble:
92
+ AppendFormat(s, "%Lg", va_arg(*args, long double));
93
+ break;
94
+ case CheckArgType::kCharP:
95
+ s->append(va_arg(*args, const char*));
96
+ break;
97
+ case CheckArgType::kStdString:
98
+ s->append(*va_arg(*args, const std::string*));
99
+ break;
100
+ case CheckArgType::kStringView: {
101
+ const absl::string_view sv = *va_arg(*args, const absl::string_view*);
102
+ s->append(sv.data(), sv.size());
103
+ break;
104
+ }
105
+ case CheckArgType::kVoidP:
106
+ AppendFormat(s, "%p", va_arg(*args, const void*));
107
+ break;
108
+ default:
109
+ s->append("[Invalid CheckArgType]");
110
+ return false;
111
+ }
112
+ (*fmt)++;
113
+ return true;
114
+ }
115
+
116
+ RTC_NORETURN void FatalLog(const char* file,
117
+ int line,
118
+ const char* message,
119
+ const CheckArgType* fmt,
120
+ ...) {
121
+ va_list args;
122
+ va_start(args, fmt);
123
+
124
+ std::string s;
125
+ AppendFormat(&s,
126
+ "\n\n"
127
+ "#\n"
128
+ "# Fatal error in: %s, line %d\n"
129
+ "# last system error: %u\n"
130
+ "# Check failed: %s",
131
+ file, line, LAST_SYSTEM_ERROR, message);
132
+
133
+ if (*fmt == CheckArgType::kCheckOp) {
134
+ // This log message was generated by RTC_CHECK_OP, so we have to complete
135
+ // the error message using the operands that have been passed as the first
136
+ // two arguments.
137
+ fmt++;
138
+
139
+ std::string s1, s2;
140
+ if (ParseArg(&args, &fmt, &s1) && ParseArg(&args, &fmt, &s2))
141
+ AppendFormat(&s, " (%s vs. %s)\n# ", s1.c_str(), s2.c_str());
142
+ } else {
143
+ s.append("\n# ");
144
+ }
145
+
146
+ // Append all the user-supplied arguments to the message.
147
+ while (ParseArg(&args, &fmt, &s))
148
+ ;
149
+
150
+ va_end(args);
151
+
152
+ const char* output = s.c_str();
153
+
154
+ #if defined(WEBRTC_ANDROID)
155
+ __android_log_print(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, "%s\n", output);
156
+ #endif
157
+
158
+ fflush(stdout);
159
+ fprintf(stderr, "%s", output);
160
+ fflush(stderr);
161
+ #if defined(WEBRTC_WIN)
162
+ DebugBreak();
163
+ #endif
164
+ abort();
165
+ }
166
+ #else // RTC_CHECK_MSG_ENABLED
167
+ RTC_NORETURN void FatalLog(const char* file, int line) {
168
+ std::string s;
169
+ AppendFormat(&s,
170
+ "\n\n"
171
+ "#\n"
172
+ "# Fatal error in: %s, line %d\n"
173
+ "# last system error: %u\n"
174
+ "# Check failed.\n"
175
+ "# ",
176
+ file, line, LAST_SYSTEM_ERROR);
177
+ const char* output = s.c_str();
178
+
179
+ #if defined(WEBRTC_ANDROID)
180
+ __android_log_print(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, "%s\n", output);
181
+ #endif
182
+
183
+ fflush(stdout);
184
+ fprintf(stderr, "%s", output);
185
+ fflush(stderr);
186
+ #if defined(WEBRTC_WIN)
187
+ DebugBreak();
188
+ #endif
189
+ abort();
190
+ }
191
+ #endif // RTC_CHECK_MSG_ENABLED
192
+
193
+ } // namespace webrtc_checks_impl
194
+ } // namespace rtc
195
+
196
+ // Function to call from the C version of the RTC_CHECK and RTC_DCHECK macros.
197
+ RTC_NORETURN void rtc_FatalMessage(const char* file,
198
+ int line,
199
+ const char* msg) {
200
+ #if RTC_CHECK_MSG_ENABLED
201
+ static constexpr rtc::webrtc_checks_impl::CheckArgType t[] = {
202
+ rtc::webrtc_checks_impl::CheckArgType::kEnd};
203
+ rtc::webrtc_checks_impl::FatalLog(file, line, msg, t);
204
+ #else
205
+ rtc::webrtc_checks_impl::FatalLog(file, line);
206
+ #endif
207
+ }
@@ -0,0 +1,400 @@
1
+ /*
2
+ * Copyright 2006 The WebRTC Project Authors. All rights reserved.
3
+ *
4
+ * Use of this source code is governed by a BSD-style license
5
+ * that can be found in the LICENSE file in the root of the source
6
+ * tree. An additional intellectual property rights grant can be found
7
+ * in the file PATENTS. All contributing project authors may
8
+ * be found in the AUTHORS file in the root of the source tree.
9
+ */
10
+
11
+ #ifndef RTC_BASE_CHECKS_H_
12
+ #define RTC_BASE_CHECKS_H_
13
+
14
+ // If you for some reson need to know if DCHECKs are on, test the value of
15
+ // RTC_DCHECK_IS_ON. (Test its value, not if it's defined; it'll always be
16
+ // defined, to either a true or a false value.)
17
+ #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
18
+ #define RTC_DCHECK_IS_ON 1
19
+ #else
20
+ #define RTC_DCHECK_IS_ON 0
21
+ #endif
22
+
23
+ // Annotate a function that will not return control flow to the caller.
24
+ #if defined(_MSC_VER)
25
+ #define RTC_NORETURN __declspec(noreturn)
26
+ #elif defined(__GNUC__)
27
+ #define RTC_NORETURN __attribute__ ((__noreturn__))
28
+ #else
29
+ #define RTC_NORETURN
30
+ #endif
31
+
32
+ #ifdef __cplusplus
33
+ extern "C" {
34
+ #endif
35
+ RTC_NORETURN void rtc_FatalMessage(const char* file, int line, const char* msg);
36
+ #ifdef __cplusplus
37
+ } // extern "C"
38
+ #endif
39
+
40
+ #ifdef __cplusplus
41
+ // C++ version.
42
+
43
+ #include <string>
44
+
45
+ #include "webrtc/rtc_base/numerics/safe_compare.h"
46
+ #include "webrtc/rtc_base/system/inline.h"
47
+
48
+ // The macros here print a message to stderr and abort under various
49
+ // conditions. All will accept additional stream messages. For example:
50
+ // RTC_DCHECK_EQ(foo, bar) << "I'm printed when foo != bar.";
51
+ //
52
+ // - RTC_CHECK(x) is an assertion that x is always true, and that if it isn't,
53
+ // it's better to terminate the process than to continue. During development,
54
+ // the reason that it's better to terminate might simply be that the error
55
+ // handling code isn't in place yet; in production, the reason might be that
56
+ // the author of the code truly believes that x will always be true, but that
57
+ // she recognizes that if she is wrong, abrupt and unpleasant process
58
+ // termination is still better than carrying on with the assumption violated.
59
+ //
60
+ // RTC_CHECK always evaluates its argument, so it's OK for x to have side
61
+ // effects.
62
+ //
63
+ // - RTC_DCHECK(x) is the same as RTC_CHECK(x)---an assertion that x is always
64
+ // true---except that x will only be evaluated in debug builds; in production
65
+ // builds, x is simply assumed to be true. This is useful if evaluating x is
66
+ // expensive and the expected cost of failing to detect the violated
67
+ // assumption is acceptable. You should not handle cases where a production
68
+ // build fails to spot a violated condition, even those that would result in
69
+ // crashes. If the code needs to cope with the error, make it cope, but don't
70
+ // call RTC_DCHECK; if the condition really can't occur, but you'd sleep
71
+ // better at night knowing that the process will suicide instead of carrying
72
+ // on in case you were wrong, use RTC_CHECK instead of RTC_DCHECK.
73
+ //
74
+ // RTC_DCHECK only evaluates its argument in debug builds, so if x has visible
75
+ // side effects, you need to write e.g.
76
+ // bool w = x; RTC_DCHECK(w);
77
+ //
78
+ // - RTC_CHECK_EQ, _NE, _GT, ..., and RTC_DCHECK_EQ, _NE, _GT, ... are
79
+ // specialized variants of RTC_CHECK and RTC_DCHECK that print prettier
80
+ // messages if the condition doesn't hold. Prefer them to raw RTC_CHECK and
81
+ // RTC_DCHECK.
82
+ //
83
+ // - FATAL() aborts unconditionally.
84
+ //
85
+ // TODO(ajm): Ideally, checks.h would be combined with logging.h, but
86
+ // consolidation with system_wrappers/logging.h should happen first.
87
+
88
+ namespace rtc {
89
+ namespace webrtc_checks_impl {
90
+ enum class CheckArgType : int8_t {
91
+ kEnd = 0,
92
+ kInt,
93
+ kLong,
94
+ kLongLong,
95
+ kUInt,
96
+ kULong,
97
+ kULongLong,
98
+ kDouble,
99
+ kLongDouble,
100
+ kCharP,
101
+ kStdString,
102
+ kVoidP,
103
+
104
+ // kCheckOp doesn't represent an argument type. Instead, it is sent as the
105
+ // first argument from RTC_CHECK_OP to make FatalLog use the next two
106
+ // arguments to build the special CHECK_OP error message
107
+ // (the "a == b (1 vs. 2)" bit).
108
+ kCheckOp,
109
+ };
110
+
111
+ RTC_NORETURN void FatalLog(const char* file,
112
+ int line,
113
+ const char* message,
114
+ const CheckArgType* fmt,
115
+ ...);
116
+
117
+ // Wrapper for log arguments. Only ever make values of this type with the
118
+ // MakeVal() functions.
119
+ template <CheckArgType N, typename T>
120
+ struct Val {
121
+ static constexpr CheckArgType Type() { return N; }
122
+ T GetVal() const { return val; }
123
+ T val;
124
+ };
125
+
126
+ inline Val<CheckArgType::kInt, int> MakeVal(int x) {
127
+ return {x};
128
+ }
129
+ inline Val<CheckArgType::kLong, long> MakeVal(long x) {
130
+ return {x};
131
+ }
132
+ inline Val<CheckArgType::kLongLong, long long> MakeVal(long long x) {
133
+ return {x};
134
+ }
135
+ inline Val<CheckArgType::kUInt, unsigned int> MakeVal(unsigned int x) {
136
+ return {x};
137
+ }
138
+ inline Val<CheckArgType::kULong, unsigned long> MakeVal(unsigned long x) {
139
+ return {x};
140
+ }
141
+ inline Val<CheckArgType::kULongLong, unsigned long long> MakeVal(
142
+ unsigned long long x) {
143
+ return {x};
144
+ }
145
+
146
+ inline Val<CheckArgType::kDouble, double> MakeVal(double x) {
147
+ return {x};
148
+ }
149
+ inline Val<CheckArgType::kLongDouble, long double> MakeVal(long double x) {
150
+ return {x};
151
+ }
152
+
153
+ inline Val<CheckArgType::kCharP, const char*> MakeVal(const char* x) {
154
+ return {x};
155
+ }
156
+ inline Val<CheckArgType::kStdString, const std::string*> MakeVal(
157
+ const std::string& x) {
158
+ return {&x};
159
+ }
160
+
161
+ inline Val<CheckArgType::kVoidP, const void*> MakeVal(const void* x) {
162
+ return {x};
163
+ }
164
+
165
+ // Ephemeral type that represents the result of the logging << operator.
166
+ template <typename... Ts>
167
+ class LogStreamer;
168
+
169
+ // Base case: Before the first << argument.
170
+ template <>
171
+ class LogStreamer<> final {
172
+ public:
173
+ template <
174
+ typename U,
175
+ typename std::enable_if<std::is_arithmetic<U>::value>::type* = nullptr>
176
+ RTC_FORCE_INLINE LogStreamer<decltype(MakeVal(std::declval<U>()))> operator<<(
177
+ U arg) const {
178
+ return LogStreamer<decltype(MakeVal(std::declval<U>()))>(MakeVal(arg),
179
+ this);
180
+ }
181
+
182
+ template <
183
+ typename U,
184
+ typename std::enable_if<!std::is_arithmetic<U>::value>::type* = nullptr>
185
+ RTC_FORCE_INLINE LogStreamer<decltype(MakeVal(std::declval<U>()))> operator<<(
186
+ const U& arg) const {
187
+ return LogStreamer<decltype(MakeVal(std::declval<U>()))>(MakeVal(arg),
188
+ this);
189
+ }
190
+
191
+ template <typename... Us>
192
+ RTC_NORETURN RTC_FORCE_INLINE static void Call(const char* file,
193
+ const int line,
194
+ const char* message,
195
+ const Us&... args) {
196
+ static constexpr CheckArgType t[] = {Us::Type()..., CheckArgType::kEnd};
197
+ FatalLog(file, line, message, t, args.GetVal()...);
198
+ }
199
+
200
+ template <typename... Us>
201
+ RTC_NORETURN RTC_FORCE_INLINE static void CallCheckOp(const char* file,
202
+ const int line,
203
+ const char* message,
204
+ const Us&... args) {
205
+ static constexpr CheckArgType t[] = {CheckArgType::kCheckOp, Us::Type()...,
206
+ CheckArgType::kEnd};
207
+ FatalLog(file, line, message, t, args.GetVal()...);
208
+ }
209
+ };
210
+
211
+ // Inductive case: We've already seen at least one << argument. The most recent
212
+ // one had type `T`, and the earlier ones had types `Ts`.
213
+ template <typename T, typename... Ts>
214
+ class LogStreamer<T, Ts...> final {
215
+ public:
216
+ RTC_FORCE_INLINE LogStreamer(T arg, const LogStreamer<Ts...>* prior)
217
+ : arg_(arg), prior_(prior) {}
218
+
219
+ template <
220
+ typename U,
221
+ typename std::enable_if<std::is_arithmetic<U>::value>::type* = nullptr>
222
+ RTC_FORCE_INLINE LogStreamer<decltype(MakeVal(std::declval<U>())), T, Ts...>
223
+ operator<<(U arg) const {
224
+ return LogStreamer<decltype(MakeVal(std::declval<U>())), T, Ts...>(
225
+ MakeVal(arg), this);
226
+ }
227
+
228
+ template <
229
+ typename U,
230
+ typename std::enable_if<!std::is_arithmetic<U>::value>::type* = nullptr>
231
+ RTC_FORCE_INLINE LogStreamer<decltype(MakeVal(std::declval<U>())), T, Ts...>
232
+ operator<<(const U& arg) const {
233
+ return LogStreamer<decltype(MakeVal(std::declval<U>())), T, Ts...>(
234
+ MakeVal(arg), this);
235
+ }
236
+
237
+ template <typename... Us>
238
+ RTC_NORETURN RTC_FORCE_INLINE void Call(const char* file,
239
+ const int line,
240
+ const char* message,
241
+ const Us&... args) const {
242
+ prior_->Call(file, line, message, arg_, args...);
243
+ }
244
+
245
+ template <typename... Us>
246
+ RTC_NORETURN RTC_FORCE_INLINE void CallCheckOp(const char* file,
247
+ const int line,
248
+ const char* message,
249
+ const Us&... args) const {
250
+ prior_->CallCheckOp(file, line, message, arg_, args...);
251
+ }
252
+
253
+ private:
254
+ // The most recent argument.
255
+ T arg_;
256
+
257
+ // Earlier arguments.
258
+ const LogStreamer<Ts...>* prior_;
259
+ };
260
+
261
+ template <bool isCheckOp>
262
+ class FatalLogCall final {
263
+ public:
264
+ FatalLogCall(const char* file, int line, const char* message)
265
+ : file_(file), line_(line), message_(message) {}
266
+
267
+ // This can be any binary operator with precedence lower than <<.
268
+ template <typename... Ts>
269
+ RTC_NORETURN RTC_FORCE_INLINE void operator&(
270
+ const LogStreamer<Ts...>& streamer) {
271
+ isCheckOp ? streamer.CallCheckOp(file_, line_, message_)
272
+ : streamer.Call(file_, line_, message_);
273
+ }
274
+
275
+ private:
276
+ const char* file_;
277
+ int line_;
278
+ const char* message_;
279
+ };
280
+ } // namespace webrtc_checks_impl
281
+
282
+ // The actual stream used isn't important. We reference |ignored| in the code
283
+ // but don't evaluate it; this is to avoid "unused variable" warnings (we do so
284
+ // in a particularly convoluted way with an extra ?: because that appears to be
285
+ // the simplest construct that keeps Visual Studio from complaining about
286
+ // condition being unused).
287
+ #define RTC_EAT_STREAM_PARAMETERS(ignored) \
288
+ (true ? true : ((void)(ignored), true)) \
289
+ ? static_cast<void>(0) \
290
+ : rtc::webrtc_checks_impl::FatalLogCall<false>("", 0, "") & \
291
+ rtc::webrtc_checks_impl::LogStreamer<>()
292
+
293
+ // Call RTC_EAT_STREAM_PARAMETERS with an argument that fails to compile if
294
+ // values of the same types as |a| and |b| can't be compared with the given
295
+ // operation, and that would evaluate |a| and |b| if evaluated.
296
+ #define RTC_EAT_STREAM_PARAMETERS_OP(op, a, b) \
297
+ RTC_EAT_STREAM_PARAMETERS(((void)rtc::Safe##op(a, b)))
298
+
299
+ // RTC_CHECK dies with a fatal error if condition is not true. It is *not*
300
+ // controlled by NDEBUG or anything else, so the check will be executed
301
+ // regardless of compilation mode.
302
+ //
303
+ // We make sure RTC_CHECK et al. always evaluates |condition|, as
304
+ // doing RTC_CHECK(FunctionWithSideEffect()) is a common idiom.
305
+ #define RTC_CHECK(condition) \
306
+ while (!(condition)) \
307
+ rtc::webrtc_checks_impl::FatalLogCall<false>(__FILE__, __LINE__, \
308
+ #condition) & \
309
+ rtc::webrtc_checks_impl::LogStreamer<>()
310
+
311
+ // Helper macro for binary operators.
312
+ // Don't use this macro directly in your code, use RTC_CHECK_EQ et al below.
313
+ #define RTC_CHECK_OP(name, op, val1, val2) \
314
+ while (!rtc::Safe##name((val1), (val2))) \
315
+ rtc::webrtc_checks_impl::FatalLogCall<true>(__FILE__, __LINE__, \
316
+ #val1 " " #op " " #val2) & \
317
+ rtc::webrtc_checks_impl::LogStreamer<>() << (val1) << (val2)
318
+
319
+ #define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(Eq, ==, val1, val2)
320
+ #define RTC_CHECK_NE(val1, val2) RTC_CHECK_OP(Ne, !=, val1, val2)
321
+ #define RTC_CHECK_LE(val1, val2) RTC_CHECK_OP(Le, <=, val1, val2)
322
+ #define RTC_CHECK_LT(val1, val2) RTC_CHECK_OP(Lt, <, val1, val2)
323
+ #define RTC_CHECK_GE(val1, val2) RTC_CHECK_OP(Ge, >=, val1, val2)
324
+ #define RTC_CHECK_GT(val1, val2) RTC_CHECK_OP(Gt, >, val1, val2)
325
+
326
+ // The RTC_DCHECK macro is equivalent to RTC_CHECK except that it only generates
327
+ // code in debug builds. It does reference the condition parameter in all cases,
328
+ // though, so callers won't risk getting warnings about unused variables.
329
+ #if RTC_DCHECK_IS_ON
330
+ #define RTC_DCHECK(condition) RTC_CHECK(condition)
331
+ #define RTC_DCHECK_EQ(v1, v2) RTC_CHECK_EQ(v1, v2)
332
+ #define RTC_DCHECK_NE(v1, v2) RTC_CHECK_NE(v1, v2)
333
+ #define RTC_DCHECK_LE(v1, v2) RTC_CHECK_LE(v1, v2)
334
+ #define RTC_DCHECK_LT(v1, v2) RTC_CHECK_LT(v1, v2)
335
+ #define RTC_DCHECK_GE(v1, v2) RTC_CHECK_GE(v1, v2)
336
+ #define RTC_DCHECK_GT(v1, v2) RTC_CHECK_GT(v1, v2)
337
+ #else
338
+ #define RTC_DCHECK(condition) RTC_EAT_STREAM_PARAMETERS(condition)
339
+ #define RTC_DCHECK_EQ(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Eq, v1, v2)
340
+ #define RTC_DCHECK_NE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ne, v1, v2)
341
+ #define RTC_DCHECK_LE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Le, v1, v2)
342
+ #define RTC_DCHECK_LT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Lt, v1, v2)
343
+ #define RTC_DCHECK_GE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ge, v1, v2)
344
+ #define RTC_DCHECK_GT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Gt, v1, v2)
345
+ #endif
346
+
347
+ #define RTC_UNREACHABLE_CODE_HIT false
348
+ #define RTC_NOTREACHED() RTC_DCHECK(RTC_UNREACHABLE_CODE_HIT)
349
+
350
+ // TODO(bugs.webrtc.org/8454): Add an RTC_ prefix or rename differently.
351
+ #define FATAL() \
352
+ rtc::webrtc_checks_impl::FatalLogCall<false>(__FILE__, __LINE__, \
353
+ "FATAL()") & \
354
+ rtc::webrtc_checks_impl::LogStreamer<>()
355
+
356
+ // Performs the integer division a/b and returns the result. CHECKs that the
357
+ // remainder is zero.
358
+ template <typename T>
359
+ inline T CheckedDivExact(T a, T b) {
360
+ RTC_CHECK_EQ(a % b, 0) << a << " is not evenly divisible by " << b;
361
+ return a / b;
362
+ }
363
+
364
+ } // namespace rtc
365
+
366
+ #else // __cplusplus not defined
367
+ // C version. Lacks many features compared to the C++ version, but usage
368
+ // guidelines are the same.
369
+
370
+ #define RTC_CHECK(condition) \
371
+ do { \
372
+ if (!(condition)) { \
373
+ rtc_FatalMessage(__FILE__, __LINE__, "CHECK failed: " #condition); \
374
+ } \
375
+ } while (0)
376
+
377
+ #define RTC_CHECK_EQ(a, b) RTC_CHECK((a) == (b))
378
+ #define RTC_CHECK_NE(a, b) RTC_CHECK((a) != (b))
379
+ #define RTC_CHECK_LE(a, b) RTC_CHECK((a) <= (b))
380
+ #define RTC_CHECK_LT(a, b) RTC_CHECK((a) < (b))
381
+ #define RTC_CHECK_GE(a, b) RTC_CHECK((a) >= (b))
382
+ #define RTC_CHECK_GT(a, b) RTC_CHECK((a) > (b))
383
+
384
+ #define RTC_DCHECK(condition) \
385
+ do { \
386
+ if (RTC_DCHECK_IS_ON && !(condition)) { \
387
+ rtc_FatalMessage(__FILE__, __LINE__, "DCHECK failed: " #condition); \
388
+ } \
389
+ } while (0)
390
+
391
+ #define RTC_DCHECK_EQ(a, b) RTC_DCHECK((a) == (b))
392
+ #define RTC_DCHECK_NE(a, b) RTC_DCHECK((a) != (b))
393
+ #define RTC_DCHECK_LE(a, b) RTC_DCHECK((a) <= (b))
394
+ #define RTC_DCHECK_LT(a, b) RTC_DCHECK((a) < (b))
395
+ #define RTC_DCHECK_GE(a, b) RTC_DCHECK((a) >= (b))
396
+ #define RTC_DCHECK_GT(a, b) RTC_DCHECK((a) > (b))
397
+
398
+ #endif // __cplusplus
399
+
400
+ #endif // RTC_BASE_CHECKS_H_