blob: 1b9542e7ef7a2059a09be556057ef76e175fdaf8 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
kma@webrtc.orgbeb18512012-03-01 20:03:26 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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/*
12 * This file contains the implementation of functions
kma@webrtc.org0221b782012-09-08 00:09:26 +000013 * WebRtcSpl_MaxAbsValueW16C()
14 * WebRtcSpl_MaxAbsValueW32C()
15 * WebRtcSpl_MaxValueW16C()
16 * WebRtcSpl_MaxValueW32C()
17 * WebRtcSpl_MinValueW16C()
18 * WebRtcSpl_MinValueW32C()
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000019 * WebRtcSpl_MaxAbsIndexW16()
20 * WebRtcSpl_MaxIndexW16()
21 * WebRtcSpl_MaxIndexW32()
22 * WebRtcSpl_MinIndexW16()
niklase@google.com470e71d2011-07-07 08:21:25 +000023 * WebRtcSpl_MinIndexW32()
24 *
niklase@google.com470e71d2011-07-07 08:21:25 +000025 */
26
kma@webrtc.orgbeb18512012-03-01 20:03:26 +000027#include <stdlib.h>
28
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "rtc_base/checks.h"
30#include "common_audio/signal_processing/include/signal_processing_library.h"
Peter Kasting1380e262015-08-28 17:31:03 -070031
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000032// TODO(bjorn/kma): Consolidate function pairs (e.g. combine
kma@webrtc.org0221b782012-09-08 00:09:26 +000033// WebRtcSpl_MaxAbsValueW16C and WebRtcSpl_MaxAbsIndexW16 into a single one.)
34// TODO(kma): Move the next six functions into min_max_operations_c.c.
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000035
kma@webrtc.org0221b782012-09-08 00:09:26 +000036// Maximum absolute value of word16 vector. C version for generic platforms.
Peter Kastingdce40cf2015-08-24 14:52:23 -070037int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t* vector, size_t length) {
38 size_t i = 0;
39 int absolute = 0, maximum = 0;
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000040
kwiberg1e8ed4a2016-08-26 04:33:34 -070041 RTC_DCHECK_GT(length, 0);
niklase@google.com470e71d2011-07-07 08:21:25 +000042
kma@webrtc.orgbeb18512012-03-01 20:03:26 +000043 for (i = 0; i < length; i++) {
44 absolute = abs((int)vector[i]);
45
46 if (absolute > maximum) {
47 maximum = absolute;
niklase@google.com470e71d2011-07-07 08:21:25 +000048 }
kma@webrtc.orgbeb18512012-03-01 20:03:26 +000049 }
50
51 // Guard the case for abs(-32768).
52 if (maximum > WEBRTC_SPL_WORD16_MAX) {
53 maximum = WEBRTC_SPL_WORD16_MAX;
54 }
55
56 return (int16_t)maximum;
niklase@google.com470e71d2011-07-07 08:21:25 +000057}
58
kma@webrtc.org0221b782012-09-08 00:09:26 +000059// Maximum absolute value of word32 vector. C version for generic platforms.
Peter Kastingdce40cf2015-08-24 14:52:23 -070060int32_t WebRtcSpl_MaxAbsValueW32C(const int32_t* vector, size_t length) {
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000061 // Use uint32_t for the local variables, to accommodate the return value
62 // of abs(0x80000000), which is 0x80000000.
kma@webrtc.org95c3d402012-04-02 03:55:20 +000063
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000064 uint32_t absolute = 0, maximum = 0;
Peter Kastingdce40cf2015-08-24 14:52:23 -070065 size_t i = 0;
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000066
kwiberg1e8ed4a2016-08-26 04:33:34 -070067 RTC_DCHECK_GT(length, 0);
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000068
69 for (i = 0; i < length; i++) {
70 absolute = abs((int)vector[i]);
71 if (absolute > maximum) {
72 maximum = absolute;
henrika@webrtc.orgafedb632012-04-02 07:12:08 +000073 }
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000074 }
75
76 maximum = WEBRTC_SPL_MIN(maximum, WEBRTC_SPL_WORD32_MAX);
77
78 return (int32_t)maximum;
niklase@google.com470e71d2011-07-07 08:21:25 +000079}
80
kma@webrtc.org0221b782012-09-08 00:09:26 +000081// Maximum value of word16 vector. C version for generic platforms.
Peter Kastingdce40cf2015-08-24 14:52:23 -070082int16_t WebRtcSpl_MaxValueW16C(const int16_t* vector, size_t length) {
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000083 int16_t maximum = WEBRTC_SPL_WORD16_MIN;
Peter Kastingdce40cf2015-08-24 14:52:23 -070084 size_t i = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000085
kwiberg1e8ed4a2016-08-26 04:33:34 -070086 RTC_DCHECK_GT(length, 0);
henrika@webrtc.orgafedb632012-04-02 07:12:08 +000087
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000088 for (i = 0; i < length; i++) {
89 if (vector[i] > maximum)
90 maximum = vector[i];
91 }
92 return maximum;
henrika@webrtc.orgafedb632012-04-02 07:12:08 +000093}
94
kma@webrtc.org0221b782012-09-08 00:09:26 +000095// Maximum value of word32 vector. C version for generic platforms.
Peter Kastingdce40cf2015-08-24 14:52:23 -070096int32_t WebRtcSpl_MaxValueW32C(const int32_t* vector, size_t length) {
kma@webrtc.org33ced9c2012-04-11 17:40:40 +000097 int32_t maximum = WEBRTC_SPL_WORD32_MIN;
Peter Kastingdce40cf2015-08-24 14:52:23 -070098 size_t i = 0;
henrika@webrtc.orgafedb632012-04-02 07:12:08 +000099
kwiberg1e8ed4a2016-08-26 04:33:34 -0700100 RTC_DCHECK_GT(length, 0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000101
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000102 for (i = 0; i < length; i++) {
103 if (vector[i] > maximum)
104 maximum = vector[i];
105 }
106 return maximum;
henrika@webrtc.orgafedb632012-04-02 07:12:08 +0000107}
kma@webrtc.org95c3d402012-04-02 03:55:20 +0000108
kma@webrtc.org0221b782012-09-08 00:09:26 +0000109// Minimum value of word16 vector. C version for generic platforms.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700110int16_t WebRtcSpl_MinValueW16C(const int16_t* vector, size_t length) {
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000111 int16_t minimum = WEBRTC_SPL_WORD16_MAX;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700112 size_t i = 0;
henrika@webrtc.orgafedb632012-04-02 07:12:08 +0000113
kwiberg1e8ed4a2016-08-26 04:33:34 -0700114 RTC_DCHECK_GT(length, 0);
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000115
116 for (i = 0; i < length; i++) {
117 if (vector[i] < minimum)
118 minimum = vector[i];
119 }
120 return minimum;
121}
122
kma@webrtc.org0221b782012-09-08 00:09:26 +0000123// Minimum value of word32 vector. C version for generic platforms.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700124int32_t WebRtcSpl_MinValueW32C(const int32_t* vector, size_t length) {
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000125 int32_t minimum = WEBRTC_SPL_WORD32_MAX;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700126 size_t i = 0;
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000127
kwiberg1e8ed4a2016-08-26 04:33:34 -0700128 RTC_DCHECK_GT(length, 0);
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000129
130 for (i = 0; i < length; i++) {
131 if (vector[i] < minimum)
132 minimum = vector[i];
133 }
134 return minimum;
135}
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000136
137// Index of maximum absolute value in a word16 vector.
Peter Kasting1380e262015-08-28 17:31:03 -0700138size_t WebRtcSpl_MaxAbsIndexW16(const int16_t* vector, size_t length) {
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000139 // Use type int for local variables, to accomodate the value of abs(-32768).
140
Peter Kastingdce40cf2015-08-24 14:52:23 -0700141 size_t i = 0, index = 0;
142 int absolute = 0, maximum = 0;
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000143
kwiberg1e8ed4a2016-08-26 04:33:34 -0700144 RTC_DCHECK_GT(length, 0);
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000145
146 for (i = 0; i < length; i++) {
147 absolute = abs((int)vector[i]);
148
149 if (absolute > maximum) {
150 maximum = absolute;
151 index = i;
henrika@webrtc.orgafedb632012-04-02 07:12:08 +0000152 }
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000153 }
154
Peter Kasting1380e262015-08-28 17:31:03 -0700155 return index;
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000156}
157
Ivo Creusen6031b742021-01-20 16:26:43 +0100158int16_t WebRtcSpl_MaxAbsElementW16(const int16_t* vector, size_t length) {
159 int16_t min_val, max_val;
160 WebRtcSpl_MinMaxW16(vector, length, &min_val, &max_val);
161 if (min_val == max_val || min_val < -max_val) {
162 return min_val;
163 }
164 return max_val;
165}
166
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000167// Index of maximum value in a word16 vector.
Peter Kasting1380e262015-08-28 17:31:03 -0700168size_t WebRtcSpl_MaxIndexW16(const int16_t* vector, size_t length) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700169 size_t i = 0, index = 0;
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000170 int16_t maximum = WEBRTC_SPL_WORD16_MIN;
171
kwiberg1e8ed4a2016-08-26 04:33:34 -0700172 RTC_DCHECK_GT(length, 0);
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000173
174 for (i = 0; i < length; i++) {
175 if (vector[i] > maximum) {
176 maximum = vector[i];
177 index = i;
178 }
179 }
180
Peter Kasting1380e262015-08-28 17:31:03 -0700181 return index;
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000182}
183
184// Index of maximum value in a word32 vector.
Peter Kasting1380e262015-08-28 17:31:03 -0700185size_t WebRtcSpl_MaxIndexW32(const int32_t* vector, size_t length) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700186 size_t i = 0, index = 0;
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000187 int32_t maximum = WEBRTC_SPL_WORD32_MIN;
188
kwiberg1e8ed4a2016-08-26 04:33:34 -0700189 RTC_DCHECK_GT(length, 0);
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000190
191 for (i = 0; i < length; i++) {
192 if (vector[i] > maximum) {
193 maximum = vector[i];
194 index = i;
195 }
196 }
197
Peter Kasting1380e262015-08-28 17:31:03 -0700198 return index;
niklase@google.com470e71d2011-07-07 08:21:25 +0000199}
200
201// Index of minimum value in a word16 vector.
Peter Kasting1380e262015-08-28 17:31:03 -0700202size_t WebRtcSpl_MinIndexW16(const int16_t* vector, size_t length) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700203 size_t i = 0, index = 0;
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000204 int16_t minimum = WEBRTC_SPL_WORD16_MAX;
niklase@google.com470e71d2011-07-07 08:21:25 +0000205
kwiberg1e8ed4a2016-08-26 04:33:34 -0700206 RTC_DCHECK_GT(length, 0);
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000207
208 for (i = 0; i < length; i++) {
209 if (vector[i] < minimum) {
210 minimum = vector[i];
211 index = i;
niklase@google.com470e71d2011-07-07 08:21:25 +0000212 }
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000213 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000214
Peter Kasting1380e262015-08-28 17:31:03 -0700215 return index;
niklase@google.com470e71d2011-07-07 08:21:25 +0000216}
217
218// Index of minimum value in a word32 vector.
Peter Kasting1380e262015-08-28 17:31:03 -0700219size_t WebRtcSpl_MinIndexW32(const int32_t* vector, size_t length) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700220 size_t i = 0, index = 0;
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000221 int32_t minimum = WEBRTC_SPL_WORD32_MAX;
niklase@google.com470e71d2011-07-07 08:21:25 +0000222
kwiberg1e8ed4a2016-08-26 04:33:34 -0700223 RTC_DCHECK_GT(length, 0);
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000224
225 for (i = 0; i < length; i++) {
226 if (vector[i] < minimum) {
227 minimum = vector[i];
228 index = i;
niklase@google.com470e71d2011-07-07 08:21:25 +0000229 }
kma@webrtc.org33ced9c2012-04-11 17:40:40 +0000230 }
231
Peter Kasting1380e262015-08-28 17:31:03 -0700232 return index;
niklase@google.com470e71d2011-07-07 08:21:25 +0000233}
Ivo Creusen6031b742021-01-20 16:26:43 +0100234
235// Finds both the minimum and maximum elements in an array of 16-bit integers.
236void WebRtcSpl_MinMaxW16(const int16_t* vector, size_t length,
237 int16_t* min_val, int16_t* max_val) {
238#if defined(WEBRTC_HAS_NEON)
239 return WebRtcSpl_MinMaxW16Neon(vector, length, min_val, max_val);
240#else
241 int16_t minimum = WEBRTC_SPL_WORD16_MAX;
242 int16_t maximum = WEBRTC_SPL_WORD16_MIN;
243 size_t i = 0;
244
245 RTC_DCHECK_GT(length, 0);
246
247 for (i = 0; i < length; i++) {
248 if (vector[i] < minimum)
249 minimum = vector[i];
250 if (vector[i] > maximum)
251 maximum = vector[i];
252 }
253 *min_val = minimum;
254 *max_val = maximum;
255#endif
256}