12024
|
1 /*
|
|
2 The mediastreamer library aims at providing modular media processing and I/O
|
|
3 for linphone, but also for any telephony application.
|
|
4 Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
|
|
5
|
|
6 This library is free software; you can redistribute it and/or
|
|
7 modify it under the terms of the GNU Lesser General Public
|
|
8 License as published by the Free Software Foundation; either
|
|
9 version 2.1 of the License, or (at your option) any later version.
|
|
10
|
|
11 This library is distributed in the hope that it will be useful,
|
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14 Lesser General Public License for more details.
|
|
15
|
|
16 You should have received a copy of the GNU Lesser General Public
|
|
17 License along with this library; if not, write to the Free Software
|
|
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
19 */
|
|
20
|
|
21 #include <config.h>
|
|
22
|
|
23 #ifdef HAVE_ILBC
|
|
24
|
|
25 #include <stdlib.h>
|
|
26 #include <stdio.h>
|
|
27 #include "msilbcenc.h"
|
|
28
|
|
29 extern MSCodecInfo ilbc_info;
|
|
30
|
|
31 /* The return value of each of these calls is the same as that
|
|
32 returned by fread/fwrite, which should be the number of samples
|
|
33 successfully read/written, not the number of bytes. */
|
|
34
|
|
35 int
|
|
36 ilbc_read_16bit_samples(gint16 int16samples[], float speech[], int n)
|
|
37 {
|
|
38 int i;
|
|
39
|
|
40 /* Convert 16 bit integer samples to floating point values in the
|
|
41 range [-1,+1]. */
|
|
42
|
|
43 for (i = 0; i < n; i++) {
|
|
44 speech[i] = int16samples[i];
|
|
45 }
|
|
46
|
|
47 return (n);
|
|
48 }
|
|
49
|
|
50
|
|
51
|
|
52 int
|
|
53 ilbc_write_16bit_samples(gint16 int16samples[], float speech[], int n)
|
|
54 {
|
|
55 int i;
|
|
56 float real_sample;
|
|
57
|
|
58 /* Convert floating point samples in range [-1,+1] to 16 bit
|
|
59 integers. */
|
|
60 for (i = 0; i < n; i++) {
|
|
61 float dtmp=speech[i];
|
|
62 if (dtmp<MIN_SAMPLE)
|
|
63 dtmp=MIN_SAMPLE;
|
|
64 else if (dtmp>MAX_SAMPLE)
|
|
65 dtmp=MAX_SAMPLE;
|
|
66 int16samples[i] = (short) dtmp;
|
|
67 }
|
|
68 return (n);
|
|
69 }
|
|
70
|
|
71 /*
|
|
72
|
|
73 Write the bits in bits[0] through bits[len-1] to file f, in "packed"
|
|
74 format.
|
|
75
|
|
76 bits is expected to be an array of len integer values, where each
|
|
77 integer is 0 to represent a 0 bit, and any other value represents a 1
|
|
78 bit. This bit string is written to the file f in the form of several
|
|
79 8 bit characters. If len is not a multiple of 8, then the last
|
|
80 character is padded with 0 bits -- the padding is in the least
|
|
81 significant bits of the last byte. The 8 bit characters are "filled"
|
|
82 in order from most significant bit to least significant.
|
|
83
|
|
84 */
|
|
85
|
|
86 void
|
|
87 ilbc_write_bits(unsigned char *data, unsigned char *bits, int nbytes)
|
|
88 {
|
|
89 memcpy(data, bits, nbytes);
|
|
90 }
|
|
91
|
|
92
|
|
93
|
|
94 /*
|
|
95
|
|
96 Read bits from file f into bits[0] through bits[len-1], in "packed"
|
|
97 format.
|
|
98
|
|
99 */
|
|
100
|
|
101 int
|
|
102 ilbc_read_bits(unsigned char *data, unsigned char *bits, int nbytes)
|
|
103 {
|
|
104
|
|
105 memcpy(bits, data, nbytes);
|
|
106
|
|
107 return (nbytes);
|
|
108 }
|
|
109
|
|
110
|
|
111
|
|
112
|
|
113 static MSILBCEncoderClass *ms_ilbc_encoder_class=NULL;
|
|
114
|
|
115 MSFilter * ms_ilbc_encoder_new(void)
|
|
116 {
|
|
117 MSILBCEncoder *r;
|
|
118
|
|
119 r=g_new(MSILBCEncoder,1);
|
|
120 ms_ilbc_encoder_init(r);
|
|
121 if (ms_ilbc_encoder_class==NULL)
|
|
122 {
|
|
123 ms_ilbc_encoder_class=g_new(MSILBCEncoderClass,1);
|
|
124 ms_ilbc_encoder_class_init(ms_ilbc_encoder_class);
|
|
125 }
|
|
126 MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_ilbc_encoder_class);
|
|
127 return(MS_FILTER(r));
|
|
128 }
|
|
129
|
|
130
|
|
131 int ms_ilbc_encoder_set_property(MSILBCEncoder *obj, MSFilterProperty prop, char *value)
|
|
132 {
|
|
133 switch(prop){
|
|
134 case MS_FILTER_PROPERTY_FMTP:
|
|
135 obj->ms_per_frame=30;
|
|
136 #if 0 // SME
|
|
137 if (strstr(value,"ptime=20")!=NULL) obj->ms_per_frame=20;
|
|
138 else if (strstr(value,"ptime=30")!=NULL) obj->ms_per_frame=30;
|
|
139 else g_warning("Unrecognized fmtp parameter for ilbc encoder!");
|
|
140 #endif
|
|
141 break;
|
|
142 }
|
|
143 return 0;
|
|
144 }
|
|
145
|
|
146
|
|
147 int ms_ilbc_encoder_get_property(MSILBCEncoder *obj, MSFilterProperty prop, char *value)
|
|
148 {
|
|
149 switch(prop){
|
|
150 case MS_FILTER_PROPERTY_FMTP:
|
|
151 if (obj->ms_per_frame==20) strncpy(value,"ptime=20",MS_FILTER_PROPERTY_STRING_MAX_SIZE);
|
|
152 if (obj->ms_per_frame==30) strncpy(value,"ptime=30",MS_FILTER_PROPERTY_STRING_MAX_SIZE);
|
|
153 break;
|
|
154 }
|
|
155 return 0;
|
|
156 }
|
|
157
|
|
158 void ms_ilbc_encoder_setup(MSILBCEncoder *r)
|
|
159 {
|
|
160 MSFilterClass *klass = NULL;
|
|
161 switch (r->ms_per_frame) {
|
|
162 case 20:
|
|
163 r->samples_per_frame = BLOCKL_20MS;
|
|
164 r->bytes_per_compressed_frame = NO_OF_BYTES_20MS;
|
|
165 break;
|
|
166 case 30:
|
|
167 r->samples_per_frame = BLOCKL_30MS;
|
|
168 r->bytes_per_compressed_frame = NO_OF_BYTES_30MS;
|
|
169 break;
|
|
170 default:
|
|
171 g_error("Bad bitrate value (%i) for ilbc encoder!", r->ms_per_frame);
|
|
172 break;
|
|
173 }
|
|
174 MS_FILTER(r)->r_mingran= (r->samples_per_frame * 2);
|
|
175 g_message("Using ilbc encoder with %i ms frames mode.",r->ms_per_frame);
|
|
176 initEncode(&r->ilbc_enc, r->ms_per_frame /* ms frames */);
|
|
177 }
|
|
178
|
|
179 /* FOR INTERNAL USE*/
|
|
180 void ms_ilbc_encoder_init(MSILBCEncoder *r)
|
|
181 {
|
|
182 /* default bitrate */
|
|
183 r->bitrate = 15200;
|
|
184 r->ms_per_frame = 20;
|
|
185 r->samples_per_frame = BLOCKL_20MS;
|
|
186 r->bytes_per_compressed_frame = NO_OF_BYTES_20MS;
|
|
187
|
|
188 ms_filter_init(MS_FILTER(r));
|
|
189 MS_FILTER(r)->infifos=r->f_inputs;
|
|
190 MS_FILTER(r)->outqueues=r->q_outputs;
|
|
191 MS_FILTER(r)->r_mingran= (r->samples_per_frame * 2);
|
|
192 memset(r->f_inputs,0,sizeof(MSFifo*)*MSILBCENCODER_MAX_INPUTS);
|
|
193 memset(r->q_outputs,0,sizeof(MSFifo*)*MSILBCENCODER_MAX_INPUTS);
|
|
194 }
|
|
195
|
|
196 void ms_ilbc_encoder_class_init(MSILBCEncoderClass *klass)
|
|
197 {
|
|
198 ms_filter_class_init(MS_FILTER_CLASS(klass));
|
|
199 ms_filter_class_set_name(MS_FILTER_CLASS(klass),"ILBCEnc");
|
|
200 MS_FILTER_CLASS(klass)->max_finputs=MSILBCENCODER_MAX_INPUTS;
|
|
201 MS_FILTER_CLASS(klass)->max_qoutputs=MSILBCENCODER_MAX_INPUTS;
|
|
202 MS_FILTER_CLASS(klass)->r_maxgran=ILBC_MAX_SAMPLES_PER_FRAME*2;
|
|
203 MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_ilbc_encoder_set_property;
|
|
204 MS_FILTER_CLASS(klass)->get_property=(MSFilterPropertyFunc)ms_ilbc_encoder_get_property;
|
|
205 MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_ilbc_encoder_setup;
|
|
206 MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_ilbc_encoder_destroy;
|
|
207 MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_ilbc_encoder_process;
|
|
208 MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&ilbc_info;
|
|
209 }
|
|
210
|
|
211 void ms_ilbc_encoder_process(MSILBCEncoder *r)
|
|
212 {
|
|
213 MSFifo *fi;
|
|
214 MSQueue *qo;
|
|
215 MSMessage *m;
|
|
216 void *src=NULL;
|
|
217 float speech[ILBC_MAX_SAMPLES_PER_FRAME];
|
|
218
|
|
219 /* process output fifos, but there is only one for this class of filter*/
|
|
220
|
|
221 qo=r->q_outputs[0];
|
|
222 fi=r->f_inputs[0];
|
|
223 ms_fifo_get_read_ptr(fi,r->samples_per_frame*2,&src);
|
|
224 if (src==NULL) {
|
|
225 g_warning( "src=%p\n", src);
|
|
226 return;
|
|
227 }
|
|
228 m=ms_message_new(r->bytes_per_compressed_frame);
|
|
229
|
|
230 ilbc_read_16bit_samples((gint16*)src, speech, r->samples_per_frame);
|
|
231 iLBC_encode((unsigned char *)m->data, speech, &r->ilbc_enc);
|
|
232 ms_queue_put(qo,m);
|
|
233 }
|
|
234
|
|
235 void ms_ilbc_encoder_uninit(MSILBCEncoder *obj)
|
|
236 {
|
|
237 }
|
|
238
|
|
239 void ms_ilbc_encoder_destroy( MSILBCEncoder *obj)
|
|
240 {
|
|
241 ms_ilbc_encoder_uninit(obj);
|
|
242 g_free(obj);
|
|
243 }
|
|
244
|
|
245 #endif
|