Mercurial > pidgin
annotate src/mediastreamer/msspeexdec.c @ 12237:3294e27cb54a
[gaim-migrate @ 14539]
Patch from sadrul to fix working with gtk < 2.6. Also a leak fix and a fix
for where we were double-markup-escaping things.
committer: Tailor Script <tailor@pidgin.im>
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Sun, 27 Nov 2005 18:03:51 +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 | |
22 #include "msspeexdec.h" | |
23 | |
24 #ifdef HAVE_GLIB | |
25 #include <gmodule.h> | |
26 #endif | |
27 | |
28 extern MSFilter * ms_speex_enc_new(); | |
29 | |
30 MSCodecInfo speex_info= | |
31 { | |
32 { | |
33 "Speex codec", | |
34 0, | |
35 MS_FILTER_AUDIO_CODEC, | |
36 ms_speex_dec_new, | |
37 "A high quality variable bit-rate codec from Jean Marc Valin and David Rowe." | |
38 }, | |
39 ms_speex_enc_new, | |
40 ms_speex_dec_new, | |
41 0, /*frame size */ | |
42 0, | |
43 8000, /*minimal bitrate */ | |
44 -1, /* sampling frequency */ | |
45 110, /* payload type */ | |
46 "speex", | |
47 1, | |
48 1 | |
49 }; | |
50 | |
51 | |
52 | |
53 void ms_speex_codec_init() | |
54 { | |
55 | |
56 ms_filter_register(MS_FILTER_INFO(&speex_info)); | |
57 //ms_filter_register(MS_FILTER_INFO(&speex_lbr_info)); | |
58 } | |
59 | |
60 #ifdef HAVE_GLIB | |
61 gchar * g_module_check_init(GModule *module) | |
62 { | |
63 ms_speex_codec_init(); | |
64 | |
65 return NULL; | |
66 } | |
67 #else | |
68 gchar * g_module_check_init() | |
69 { | |
70 ms_speex_codec_init(); | |
71 | |
72 return NULL; | |
73 } | |
74 #endif | |
75 | |
76 static MSSpeexDecClass * ms_speex_dec_class=NULL; | |
77 //static MSSpeexDecClass * ms_speexnb_dec_class=NULL; | |
78 | |
79 MSFilter * ms_speex_dec_new() | |
80 { | |
81 MSSpeexDec *obj=g_new(MSSpeexDec,1); | |
82 | |
83 if (ms_speex_dec_class==NULL){ | |
84 ms_speex_dec_class=g_new(MSSpeexDecClass,1); | |
85 ms_speex_dec_class_init(ms_speex_dec_class); | |
86 } | |
87 MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_speex_dec_class); | |
88 | |
89 ms_speex_dec_init(obj); | |
90 return MS_FILTER(obj); | |
91 } | |
92 | |
93 void ms_speex_dec_init(MSSpeexDec *obj) | |
94 { | |
95 ms_filter_init(MS_FILTER(obj)); | |
96 obj->initialized=0; | |
97 MS_FILTER(obj)->outfifos=obj->outf; | |
98 MS_FILTER(obj)->inqueues=obj->inq; | |
99 obj->outf[0]=NULL; | |
100 obj->inq[0]=NULL; | |
101 obj->frequency=8000; /*default value */ | |
102 | |
103 } | |
104 | |
105 void ms_speex_dec_init_core(MSSpeexDec *obj,const SpeexMode *mode) | |
106 { | |
107 int pf=1; | |
108 | |
109 obj->speex_state=speex_decoder_init(mode); | |
110 speex_bits_init(&obj->bits); | |
111 /* enable the perceptual post filter */ | |
112 speex_decoder_ctl(obj->speex_state,SPEEX_SET_PF, &pf); | |
113 | |
114 speex_mode_query(mode, SPEEX_MODE_FRAME_SIZE, &obj->frame_size); | |
115 | |
116 obj->initialized=1; | |
117 } | |
118 | |
119 int ms_speex_dec_set_property(MSSpeexDec *obj, MSFilterProperty prop, int *value) | |
120 { | |
121 if (obj->initialized){ | |
122 /* we are called when speex is running !! forbid that! */ | |
123 ms_warning("ms_speex_dec_set_property: cannot call this function when running!"); | |
124 return -1; | |
125 } | |
126 switch(prop){ | |
127 case MS_FILTER_PROPERTY_FREQ: | |
128 obj->frequency=value[0]; | |
129 break; | |
12029
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
130 case MS_FILTER_PROPERTY_BITRATE: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
131 case MS_FILTER_PROPERTY_CHANNELS: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
132 case MS_FILTER_PROPERTY_FMTP: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
133 default: |
1c771536a032
[gaim-migrate @ 14322]
Gary Kramlich <grim@reaperworld.com>
parents:
12024
diff
changeset
|
134 break; |
12024 | 135 } |
136 return 0; | |
137 } | |
138 | |
139 void ms_speex_dec_setup(MSSpeexDec *obj) | |
140 { | |
141 const SpeexMode *mode; | |
142 g_message("Speex decoder setup: freq=%i",obj->frequency); | |
143 if ( obj->frequency< 16000) mode=&speex_nb_mode; | |
144 else mode=&speex_wb_mode; | |
145 ms_speex_dec_init_core(obj,mode); | |
146 } | |
147 | |
148 void ms_speex_dec_unsetup(MSSpeexDec *obj) | |
149 { | |
150 ms_speex_dec_uninit_core(obj); | |
151 } | |
152 | |
153 void ms_speex_dec_class_init(MSSpeexDecClass *klass) | |
154 { | |
155 gint frame_size=0; | |
156 | |
157 ms_filter_class_init(MS_FILTER_CLASS(klass)); | |
158 /* use the largest frame size to configure fifos */ | |
159 speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &frame_size); | |
160 MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_speex_dec_process; | |
161 MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_speex_dec_setup; | |
162 MS_FILTER_CLASS(klass)->unsetup=(MSFilterSetupFunc)ms_speex_dec_unsetup; | |
163 MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_speex_dec_destroy; | |
164 MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_speex_dec_set_property; | |
165 ms_filter_class_set_name(MS_FILTER_CLASS(klass),"SpeexDecoder"); | |
166 MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&speex_info; | |
167 MS_FILTER_CLASS(klass)->max_foutputs=1; | |
168 MS_FILTER_CLASS(klass)->max_qinputs=1; | |
169 MS_FILTER_CLASS(klass)->w_maxgran=frame_size*2; | |
170 ms_trace("ms_speex_dec_class_init: w_maxgran is %i.",MS_FILTER_CLASS(klass)->w_maxgran); | |
171 } | |
172 | |
173 void ms_speex_dec_uninit_core(MSSpeexDec *obj) | |
174 { | |
175 speex_decoder_destroy(obj->speex_state); | |
176 obj->initialized=0; | |
177 } | |
178 | |
179 void ms_speex_dec_uninit(MSSpeexDec *obj) | |
180 { | |
181 | |
182 } | |
183 | |
184 void ms_speex_dec_destroy(MSSpeexDec *obj) | |
185 { | |
186 ms_speex_dec_uninit(obj); | |
187 g_free(obj); | |
188 } | |
189 | |
190 void ms_speex_dec_process(MSSpeexDec *obj) | |
191 { | |
192 MSFifo *outf=obj->outf[0]; | |
193 MSQueue *inq=obj->inq[0]; | |
194 gint16 *output; | |
195 gint gran=obj->frame_size*2; | |
196 MSMessage *m; | |
197 | |
198 g_return_if_fail(inq!=NULL); | |
199 g_return_if_fail(outf!=NULL); | |
200 | |
201 m=ms_queue_get(inq); | |
202 g_return_if_fail(m!=NULL); | |
203 speex_bits_reset(&obj->bits); | |
204 ms_fifo_get_write_ptr(outf,gran,(void**)&output); | |
205 g_return_if_fail(output!=NULL); | |
206 if (m->data!=NULL){ | |
207 | |
208 speex_bits_read_from(&obj->bits,m->data,m->size); | |
209 /* decode */ | |
210 speex_decode_int(obj->speex_state,&obj->bits,(short*)output); | |
211 }else{ | |
212 /* we have a missing packet */ | |
213 speex_decode_int(obj->speex_state,NULL,(short*)output); | |
214 } | |
215 ms_message_destroy(m); | |
216 | |
217 } |