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