Skip to content

Commit 6ff63ca

Browse files
author
litongjava
committed
add simple-vad ahd webrtc
1 parent af7ef61 commit 6ff63ca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+10042
-0
lines changed

simplevad/common.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// Created by fu on 3/7/18.
3+
//
4+
5+
#ifndef VAD_DEMO_COMMON_H
6+
#define VAD_DEMO_COMMON_H
7+
8+
#include <stdint.h>
9+
10+
11+
12+
// MULTI = 1 2 3 webrtc vad可以设置分别为以10ms 20ms 30ms作为包
13+
#define MULTI 1
14+
15+
// VAD 模式 Aggressiveness mode (0, 1, 2, or 3). 数值越大,判断越是粗略,连着的静音或者响声增多
16+
#define WEBRTC_VAD_MODE 3
17+
18+
// 有声音的音频段,xxx 毫秒后,认为该音频段结束,不能为0
19+
#define FILE_CUT_SILENCE_AFTER_ACTIVE_MS 500
20+
21+
// 静音的音频段,切分xxx毫秒给之后有声音的音频段
22+
#define FILE_CUT_SILENCE_BEFORE_ACTIVE_MS 300
23+
24+
// 最小的音频切分长度,即每个切分后音频文件不少于这个时长,最后一个除外
25+
#define FILE_CUT_MIN_MS (10 * 1000)
26+
27+
// 最大的音频切分长度,即每个切分后音频文件不多于这个时长
28+
#define FILE_CUT_MAX_MS (60 * 1000)
29+
30+
//16000 采样率固定
31+
#define SAMPLE_RATE 16000
32+
33+
// 用于period_format.h
34+
#define PERIODS_SIZE_INITIED 100
35+
36+
#define FRAME_SIZE (16 * MULTI * 10 )
37+
38+
#define CAL_TIME_BY_FRAME(frame) (MULTI * 10 * frame)
39+
40+
#define CAL_FRAME_BY_TIME(time) (time / (MULTI * 10))
41+
42+
/*`
43+
uint64_t inline CAL_TIME_BY_FRAME(int frame){
44+
return MULTI * frame * 10;
45+
};
46+
47+
int inline CAL_FRAME_BY_TIME(uint64_t time){
48+
return time / (MULTI * 10);
49+
};
50+
*/
51+
#endif //VAD_DEMO_COMMON_H

