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 <signal.h>
11 
12 #include "uvoice_os.h"
13 #include "uvoice_types.h"
14 #include "uvoice_recorder.h"
15 
16 #include "uvoice_common.h"
17 #include "uvoice_record.h"
18 
19 #include "opensource/amrwb/enc_if.h"
20 
21 
22 #define AMRWB_MAGIC_NUMBER		"#!AMR-WB\n"
23 
24 typedef struct {
25 	void *amrwbenc;
26 	uint8_t *enc_buffer;
27 } amrwb_encoder_t;
28 
amrwb_encode_process(void * priv,uint8_t * buffer,int nbytes)29 static int amrwb_encode_process(void *priv, uint8_t *buffer, int nbytes)
30 {
31 	media_encoder_t *mencoder = (media_encoder_t *)priv;
32 	if (!mencoder) {
33 		M_LOGE("mencoder null !\n");
34 		return -1;
35 	}
36 
37 	amrwb_encoder_t *amrwb = mencoder->encoder;
38 	if (!amrwb) {
39 		M_LOGE("speex null !\n");
40 		return -1;
41 	}
42 
43 	int16_t mode = 4;
44 	int16_t allow_dtx = 0;
45 	int rem_size = nbytes;
46 	uint8_t *ptr = buffer;
47 	uint8_t *enc_ptr = buffer;
48 	int enc_sum = 0;
49 	int enc_ret;
50 	int i;
51 
52 	if (rem_size < 640) { /* 640: L_FRAME16k * sizeof(short) */
53 		M_LOGE("samples too less !\n");
54 		return -1;
55 	}
56 
57 	while (1) {
58 		enc_ret = E_IF_encode(amrwb->amrwbenc, mode, ptr, amrwb->enc_buffer, allow_dtx);
59 		snd_memcpy(enc_ptr, amrwb->enc_buffer, enc_ret);
60 		enc_ptr += enc_ret;
61 		enc_sum += enc_ret;
62 		rem_size -= 640;
63 		//M_LOGD("enc_ret %d rem_size %d\n", enc_ret, rem_size);
64 		if (rem_size < 640) {
65 			if (rem_size > 0)
66 				M_LOGW("discard unproc data %d\n", rem_size);
67 			break;
68 		}
69 		ptr += 640;
70 	}
71 
72 	return enc_sum;
73 }
74 
amrwb_encode_header_gen(void * priv,void * arg)75 static int amrwb_encode_header_gen(void *priv, void *arg)
76 {
77 	media_encoder_t *mencoder = (media_encoder_t *)priv;
78 	if (!mencoder) {
79 		M_LOGE("mencoder null !\n");
80 		return -1;
81 	}
82 
83 	mencoder->header_size = strlen(AMRWB_MAGIC_NUMBER);
84 
85 	char *header = snd_zalloc(mencoder->header_size, AFM_EXTN);
86 	if (!header) {
87 		M_LOGE("alloc header failed !\n");
88 		return -1;
89 	}
90 
91 	memcpy(header, AMRWB_MAGIC_NUMBER, strlen(AMRWB_MAGIC_NUMBER));
92 
93 	mencoder->header = header;
94 	mencoder->header_cplt = 1;
95 	return 0;
96 }
97 
amrwb_encode_action(void * priv,recorder_action_t action,void * arg)98 static int amrwb_encode_action(void *priv, recorder_action_t action, void *arg)
99 {
100 	return 0;
101 }
102 
amrwb_encoder_create(media_encoder_t * mencoder)103 int amrwb_encoder_create(media_encoder_t *mencoder)
104 {
105 	amrwb_encoder_t *amrwb;
106 
107 	if (!mencoder) {
108 		M_LOGE("mencoder null !\n");
109 		return -1;
110 	}
111 
112 	amrwb = snd_zalloc(sizeof(amrwb_encoder_t), AFM_MAIN);
113 	if (!amrwb) {
114 		M_LOGE("alloc speex encoder failed !\n");
115 		return -1;
116 	}
117 
118 	amrwb->amrwbenc = E_IF_init();
119 	if (!amrwb->amrwbenc) {
120 		M_LOGE("init amrwb encoder failed !\n");
121 		snd_free(amrwb);
122 		return -1;
123 	}
124 
125 	amrwb->enc_buffer = snd_zalloc(L_FRAME16k * sizeof(short), AFM_MAIN);
126 	if (!amrwb->enc_buffer) {
127 		M_LOGE("alloc enc buffer failed !\n");
128 		E_IF_exit(amrwb->amrwbenc);
129 		snd_free(amrwb);
130 		return -1;
131 	}
132 
133 	mencoder->encoder = amrwb;
134 	mencoder->encode = amrwb_encode_process;
135 	mencoder->action = amrwb_encode_action;
136 	mencoder->header_gen = amrwb_encode_header_gen;
137 
138 	M_LOGD("amrwb encoder create\n");
139 	return 0;
140 }
141 
amrwb_encoder_release(media_encoder_t * mencoder)142 int amrwb_encoder_release(media_encoder_t *mencoder)
143 {
144 	amrwb_encoder_t *amrwb;
145 
146 	if (!mencoder) {
147 		M_LOGE("mencoder null !\n");
148 		return -1;
149 	}
150 
151 	amrwb = mencoder->encoder;
152 	if (!amrwb) {
153 		M_LOGE("amrwb encoder null !\n");
154 		return -1;
155 	}
156 
157 	snd_free(amrwb->enc_buffer);
158 	E_IF_exit(amrwb->amrwbenc);
159 	snd_free(amrwb);
160 	mencoder->encoder = NULL;
161 
162 	M_LOGD("amrwb encoder release\n");
163 	return 0;
164 }
165