1998-06-16 16:06:32 +00:00
|
|
|
*** linux_a.c.orig Mon May 20 17:09:46 1996
|
1998-06-16 18:28:32 +00:00
|
|
|
--- linux_a.c Tue Jun 16 21:40:17 1998
|
1998-06-16 16:06:32 +00:00
|
|
|
***************
|
|
|
|
*** 71,82 ****
|
|
|
|
then 8-bit unsigned if it fails. If you have a sound device that
|
|
|
|
can't handle either, let me know. */
|
|
|
|
|
|
|
|
static int open_output(void)
|
|
|
|
{
|
|
|
|
int fd, tmp, i, warnings=0;
|
|
|
|
|
|
|
|
/* Open the audio device */
|
|
|
|
! fd=open(dpm.name, O_RDWR | O_NDELAY);
|
|
|
|
if (fd<0)
|
|
|
|
{
|
|
|
|
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
|
|
|
|
--- 71,85 ----
|
|
|
|
then 8-bit unsigned if it fails. If you have a sound device that
|
|
|
|
can't handle either, let me know. */
|
|
|
|
|
|
|
|
+ /* Flag for Luigi Rizzo new sound driver (as opposed to VoxWare) */
|
|
|
|
+ static luigi_driver = 0;
|
|
|
|
+
|
|
|
|
static int open_output(void)
|
|
|
|
{
|
|
|
|
int fd, tmp, i, warnings=0;
|
|
|
|
|
|
|
|
/* Open the audio device */
|
|
|
|
! fd=open(dpm.name, O_RDWR);
|
|
|
|
if (fd<0)
|
|
|
|
{
|
|
|
|
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
|
|
|
|
***************
|
|
|
|
*** 84,89 ****
|
|
|
|
--- 87,109 ----
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ /* Figure out if we're running with the Luigi driver or
|
|
|
|
+ the original VoxWare driver, with code based on dburr/luigi
|
|
|
|
+ in ports/5607. It'd be great if we could do this before
|
|
|
|
+ opening the audio device, but oh well... */
|
|
|
|
+ #if defined(AIOGFMT) /* only defined in Luigi driver */
|
|
|
|
+ {
|
|
|
|
+ snd_chan_param s;
|
|
|
|
+ int i;
|
|
|
|
+ i = ioctl(fd, AIOGFMT, &s);
|
|
|
|
+ if (i != -1)
|
|
|
|
+ luigi_driver = 1;
|
|
|
|
+ }
|
|
|
|
+ #endif defined (AIOGFMT)
|
|
|
|
+
|
|
|
|
+ ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "Using %s sound driver",
|
|
|
|
+ luigi_driver ? "luigi" : "VoxWare");
|
|
|
|
+
|
|
|
|
/* They can't mean these */
|
|
|
|
dpm.encoding &= ~(PE_ULAW|PE_BYTESWAP);
|
|
|
|
|
|
|
|
***************
|
|
|
|
*** 92,97 ****
|
|
|
|
--- 112,140 ----
|
|
|
|
the other one. */
|
|
|
|
|
|
|
|
i=tmp=(dpm.encoding & PE_16BIT) ? 16 : 8;
|
|
|
|
+ if (luigi_driver)
|
|
|
|
+ {
|
|
|
|
+ if (dpm.encoding & PE_16BIT) {
|
|
|
|
+ int fmt = AFMT_S16_LE ;
|
|
|
|
+
|
|
|
|
+ if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) < 0 || fmt != AFMT_S16_LE) {
|
|
|
|
+ fmt = AFMT_U8 ;
|
|
|
|
+ if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) < 0 || fmt != AFMT_U8) {
|
|
|
|
+ ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
|
|
|
|
+ "%s doesn't support 16- or 8-bit sample width",
|
|
|
|
+ dpm.name);
|
|
|
|
+ close(fd);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
|
|
|
|
+ "Sample width adjusted to %d bits", tmp);
|
|
|
|
+ dpm.encoding ^= PE_16BIT;
|
|
|
|
+ warnings = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
if (ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &tmp)<0 || tmp!=i)
|
|
|
|
{
|
|
|
|
/* Try the other one */
|
|
|
|
***************
|
|
|
|
*** 109,114 ****
|
|
|
|
--- 152,158 ----
|
|
|
|
dpm.encoding ^= PE_16BIT;
|
|
|
|
warnings=1;
|
|
|
|
}
|
|
|
|
+ }
|
|
|
|
if (dpm.encoding & PE_16BIT)
|
|
|
|
dpm.encoding |= PE_SIGNED;
|
|
|
|
else
|
|
|
|
***************
|
|
|
|
*** 163,168 ****
|
|
|
|
--- 207,214 ----
|
|
|
|
/* Set buffer fragments (in extra_param[0]) */
|
|
|
|
|
|
|
|
tmp=AUDIO_BUFFER_BITS;
|
|
|
|
+ if (luigi_driver)
|
|
|
|
+ tmp += 2;
|
|
|
|
if (!(dpm.encoding & PE_MONO)) tmp++;
|
|
|
|
if (dpm.encoding & PE_16BIT) tmp++;
|
|
|
|
tmp |= (dpm.extra_param[0]<<16);
|
|
|
|
***************
|
1998-06-16 18:28:32 +00:00
|
|
|
*** 189,216 ****
|
1998-06-16 16:06:32 +00:00
|
|
|
return warnings;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void output_data(int32 *buf, int32 count)
|
|
|
|
{
|
1998-06-16 18:28:32 +00:00
|
|
|
if (!(dpm.encoding & PE_MONO)) count*=2; /* Stereo samples */
|
1998-06-16 16:06:32 +00:00
|
|
|
|
|
|
|
! if (dpm.encoding & PE_16BIT)
|
|
|
|
! {
|
|
|
|
/* Convert data to signed 16-bit PCM */
|
|
|
|
s32tos16(buf, count);
|
|
|
|
!
|
|
|
|
! /* Write the data out. Linux likes to give an EINTR if you suspend
|
|
|
|
! a program while waiting on a write, so we may need to retry. */
|
|
|
|
! while ((-1==write(dpm.fd, buf, count * 2)) && errno==EINTR)
|
|
|
|
! ;
|
|
|
|
! }
|
|
|
|
! else
|
|
|
|
! {
|
|
|
|
/* Convert to 8-bit unsigned and write out. */
|
|
|
|
s32tou8(buf, count);
|
|
|
|
!
|
|
|
|
! while ((-1==write(dpm.fd, buf, count)) && errno==EINTR)
|
|
|
|
! ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-06-16 18:28:32 +00:00
|
|
|
static void close_output(void)
|
|
|
|
--- 235,269 ----
|
1998-06-16 16:06:32 +00:00
|
|
|
return warnings;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ /* output_data comes from Luigi's linux_a.c. This version seems to allow
|
|
|
|
+ for partial writes to the sound device, where as the original version
|
|
|
|
+ doesn't. */
|
|
|
|
static void output_data(int32 *buf, int32 count)
|
|
|
|
{
|
1998-06-16 18:28:32 +00:00
|
|
|
+ char *p;
|
|
|
|
+ int res, l;
|
|
|
|
+
|
|
|
|
if (!(dpm.encoding & PE_MONO)) count*=2; /* Stereo samples */
|
1998-06-16 16:06:32 +00:00
|
|
|
|
|
|
|
! if (dpm.encoding & PE_16BIT) {
|
|
|
|
/* Convert data to signed 16-bit PCM */
|
|
|
|
s32tos16(buf, count);
|
1998-06-16 18:28:32 +00:00
|
|
|
! res = count*2;
|
1998-06-16 16:06:32 +00:00
|
|
|
! } else {
|
|
|
|
/* Convert to 8-bit unsigned and write out. */
|
|
|
|
s32tou8(buf, count);
|
1998-06-16 18:28:32 +00:00
|
|
|
! res = count;
|
1998-06-16 16:06:32 +00:00
|
|
|
! }
|
1998-06-16 18:28:32 +00:00
|
|
|
! for (p = (char *) buf; res > 0; res -= l) {
|
|
|
|
! again:
|
1998-06-16 16:06:32 +00:00
|
|
|
! l = write(dpm.fd, p, res);
|
1998-06-16 18:28:32 +00:00
|
|
|
! if (l < 0) {
|
|
|
|
! if (errno == EINTR)
|
|
|
|
! goto again;
|
|
|
|
! return;
|
1998-06-16 16:06:32 +00:00
|
|
|
}
|
1998-06-16 18:28:32 +00:00
|
|
|
+ p += l;
|
|
|
|
+ }
|
1998-06-16 16:06:32 +00:00
|
|
|
}
|
|
|
|
|
1998-06-16 18:28:32 +00:00
|
|
|
static void close_output(void)
|