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