webrtcvad 0.1.0 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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_