1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
27 #include "allobjects.h"
28 #include "modsupport.h"
29 #include "structmember.h"
31 #ifdef HAVE_SYS_AUDIOIO_H
36 #include <sys/ioctl.h>
38 #include <sys/audioio.h>
40 #include <sun/audioio.h>
43 /* #define offsetof(str,mem) ((int)(((str *)0)->mem)) */
47 int x_fd
; /* The open file */
48 int x_icount
; /* # samples read */
49 int x_ocount
; /* # samples written */
50 int x_isctl
; /* True if control device */
59 staticforward typeobject Sadtype
;
60 staticforward typeobject Sadstatustype
;
61 static sadstatusobject
*sads_alloc(); /* Forward */
63 static object
*SunAudioError
;
65 static int dummy_for_dl
;
67 #define is_sadobject(v) ((v)->ob_type == &Sadtype)
68 #define is_sadstatusobject(v) ((v)->ob_type == &Sadstatustype)
79 /* Check arg for r/w/rw */
80 if ( !getargs(arg
, "s", &mode
) )
82 if ( strcmp(mode
, "r") == 0 )
84 else if ( strcmp(mode
, "w") == 0 )
86 else if ( strcmp(mode
, "rw") == 0 )
88 else if ( strcmp(mode
, "control") == 0 )
91 err_setstr(SunAudioError
,
92 "Mode should be one of 'r', 'w', 'rw' or 'control'");
96 /* Open the correct device */
98 fd
= open("/dev/audioctl", 2); /* XXXX Chaeck that this works */
100 fd
= open("/dev/audio", imode
);
102 err_errno(SunAudioError
);
106 /* Create and initialize the object */
107 xp
= NEWOBJ(sadobject
, &Sadtype
);
111 xp
->x_icount
= xp
->x_ocount
= 0;
112 xp
->x_isctl
= (imode
< 0);
136 if ( !getargs(args
, "i", &size
) )
138 rv
= newsizedstringobject(NULL
, size
);
142 cp
= getstringvalue(rv
);
144 count
= read(self
->x_fd
, cp
, size
);
147 err_errno(SunAudioError
);
151 printf("sunaudio: funny read rv %d wtd %d\n", count
, size
);
152 self
->x_icount
+= count
;
157 sad_write(self
, args
)
164 if ( !getargs(args
, "s#", &cp
, &size
) )
167 count
= write(self
->x_fd
, cp
, size
);
169 err_errno(SunAudioError
);
173 printf("sunaudio: funny write rv %d wanted %d\n", count
, size
);
174 self
->x_ocount
+= count
;
181 sad_getinfo(self
, args
)
187 if ( !getargs(args
, "") )
190 if ( ioctl(self
->x_fd
, AUDIO_GETINFO
, &rv
->ai
) < 0 ) {
191 err_errno(SunAudioError
);
199 sad_setinfo(self
, arg
)
201 sadstatusobject
*arg
;
203 if ( !is_sadstatusobject(arg
) ) {
204 err_setstr(TypeError
, "Must be sun audio status object");
207 if ( ioctl(self
->x_fd
, AUDIO_SETINFO
, &arg
->ai
) < 0 ) {
208 err_errno(SunAudioError
);
216 sad_ibufcount(self
, args
)
223 if ( !getargs(args
, "") )
225 if ( ioctl(self
->x_fd
, AUDIO_GETINFO
, &ai
) < 0 ) {
226 err_errno(SunAudioError
);
229 rv
= newintobject(ai
.record
.samples
- self
->x_icount
);
234 sad_obufcount(self
, args
)
241 if ( !getargs(args
, "") )
243 if ( ioctl(self
->x_fd
, AUDIO_GETINFO
, &ai
) < 0 ) {
244 err_errno(SunAudioError
);
247 rv
= newintobject(self
->x_ocount
- ai
.play
.samples
);
252 sad_drain(self
, args
)
257 if ( !getargs(args
, "") )
259 if ( ioctl(self
->x_fd
, AUDIO_DRAIN
, 0) < 0 ) {
260 err_errno(SunAudioError
);
269 sad_getdev(self
, args
)
273 struct audio_device ad
;
275 if ( !getargs(args
, "") )
277 if ( ioctl(self
->x_fd
, AUDIO_GETDEV
, &ad
) < 0 ) {
278 err_errno(SunAudioError
);
281 return mkvalue("(sss)", ad
.name
, ad
.version
, ad
.config
);
286 sad_flush(self
, args
)
291 if ( !getargs(args
, "") )
293 if ( ioctl(self
->x_fd
, I_FLUSH
, FLUSHW
) < 0 ) {
294 err_errno(SunAudioError
);
302 sad_close(self
, args
)
307 if ( !getargs(args
, "") )
309 if ( self
->x_fd
>= 0 ) {
317 static struct methodlist sad_methods
[] = {
318 { "read", sad_read
},
319 { "write", sad_write
},
320 { "ibufcount", sad_ibufcount
},
321 { "obufcount", sad_obufcount
},
322 #define CTL_METHODS 4
323 { "getinfo", sad_getinfo
},
324 { "setinfo", sad_setinfo
},
325 { "drain", sad_drain
},
326 { "flush", sad_flush
},
328 { "getdev", sad_getdev
},
330 { "close", sad_close
},
331 {NULL
, NULL
} /* sentinel */
335 sad_getattr(xp
, name
)
340 return findmethod(sad_methods
+CTL_METHODS
, (object
*)xp
, name
);
342 return findmethod(sad_methods
, (object
*)xp
, name
);
345 /* ----------------------------------------------------------------- */
347 static sadstatusobject
*
351 rv
= NEWOBJ(sadstatusobject
, &Sadstatustype
);
362 #define OFF(x) offsetof(audio_info_t,x)
363 static struct memberlist sads_ml
[] = {
364 { "i_sample_rate", T_UINT
, OFF(record
.sample_rate
) },
365 { "i_channels", T_UINT
, OFF(record
.channels
) },
366 { "i_precision", T_UINT
, OFF(record
.precision
) },
367 { "i_encoding", T_UINT
, OFF(record
.encoding
) },
368 { "i_gain", T_UINT
, OFF(record
.gain
) },
369 { "i_port", T_UINT
, OFF(record
.port
) },
370 { "i_samples", T_UINT
, OFF(record
.samples
) },
371 { "i_eof", T_UINT
, OFF(record
.eof
) },
372 { "i_pause", T_UBYTE
, OFF(record
.pause
) },
373 { "i_error", T_UBYTE
, OFF(record
.error
) },
374 { "i_waiting", T_UBYTE
, OFF(record
.waiting
) },
375 { "i_open", T_UBYTE
, OFF(record
.open
) , RO
},
376 { "i_active", T_UBYTE
, OFF(record
.active
) , RO
},
378 { "i_buffer_size", T_UINT
, OFF(record
.buffer_size
) },
379 { "i_balance", T_UBYTE
, OFF(record
.balance
) },
380 { "i_avail_ports", T_UINT
, OFF(record
.avail_ports
) },
383 { "o_sample_rate", T_UINT
, OFF(play
.sample_rate
) },
384 { "o_channels", T_UINT
, OFF(play
.channels
) },
385 { "o_precision", T_UINT
, OFF(play
.precision
) },
386 { "o_encoding", T_UINT
, OFF(play
.encoding
) },
387 { "o_gain", T_UINT
, OFF(play
.gain
) },
388 { "o_port", T_UINT
, OFF(play
.port
) },
389 { "o_samples", T_UINT
, OFF(play
.samples
) },
390 { "o_eof", T_UINT
, OFF(play
.eof
) },
391 { "o_pause", T_UBYTE
, OFF(play
.pause
) },
392 { "o_error", T_UBYTE
, OFF(play
.error
) },
393 { "o_waiting", T_UBYTE
, OFF(play
.waiting
) },
394 { "o_open", T_UBYTE
, OFF(play
.open
) , RO
},
395 { "o_active", T_UBYTE
, OFF(play
.active
) , RO
},
397 { "o_buffer_size", T_UINT
, OFF(play
.buffer_size
) },
398 { "o_balance", T_UBYTE
, OFF(play
.balance
) },
399 { "o_avail_ports", T_UINT
, OFF(play
.avail_ports
) },
402 { "monitor_gain", T_UINT
, OFF(monitor_gain
) },
407 sads_getattr(xp
, name
)
411 return getmember((char *)&xp
->ai
, sads_ml
, name
);
415 sads_setattr(xp
, name
, v
)
422 err_setstr(TypeError
,
423 "can't delete sun audio status attributes");
426 return setmember((char *)&xp
->ai
, sads_ml
, name
, v
);
429 /* ------------------------------------------------------------------- */
432 static typeobject Sadtype
= {
433 OB_HEAD_INIT(&Typetype
)
435 "sun_audio_device", /*tp_name*/
436 sizeof(sadobject
), /*tp_size*/
439 (destructor
)sad_dealloc
, /*tp_dealloc*/
441 (getattrfunc
)sad_getattr
, /*tp_getattr*/
447 static typeobject Sadstatustype
= {
448 OB_HEAD_INIT(&Typetype
)
450 "sun_audio_device_status", /*tp_name*/
451 sizeof(sadstatusobject
), /*tp_size*/
454 (destructor
)sads_dealloc
, /*tp_dealloc*/
456 (getattrfunc
)sads_getattr
, /*tp_getattr*/
457 (setattrfunc
)sads_setattr
, /*tp_setattr*/
461 /* ------------------------------------------------------------------- */
470 rv
= (object
*)newsadobject(args
);
474 static struct methodlist sunaudiodev_methods
[] = {
483 m
= initmodule("sunaudiodev", sunaudiodev_methods
);
484 d
= getmoduledict(m
);
485 SunAudioError
= newstringobject("sunaudiodev.error");
486 if ( SunAudioError
== NULL
|| dictinsert(d
, "error", SunAudioError
) )
487 fatal("can't define sunaudiodev.error");