Skip to content

Commit

Permalink
DMIC: Add min/max, ceil divide, find number, and normalize utils
Browse files Browse the repository at this point in the history
Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
  • Loading branch information
singalsu authored and lrgirdwo committed May 7, 2018
1 parent 8848856 commit ea5f722
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/include/sof/math/numbers.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,29 @@
#ifndef NUMBERS_H
#define NUMBERS_H

#include <stdint.h>

#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

int gcd(int a, int b); /* Calculate greatest common divisor for a and b */

/* Divide function that returns ceil() of quotient */
int ceil_divide(int a, int b);

/* Find indices of equal values in a vector of integer values */
int find_equal_int16(int16_t idx[], int16_t vec[], int n, int vec_length,
int max_results);

/* Return the smallest value found in a vector */
int16_t find_min_int16(int16_t vec[], int vec_length);

/* Return the largest absolute value found in a vector */
int32_t find_max_abs_int32(int32_t vec[], int vec_length);

/* Count the left shift amount to normalize a 32 bit signed integer value
* without causing overflow. Input value 0 will result to 31.
*/
int norm_int32(int32_t val);

#endif /* NUMBERS_H */
96 changes: 96 additions & 0 deletions src/math/numbers.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
*/

#include <sof/math/numbers.h>
#include <sof/audio/format.h>

int gcd(int a, int b)
{
Expand All @@ -47,3 +48,98 @@ int gcd(int a, int b)
}
return a;
}

/* This is a divide function that returns ceil of the quotient.
* E.g. ceil_divide(9, 3) returns 3, ceil_divide(10, 3) returns 4.
*/
int ceil_divide(int a, int b)
{
int c;

c = a / b;
if (c * b < a)
c++;

return c;
}

/* This function searches from vec[] (of length vec_length) integer values
* of n. The indexes to equal values is returned in idx[]. The function
* returns the number of found matches. The max_results should be set to
* 0 (or negative) or vec_length get all the matches. The max_result can be set
* to 1 to receive only the first match in ascending order. It avoids need
* for an array for idx.
*/
int find_equal_int16(int16_t idx[], int16_t vec[], int n, int vec_length,
int max_results)
{
int nresults = 0;
int i;

for (i = 0; i < vec_length; i++) {
if (vec[i] == n) {
idx[nresults++] = i;
if (nresults == max_results)
break;
}
}

return nresults;
}

/* Return the smallest value found in the vector */
int16_t find_min_int16(int16_t vec[], int vec_length)
{
int i;
int min = vec[0];

for (i = 1; i < vec_length; i++)
min = (vec[i] < min) ? vec[i] : min;

return min;
}

/* Return the largest absolute value found in the vector. Note that
* smallest negative value need to be saturated to preset as int32_t.
*/
int32_t find_max_abs_int32(int32_t vec[], int vec_length)
{
int i;
int64_t amax = (vec[0] > 0) ? vec[0] : -vec[0];

for (i = 1; i < vec_length; i++) {
amax = (vec[i] > amax) ? vec[i] : amax;
amax = (-vec[i] > amax) ? -vec[i] : amax;
}

return SATP_INT32(amax); /* Amax is always a positive value */
}

/* Count the left shift amount to normalize a 32 bit signed integer value
* without causing overflow. Input value 0 will result to 31.
*/
int norm_int32(int32_t val)
{
int s;
int32_t n;

if (!val)
return 31;

if (val > 0) {
n = val << 1;
s = 0;
while (n > 0) {
n = n << 1;
s++;
}
} else {
n = val << 1;
s = 0;
while (n < 0) {
n = n << 1;
s++;
}
}
return s;
}

0 comments on commit ea5f722

Please sign in to comment.