simplevad/file_cut.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
//
2+
// Created by fu on 3/7/18.
3+
//
4+
5+
#include <stdlib.h>
6+
#include "file_cut.h"
7+
8+
// static size_t file_total = 0;
9+
10+
static inline int cut_write_file(struct cut_info *cut, int frames) {
11+
int size = frames * FRAME_SIZE ;
12+
uint16_t buffer[size];
13+
int readed = fread(buffer, sizeof(uint16_t), size, cut->fp);
14+
if (readed > 0) {
15+
FILE *res_file = fopen(cut->result_filename, "wb+");
16+
if (res_file == NULL) {
17+
fprintf(stderr, "file open failed, %s\n", cut->result_filename);
18+
return 3;
19+
}
20+
int written = fwrite(buffer, sizeof(uint16_t), readed, res_file);
21+
fclose(res_file);
22+
if (written != readed) {
23+
fprintf(stderr, "written is %d, readed is %d\n", written, readed);
24+
return 2;
25+
}
26+
// file_total += written;
27+
// printf("file write success, %s, written %d\n", cut->result_filename, written);
28+
return 0;
29+
30+
} else {
31+
return 1;
32+
}
33+
34+
}
35+
36+
static inline int cut_frame(struct cut_info *cut, int last_frame, int force) {
37+
int frames = last_frame - cut->cut_begin_frame;
38+
if (force || (frames >= CAL_FRAME_BY_TIME(FILE_CUT_MIN_MS))) {
39+
if (last_frame == 109) {
40+
printf("%d", 109);
41+
}
42+
//printf("cut file at frame: %d\n", last_frame);
43+
snprintf(cut->result_filename, sizeof(cut->result_filename),
44+
"%s/%s_%ld-%ld_%s.pcm", cut->output_file_dir,
45+
cut->output_filename_prefix, CAL_TIME_BY_FRAME(cut->cut_begin_frame),
46+
CAL_TIME_BY_FRAME(last_frame) - 1, cut->is_contain_active ? "A" : "I");
47+
cut_write_file(cut, frames);
48+
cut->is_pervious_active = 0;
49+
cut->is_contain_active = 0;
50+
cut->cut_begin_frame = last_frame;
51+
return 0;
52+
} else {
53+
return 1;
54+
}
55+
}
56+
57+
static inline int add_continued(struct cut_info *cut, int is_active) {
58+
if (!is_active && cut->is_contain_active) {
59+
// 有响声,之后连续静音
60+
int diff = cut->previous_along_frames - CAL_FRAME_BY_TIME(FILE_CUT_SILENCE_AFTER_ACTIVE_MS);
61+
if (diff >= 0) {
62+
int res = cut_frame(cut, cut->current_frame, 0);
63+
if (res == 0) {
64+
int frame = -1 * (cut->current_frame);
65+
cut->previous_along_frames = 1;
66+
return frame;
67+
}
68+
}
69+
}
70+
cut->previous_along_frames++;
71+
return 0;
72+
}
73+
74+
75+
static inline int add_changed(struct cut_info *cut, int is_active) {
76+
int frame = 0;
77+
if (is_active) {
78+
// 连续静音,之后遇到响声
79+
if (cut->previous_along_frames > CAL_FRAME_BY_TIME(FILE_CUT_SILENCE_BEFORE_ACTIVE_MS)) {
80+
int c_frames =
81+
cut->current_frame - CAL_FRAME_BY_TIME(FILE_CUT_SILENCE_BEFORE_ACTIVE_MS);
82+
int res = cut_frame(cut, c_frames, 0);
83+
if (res == 0) {
84+
frame = -1 * (c_frames);
85+
}
86+
// cut->previous_along_frames = FILE_CUT_SILENCE_AFTER_ACTIVE_MS;
87+
}
88+
}
89+
90+
cut->previous_along_frames = 1;
91+
return frame;
92+
}
93+
94+
struct cut_info *cut_info_create(FILE *fp) {
95+
struct cut_info *cut = calloc(1, sizeof(struct cut_info));
96+
cut->fp = fp;
97+
return cut;
98+
}
99+
100+
101+
int cut_add_vad_activity(struct cut_info *cut, int is_active, int is_last) {
102+
int res;
103+
if (is_last ||
104+
(cut->current_frame - cut->cut_begin_frame == CAL_FRAME_BY_TIME(FILE_CUT_MAX_MS))) {
105+
cut_frame(cut, cut->current_frame, is_last);
106+
res = -1 * cut->current_frame;
107+
} else if (cut->is_pervious_active == is_active) {
108+
res = add_continued(cut, is_active);
109+
} else {
110+
res = add_changed(cut, is_active);
111+
if (is_active) {
112+
cut->is_contain_active = 1;
113+
}
114+
}
115+
cut->is_pervious_active = is_active;
116+
cut->current_frame++;
117+
return res;
118+
}
119+
120+
void cut_info_free(struct cut_info *cut) {
121+
free(cut);
122+
}
123+
124+
125+
void cut_info_print(struct cut_info *cut) {
126+
printf("%s, %s, %d, frame %d\n", cut->is_pervious_active ? "PA" : "PI",
127+
cut->is_contain_active ? "CA" : "CI", cut->previous_along_frames, cut->current_frame);
128+
}

simplevad/file_cut.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// Created by fu on 3/7/18.
3+
//
4+
5+
#ifndef VAD_DEMO_FILE_CUT_H
6+
#define VAD_DEMO_FILE_CUT_H
7+
8+
#include <stdio.h>
9+
#include "common.h"
10+
#include "stdint.h"
11+
12+
struct cut_info {
13+
int is_pervious_active;
14+
int is_contain_active;
15+
int previous_along_frames;
16+
FILE *fp;
17+
int current_frame;
18+
int cut_begin_frame;
19+
char result_filename[200];
20+
char output_file_dir[100];
21+
char output_filename_prefix[100];
22+
23+
};
24+
25+
struct cut_info *cut_info_create(FILE *fp);
26+
27+
int cut_add_vad_activity(struct cut_info *cut, int is_active, int is_last);
28+
29+
void cut_info_free(struct cut_info *cut);
30+
31+
void cut_info_print(struct cut_info *cut);
32+
33+
#endif //VAD_DEMO_FILE_CUT_H
34+
/**
35+
36+
struct cut_info *cut = cut_create_info(NULL);
37+
int acts[] = {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0};
38+
int len = sizeof(acts) / sizeof(int);
39+
int is_cuts[len];
40+
printf(" acts length: %d\n", len);
41+
42+
int j, k;
43+
for (k = 0; k < len; k++) {
44+
printf("%d ", acts[k]);
45+
is_cuts[k] = 0;
46+
}
47+
printf("\n");
48+
for (k = 0; k < len; k++) {
49+
50+
printf("\n");
51+
int res = cut_add_vad_activity(cut, acts[k], k == len - 1);
52+
cut_info_print(cut);
53+
if (res < 0) {
54+
is_cuts[-1 * res] = 1;
55+
}
56+
for (j = 0; j <= k; j++) {
57+
if (is_cuts[j]) {
58+
printf("| ");
59+
}
60+
printf("%d ", acts[j]);
61+
62+
}
63+
}
64+
printf("\n");
65+
for (j = 0; j <= k; j++) {
66+
if (is_cuts[j]) {
67+
printf("| ");
68+
}
69+
printf("%d ", acts[j]);
70+
71+
}
72+
printf("\n");
73+
printf("PROGRAM FINISH\n");
74+
**/

