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/amr/sp_enc.h"
20 
21 
22 #define AMR_MAGIC_NUMBER		"#!AMR\n"
23 
24 typedef struct {
25 	void *amrenc;
26 	uint8_t *enc_buffer;
27 } amr_encoder_t;
28 
amr_encode_process(void * priv,uint8_t * buffer,int nbytes)29 static int amr_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 	amr_encoder_t *amr = mencoder->encoder;
38 	if (!amr) {
39 		M_LOGE("speex null !\n");
40 		return -1;
41 	}
42 
43 	enum Mode req_mode = MR515;
44 	int rem_size = nbytes;
45 	uint8_t *ptr = buffer;
46 	uint8_t *enc_ptr = buffer;
47 	int enc_sum = 0;
48 	int enc_ret;
49 	int i;
50 
51 	if (rem_size < 320) {
52 		M_LOGE("samples too less !\n");
53 		return -1;
54 	}
55 
56 	while (1) {
57 		enc_ret = Encoder_Interface_Encode(amr->amrenc, req_mode, ptr, amr->enc_buffer, 0);
58 		snd_memcpy(enc_ptr, amr->enc_buffer, enc_ret);
59 		enc_ptr += enc_ret;
60 		enc_sum += enc_ret;
61 		rem_size -= 320;
62 		//M_LOGD("enc_ret %d rem_size %d\n", enc_ret, rem_size);
63 		if (rem_size < 320) {
64 			if (rem_size > 0)
65 				M_LOGW("discard unproc data %d\n", rem_size);
66 			break;
67 		}
68 		ptr += 320;
69 	}
70 
71 	return enc_sum;
72 }
73 
amr_encode_header_gen(void * priv,void * arg)74 static int amr_encode_header_gen(void *priv, void *arg)
75 {
76 	media_encoder_t *mencoder = (media_encoder_t *)priv;
77 	if (!mencoder) {
78 		M_LOGE("mencoder null !\n");
79 		return -1;
80 	}
81 
82 	mencoder->header_size = strlen(AMR_MAGIC_NUMBER);
83 
84 	char *header = snd_zalloc(mencoder->header_size, AFM_EXTN);
85 	if (!header) {
86 		M_LOGE("alloc header failed !\n");
87 		return -1;
88 	}
89 
90 	memcpy(header, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER));
91 
92 	mencoder->header = header;
93 	mencoder->header_cplt = 1;
94 	return 0;
95 }
96 
amr_encode_action(void * priv,recorder_action_t action,void * arg)97 static int amr_encode_action(void *priv, recorder_action_t action, void *arg)
98 {
99 	return 0;
100 }
101 
amr_encoder_create(media_encoder_t * mencoder)102 int amr_encoder_create(media_encoder_t *mencoder)
103 {
104 	amr_encoder_t *amr;
105 
106 	if (!mencoder) {
107 		M_LOGE("mencoder null !\n");
108 		return -1;
109 	}
110 
111 	amr = snd_zalloc(sizeof(amr_encoder_t), AFM_MAIN);
112 	if (!amr) {
113 		M_LOGE("alloc speex encoder failed !\n");
114 		return -1;
115 	}
116 
117 	amr->amrenc = Encoder_Interface_init(1);
118 	if (!amr->amrenc) {
119 		M_LOGE("init amrenc failed !\n");
120 		snd_free(amr);
121 		return -1;
122 	}
123 
124 	amr->enc_buffer = snd_zalloc(160 * sizeof(short), AFM_MAIN);
125 	if (!amr->enc_buffer) {
126 		M_LOGE("alloc enc buffer failed !\n");
127 		Encoder_Interface_exit(amr->amrenc);
128 		snd_free(amr);
129 		return -1;
130 	}
131 
132 	mencoder->encoder = amr;
133 	mencoder->encode = amr_encode_process;
134 	mencoder->action = amr_encode_action;
135 	mencoder->header_gen = amr_encode_header_gen;
136 
137 	M_LOGD("amr encoder create\n");
138 	return 0;
139 }
140 
amr_encoder_release(media_encoder_t * mencoder)141 int amr_encoder_release(media_encoder_t *mencoder)
142 {
143 	amr_encoder_t *amr;
144 
145 	if (!mencoder) {
146 		M_LOGE("mencoder null !\n");
147 		return -1;
148 	}
149 
150 	amr = mencoder->encoder;
151 	if (!amr) {
152 		M_LOGE("amr encoder null !\n");
153 		return -1;
154 	}
155 
156 	snd_free(amr->enc_buffer);
157 	Encoder_Interface_exit(amr->amrenc);
158 	snd_free(amr);
159 	mencoder->encoder = NULL;
160 
161 	M_LOGD("amr encoder release\n");
162 	return 0;
163 }
164