1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 *
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <stdarg.h>
11
12 #include "uvoice_types.h"
13
14 #include "uvoice_os.h"
15 #include "uvoice_types.h"
16 #include "uvoice_event.h"
17 #include "uvoice_common.h"
18 #include "uvoice_audio.h"
19
20 #include "audio_common.h"
21 #include "audio_stream.h"
22 #include "audio_vad.h"
23
24
25 #define VAD_END_DEBOUNCE_TIME_MS 990 /* muliti of 30 */
26
27
audio_vad_process(struct voice_active_detect * vad,const uint8_t * buffer,int nbytes)28 int audio_vad_process(struct voice_active_detect *vad,
29 const uint8_t *buffer, int nbytes)
30 {
31 int ret;
32
33 if (!vad) {
34 snd_err("vad null !\n");
35 return -1;
36 }
37
38 ret = vad_process(vad, buffer, nbytes);
39 if (ret < 0) {
40 snd_err("vad process error %d !\n", ret);
41 return -1;
42 }
43
44 if (ret == VAD_STAT_SPEECH) {
45 if (vad->state == VAD_STAT_NOISE) {
46 vad->state = VAD_STAT_SPEECH;
47 uvoice_event_post(UVOICE_EV_ST,
48 UVOICE_CODE_VAD_START, 0);
49 }
50 if (vad->end_count > 0)
51 vad->end_count = 0;
52 } else if (ret == VAD_STAT_NOISE) {
53 if (vad->state == VAD_STAT_SPEECH) {
54 if (vad->end_count++ >= vad->end_target &&
55 os_current_time() - vad->start_time >= 2000) {
56 vad->state = VAD_STAT_NOISE;
57 vad->end_count = 0;
58 uvoice_event_post(UVOICE_EV_ST,
59 UVOICE_CODE_VAD_END, 0);
60 }
61 }
62 }
63
64 return 0;
65 }
66
audio_vad_create(int rate,int period_size)67 struct voice_active_detect *audio_vad_create(int rate, int period_size)
68 {
69 struct voice_active_detect *vad;
70 int proc_samples;
71
72 vad = snd_zalloc(sizeof(struct voice_active_detect), AFM_EXTN);
73 if (!vad) {
74 snd_err("alloc vad struct failed !\n");
75 return NULL;
76 }
77
78 proc_samples = MIN((rate / 100) * 3, period_size);
79
80 vad->state = VAD_STAT_NOISE;
81 vad->end_target = VAD_END_DEBOUNCE_TIME_MS /
82 ((proc_samples * 1000) / rate);
83
84 if (vad_create(vad, rate, proc_samples, 0)) {
85 snd_err("create vad failed !\n");
86 snd_free(vad);
87 return NULL;
88 }
89
90 vad->start_time = os_current_time();
91
92 snd_debug("vad create, end target %d\n",
93 vad->end_target);
94 return vad;
95 }
96
audio_vad_release(struct voice_active_detect * vad)97 int audio_vad_release(struct voice_active_detect *vad)
98 {
99 if (vad) {
100 vad_release(vad);
101 snd_free(vad);
102 snd_debug("vad release\n");
103 }
104
105 return 0;
106 }
107
108