src/mediastreamer/hpuxsndcard.c

branch
gaim
changeset 20470
77693555855f
parent 13071
b98e72d4089a
parent 20469
b2836a24d81e
child 20471
1966704b3e42
equal deleted inserted replaced
13071:b98e72d4089a 20470:77693555855f
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 "sndcard.h"
22 #include "osscard.h"
23
24 #ifdef HAVE_SYS_AUDIO_H
25 #include <sys/audio.h>
26
27
28 #include "msossread.h"
29 #include "msosswrite.h"
30
31 #include <errno.h>
32 #include <fcntl.h>
33
34
35 int hpuxsnd_open(HpuxSndCard *obj, int bits,int stereo, int rate)
36 {
37 int fd;
38 int p=0,cond=0;
39 int i=0;
40 int min_size=0,blocksize=512;
41 /* do a quick non blocking open to be sure that we are not going to be blocked here
42 for the eternity */
43 fd=open(obj->dev_name,O_RDWR|O_NONBLOCK);
44 if (fd<0) return -EWOULDBLOCK;
45 close(fd);
46 /* open the device */
47 fd=open(obj->dev_name,O_RDWR);
48
49 g_return_val_if_fail(fd>0,-errno);
50
51 ioctl(fd,AUDIO_RESET,0);
52 ioctl(fd,AUDIO_SET_SAMPLE_RATE,rate);
53 ioctl(fd,AUDIO_SET_CHANNELS,stereo);
54 p=AUDIO_FORMAT_LINEAR16BIT;
55 ioctl(fd,AUDIO_SET_DATA_FORMAT,p);
56 /* ioctl(fd,AUDIO_GET_RXBUFSIZE,&min_size); does not work ? */
57 min_size=2048;
58
59 g_message("dsp blocksize is %i.",min_size);
60 obj->fd=fd;
61 obj->readpos=0;
62 obj->writepos=0;
63 SND_CARD(obj)->bits=bits;
64 SND_CARD(obj)->stereo=stereo;
65 SND_CARD(obj)->rate=rate;
66 SND_CARD(obj)->bsize=min_size;
67 return fd;
68 }
69
70 int hpux_snd_card_probe(HpuxSndCard *obj,int bits,int stereo,int rate)
71 {
72 return 2048;
73 }
74
75
76 int hpux_snd_card_open(HpuxSndCard *obj,int bits,int stereo,int rate)
77 {
78 int fd;
79 obj->ref++;
80 if (obj->fd==0){
81 fd=hpuxsnd_open(obj,bits,stereo,rate);
82 if (fd<0) {
83 obj->fd=0;
84 obj->ref--;
85 return -1;
86 }
87 }
88 SND_CARD(obj)->flags|=SND_CARD_FLAGS_OPENED;
89 return 0;
90 }
91
92 void hpux_snd_card_close(HpuxSndCard *obj)
93 {
94 int i;
95 obj->ref--;
96 if (obj->ref==0) {
97 close(obj->fd);
98 obj->fd=0;
99 SND_CARD(obj)->flags&=~SND_CARD_FLAGS_OPENED;
100
101 }
102 }
103
104 void hpux_snd_card_destroy(HpuxSndCard *obj)
105 {
106 snd_card_uninit(SND_CARD(obj));
107 g_free(obj->dev_name);
108 g_free(obj->mixdev_name);
109 }
110
111 gboolean hpux_snd_card_can_read(HpuxSndCard *obj)
112 {
113 struct timeval tout={0,0};
114 int err;
115 fd_set fdset;
116 FD_ZERO(&fdset);
117 FD_SET(obj->fd,&fdset);
118 err=select(obj->fd+1,&fdset,NULL,NULL,&tout);
119 if (err>0) return TRUE;
120 else return FALSE;
121 }
122
123 int hpux_snd_card_read(HpuxSndCard *obj,char *buf,int size)
124 {
125 int err;
126 gint bsize=SND_CARD(obj)->bsize;
127 if (size<bsize){
128 gint canread=MIN(bsize-obj->readpos,size);
129 if (obj->readbuf==NULL) obj->readbuf=g_malloc0(bsize);
130 if (obj->readpos==0){
131 err=read(obj->fd,obj->readbuf,bsize);
132 if (err<0) {
133 g_warning("hpux_snd_card_read: read() failed:%s.",strerror(errno));
134 return -1;
135 }
136 }
137
138 memcpy(buf,&obj->readbuf[obj->readpos],canread);
139 obj->readpos+=canread;
140 if (obj->readpos>=bsize) obj->readpos=0;
141 return canread;
142 }else{
143 err=read(obj->fd,buf,size);
144 if (err<0) {
145 g_warning("hpux_snd_card_read: read-2() failed:%s.",strerror(errno));
146 }
147 return err;
148 }
149
150 }
151
152 int hpux_snd_card_write(HpuxSndCard *obj,char *buf,int size)
153 {
154 int err;
155 gint bsize=SND_CARD(obj)->bsize;
156 if (size<bsize){
157 gint canwrite=MIN(bsize-obj->writepos,size);
158 if (obj->writebuf==NULL) obj->writebuf=g_malloc0(bsize);
159
160 memcpy(&obj->writebuf[obj->writepos],buf,canwrite);
161 obj->writepos+=canwrite;
162 if (obj->writepos>=bsize){
163 err=write(obj->fd,obj->writebuf,bsize);
164 }
165 return canwrite;
166 }else{
167 return write(obj->fd,buf,bsize);
168 }
169 }
170
171 #define SND_CARD_LEVEL_TO_HPUX_LEVEL(a) (((a)*2) - 100)
172 #define HPUX_LEVEL_TO_SND_CARD_LEVEL(a) (((a)+200)/2)
173 void hpux_snd_card_set_level(HpuxSndCard *obj,gint way,gint a)
174 {
175 struct audio_gain gain;
176 int error,mix_fd;
177
178 g_return_if_fail(obj->mixdev_name!=NULL);
179 memset(&gain,0,sizeof(struct audio_gain));
180 switch(way){
181 case SND_CARD_LEVEL_GENERAL:
182 gain.cgain[0].monitor_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
183 gain.cgain[1].monitor_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
184 break;
185 case SND_CARD_LEVEL_INPUT:
186 gain.cgain[0].receive_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
187 gain.cgain[1].receive_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
188 break;
189 case SND_CARD_LEVEL_OUTPUT:
190 gain.cgain[0].transmit_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
191 gain.cgain[1].transmit_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
192 break;
193 default:
194 g_warning("hpux_snd_card_set_level: unsupported command.");
195 return;
196 }
197 gain.channel_mask=AUDIO_CHANNEL_RIGHT|AUDIO_CHANNEL_LEFT;
198 mix_fd = open(obj->mixdev_name, O_WRONLY);
199 g_return_if_fail(mix_fd>0);
200 error=ioctl(mix_fd,AUDIO_SET_GAINS,&gain);
201 if (error<0){
202 g_warning("hpux_snd_card_set_level: Could not set gains: %s",strerror(errno));
203 }
204 close(mix_fd);
205 }
206
207 gint hpux_snd_card_get_level(HpuxSndCard *obj,gint way)
208 {
209 struct audio_gain gain;
210 int p=0,mix_fd,error;
211 g_return_if_fail(obj->mixdev_name!=NULL);
212
213 gain.channel_mask=AUDIO_CHANNEL_RIGHT|AUDIO_CHANNEL_LEFT;
214 mix_fd = open(obj->mixdev_name, O_RDONLY);
215 g_return_if_fail(mix_fd>0);
216 error=ioctl(mix_fd,AUDIO_GET_GAINS,&gain);
217 if (error<0){
218 g_warning("hpux_snd_card_set_level: Could not get gains: %s",strerror(errno));
219 }
220 close(mix_fd);
221
222 switch(way){
223 case SND_CARD_LEVEL_GENERAL:
224 p=gain.cgain[0].monitor_gain;
225 break;
226 case SND_CARD_LEVEL_INPUT:
227 p=gain.cgain[0].receive_gain;
228 break;
229 case SND_CARD_LEVEL_OUTPUT:
230 p=gain.cgain[0].transmit_gain;
231 break;
232 default:
233 g_warning("hpux_snd_card_get_level: unsupported command.");
234 return -1;
235 }
236 return HPUX_LEVEL_TO_SND_CARD_LEVEL(p);
237 }
238
239 void hpux_snd_card_set_source(HpuxSndCard *obj,int source)
240 {
241 gint p=0;
242 gint mix_fd;
243 gint error=0;
244 g_return_if_fail(obj->mixdev_name!=NULL);
245
246 mix_fd=open("/dev/audio",O_WRONLY);
247 g_return_if_fail(mix_fd>0);
248 switch(source){
249 case 'm':
250 error=ioctl(mix_fd,AUDIO_SET_INPUT,AUDIO_IN_MIKE);
251 break;
252 case 'l':
253 error=ioctl(mix_fd,AUDIO_SET_INPUT,AUDIO_IN_LINE);
254 break;
255 default:
256 g_warning("hpux_snd_card_set_source: unsupported source.");
257 }
258 close(mix_fd);
259 }
260
261 MSFilter *hpux_snd_card_create_read_filter(HpuxSndCard *card)
262 {
263 MSFilter *f=ms_oss_read_new();
264 ms_oss_read_set_device(MS_OSS_READ(f),SND_CARD(card)->index);
265 return f;
266 }
267
268 MSFilter *hpux_snd_card_create_write_filter(HpuxSndCard *card)
269 {
270 MSFilter *f=ms_oss_write_new();
271 ms_oss_write_set_device(MS_OSS_WRITE(f),SND_CARD(card)->index);
272 return f;
273 }
274
275
276 SndCard * hpux_snd_card_new(char *devname, char *mixdev_name)
277 {
278 HpuxSndCard * obj= g_new0(HpuxSndCard,1);
279 SndCard *base= SND_CARD(obj);
280 snd_card_init(base);
281 obj->dev_name=g_strdup(devname);
282 obj->mixdev_name=g_strdup( mixdev_name);
283 base->card_name=g_strdup(devname);
284 base->_probe=(SndCardOpenFunc)hpux_snd_card_probe;
285 base->_open_r=(SndCardOpenFunc)hpux_snd_card_open;
286 base->_open_w=(SndCardOpenFunc)hpux_snd_card_open;
287 base->_can_read=(SndCardPollFunc)hpux_snd_card_can_read;
288 base->_read=(SndCardIOFunc)hpux_snd_card_read;
289 base->_write=(SndCardIOFunc)hpux_snd_card_write;
290 base->_close_r=(SndCardCloseFunc)hpux_snd_card_close;
291 base->_close_w=(SndCardCloseFunc)hpux_snd_card_close;
292 base->_set_rec_source=(SndCardMixerSetRecSourceFunc)hpux_snd_card_set_source;
293 base->_set_level=(SndCardMixerSetLevelFunc)hpux_snd_card_set_level;
294 base->_get_level=(SndCardMixerGetLevelFunc)hpux_snd_card_get_level;
295 base->_destroy=(SndCardDestroyFunc)hpux_snd_card_destroy;
296 base->_create_read_filter=(SndCardCreateFilterFunc)hpux_snd_card_create_read_filter;
297 base->_create_write_filter=(SndCardCreateFilterFunc)hpux_snd_card_create_write_filter;
298 return base;
299 }
300
301 #endif

mercurial