Mercurial > pidgin
annotate src/mediastreamer/msilbcenc.c @ 12994:6ea877c5a444
[gaim-migrate @ 15347]
GrayShade noticed that we weren't dealing with the line delimiters that the current yahoo client sends correctly.
committer: Tailor Script <tailor@pidgin.im>
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Sun, 22 Jan 2006 22:23:00 +0000 |
parents | 1c771536a032 |
children |
rev | line source |
---|---|
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 | |
57 /* Convert floating point samples in range [-1,+1] to 16 bit | |
58 integers. */ | |
59 for (i = 0; i < n; i++) { | |
60 float dtmp=speech[i]; | |
61 if (dtmp<MIN_SAMPLE) | |
62 dtmp=MIN_SAMPLE; | |
63 else if (dtmp>MAX_SAMPLE) | |
64 dtmp=MAX_SAMPLE; | |
65 int16samples[i] = (short) dtmp; | |
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 ilbc_write_bits(unsigned char *data, unsigned char *bits, int nbytes) | |
87 { | |
88 memcpy(data, bits, nbytes); | |
89 } | |
90 | |
91 | |
92 | |
93 /* | |
94 | |
95 Read bits from file f into bits[0] through bits[len-1], in "packed" | |
96 format. | |
97 | |
98 */ | |
99 | |
100 int | |
101 ilbc_read_bits(unsigned char *data, unsigned char *bits, int nbytes) | |
102 { | |
103 | |
104 memcpy(bits, data, nbytes); | |
105 | |
106 return (nbytes); | |
107 } | |
108 | |
109 | |
110 | |
111 | |
112 static MSILBCEncoderClass *ms_ilbc_encoder_class=NULL; | |
113 | |
114 MSFilter * ms_ilbc_encoder_new(void) | |
115 { | |
116 MSILBCEncoder *r; | |
117 | |
118 r=g_new(MSILBCEncoder,1); | |
119 ms_ilbc_encoder_init(r); | |
120 if (ms_ilbc_encoder_class==NULL) | |
121 { | |
122 ms_ilbc_encoder_class=g_new(MSILBCEncoderClass,1); | |
123 ms_ilbc_encoder_class_init(ms_ilbc_encoder_class); | |
124 } | |
125 MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_ilbc_encoder_class); | |
126 return(MS_FILTER(r)); | |
127 } | |
128 | |
129 | |
130 int ms_ilbc_encoder_set_property(MSILBCEncoder *obj, MSFilterProperty prop, char *value) | |
131 { | |
132 switch(prop){ | |
133 case MS_FILTER_PROPERTY_FMTP: | |
134 obj->ms_per_frame=30; | |
135 #if 0 // SME | |
136 if (strstr(value,"ptime=20")!=NULL) obj->ms_per_frame=20; | |
137 else if (strstr(value,"ptime=30")!=NULL) obj->ms_per_frame=30; | |
138 else g_warning("Unrecognized fmtp parameter for ilbc encoder!"); | |
139 #endif | |
140 break; | |
12029
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
141 case MS_FILTER_PROPERTY_FREQ: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
142 case MS_FILTER_PROPERTY_BITRATE: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
143 case MS_FILTER_PROPERTY_CHANNELS: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
144 default: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
145 break; |
12024 | 146 } |
147 return 0; | |
148 } | |
149 | |
150 | |
151 int ms_ilbc_encoder_get_property(MSILBCEncoder *obj, MSFilterProperty prop, char *value) | |
152 { | |
153 switch(prop){ | |
154 case MS_FILTER_PROPERTY_FMTP: | |
155 if (obj->ms_per_frame==20) strncpy(value,"ptime=20",MS_FILTER_PROPERTY_STRING_MAX_SIZE); | |
156 if (obj->ms_per_frame==30) strncpy(value,"ptime=30",MS_FILTER_PROPERTY_STRING_MAX_SIZE); | |
157 break; | |
12029
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
158 case MS_FILTER_PROPERTY_FREQ: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
159 case MS_FILTER_PROPERTY_BITRATE: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
160 case MS_FILTER_PROPERTY_CHANNELS: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
161 default: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
162 break; |
12024 | 163 } |
164 return 0; | |
165 } | |
166 | |
167 void ms_ilbc_encoder_setup(MSILBCEncoder *r) | |
168 { | |
169 switch (r->ms_per_frame) { | |
170 case 20: | |
171 r->samples_per_frame = BLOCKL_20MS; | |
172 r->bytes_per_compressed_frame = NO_OF_BYTES_20MS; | |
173 break; | |
174 case 30: | |
175 r->samples_per_frame = BLOCKL_30MS; | |
176 r->bytes_per_compressed_frame = NO_OF_BYTES_30MS; | |
177 break; | |
178 default: | |
179 g_error("Bad bitrate value (%i) for ilbc encoder!", r->ms_per_frame); | |
180 break; | |
181 } | |
182 MS_FILTER(r)->r_mingran= (r->samples_per_frame * 2); | |
183 g_message("Using ilbc encoder with %i ms frames mode.",r->ms_per_frame); | |
184 initEncode(&r->ilbc_enc, r->ms_per_frame /* ms frames */); | |
185 } | |
186 | |
187 /* FOR INTERNAL USE*/ | |
188 void ms_ilbc_encoder_init(MSILBCEncoder *r) | |
189 { | |
190 /* default bitrate */ | |
191 r->bitrate = 15200; | |
192 r->ms_per_frame = 20; | |
193 r->samples_per_frame = BLOCKL_20MS; | |
194 r->bytes_per_compressed_frame = NO_OF_BYTES_20MS; | |
195 | |
196 ms_filter_init(MS_FILTER(r)); | |
197 MS_FILTER(r)->infifos=r->f_inputs; | |
198 MS_FILTER(r)->outqueues=r->q_outputs; | |
199 MS_FILTER(r)->r_mingran= (r->samples_per_frame * 2); | |
200 memset(r->f_inputs,0,sizeof(MSFifo*)*MSILBCENCODER_MAX_INPUTS); | |
201 memset(r->q_outputs,0,sizeof(MSFifo*)*MSILBCENCODER_MAX_INPUTS); | |
202 } | |
203 | |
204 void ms_ilbc_encoder_class_init(MSILBCEncoderClass *klass) | |
205 { | |
206 ms_filter_class_init(MS_FILTER_CLASS(klass)); | |
207 ms_filter_class_set_name(MS_FILTER_CLASS(klass),"ILBCEnc"); | |
208 MS_FILTER_CLASS(klass)->max_finputs=MSILBCENCODER_MAX_INPUTS; | |
209 MS_FILTER_CLASS(klass)->max_qoutputs=MSILBCENCODER_MAX_INPUTS; | |
210 MS_FILTER_CLASS(klass)->r_maxgran=ILBC_MAX_SAMPLES_PER_FRAME*2; | |
211 MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_ilbc_encoder_set_property; | |
212 MS_FILTER_CLASS(klass)->get_property=(MSFilterPropertyFunc)ms_ilbc_encoder_get_property; | |
213 MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_ilbc_encoder_setup; | |
214 MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_ilbc_encoder_destroy; | |
215 MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_ilbc_encoder_process; | |
216 MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&ilbc_info; | |
217 } | |
218 | |
219 void ms_ilbc_encoder_process(MSILBCEncoder *r) | |
220 { | |
221 MSFifo *fi; | |
222 MSQueue *qo; | |
223 MSMessage *m; | |
224 void *src=NULL; | |
225 float speech[ILBC_MAX_SAMPLES_PER_FRAME]; | |
226 | |
227 /* process output fifos, but there is only one for this class of filter*/ | |
228 | |
229 qo=r->q_outputs[0]; | |
230 fi=r->f_inputs[0]; | |
231 ms_fifo_get_read_ptr(fi,r->samples_per_frame*2,&src); | |
232 if (src==NULL) { | |
233 g_warning( "src=%p\n", src); | |
234 return; | |
235 } | |
236 m=ms_message_new(r->bytes_per_compressed_frame); | |
237 | |
238 ilbc_read_16bit_samples((gint16*)src, speech, r->samples_per_frame); | |
239 iLBC_encode((unsigned char *)m->data, speech, &r->ilbc_enc); | |
240 ms_queue_put(qo,m); | |
241 } | |
242 | |
243 void ms_ilbc_encoder_uninit(MSILBCEncoder *obj) | |
244 { | |
245 } | |
246 | |
247 void ms_ilbc_encoder_destroy( MSILBCEncoder *obj) | |
248 { | |
249 ms_ilbc_encoder_uninit(obj); | |
250 g_free(obj); | |
251 } | |
252 | |
253 #endif |