1c55a96383497a772a307b346368133960b02ad03Eric Laurent/*
2c55a96383497a772a307b346368133960b02ad03Eric Laurent *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3c55a96383497a772a307b346368133960b02ad03Eric Laurent *
4c55a96383497a772a307b346368133960b02ad03Eric Laurent *  Use of this source code is governed by a BSD-style license
5c55a96383497a772a307b346368133960b02ad03Eric Laurent *  that can be found in the LICENSE file in the root of the source
6c55a96383497a772a307b346368133960b02ad03Eric Laurent *  tree. An additional intellectual property rights grant can be found
7c55a96383497a772a307b346368133960b02ad03Eric Laurent *  in the file PATENTS.  All contributing project authors may
8c55a96383497a772a307b346368133960b02ad03Eric Laurent *  be found in the AUTHORS file in the root of the source tree.
9c55a96383497a772a307b346368133960b02ad03Eric Laurent */
10c55a96383497a772a307b346368133960b02ad03Eric Laurent
11c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "vad_sp.h"
12c55a96383497a772a307b346368133960b02ad03Eric Laurent
13c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <assert.h>
14c55a96383497a772a307b346368133960b02ad03Eric Laurent
15c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "signal_processing_library.h"
16c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "typedefs.h"
17c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "vad_defines.h"
18c55a96383497a772a307b346368133960b02ad03Eric Laurent
19c55a96383497a772a307b346368133960b02ad03Eric Laurent// Allpass filter coefficients, upper and lower, in Q13.
20c55a96383497a772a307b346368133960b02ad03Eric Laurent// Upper: 0.64, Lower: 0.17.
21c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic const int16_t kAllPassCoefsQ13[2] = { 5243, 1392 };  // Q13
22c55a96383497a772a307b346368133960b02ad03Eric Laurent
23c55a96383497a772a307b346368133960b02ad03Eric Laurent// TODO(bjornv): Move this function to vad_filterbank.c.
24c55a96383497a772a307b346368133960b02ad03Eric Laurent// Downsampling filter based on splitting filter and allpass functions.
25c55a96383497a772a307b346368133960b02ad03Eric Laurentvoid WebRtcVad_Downsampling(int16_t* signal_in,
26c55a96383497a772a307b346368133960b02ad03Eric Laurent                            int16_t* signal_out,
27c55a96383497a772a307b346368133960b02ad03Eric Laurent                            int32_t* filter_state,
28c55a96383497a772a307b346368133960b02ad03Eric Laurent                            int in_length) {
29c55a96383497a772a307b346368133960b02ad03Eric Laurent  int16_t tmp16_1 = 0, tmp16_2 = 0;
30c55a96383497a772a307b346368133960b02ad03Eric Laurent  int32_t tmp32_1 = filter_state[0];
31c55a96383497a772a307b346368133960b02ad03Eric Laurent  int32_t tmp32_2 = filter_state[1];
32c55a96383497a772a307b346368133960b02ad03Eric Laurent  int n = 0;
33c55a96383497a772a307b346368133960b02ad03Eric Laurent  int half_length = (in_length >> 1);  // Downsampling by 2 gives half length.
34c55a96383497a772a307b346368133960b02ad03Eric Laurent
35c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Filter coefficients in Q13, filter state in Q0.
36c55a96383497a772a307b346368133960b02ad03Eric Laurent  for (n = 0; n < half_length; n++) {
37c55a96383497a772a307b346368133960b02ad03Eric Laurent    // All-pass filtering upper branch.
38c55a96383497a772a307b346368133960b02ad03Eric Laurent    tmp16_1 = (int16_t) ((tmp32_1 >> 1) +
39c55a96383497a772a307b346368133960b02ad03Eric Laurent        WEBRTC_SPL_MUL_16_16_RSFT(kAllPassCoefsQ13[0], *signal_in, 14));
40c55a96383497a772a307b346368133960b02ad03Eric Laurent    *signal_out = tmp16_1;
41c55a96383497a772a307b346368133960b02ad03Eric Laurent    tmp32_1 = (int32_t) (*signal_in++) -
42c55a96383497a772a307b346368133960b02ad03Eric Laurent        WEBRTC_SPL_MUL_16_16_RSFT(kAllPassCoefsQ13[0], tmp16_1, 12);
43c55a96383497a772a307b346368133960b02ad03Eric Laurent
44c55a96383497a772a307b346368133960b02ad03Eric Laurent    // All-pass filtering lower branch.
45c55a96383497a772a307b346368133960b02ad03Eric Laurent    tmp16_2 = (int16_t) ((tmp32_2 >> 1) +
46c55a96383497a772a307b346368133960b02ad03Eric Laurent        WEBRTC_SPL_MUL_16_16_RSFT(kAllPassCoefsQ13[1], *signal_in, 14));
47c55a96383497a772a307b346368133960b02ad03Eric Laurent    *signal_out++ += tmp16_2;
48c55a96383497a772a307b346368133960b02ad03Eric Laurent    tmp32_2 = (int32_t) (*signal_in++) -
49c55a96383497a772a307b346368133960b02ad03Eric Laurent        WEBRTC_SPL_MUL_16_16_RSFT(kAllPassCoefsQ13[1], tmp16_2, 12);
50c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
51c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Store the filter states.
52c55a96383497a772a307b346368133960b02ad03Eric Laurent  filter_state[0] = tmp32_1;
53c55a96383497a772a307b346368133960b02ad03Eric Laurent  filter_state[1] = tmp32_2;
54c55a96383497a772a307b346368133960b02ad03Eric Laurent}
55c55a96383497a772a307b346368133960b02ad03Eric Laurent
56c55a96383497a772a307b346368133960b02ad03Eric Laurent// Inserts |feature_value| into |low_value_vector|, if it is one of the 16
57c55a96383497a772a307b346368133960b02ad03Eric Laurent// smallest values the last 100 frames. Then calculates and returns the median
58c55a96383497a772a307b346368133960b02ad03Eric Laurent// of the five smallest values.
59c55a96383497a772a307b346368133960b02ad03Eric Laurentint16_t WebRtcVad_FindMinimum(VadInstT* self,
60c55a96383497a772a307b346368133960b02ad03Eric Laurent                              int16_t feature_value,
61c55a96383497a772a307b346368133960b02ad03Eric Laurent                              int channel) {
62c55a96383497a772a307b346368133960b02ad03Eric Laurent  int i = 0, j = 0;
63c55a96383497a772a307b346368133960b02ad03Eric Laurent  int position = -1;
64c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Offset to beginning of the 16 minimum values in memory.
65c55a96383497a772a307b346368133960b02ad03Eric Laurent  int offset = (channel << 4);
66c55a96383497a772a307b346368133960b02ad03Eric Laurent  int16_t current_median = 1600;
67c55a96383497a772a307b346368133960b02ad03Eric Laurent  int16_t alpha = 0;
68c55a96383497a772a307b346368133960b02ad03Eric Laurent  int32_t tmp32 = 0;
69c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Pointer to memory for the 16 minimum values and the age of each value of
70c55a96383497a772a307b346368133960b02ad03Eric Laurent  // the |channel|.
71c55a96383497a772a307b346368133960b02ad03Eric Laurent  int16_t* age_ptr = &self->index_vector[offset];
72c55a96383497a772a307b346368133960b02ad03Eric Laurent  int16_t* value_ptr = &self->low_value_vector[offset];
73c55a96383497a772a307b346368133960b02ad03Eric Laurent  int16_t *p1, *p2, *p3;
74c55a96383497a772a307b346368133960b02ad03Eric Laurent
75c55a96383497a772a307b346368133960b02ad03Eric Laurent  assert(channel < NUM_CHANNELS);
76c55a96383497a772a307b346368133960b02ad03Eric Laurent
77c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Each value in |low_value_vector| is getting 1 loop older.
78c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Update age of each value in |age_ptr|, and remove old values.
79c55a96383497a772a307b346368133960b02ad03Eric Laurent  for (i = 0; i < 16; i++) {
80c55a96383497a772a307b346368133960b02ad03Eric Laurent    p3 = age_ptr + i;
81c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (*p3 != 100) {
82c55a96383497a772a307b346368133960b02ad03Eric Laurent      *p3 += 1;
83c55a96383497a772a307b346368133960b02ad03Eric Laurent    } else {
84c55a96383497a772a307b346368133960b02ad03Eric Laurent      p1 = value_ptr + i + 1;
85c55a96383497a772a307b346368133960b02ad03Eric Laurent      p2 = p3 + 1;
86c55a96383497a772a307b346368133960b02ad03Eric Laurent      for (j = i; j < 16; j++) {
87c55a96383497a772a307b346368133960b02ad03Eric Laurent        *(value_ptr + j) = *p1++;
88c55a96383497a772a307b346368133960b02ad03Eric Laurent        *(age_ptr + j) = *p2++;
89c55a96383497a772a307b346368133960b02ad03Eric Laurent      }
90c55a96383497a772a307b346368133960b02ad03Eric Laurent      *(age_ptr + 15) = 101;
91c55a96383497a772a307b346368133960b02ad03Eric Laurent      *(value_ptr + 15) = 10000;
92c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
93c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
94c55a96383497a772a307b346368133960b02ad03Eric Laurent
95c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Check if |feature_value| is smaller than any of the values in
96c55a96383497a772a307b346368133960b02ad03Eric Laurent  // |low_value_vector|. If so, find the |position| where to insert the new
97c55a96383497a772a307b346368133960b02ad03Eric Laurent  // value.
98c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (feature_value < *(value_ptr + 7)) {
99c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (feature_value < *(value_ptr + 3)) {
100c55a96383497a772a307b346368133960b02ad03Eric Laurent      if (feature_value < *(value_ptr + 1)) {
101c55a96383497a772a307b346368133960b02ad03Eric Laurent        if (feature_value < *value_ptr) {
102c55a96383497a772a307b346368133960b02ad03Eric Laurent          position = 0;
103c55a96383497a772a307b346368133960b02ad03Eric Laurent        } else {
104c55a96383497a772a307b346368133960b02ad03Eric Laurent          position = 1;
105c55a96383497a772a307b346368133960b02ad03Eric Laurent        }
106c55a96383497a772a307b346368133960b02ad03Eric Laurent      } else if (feature_value < *(value_ptr + 2)) {
107c55a96383497a772a307b346368133960b02ad03Eric Laurent        position = 2;
108c55a96383497a772a307b346368133960b02ad03Eric Laurent      } else {
109c55a96383497a772a307b346368133960b02ad03Eric Laurent        position = 3;
110c55a96383497a772a307b346368133960b02ad03Eric Laurent      }
111c55a96383497a772a307b346368133960b02ad03Eric Laurent    } else if (feature_value < *(value_ptr + 5)) {
112c55a96383497a772a307b346368133960b02ad03Eric Laurent      if (feature_value < *(value_ptr + 4)) {
113c55a96383497a772a307b346368133960b02ad03Eric Laurent        position = 4;
114c55a96383497a772a307b346368133960b02ad03Eric Laurent      } else {
115c55a96383497a772a307b346368133960b02ad03Eric Laurent        position = 5;
116c55a96383497a772a307b346368133960b02ad03Eric Laurent      }
117c55a96383497a772a307b346368133960b02ad03Eric Laurent    } else if (feature_value < *(value_ptr + 6)) {
118c55a96383497a772a307b346368133960b02ad03Eric Laurent      position = 6;
119c55a96383497a772a307b346368133960b02ad03Eric Laurent    } else {
120c55a96383497a772a307b346368133960b02ad03Eric Laurent      position = 7;
121c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
122c55a96383497a772a307b346368133960b02ad03Eric Laurent  } else if (feature_value < *(value_ptr + 15)) {
123c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (feature_value < *(value_ptr + 11)) {
124c55a96383497a772a307b346368133960b02ad03Eric Laurent      if (feature_value < *(value_ptr + 9)) {
125c55a96383497a772a307b346368133960b02ad03Eric Laurent        if (feature_value < *(value_ptr + 8)) {
126c55a96383497a772a307b346368133960b02ad03Eric Laurent          position = 8;
127c55a96383497a772a307b346368133960b02ad03Eric Laurent        } else {
128c55a96383497a772a307b346368133960b02ad03Eric Laurent          position = 9;
129c55a96383497a772a307b346368133960b02ad03Eric Laurent        }
130c55a96383497a772a307b346368133960b02ad03Eric Laurent      } else if (feature_value < *(value_ptr + 10)) {
131c55a96383497a772a307b346368133960b02ad03Eric Laurent        position = 10;
132c55a96383497a772a307b346368133960b02ad03Eric Laurent      } else {
133c55a96383497a772a307b346368133960b02ad03Eric Laurent        position = 11;
134c55a96383497a772a307b346368133960b02ad03Eric Laurent      }
135c55a96383497a772a307b346368133960b02ad03Eric Laurent    } else if (feature_value < *(value_ptr + 13)) {
136c55a96383497a772a307b346368133960b02ad03Eric Laurent      if (feature_value < *(value_ptr + 12)) {
137c55a96383497a772a307b346368133960b02ad03Eric Laurent        position = 12;
138c55a96383497a772a307b346368133960b02ad03Eric Laurent      } else {
139c55a96383497a772a307b346368133960b02ad03Eric Laurent        position = 13;
140c55a96383497a772a307b346368133960b02ad03Eric Laurent      }
141c55a96383497a772a307b346368133960b02ad03Eric Laurent    } else if (feature_value < *(value_ptr + 14)) {
142c55a96383497a772a307b346368133960b02ad03Eric Laurent      position = 14;
143c55a96383497a772a307b346368133960b02ad03Eric Laurent    } else {
144c55a96383497a772a307b346368133960b02ad03Eric Laurent      position = 15;
145c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
146c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
147c55a96383497a772a307b346368133960b02ad03Eric Laurent
148c55a96383497a772a307b346368133960b02ad03Eric Laurent  // If we have a new small value, put it in the correct position and shift
149c55a96383497a772a307b346368133960b02ad03Eric Laurent  // larger values up.
150c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (position > -1) {
151c55a96383497a772a307b346368133960b02ad03Eric Laurent    for (i = 15; i > position; i--) {
152c55a96383497a772a307b346368133960b02ad03Eric Laurent      j = i - 1;
153c55a96383497a772a307b346368133960b02ad03Eric Laurent      *(value_ptr + i) = *(value_ptr + j);
154c55a96383497a772a307b346368133960b02ad03Eric Laurent      *(age_ptr + i) = *(age_ptr + j);
155c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
156c55a96383497a772a307b346368133960b02ad03Eric Laurent    *(value_ptr + position) = feature_value;
157c55a96383497a772a307b346368133960b02ad03Eric Laurent    *(age_ptr + position) = 1;
158c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
159c55a96383497a772a307b346368133960b02ad03Eric Laurent
160c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Get |current_median|.
161c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self->frame_counter > 2) {
162c55a96383497a772a307b346368133960b02ad03Eric Laurent    current_median = *(value_ptr + 2);
163c55a96383497a772a307b346368133960b02ad03Eric Laurent  } else if (self->frame_counter > 0) {
164c55a96383497a772a307b346368133960b02ad03Eric Laurent    current_median = *value_ptr;
165c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
166c55a96383497a772a307b346368133960b02ad03Eric Laurent
167c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Smooth the median value.
168c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self->frame_counter > 0) {
169c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (current_median < self->mean_value[channel]) {
170c55a96383497a772a307b346368133960b02ad03Eric Laurent      alpha = (int16_t) ALPHA1;  // 0.2 in Q15.
171c55a96383497a772a307b346368133960b02ad03Eric Laurent    } else {
172c55a96383497a772a307b346368133960b02ad03Eric Laurent      alpha = (int16_t) ALPHA2;  // 0.99 in Q15.
173c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
174c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
175c55a96383497a772a307b346368133960b02ad03Eric Laurent  tmp32 = WEBRTC_SPL_MUL_16_16(alpha + 1, self->mean_value[channel]);
176c55a96383497a772a307b346368133960b02ad03Eric Laurent  tmp32 += WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_WORD16_MAX - alpha, current_median);
177c55a96383497a772a307b346368133960b02ad03Eric Laurent  tmp32 += 16384;
178c55a96383497a772a307b346368133960b02ad03Eric Laurent  self->mean_value[channel] = (int16_t) (tmp32 >> 15);
179c55a96383497a772a307b346368133960b02ad03Eric Laurent
180c55a96383497a772a307b346368133960b02ad03Eric Laurent  return self->mean_value[channel];
181c55a96383497a772a307b346368133960b02ad03Eric Laurent}
182