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 <stdlib.h>
|
|
22 #include "msLPC10encoder.h"
|
|
23 #include <lpc10.h>
|
|
24
|
|
25
|
|
26 extern MSCodecInfo LPC10info;
|
|
27
|
|
28 /* The return value of each of these calls is the same as that
|
|
29 returned by fread/fwrite, which should be the number of samples
|
|
30 successfully read/written, not the number of bytes. */
|
|
31
|
|
32 int
|
|
33 read_16bit_samples(INT16 int16samples[], float speech[], int n)
|
|
34 {
|
|
35 int i;
|
|
36
|
|
37 /* Convert 16 bit integer samples to floating point values in the
|
|
38 range [-1,+1]. */
|
|
39
|
|
40 for (i = 0; i < n; i++) {
|
|
41 speech[i] = ((float) int16samples[i]) / 32768.0;
|
|
42 }
|
|
43
|
|
44 return (n);
|
|
45 }
|
|
46
|
|
47
|
|
48
|
|
49 int
|
|
50 write_16bit_samples(INT16 int16samples[], float speech[], int n)
|
|
51 {
|
|
52 int i;
|
|
53 float real_sample;
|
|
54
|
|
55 /* Convert floating point samples in range [-1,+1] to 16 bit
|
|
56 integers. */
|
|
57 for (i = 0; i < n; i++) {
|
|
58 real_sample = 32768.0 * speech[i];
|
|
59 if (real_sample < -32768.0) {
|
|
60 int16samples[i] = -32768;
|
|
61 } else if (real_sample > 32767.0) {
|
|
62 int16samples[i] = 32767;
|
|
63 } else {
|
|
64 int16samples[i] = real_sample;
|
|
65 }
|
|
66 }
|
|
67 return (n);
|
|
68 }
|
|
69
|
|
70 /*
|
|
71
|
|
72 Write the bits in bits[0] through bits[len-1] to file f, in "packed"
|
|
73 format.
|
|
74
|
|
75 bits is expected to be an array of len integer values, where each
|
|
76 integer is 0 to represent a 0 bit, and any other value represents a 1
|
|
77 bit. This bit string is written to the file f in the form of several
|
|
78 8 bit characters. If len is not a multiple of 8, then the last
|
|
79 character is padded with 0 bits -- the padding is in the least
|
|
80 significant bits of the last byte. The 8 bit characters are "filled"
|
|
81 in order from most significant bit to least significant.
|
|
82
|
|
83 */
|
|
84
|
|
85 void
|
|
86 write_bits(unsigned char *data, INT32 *bits, int len)
|
|
87 {
|
|
88 int i; /* generic loop variable */
|
|
89 unsigned char mask; /* The next bit position within the
|
|
90 variable "data" to place the next
|
|
91 bit. */
|
|
92
|
|
93
|
|
94 /* Fill in the array bits.
|
|
95 * The first compressed output bit will be the most significant
|
|
96 * bit of the byte, so initialize mask to 0x80. The next byte of
|
|
97 * compressed data is initially 0, and the desired bits will be
|
|
98 * turned on below.
|
|
99 */
|
|
100 mask = 0x80;
|
|
101 *data = 0;
|
|
102
|
|
103 for (i = 0; i < len; i++) {
|
|
104 /* Turn on the next bit of output data, if necessary. */
|
|
105 if (bits[i]) {
|
|
106 (*data) |= mask;
|
|
107 }
|
|
108 /*
|
|
109 * If the byte data is full, determined by mask becoming 0,
|
|
110 * then write the byte to the output file, and reinitialize
|
|
111 * data and mask for the next output byte. Also add the byte
|
|
112 * if (i == len-1), because if len is not a multiple of 8,
|
|
113 * then mask won't yet be 0. */
|
|
114 mask >>= 1;
|
|
115 if ((mask == 0) || (i == len-1)) {
|
|
116 data++;
|
|
117 *data = 0;
|
|
118 mask = 0x80;
|
|
119 }
|
|
120 }
|
|
121 }
|
|
122
|
|
123
|
|
124
|
|
125 /*
|
|
126
|
|
127 Read bits from file f into bits[0] through bits[len-1], in "packed"
|
|
128 format.
|
|
129
|
|
130 Read ceiling(len/8) characters from file f, if that many are available
|
|
131 to read, otherwise read to the end of the file. The first character's
|
|
132 8 bits, in order from MSB to LSB, are used to fill bits[0] through
|
|
133 bits[7]. The second character's bits are used to fill bits[8] through
|
|
134 bits[15], and so on. If ceiling(len/8) characters are available to
|
|
135 read, and len is not a multiple of 8, then some of the least
|
|
136 significant bits of the last character read are completely ignored.
|
|
137 Every entry of bits[] that is modified is changed to either a 0 or a
|
|
138 1.
|
|
139
|
|
140 The number of bits successfully read is returned, and is always in the
|
|
141 range 0 to len, inclusive. If it is less than len, it will always be
|
|
142 a multiple of 8.
|
|
143
|
|
144 */
|
|
145
|
|
146 int
|
|
147 read_bits(unsigned char *data, INT32 *bits, int len)
|
|
148 {
|
|
149 int i,ind=0; /* generic loop variable */
|
|
150 int c=0;
|
|
151
|
|
152 /* Unpack the array bits into coded_frame. */
|
|
153 for (i = 0; i < len; i++) {
|
|
154 if ((i % 8) == 0) {
|
|
155 c = (int)(data[ind]);
|
|
156 ind++;
|
|
157 }
|
|
158 if (c & (0x80 >> (i & 7))) {
|
|
159 bits[i] = 1;
|
|
160 } else {
|
|
161 bits[i] = 0;
|
|
162 }
|
|
163 }
|
|
164 return (len);
|
|
165 }
|
|
166
|
|
167
|
|
168
|
|
169
|
|
170 static MSLPC10EncoderClass *ms_LPC10encoder_class=NULL;
|
|
171
|
|
172 MSFilter * ms_LPC10encoder_new(void)
|
|
173 {
|
|
174 MSLPC10Encoder *r;
|
|
175
|
|
176 r=g_new(MSLPC10Encoder,1);
|
|
177 ms_LPC10encoder_init(r);
|
|
178 if (ms_LPC10encoder_class==NULL)
|
|
179 {
|
|
180 ms_LPC10encoder_class=g_new(MSLPC10EncoderClass,1);
|
|
181 ms_LPC10encoder_class_init(ms_LPC10encoder_class);
|
|
182 }
|
|
183 MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_LPC10encoder_class);
|
|
184 return(MS_FILTER(r));
|
|
185 }
|
|
186
|
|
187
|
|
188 /* FOR INTERNAL USE*/
|
|
189 void ms_LPC10encoder_init(MSLPC10Encoder *r)
|
|
190 {
|
|
191 ms_filter_init(MS_FILTER(r));
|
|
192 MS_FILTER(r)->infifos=r->f_inputs;
|
|
193 MS_FILTER(r)->outfifos=r->f_outputs;
|
|
194 MS_FILTER(r)->r_mingran=LPC10_SAMPLES_PER_FRAME*2;
|
|
195 memset(r->f_inputs,0,sizeof(MSFifo*)*MSLPC10ENCODER_MAX_INPUTS);
|
|
196 memset(r->f_outputs,0,sizeof(MSFifo*)*MSLPC10ENCODER_MAX_INPUTS);
|
|
197 r->lpc10_enc=create_lpc10_encoder_state();
|
|
198 }
|
|
199
|
|
200 void ms_LPC10encoder_class_init(MSLPC10EncoderClass *klass)
|
|
201 {
|
|
202 ms_filter_class_init(MS_FILTER_CLASS(klass));
|
|
203 ms_filter_class_set_name(MS_FILTER_CLASS(klass),"LPC10Enc");
|
|
204 MS_FILTER_CLASS(klass)->max_finputs=MSLPC10ENCODER_MAX_INPUTS;
|
|
205 MS_FILTER_CLASS(klass)->max_foutputs=MSLPC10ENCODER_MAX_INPUTS;
|
|
206 MS_FILTER_CLASS(klass)->r_maxgran=LPC10_SAMPLES_PER_FRAME*2;
|
|
207 MS_FILTER_CLASS(klass)->w_maxgran=7;
|
|
208 MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_LPC10encoder_destroy;
|
|
209 MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_LPC10encoder_process;
|
|
210 MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&LPC10info;
|
|
211 }
|
|
212
|
|
213 void ms_LPC10encoder_process(MSLPC10Encoder *r)
|
|
214 {
|
|
215 MSFifo *fi,*fo;
|
|
216 int err1;
|
|
217 void *s,*d;
|
|
218 float speech[LPC10_SAMPLES_PER_FRAME];
|
|
219 INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
|
|
220
|
|
221 /* process output fifos, but there is only one for this class of filter*/
|
|
222
|
|
223 fi=r->f_inputs[0];
|
|
224 fo=r->f_outputs[0];
|
|
225 if (fi!=NULL)
|
|
226 {
|
|
227 err1=ms_fifo_get_read_ptr(fi,LPC10_SAMPLES_PER_FRAME*2,&s);
|
|
228 if (err1>0)
|
|
229 {
|
|
230 err1=ms_fifo_get_write_ptr(fo,7,&d);
|
|
231 if (d!=NULL)
|
|
232 {
|
|
233 read_16bit_samples((INT16*)s, speech, LPC10_SAMPLES_PER_FRAME);
|
|
234 lpc10_encode(speech, bits, r->lpc10_enc);
|
|
235 write_bits(d, bits, LPC10_BITS_IN_COMPRESSED_FRAME);
|
|
236 }
|
|
237 }
|
|
238
|
|
239 }
|
|
240 }
|
|
241
|
|
242 void ms_LPC10encoder_uninit(MSLPC10Encoder *obj)
|
|
243 {
|
|
244 free(obj->lpc10_enc);
|
|
245 }
|
|
246
|
|
247 void ms_LPC10encoder_destroy( MSLPC10Encoder *obj)
|
|
248 {
|
|
249 ms_LPC10encoder_uninit(obj);
|
|
250 g_free(obj);
|
|
251 }
|