simplevad/period_format.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
//
2+
// Created by fu on 3/6/18.
3+
//
4+
5+
#ifdef __APPLE__
6+
#include <sys/malloc.h>
7+
#include <stdlib.h>
8+
9+
#else
10+
#include <malloc.h>
11+
#endif
12+
13+
#include "common.h"
14+
#include "period_format.h"
15+
16+
static int add_period_start(struct periods *per) {
17+
per->size++;
18+
if (per->size > per->size_allocated) {
19+
size_t new_size = per->size_allocated * 2 * sizeof(uint64_t);
20+
per->period_start = realloc(per->period_start, new_size);
21+
if (per->period_start == NULL) {
22+
fprintf(stderr, "per->period_start allocated failed %ld", new_size);
23+
return 1;
24+
}
25+
per->period_end = realloc(per->period_end, new_size);
26+
if (per->period_end == NULL) {
27+
fprintf(stderr, "per->period_end allocated failed %ld", new_size);
28+
return 2;
29+
}
30+
per->size_allocated *= 2;
31+
}
32+
uint64_t start_time = CAL_TIME_BY_FRAME(per->current_frame);
33+
per->period_start[per->size - 1] = start_time;
34+
per->is_end_filled = 0;
35+
return 0;
36+
}
37+
38+
static void add_period_end(struct periods *per) {
39+
size_t end_time = CAL_TIME_BY_FRAME(per->current_frame);
40+
per->period_end[per->size - 1] = end_time;
41+
per->is_end_filled = 1;
42+
}
43+
44+
struct periods *periods_create() {
45+
struct periods *per = calloc(1, sizeof(struct periods));
46+
if (per == NULL) {
47+
fprintf(stderr, "per alloc failed");
48+
return NULL;
49+
}
50+
per->period_start = calloc(PERIODS_SIZE_INITIED, sizeof(uint64_t));
51+
if (per->period_start == NULL) {
52+
fprintf(stderr, "per->period_start alloc failed");
53+
} else {
54+
per->period_end = calloc(PERIODS_SIZE_INITIED, sizeof(uint64_t));
55+
if (per->period_end == NULL) {
56+
fprintf(stderr, "per->period_start alloc failed");
57+
} else {
58+
per->size_allocated = PERIODS_SIZE_INITIED;
59+
return per;
60+
}
61+
}
62+
return NULL;
63+
}
64+
65+
66+
void periods_print(struct periods *per) {
67+
int size = per->size;
68+
int is_ended_fill = per->is_end_filled;
69+
printf("PERIODS SIZE :%d, is_end_filled:%s ", size, is_ended_fill ? "true" : "false");
70+
71+
int i;
72+
for (i = 0; i < size; i++) {
73+
if ((i != size - 1) || is_ended_fill) {
74+
printf("[%llu, %llu] ", per->period_start[i], per->period_end[i]);
75+
} else {
76+
printf("[ %llu, N]", per->period_start[size]);
77+
}
78+
}
79+
80+
// printf("size %ld allocated %ld", per->size, per->size_allocated);
81+
printf("\n");
82+
}
83+
84+
int period_add_vad_activity(struct periods *per, int is_active, int is_last) {
85+
if (!per->is_pervious_active && is_active) {
86+
int res = add_period_start(per);
87+
if (res != 0) {
88+
return res;
89+
}
90+
per->is_pervious_active = is_active;
91+
} else if (per->is_pervious_active && (!is_active || is_last)) {
92+
add_period_end(per);
93+
per->is_pervious_active = is_active;
94+
}
95+
96+
per->current_frame++;
97+
return 0;
98+
}
99+
100+
void periods_free(struct periods *per) {
101+
free(per->period_start);
102+
free(per->period_end);
103+
free(per);
104+
}

0 commit comments

Comments
 (0)