1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-04 22:33:27 +00:00
freebsd-ports/audio/rat/files/patch-aa
Munechika SUMIKAWA eb92024368 Enable IPv6.
PR:		21445
Submitted by:	maintainer
2000-09-21 18:23:43 +00:00

942 lines
27 KiB
Plaintext

diff -uPr rat/MODS /home/oh/src/rat-newpcm/rat/MODS
--- rat/MODS Fri Sep 8 21:02:40 2000
+++ /home/oh/src/rat-newpcm/rat/MODS Sat Sep 16 20:33:47 2000
@@ -1,7 +1,7 @@
MODIFICATIONS FILE
------------------
-$Id: MODS,v 1.225 2000/09/08 19:58:13 ucaccsp Exp $
+$Id: MODS,v 1.226 2000/09/16 17:43:21 ucacoxh Exp $
Copyright (C) 1995-2000 University College London
All rights reserved.
@@ -1429,18 +1429,23 @@
- Fix labelling of transcoder input/output ports
* Released 8 September 2000
-
-
-
+v4.2.9p1 - Added auddev_newpcm.[ch] with newpcm style mixer control. Includes
+ support for loopback and preservation of mixer settings so mixer is
+ returned to original state upon exit. [oh]
+
+ Note: both driver interfaces (luigi, newpcm) are pulled in
+ by configure and this is possible whilst luigi pcm and
+ newpcm maintain the same function call interface. This may
+ break in future. Both are necessary because mixer operation
+ is not consistent between the two interfaces.
TODO -- They're features not bugs dammit!
----
- Assorted audio driver problems:
- - FreeBSD driver bug on SoundBlaster 16 has small write buffers
+ - Luigi pcm driver bug on SoundBlaster 16 has small write buffers
and stops working full duplex mode after a time. Hard to fix because
of cushion.
- - Loopback support is broken on FreeBSD newpcm driver.
- Broken auddev_pca with adding of audio interface conversion code.
FreeBSD 3.1 pca audio does not seem to work anymore.
- SunVideoPlus interface code does not work properly. The driver Sun
diff -uPr rat/acconfig.h /home/oh/src/rat-newpcm/rat/acconfig.h
--- rat/acconfig.h Fri Sep 8 21:02:44 2000
+++ /home/oh/src/rat-newpcm/rat/acconfig.h Sat Sep 16 20:33:49 2000
@@ -1,7 +1,7 @@
/*
* Define this if your C library doesn't have usleep.
*
- * $Id: acconfig.h,v 1.10 2000/02/06 22:04:23 ucacoxh Exp $
+ * $Id: acconfig.h,v 1.11 2000/09/16 17:43:22 ucacoxh Exp $
*/
#undef NEED_USLEEP
#undef NEED_SNPRINTF
@@ -42,12 +42,15 @@
#undef HAVE_SGI_AUDIO
#undef HAVE_PCA_AUDIO
#undef HAVE_LUIGI_AUDIO
+#undef HAVE_NEWPCM_AUDIO
#undef HAVE_OSS_AUDIO
#undef HAVE_HP_AUDIO
#undef HAVE_NETBSD_AUDIO
#undef HAVE_OSPREY_AUDIO
#undef HAVE_MACHINE_PCAUDIOIO_H
#undef HAVE_ALSA_AUDIO
+
+#undef HAVE_IPv6
/* GSM related */
#undef SASR
diff -uPr rat/auddev.c /home/oh/src/rat-newpcm/rat/auddev.c
--- rat/auddev.c Fri Sep 8 21:02:44 2000
+++ /home/oh/src/rat-newpcm/rat/auddev.c Sat Sep 16 20:33:52 2000
@@ -9,7 +9,7 @@
#ifndef HIDE_SOURCE_STRINGS
static const char cvsid[] =
- "$Id: auddev.c,v 1.58 2000/05/08 10:11:40 ucaccsp Exp $";
+ "$Id: auddev.c,v 1.59 2000/09/16 17:43:22 ucacoxh Exp $";
#endif /* HIDE_SOURCE_STRINGS */
#include "config_unix.h"
@@ -22,6 +22,7 @@
#include "auddev.h"
#include "auddev_null.h"
#include "auddev_luigi.h"
+#include "auddev_newpcm.h"
#include "auddev_osprey.h"
#include "auddev_oss.h"
#include "auddev_alsa.h"
@@ -298,6 +299,38 @@
luigi_audio_supports
},
#endif /* HAVE_LUIGI_AUDIO */
+#ifdef HAVE_NEWPCM_AUDIO
+ {
+ newpcm_audio_query_devices,
+ NULL,
+ newpcm_get_device_count,
+ newpcm_get_device_name,
+ newpcm_audio_open,
+ newpcm_audio_close,
+ newpcm_audio_drain,
+ newpcm_audio_duplex,
+ newpcm_audio_read,
+ newpcm_audio_write,
+ newpcm_audio_non_block,
+ newpcm_audio_block,
+ newpcm_audio_set_igain,
+ newpcm_audio_get_igain,
+ newpcm_audio_set_ogain,
+ newpcm_audio_get_ogain,
+ newpcm_audio_loopback,
+ newpcm_audio_oport_set,
+ newpcm_audio_oport_get,
+ newpcm_audio_oport_details,
+ newpcm_audio_oport_count,
+ newpcm_audio_iport_set,
+ newpcm_audio_iport_get,
+ newpcm_audio_iport_details,
+ newpcm_audio_iport_count,
+ newpcm_audio_is_ready,
+ newpcm_audio_wait_for,
+ newpcm_audio_supports
+ },
+#endif /* HAVE_NEWPCM_AUDIO */
#ifdef HAVE_PCA_AUDIO
{
pca_audio_init,
diff -uPr rat/auddev_luigi.c /home/oh/src/rat-newpcm/rat/auddev_luigi.c
--- rat/auddev_luigi.c Fri Sep 8 21:02:46 2000
+++ /home/oh/src/rat-newpcm/rat/auddev_luigi.c Sat Sep 16 20:33:54 2000
@@ -1,15 +1,13 @@
/*
* FILE: auddev_luigi.c - Sound interface for Luigi Rizzo's FreeBSD driver
*
- * Modified to support newpcm (July 2000).
- *
* Copyright (c) 1996-2000 University College London
* All rights reserved.
*/
#ifndef HIDE_SOURCE_STRINGS
static const char cvsid[] =
- "$Id: auddev_luigi.c,v 1.51 2000/07/23 10:33:29 ucacoxh Exp $";
+ "$Id: auddev_luigi.c,v 1.52 2000/09/16 17:43:23 ucacoxh Exp $";
#endif /* HIDE_SOURCE_STRINGS */
#include "config_unix.h"
@@ -51,24 +49,6 @@
static audio_format *input_format, *output_format, *tmp_format;
static snd_capabilities soundcaps[LUIGI_MAX_AUDIO_DEVICES];
-/* There are some differences between the FreeBSD 4x newpcm driver
- * and Luigi's pcm driver:
- *
- * 1) Mixer loopback writes are handled differently (not supported
- * on newpcm yet - new mixer infrastructure looks to be WIP)
- *
- * 2) newpcm does not set AFMT_FULLDUPLEX when device caps are queried.
- * Luigi's driver does. Luigi's driver also opens half-duplex devices
- * when open() use O_RDWR. So with Luigi's driver we have to check
- * AFMT_FULLDUPLEX, with newpcm we assume if device opens O_RDWR it
- * is full duplex.
- *
- * The variable is_newpcm indicates applications understanding of which
- * driver it is talking to.
- */
-
-static int is_newpcm;
-
int
luigi_audio_open(audio_desc_t ad, audio_format *ifmt, audio_format *ofmt)
{
@@ -100,16 +80,12 @@
LUIGI_AUDIO_IOCTL(audio_fd,SNDCTL_DSP_RESET,0);
/* Check card is full duplex - need for Luigi driver only */
- if (is_newpcm == FALSE &&
- (soundcaps[ad].formats & AFMT_FULLDUPLEX) == 0) {
+ if ((soundcaps[ad].formats & AFMT_FULLDUPLEX) == 0) {
fprintf(stderr, "Sorry driver does support full duplex for this soundcard\n");
luigi_audio_close(ad);
return FALSE;
}
- /* From newpcm source code it looks like AFMT_WEIRD is handled
- * by driver interface, but Luigi's driver needs this.
- */
if (soundcaps[ad].formats & AFMT_WEIRD) {
/* this is a sb16/32/64...
* you can change either ifmt or ofmt to U8
@@ -556,16 +532,14 @@
ndev++;
} else if (strstr(buf, "newpcm")) {
/* This is a clunky check for the
- * newpcm driver.
+ * newpcm driver. Don't use luigi in this case
*/
- is_newpcm = TRUE;
+ ndev = 0;
+ break;
}
}
fclose(f);
}
-
- debug_msg("Audio driver is %s\n",
- (is_newpcm) ? "newpcm" : "luigi");
return (ndev);
}
diff -uPr rat/auddev_newpcm.c /home/oh/src/rat-newpcm/rat/auddev_newpcm.c
--- rat/auddev_newpcm.c Thu Jan 1 01:00:00 1970
+++ /home/oh/src/rat-newpcm/rat/auddev_newpcm.c Sat Sep 16 20:33:54 2000
@@ -0,0 +1,622 @@
+/*
+ * FILE: auddev_newpcm.c - Sound interface for newpcm FreeBSD driver.
+ *
+ * Modified to support newpcm (July 2000).
+ *
+ * Copyright (c) 1996-2000 University College London
+ * All rights reserved.
+ */
+
+#ifndef HIDE_SOURCE_STRINGS
+static const char cvsid[] =
+ "$Id: auddev_newpcm.c,v 1.1 2000/09/16 17:43:23 ucacoxh Exp $";
+#endif /* HIDE_SOURCE_STRINGS */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "audio_types.h"
+#include "audio_fmt.h"
+#include "auddev_newpcm.h"
+#include "memory.h"
+#include "debug.h"
+
+#include <machine/soundcard.h>
+
+static char *port_names[] = SOUND_DEVICE_LABELS;
+static int iport, oport, loop;
+static snd_chan_param pa;
+static struct snd_size sz;
+static int audio_fd = -1;
+
+#define RAT_TO_DEVICE(x) ((x) * 100 / MAX_AMP)
+#define DEVICE_TO_RAT(x) ((x) * MAX_AMP / 100)
+
+#define NEWPCM_AUDIO_IOCTL(fd, cmd, val) if (ioctl((fd), (cmd), (val)) < 0) { \
+ debug_msg("Failed %s - line %d\n",#cmd, __LINE__); \
+ newpcm_error = __LINE__; \
+ }
+
+#define NEWPCM_MAX_AUDIO_NAME_LEN 32
+#define NEWPCM_MAX_AUDIO_DEVICES 3
+
+static int dev_ids[NEWPCM_MAX_AUDIO_DEVICES];
+static char names[NEWPCM_MAX_AUDIO_DEVICES][NEWPCM_MAX_AUDIO_NAME_LEN];
+static int ndev = 0;
+static int newpcm_error;
+static audio_format *input_format, *output_format, *tmp_format;
+static snd_capabilities soundcaps[NEWPCM_MAX_AUDIO_DEVICES];
+
+static void newpcm_mixer_save(int fd);
+static void newpcm_mixer_restore(int fd);
+static void newpcm_mixer_init(int fd);
+static void newpcm_audio_loopback_config(int gain);
+
+int
+newpcm_audio_open(audio_desc_t ad, audio_format *ifmt, audio_format *ofmt)
+{
+ int32_t fragment;
+ char thedev[64];
+
+ assert(ad >= 0 && ad < ndev);
+ sprintf(thedev, "/dev/audio%d", dev_ids[ad]);
+
+ debug_msg("Opening %s\n", thedev);
+
+ audio_fd = open(thedev, O_RDWR);
+ if (audio_fd >= 0) {
+ /* Ignore any earlier errors */
+ newpcm_error = 0;
+
+ newpcm_mixer_save(audio_fd);
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, AIOGCAP, &soundcaps[ad]);
+ debug_msg("soundcaps[%d].rate_min = %d\n", ad, soundcaps[ad].rate_min);
+ debug_msg("soundcaps[%d].rate_max = %d\n", ad, soundcaps[ad].rate_max);
+ debug_msg("soundcaps[%d].formats = 0x%08lx\n", ad, soundcaps[ad].formats);
+ debug_msg("soundcaps[%d].bufsize = %d\n", ad, soundcaps[ad].bufsize);
+ debug_msg("soundcaps[%d].mixers = 0x%08lx\n", ad, soundcaps[ad].mixers);
+ debug_msg("soundcaps[%d].inputs = 0x%08lx\n", ad, soundcaps[ad].inputs);
+ debug_msg("soundcaps[%d].left = 0x%04lx\n", ad, soundcaps[ad].left);
+ debug_msg("soundcaps[%d].right = 0x%04lx\n", ad, soundcaps[ad].right);
+
+ /* Setup input and output format settings */
+ assert(ofmt->channels == ifmt->channels);
+ memset(&pa, 0, sizeof(pa));
+ if (ifmt->channels == 2) {
+ if (!soundcaps[ad].formats & AFMT_STEREO) {
+ fprintf(stderr,"Driver does not support stereo for this soundcard\n");
+ newpcm_audio_close(ad);
+ return FALSE;
+ }
+ pa.rec_format = AFMT_STEREO;
+ pa.play_format = AFMT_STEREO;
+ }
+
+ switch(ifmt->encoding) {
+ case DEV_PCMU: pa.rec_format |= AFMT_MU_LAW; break;
+ case DEV_PCMA: pa.rec_format |= AFMT_A_LAW; break;
+ case DEV_S8: pa.rec_format |= AFMT_S8; break;
+ case DEV_S16: pa.rec_format |= AFMT_S16_LE; break;
+ case DEV_U8: pa.rec_format |= AFMT_U8; break;
+ }
+
+ switch(ofmt->encoding) {
+ case DEV_PCMU: pa.play_format |= AFMT_MU_LAW; break;
+ case DEV_PCMA: pa.play_format |= AFMT_A_LAW; break;
+ case DEV_S8: pa.play_format |= AFMT_S8; break;
+ case DEV_S16: pa.play_format |= AFMT_S16_LE; break;
+ case DEV_U8: pa.play_format |= AFMT_U8; break;
+ }
+ pa.play_rate = ofmt->sample_rate;
+ pa.rec_rate = ifmt->sample_rate;
+ NEWPCM_AUDIO_IOCTL(audio_fd, AIOSFMT, &pa);
+
+ sz.play_size = ofmt->bytes_per_block;
+ sz.rec_size = ifmt->bytes_per_block;
+ NEWPCM_AUDIO_IOCTL(audio_fd, AIOSSIZE, &sz);
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, AIOGSIZE, &sz);
+ debug_msg("rec size %d, play size %d bytes\n",
+ sz.rec_size, sz.play_size);
+
+ /* Fragment : 8msb = #frags, 16lsbs = log2 fragsize */
+ fragment = 0x08000007;
+ NEWPCM_AUDIO_IOCTL(audio_fd, SNDCTL_DSP_SETFRAGMENT, &fragment);
+
+ if (newpcm_error != 0) {
+ /* Failed somewhere in initialization - reset error and exit*/
+ newpcm_audio_close(ad);
+ newpcm_error = 0;
+ return FALSE;
+ }
+
+ /* Store format in case we have to re-open device because
+ * of driver bug. Careful with freeing format as input format
+ * could be static input_format if device reset during write.
+ */
+ tmp_format = audio_format_dup(ifmt);
+ if (input_format != NULL) {
+ audio_format_free(&input_format);
+ }
+ input_format = tmp_format;
+
+ tmp_format = audio_format_dup(ofmt);
+ if (output_format != NULL) {
+ audio_format_free(&output_format);
+ }
+ output_format = tmp_format;
+
+ newpcm_mixer_init(audio_fd);
+ /* Turn off loopback from input to output... not fatal so
+ * after error check.
+ */
+ newpcm_audio_loopback(ad, 0);
+
+ read(audio_fd, thedev, 64);
+ return TRUE;
+ } else {
+ fprintf(stderr,
+ "Could not open device: %s (half-duplex?)\n",
+ names[ad]);
+ perror("newpcm_audio_open");
+ newpcm_audio_close(ad);
+ return FALSE;
+ }
+}
+
+/* Close the audio device */
+void
+newpcm_audio_close(audio_desc_t ad)
+{
+ UNUSED(ad);
+
+ if (audio_fd < 0) {
+ debug_msg("Device already closed!\n");
+ return;
+ }
+ if (input_format != NULL) {
+ audio_format_free(&input_format);
+ }
+ if (output_format != NULL) {
+ audio_format_free(&output_format);
+ }
+ newpcm_mixer_restore(audio_fd);
+ newpcm_audio_drain(audio_fd);
+ close(audio_fd);
+ audio_fd = -1;
+}
+
+/* Flush input buffer */
+void
+newpcm_audio_drain(audio_desc_t ad)
+{
+ u_char buf[4];
+ int pre, post;
+
+ assert(audio_fd > 0);
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, FIONREAD, &pre);
+ NEWPCM_AUDIO_IOCTL(audio_fd, SNDCTL_DSP_RESET, 0);
+ NEWPCM_AUDIO_IOCTL(audio_fd, SNDCTL_DSP_SYNC, 0);
+ NEWPCM_AUDIO_IOCTL(audio_fd, FIONREAD, &post);
+ debug_msg("audio drain: %d -> %d\n", pre, post);
+ read(audio_fd, buf, sizeof(buf));
+
+ UNUSED(ad);
+}
+
+int
+newpcm_audio_duplex(audio_desc_t ad)
+{
+ /* We only ever open device full duplex! */
+ UNUSED(ad);
+ return TRUE;
+}
+
+int
+newpcm_audio_read(audio_desc_t ad, u_char *buf, int read_bytes)
+{
+ int done, this_read;
+ int len;
+ /* Figure out how many bytes we can read before blocking... */
+
+ UNUSED(ad); assert(audio_fd > 0);
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, FIONREAD, &len);
+
+ len = min(len, read_bytes);
+
+ /* Read the data... */
+ done = 0;
+ while(done < len) {
+ this_read = read(audio_fd, (void*)buf, len - done);
+ done += this_read;
+ buf += this_read;
+ }
+ return done;
+}
+
+int
+newpcm_audio_write(audio_desc_t ad, u_char *buf, int write_bytes)
+{
+ int done;
+
+ UNUSED(ad); assert(audio_fd > 0);
+
+ done = write(audio_fd, (void*)buf, write_bytes);
+ if (done != write_bytes && errno != EINTR) {
+ /* Only ever seen this with soundblaster cards.
+ * Driver occasionally packs in reading. Seems to be
+ * no way to reset cleanly whilst running, even
+ * closing device, waiting a few 100ms and re-opening
+ * seems to fail.
+ */
+ perror("Error writing device.");
+ fprintf(stderr, "Please email this message to rat-trap@cs.ucl.ac.uk with output of:\n\t uname -a\n\t cat /dev/sndstat\n");
+ return (write_bytes - done);
+ }
+
+ return write_bytes;
+}
+
+/* Set ops on audio device to be non-blocking */
+void
+newpcm_audio_non_block(audio_desc_t ad)
+{
+ int frag = 1;
+
+ UNUSED(ad); assert(audio_fd != -1);
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, SNDCTL_DSP_NONBLOCK, &frag);
+}
+
+/* Set ops on audio device to be blocking */
+void
+newpcm_audio_block(audio_desc_t ad)
+{
+ int frag = 0;
+
+ UNUSED(ad); assert(audio_fd > 0);
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, SNDCTL_DSP_NONBLOCK, &frag);
+}
+
+
+static int recmask, playmask;
+
+static void
+newpcm_mixer_init(int fd)
+{
+ int devmask;
+
+ NEWPCM_AUDIO_IOCTL(fd, SOUND_MIXER_READ_RECMASK, &recmask);
+
+ if (recmask & SOUND_MASK_MIC) {
+ iport = SOUND_MASK_MIC;
+ } else {
+ iport = 1;
+ while ((iport & recmask) == 0) {
+ iport <<= 1;
+ }
+ }
+
+ NEWPCM_AUDIO_IOCTL(fd, SOUND_MIXER_READ_DEVMASK, &devmask);
+ playmask = devmask & ~recmask & ~SOUND_MASK_RECLEV;
+ debug_msg("devmask 0x%08x recmask 0x%08x playmask 0x%08x\n",
+ devmask,
+ recmask,
+ playmask);
+}
+
+static int
+newpcm_count_ports(int mask)
+{
+ int n = 0, m = mask;
+
+ while (m > 0) {
+ n += (m & 0x01);
+ m >>= 1;
+ }
+
+ return n;
+}
+
+static int
+newpcm_get_nth_port_mask(int mask, int n)
+{
+ static int lgmask;
+
+ lgmask = -1;
+ do {
+ lgmask ++;
+ if ((1 << lgmask) & mask) {
+ n--;
+ }
+ } while (n >= 0);
+
+ assert((1 << lgmask) & mask);
+ return lgmask;
+}
+
+/* Gain and volume values are in the range 0 - MAX_AMP */
+void
+newpcm_audio_set_ogain(audio_desc_t ad, int vol)
+{
+ int volume, lgport, op;
+
+ UNUSED(ad); assert(audio_fd > 0);
+
+ volume = vol << 8 | vol;
+
+ lgport = -1;
+ op = oport;
+ while (op > 0) {
+ op >>= 1;
+ lgport ++;
+ }
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, MIXER_WRITE(lgport), &volume);
+}
+
+int
+newpcm_audio_get_ogain(audio_desc_t ad)
+{
+ int volume, lgport, op;
+
+ UNUSED(ad); assert(audio_fd > 0);
+
+ lgport = -1;
+ op = oport;
+ while (op > 0) {
+ op >>= 1;
+ lgport ++;
+ }
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, MIXER_READ(lgport), &volume);
+
+ return DEVICE_TO_RAT(volume & 0xff); /* Extract left channel volume */
+}
+
+void
+newpcm_audio_oport_set(audio_desc_t ad, audio_port_t port)
+{
+ UNUSED(ad);
+ oport = port;
+ return;
+}
+
+audio_port_t
+newpcm_audio_oport_get(audio_desc_t ad)
+{
+ UNUSED(ad);
+ return oport;
+}
+
+int
+newpcm_audio_oport_count(audio_desc_t ad)
+{
+ UNUSED(ad);
+ return newpcm_count_ports(playmask);
+}
+
+const audio_port_details_t*
+newpcm_audio_oport_details(audio_desc_t ad, int idx)
+{
+ static audio_port_details_t ap;
+ int lgmask;
+
+ UNUSED(ad);
+
+ lgmask = newpcm_get_nth_port_mask(playmask, idx);
+ ap.port = 1 << lgmask;
+ sprintf(ap.name, "%s", port_names[lgmask]);
+
+ return &ap;
+}
+
+void
+newpcm_audio_set_igain(audio_desc_t ad, int gain)
+{
+ int volume = RAT_TO_DEVICE(gain) << 8 | RAT_TO_DEVICE(gain);
+
+ UNUSED(ad); assert(audio_fd > 0);
+ newpcm_audio_loopback_config(gain);
+ NEWPCM_AUDIO_IOCTL(audio_fd, SOUND_MIXER_WRITE_RECLEV, &volume);
+}
+
+int
+newpcm_audio_get_igain(audio_desc_t ad)
+{
+ int volume;
+
+ UNUSED(ad); assert(audio_fd > 0);
+ NEWPCM_AUDIO_IOCTL(audio_fd, SOUND_MIXER_READ_RECLEV, &volume);
+ return (DEVICE_TO_RAT(volume & 0xff));
+}
+
+void
+newpcm_audio_iport_set(audio_desc_t ad, audio_port_t port)
+{
+ /* Check port is in record mask */
+ int gain;
+
+ debug_msg("port 0x%08x recmask 0x%08x\n", port, recmask);
+
+ assert((port & recmask) != 0);
+
+ if (ioctl(audio_fd, SOUND_MIXER_WRITE_RECSRC, &port) < 0) {
+ perror("Unable to write record mask\n");
+ return;
+ }
+ iport = port;
+ gain = newpcm_audio_get_igain(ad);
+ newpcm_audio_loopback_config(gain);
+ UNUSED(ad);
+}
+
+audio_port_t
+newpcm_audio_iport_get(audio_desc_t ad)
+{
+ UNUSED(ad); assert(audio_fd > 0);
+ return iport;
+}
+
+int
+newpcm_audio_iport_count(audio_desc_t ad)
+{
+ UNUSED(ad);
+ return newpcm_count_ports(recmask);
+}
+
+const audio_port_details_t *
+newpcm_audio_iport_details(audio_desc_t ad, int idx)
+{
+ static audio_port_details_t ap;
+ int lgmask;
+
+ UNUSED(ad);
+
+ lgmask = newpcm_get_nth_port_mask(recmask, idx);
+ ap.port = 1 << lgmask;
+ sprintf(ap.name, "%s", port_names[lgmask]);
+
+ return &ap;
+}
+
+void
+newpcm_audio_loopback(audio_desc_t ad, int gain)
+{
+ UNUSED(ad); assert(audio_fd > 0);
+ loop = gain;
+}
+
+static void
+newpcm_audio_loopback_config(int gain)
+{
+ int lgport, vol;
+
+ /* Find current input port id */
+ lgport = newpcm_get_nth_port_mask(iport, 0);
+
+ if (loop) {
+ vol = RAT_TO_DEVICE(gain) << 8 | RAT_TO_DEVICE(gain);
+ } else {
+ vol = 0;
+ }
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, MIXER_WRITE(lgport), &vol);
+}
+
+void
+newpcm_audio_wait_for(audio_desc_t ad, int delay_ms)
+{
+ if (!newpcm_audio_is_ready(ad)) {
+ usleep((unsigned int)delay_ms * 1000);
+ }
+}
+
+int
+newpcm_audio_is_ready(audio_desc_t ad)
+{
+ int avail;
+
+ UNUSED(ad);
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, FIONREAD, &avail);
+
+ return (avail >= sz.rec_size);
+}
+
+int
+newpcm_audio_supports(audio_desc_t ad, audio_format *fmt)
+{
+ snd_capabilities s;
+
+ UNUSED(ad);
+
+ NEWPCM_AUDIO_IOCTL(audio_fd, AIOGCAP, &s);
+ if (!newpcm_error) {
+ if ((unsigned)fmt->sample_rate < s.rate_min || (unsigned)fmt->sample_rate > s.rate_max) return FALSE;
+ if (fmt->channels == 1) return TRUE; /* Always supports mono */
+ assert(fmt->channels == 2);
+ if (s.formats & AFMT_STEREO) return TRUE;
+ }
+ return FALSE;
+}
+
+int
+newpcm_audio_query_devices()
+{
+ FILE *f;
+ char buf[128], *p;
+ int n, newpcm = FALSE;
+
+ f = fopen("/dev/sndstat", "r");
+ if (f) {
+ while (!feof(f) && ndev < NEWPCM_MAX_AUDIO_DEVICES) {
+ p = fgets(buf, 128, f);
+ n = sscanf(buf, "pcm%d: <%[A-z0-9 ]>", dev_ids + ndev, names[ndev]);
+ if (p && n == 2) {
+ debug_msg("dev (%d) name (%s)\n", dev_ids[ndev], names[ndev]);
+ ndev++;
+ } else if (strstr(buf, "newpcm")) {
+ newpcm = TRUE;
+ }
+ }
+ fclose(f);
+ }
+
+ if (newpcm == FALSE) {
+ ndev = 0; /* Should be using Luigi's interface */
+ }
+
+ return (ndev);
+}
+
+int
+newpcm_get_device_count()
+{
+ return ndev;
+}
+
+char *
+newpcm_get_device_name(audio_desc_t idx)
+{
+ if (idx >=0 && idx < ndev) {
+ return names[idx];
+ }
+ return NULL;
+}
+
+/* Functions to save and restore recording source and mixer levels */
+
+static int saved_rec_mask, saved_gain_values[SOUND_MIXER_NRDEVICES];
+
+static void
+newpcm_mixer_save(int fd)
+{
+ int devmask, i;
+ NEWPCM_AUDIO_IOCTL(fd, SOUND_MIXER_READ_RECSRC, &saved_rec_mask);
+ NEWPCM_AUDIO_IOCTL(fd, SOUND_MIXER_READ_DEVMASK, &devmask);
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+ if ((1 << i) & devmask) {
+ NEWPCM_AUDIO_IOCTL(fd, MIXER_READ(i), &saved_gain_values[i]);
+ } else {
+ saved_gain_values[i] = 0;
+ }
+ }
+}
+
+static void
+newpcm_mixer_restore(int fd)
+{
+ int devmask, i;
+ NEWPCM_AUDIO_IOCTL(fd, SOUND_MIXER_WRITE_RECSRC, &saved_rec_mask);
+
+ NEWPCM_AUDIO_IOCTL(fd, SOUND_MIXER_READ_DEVMASK, &devmask);
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+ if ((1 << i) & devmask) {
+ NEWPCM_AUDIO_IOCTL(fd, MIXER_WRITE(i), &saved_gain_values[i]);
+ }
+ }
+}
diff -uPr rat/auddev_newpcm.h /home/oh/src/rat-newpcm/rat/auddev_newpcm.h
--- rat/auddev_newpcm.h Thu Jan 1 01:00:00 1970
+++ /home/oh/src/rat-newpcm/rat/auddev_newpcm.h Sat Sep 16 20:33:54 2000
@@ -0,0 +1,52 @@
+/*
+ * FILE: auddev_newpcm.h
+ * PROGRAM: RAT
+ * AUTHOR: Orion Hodson
+ *
+ * Copyright (c) 1998-2000 University College London
+ * All rights reserved.
+ *
+ * $Id: auddev_newpcm.h,v 1.1 2000/09/16 17:43:24 ucacoxh Exp $
+ */
+
+#ifndef _AUDDEV_NEWPCM_H_
+#define _AUDDEV_NEWPCM_H_
+
+int newpcm_audio_open (audio_desc_t ad, audio_format* ifmt, audio_format *ofmt);
+void newpcm_audio_close (audio_desc_t ad);
+void newpcm_audio_drain (audio_desc_t ad);
+int newpcm_audio_duplex (audio_desc_t ad);
+
+void newpcm_audio_set_igain (audio_desc_t ad, int gain);
+int newpcm_audio_get_igain (audio_desc_t ad);
+void newpcm_audio_set_ogain (audio_desc_t ad, int vol);
+int newpcm_audio_get_ogain (audio_desc_t ad);
+void newpcm_audio_loopback (audio_desc_t ad, int gain);
+
+int newpcm_audio_read (audio_desc_t ad, u_char *buf, int buf_len);
+int newpcm_audio_write (audio_desc_t ad, u_char *buf, int buf_len);
+void newpcm_audio_non_block (audio_desc_t ad);
+void newpcm_audio_block (audio_desc_t ad);
+
+void newpcm_audio_oport_set (audio_desc_t ad, audio_port_t port);
+audio_port_t newpcm_audio_oport_get (audio_desc_t ad);
+int newpcm_audio_oport_count (audio_desc_t ad);
+const audio_port_details_t*
+ newpcm_audio_oport_details (audio_desc_t ad, int idx);
+
+void newpcm_audio_iport_set (audio_desc_t ad, audio_port_t port);
+audio_port_t newpcm_audio_iport_get (audio_desc_t ad);
+int newpcm_audio_iport_count (audio_desc_t ad);
+const audio_port_details_t*
+ newpcm_audio_iport_details (audio_desc_t ad, int idx);
+
+int newpcm_audio_is_ready (audio_desc_t ad);
+void newpcm_audio_wait_for (audio_desc_t ad, int delay_ms);
+int newpcm_audio_supports (audio_desc_t ad, audio_format *f);
+
+/* Functions to get names of devices */
+int newpcm_audio_query_devices (void);
+int newpcm_get_device_count (void);
+char *newpcm_get_device_name (audio_desc_t ad);
+
+#endif /* _AUDDEV_NEWPCM_H_ */
diff -uPr rat/config.h.in /home/oh/src/rat-newpcm/rat/config.h.in
--- rat/config.h.in Fri Sep 8 21:03:01 2000
+++ /home/oh/src/rat-newpcm/rat/config.h.in Sat Sep 16 20:34:04 2000
@@ -27,7 +27,7 @@
/*
* Define this if your C library doesn't have usleep.
*
- * $Id: config.h.in,v 1.18 2000/03/03 15:05:32 ucaccsp Exp $
+ * $Id: config.h.in,v 1.19 2000/09/16 17:43:24 ucacoxh Exp $
*/
#undef NEED_USLEEP
#undef NEED_SNPRINTF
@@ -68,12 +68,15 @@
#undef HAVE_SGI_AUDIO
#undef HAVE_PCA_AUDIO
#undef HAVE_LUIGI_AUDIO
+#undef HAVE_NEWPCM_AUDIO
#undef HAVE_OSS_AUDIO
#undef HAVE_HP_AUDIO
#undef HAVE_NETBSD_AUDIO
#undef HAVE_OSPREY_AUDIO
#undef HAVE_MACHINE_PCAUDIOIO_H
#undef HAVE_ALSA_AUDIO
+
+#undef HAVE_IPv6
/* GSM related */
#undef SASR
diff -uPr common/configure.in /home/oh/src/rat-newpcm/common/configure.in
--- common/configure.in Sat Sep 9 05:02:27 2000
+++ /home/oh/src/rat-newpcm/common/configure.in Thu Sep 21 10:15:12 2000
@@ -179,7 +179,7 @@
AC_DEFINE(HAVE_IPv6)
case "$host_os" in
# FreeBSD Kame uses seperate libinet6
- freebsd*)
+ freebsd[23]*)
LIBS="$LIBS -L/usr/local/v6/lib -linet6"
;;
*) ;;
@@ -216,6 +216,7 @@
#ifdef HAVE_NETINET6_IN6_H
#include <netinet6/in6.h>
#else
+ #include <sys/types.h>
#include <netinet/in.h>
#endif /* HAVE_NETINET_IN6_H */
],[