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