|
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 "msosswrite.h"
|
|
|
22 #include "mssync.h"
|
|
|
23 #include <unistd.h>
|
|
|
24 #include <math.h>
|
|
|
25
|
|
|
26 MSFilterInfo oss_write_info={
|
|
|
27 "OSS write",
|
|
|
28 0,
|
|
|
29 MS_FILTER_OTHER,
|
|
|
30 ms_oss_write_new,
|
|
|
31 NULL
|
|
|
32 };
|
|
|
33
|
|
|
34
|
|
|
35 static MSOssWriteClass *msosswriteclass=NULL;
|
|
|
36
|
|
|
37 MSFilter * ms_oss_write_new()
|
|
|
38 {
|
|
|
39 MSOssWrite *w;
|
|
|
40
|
|
|
41 if (msosswriteclass==NULL)
|
|
|
42 {
|
|
|
43 msosswriteclass=g_new(MSOssWriteClass,1);
|
|
|
44 ms_oss_write_class_init( msosswriteclass );
|
|
|
45 }
|
|
|
46 w=g_new(MSOssWrite,1);
|
|
|
47 MS_FILTER(w)->klass=MS_FILTER_CLASS(msosswriteclass);
|
|
|
48 ms_oss_write_init(w);
|
|
|
49 return(MS_FILTER(w));
|
|
|
50 }
|
|
|
51
|
|
|
52 /* FOR INTERNAL USE*/
|
|
|
53 void ms_oss_write_init(MSOssWrite *w)
|
|
|
54 {
|
|
|
55 ms_sound_write_init(MS_SOUND_WRITE(w));
|
|
|
56 MS_FILTER(w)->infifos=w->f_inputs;
|
|
|
57 MS_FILTER(w)->infifos[0]=NULL;
|
|
|
58 MS_FILTER(w)->r_mingran=512; /* very few cards can do that...*/
|
|
|
59 w->devid=0;
|
|
|
60 w->sndcard=NULL;
|
|
|
61 w->freq=8000;
|
|
|
62 w->channels=1;
|
|
|
63 w->dtmf_time=-1;
|
|
|
64 }
|
|
|
65
|
|
|
66 gint ms_oss_write_set_property(MSOssWrite *f,MSFilterProperty prop, void *value)
|
|
|
67 {
|
|
|
68 switch(prop){
|
|
|
69 case MS_FILTER_PROPERTY_FREQ:
|
|
|
70 f->freq=((gint*)value)[0];
|
|
|
71 break;
|
|
|
72 case MS_FILTER_PROPERTY_CHANNELS:
|
|
|
73 f->channels=((gint*)value)[0];
|
|
|
74 break;
|
|
|
75 }
|
|
|
76 return 0;
|
|
|
77 }
|
|
|
78
|
|
|
79 void ms_oss_write_class_init(MSOssWriteClass *klass)
|
|
|
80 {
|
|
|
81 ms_sound_write_class_init(MS_SOUND_WRITE_CLASS(klass));
|
|
|
82 MS_FILTER_CLASS(klass)->max_finputs=1; /* one fifo input only */
|
|
|
83 MS_FILTER_CLASS(klass)->r_maxgran=MS_OSS_WRITE_DEF_GRAN;
|
|
|
84 MS_FILTER_CLASS(klass)->process= (MSFilterProcessFunc)ms_oss_write_process;
|
|
|
85 MS_FILTER_CLASS(klass)->destroy= (MSFilterDestroyFunc)ms_oss_write_destroy;
|
|
|
86 MS_FILTER_CLASS(klass)->setup= (MSFilterSetupFunc)ms_oss_write_setup;
|
|
|
87 MS_FILTER_CLASS(klass)->unsetup= (MSFilterSetupFunc)ms_oss_write_stop;
|
|
|
88 MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_oss_write_set_property;
|
|
|
89 MS_FILTER_CLASS(klass)->info=&oss_write_info;
|
|
|
90 MS_SOUND_WRITE_CLASS(klass)->set_device=(gint (*)(MSSoundWrite*,gint))ms_oss_write_set_device;
|
|
|
91 MS_SOUND_WRITE_CLASS(klass)->start=(void (*)(MSSoundWrite*))ms_oss_write_start;
|
|
|
92 MS_SOUND_WRITE_CLASS(klass)->stop=(void (*)(MSSoundWrite*))ms_oss_write_stop;
|
|
|
93 MS_SOUND_WRITE_CLASS(klass)->set_level=(void (*)(MSSoundWrite*, gint))ms_oss_write_set_level;
|
|
|
94 ms_filter_class_set_name(MS_FILTER_CLASS(klass),"OssWrite");
|
|
|
95 }
|
|
|
96
|
|
|
97 void ms_oss_write_destroy( MSOssWrite *obj)
|
|
|
98 {
|
|
|
99
|
|
|
100 g_free(obj);
|
|
|
101 }
|
|
|
102
|
|
|
103 void ms_oss_write_process(MSOssWrite *f)
|
|
|
104 {
|
|
|
105 MSFifo *fifo;
|
|
|
106 void *p;
|
|
|
107 int i;
|
|
|
108 gint gran=ms_filter_get_mingran(MS_FILTER(f));
|
|
|
109
|
|
|
110 /* always consume something */
|
|
|
111 fifo=f->f_inputs[0];
|
|
|
112 ms_fifo_get_read_ptr(fifo,gran,&p);
|
|
|
113 if (p==NULL) {
|
|
|
114 g_warning("Not enough data: gran=%i.",gran);
|
|
|
115 return;
|
|
|
116 }
|
|
|
117 g_return_if_fail(f->sndcard!=NULL);
|
|
|
118 if (f->dtmf_time!=-1){
|
|
|
119 gint16 *buf=(gint16*)p;
|
|
|
120 /* generate a DTMF*/
|
|
|
121 for(i=0;i<gran/2;i++){
|
|
|
122 buf[i]=(gint16)(10000.0*sin(2*M_PI*(double)f->dtmf_time*f->lowfreq));
|
|
|
123 buf[i]+=(gint16)(10000.0*sin(2*M_PI*(double)f->dtmf_time*f->highfreq));
|
|
|
124 f->dtmf_time++;
|
|
|
125 //printf("buf[%i]=%i\n",i,buf[i]);
|
|
|
126 }
|
|
|
127 if (f->dtmf_time>f->dtmf_duration) f->dtmf_time=-1; /*finished*/
|
|
|
128 }
|
|
|
129 snd_card_write(f->sndcard,p,gran);
|
|
|
130 }
|
|
|
131
|
|
|
132 void ms_oss_write_start(MSOssWrite *w)
|
|
|
133 {
|
|
|
134 gint bsize;
|
|
|
135 g_return_if_fail(w->devid!=-1);
|
|
|
136 w->sndcard=snd_card_manager_get_card(snd_card_manager,w->devid);
|
|
|
137 g_return_if_fail(w->sndcard!=NULL);
|
|
|
138 /* open the device for an audio telephony signal with minimum latency */
|
|
|
139 snd_card_open_w(w->sndcard,16,w->channels==2,w->freq);
|
|
|
140 w->bsize=snd_card_get_bsize(w->sndcard);
|
|
|
141 //MS_FILTER(w)->r_mingran=w->bsize;
|
|
|
142 //ms_sync_set_samples_per_tick(MS_FILTER(w)->sync,bsize);
|
|
|
143 }
|
|
|
144
|
|
|
145 void ms_oss_write_stop(MSOssWrite *w)
|
|
|
146 {
|
|
|
147 g_return_if_fail(w->devid!=-1);
|
|
|
148 g_return_if_fail(w->sndcard!=NULL);
|
|
|
149 snd_card_close_w(w->sndcard);
|
|
|
150 w->sndcard=NULL;
|
|
|
151 }
|
|
|
152
|
|
|
153 void ms_oss_write_set_level(MSOssWrite *w,gint a)
|
|
|
154 {
|
|
|
155
|
|
|
156 }
|
|
|
157
|
|
|
158 gint ms_oss_write_set_device(MSOssWrite *w, gint devid)
|
|
|
159 {
|
|
|
160 w->devid=devid;
|
|
|
161 return 0;
|
|
|
162 }
|
|
|
163
|
|
|
164 void ms_oss_write_setup(MSOssWrite *r)
|
|
|
165 {
|
|
|
166 //g_message("starting MSOssWrite..");
|
|
|
167 ms_oss_write_start(r);
|
|
|
168 }
|
|
|
169
|
|
|
170
|
|
|
171
|
|
|
172 void ms_oss_write_play_dtmf(MSOssWrite *w, char dtmf){
|
|
|
173
|
|
|
174 w->dtmf_duration=0.1*w->freq;
|
|
|
175 switch(dtmf){
|
|
|
176 case '0':
|
|
|
177 w->lowfreq=941;
|
|
|
178 w->highfreq=1336;
|
|
|
179 break;
|
|
|
180 case '1':
|
|
|
181 w->lowfreq=697;
|
|
|
182 w->highfreq=1209;
|
|
|
183 break;
|
|
|
184 case '2':
|
|
|
185 w->lowfreq=697;
|
|
|
186 w->highfreq=1336;
|
|
|
187 break;
|
|
|
188 case '3':
|
|
|
189 w->lowfreq=697;
|
|
|
190 w->highfreq=1477;
|
|
|
191 break;
|
|
|
192 case '4':
|
|
|
193 w->lowfreq=770;
|
|
|
194 w->highfreq=1209;
|
|
|
195 break;
|
|
|
196 case '5':
|
|
|
197 w->lowfreq=770;
|
|
|
198 w->highfreq=1336;
|
|
|
199 break;
|
|
|
200 case '6':
|
|
|
201 w->lowfreq=770;
|
|
|
202 w->highfreq=1477;
|
|
|
203 break;
|
|
|
204 case '7':
|
|
|
205 w->lowfreq=852;
|
|
|
206 w->highfreq=1209;
|
|
|
207 break;
|
|
|
208 case '8':
|
|
|
209 w->lowfreq=852;
|
|
|
210 w->highfreq=1336;
|
|
|
211 break;
|
|
|
212 case '9':
|
|
|
213 w->lowfreq=852;
|
|
|
214 w->highfreq=1477;
|
|
|
215 break;
|
|
|
216 case '*':
|
|
|
217 w->lowfreq=941;
|
|
|
218 w->highfreq=1209;
|
|
|
219 break;
|
|
|
220 case '#':
|
|
|
221 w->lowfreq=941;
|
|
|
222 w->highfreq=1477;
|
|
|
223 break;
|
|
|
224 case 'A':
|
|
|
225 w->lowfreq=697;
|
|
|
226 w->highfreq=1633;
|
|
|
227 break;
|
|
|
228 case 'B':
|
|
|
229 w->lowfreq=770;
|
|
|
230 w->highfreq=1633;
|
|
|
231 break;
|
|
|
232 case 'C':
|
|
|
233 w->lowfreq=852;
|
|
|
234 w->highfreq=1633;
|
|
|
235 break;
|
|
|
236 case 'D':
|
|
|
237 w->lowfreq=941;
|
|
|
238 w->highfreq=1633;
|
|
|
239 break;
|
|
|
240 default:
|
|
|
241 g_warning("Not a dtmf key.");
|
|
|
242 return;
|
|
|
243 }
|
|
|
244 w->lowfreq=w->lowfreq/w->freq;
|
|
|
245 w->highfreq=w->highfreq/w->freq;
|
|
|
246 w->dtmf_time=0;
|
|
|
247 }
|