summaryrefslogtreecommitdiff
path: root/audio/rat/files
diff options
context:
space:
mode:
authorAde Lovett <ade@FreeBSD.org>2000-09-18 16:06:05 +0000
committerAde Lovett <ade@FreeBSD.org>2000-09-18 16:06:05 +0000
commita87c59f3524ca031a40d21ba82e00b26383e6b6f (patch)
tree7d9fd80d7aa2313b384638ef50b34a852b94a8a1 /audio/rat/files
parentUpdate to latest set of patches (diff)
The port was suffering bit rot deriving from differences between the
previous pcm driver and newpcm. This replacement port adds newpcm mixer support and brings port up to date with the current rat release (4.2.9). PR: 21333 Submitted by: maintainer
Notes
Notes: svn path=/head/; revision=32813
Diffstat (limited to 'audio/rat/files')
-rw-r--r--audio/rat/files/patch-aa954
-rw-r--r--audio/rat/files/patch-ab23
-rw-r--r--audio/rat/files/patch-ac94
-rw-r--r--audio/rat/files/patch-ad22
-rw-r--r--audio/rat/files/patch-af41
-rw-r--r--audio/rat/files/patch-ag13
6 files changed, 1106 insertions, 41 deletions
diff --git a/audio/rat/files/patch-aa b/audio/rat/files/patch-aa
index 72673143c99e..703674783904 100644
--- a/audio/rat/files/patch-aa
+++ b/audio/rat/files/patch-aa
@@ -1,11 +1,947 @@
---- rat/sdr2.plugin.in.orig Wed May 12 07:36:14 1999
-+++ rat/sdr2.plugin.in Sun Aug 22 10:47:05 1999
-@@ -12,7 +12,7 @@
+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
+ ------------------
- media: audio
- proto: RTP/AVP
--tool: rat-__VERSION__
-+tool: rat
- protoname: RTP
- cryptflag: -K
+-$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 rat/configure.in /home/oh/src/rat-newpcm/rat/configure.in
+--- rat/configure.in Fri Sep 8 21:03:02 2000
++++ /home/oh/src/rat-newpcm/rat/configure.in Sat Sep 16 20:34:08 2000
+@@ -1,5 +1,5 @@
+ dnl UCL RAT configure script.
+-dnl $Header: /cs/research/mice/starship/src/local/CVS_repository/rat/configure.in,v 1.38 2000/03/23 10:00:53 ucacoxh Exp $
++dnl $Header: /cs/research/mice/starship/src/local/CVS_repository/rat/configure.in,v 1.39 2000/09/16 17:43:25 ucacoxh Exp $
+ dnl
+ dnl Process this file with GNU autoconf to generate a configure script.
+
+@@ -195,9 +195,12 @@
+ AU_OBJ="$AU_OBJ auddev_pca.o"
+ AC_DEFINE(HAVE_PCA_AUDIO)
+ fi
+- # Luigi's driver
+- AU_OBJ="$AU_OBJ auddev_luigi.o"
+- AC_DEFINE(HAVE_LUIGI_AUDIO)
++ # Note luigi and newpcm have compatible soundcard.h files but
++ # mixer behaves differently under both systems. During runtime
++ # only one of these modules will be used.
++ AU_OBJ="$AU_OBJ auddev_luigi.o auddev_newpcm.o"
++ AC_DEFINE(HAVE_LUIGI_AUDIO)
++ AC_DEFINE(HAVE_NEWPCM_AUDIO)
+ ;;
+ *netbsd*)
+ AU_OBJ="$AUDIOBJ auddev_netbsd.o"
diff --git a/audio/rat/files/patch-ab b/audio/rat/files/patch-ab
index 1494e645cbe1..4df1138df8e8 100644
--- a/audio/rat/files/patch-ab
+++ b/audio/rat/files/patch-ab
@@ -1,12 +1,11 @@
---- rat/configure.orig Sun Aug 22 10:52:06 1999
-+++ rat/configure Sun Aug 22 10:53:22 1999
-@@ -111,7 +111,8 @@
- WFLAGS=$GCCWFLAGS
- INCLUDE="-I/usr/X11R6/include -I/usr/local/include"
- LDLIBS="-L/usr/X11R6/lib -lXext -lX11 -lm"
-- TCL_LIBS="../tk-8.0/unix/libtk80.a ../tcl-8.0/unix/libtcl80.a"
-+ TCL_LIBS="-L/usr/local/lib -ltk82 -ltcl82"
-+ TCL_INCL="-I/usr/local/include/tk8.2 -I/usr/local/include/tcl8.2"
- AUDIO="auddev_luigi.o"
- DEBUG="-g"
- CHAR="-fsigned-char"
+--- rat/sdr2.plugin.in.orig Sat Sep 16 19:54:48 2000
++++ rat/sdr2.plugin.in Sat Sep 16 19:55:02 2000
+@@ -14,7 +14,7 @@
+
+ media:audio
+ proto:RTP/AVP
+-tool:rat-VERSION
++tool:rat
+ protoname:RTP
+ cryptflag:-K
+
diff --git a/audio/rat/files/patch-ac b/audio/rat/files/patch-ac
index 32e545a50c89..4f65b57ba717 100644
--- a/audio/rat/files/patch-ac
+++ b/audio/rat/files/patch-ac
@@ -1,10 +1,88 @@
---- rat/config_unix.h.orig Sat Nov 27 18:27:56 1999
-+++ rat/config_unix.h Sat Nov 27 18:33:33 1999
-@@ -17,6 +17,7 @@
+--- rat/configure.in.pre Sun Sep 17 02:34:18 2000
++++ rat/configure.in Sun Sep 17 02:36:23 2000
+@@ -280,12 +280,12 @@
+ # We could be dealing with a source installation or a full installation.
+ # Expect a source installation to have headers in TCL8_HOME/generic and libs in
+ # TCL8_HOME/unix. A full installation should have headers in
+-# INSTDIR/include/tcl8.0, or INSTDIR/include, and have libraries be in
++# INSTDIR/include/tcl8.2, or INSTDIR/include, and have libraries be in
+ # INSTDIR/lib.
+ #------------------------------------------------------------------------------
+ PARENT=`echo $PWD | sed -e 's%/[[^/]]*$%%'`
+-TCL_INC=${PARENT}/tcl-8.0
+-TCL_LIB=${PARENT}/tcl-8.0
++TCL_INC=${PARENT}/tcl-8.2
++TCL_LIB=${PARENT}/tcl-8.2
- #include <limits.h>
- #include <sys/types.h>
-+#include <sys/signal.h>
- #include <sys/time.h>
- #include <sys/resource.h>
+ AC_ARG_WITH(tcl,
+ [ --with-tcl=DIR specify location of Tcl installation],
+@@ -295,7 +295,7 @@
+ #-----------------------------------------------------------------------------
+ # Depending on config expect tcl.h to be tcl source dir or include path
+ #-----------------------------------------------------------------------------
+-for i in $TCL_INC/generic $TCL_INC/include/tcl8.0 $TCL_INC/include $TCL_INC
++for i in $TCL_INC/generic $TCL_INC/include/tcl8.2 $TCL_INC/include $TCL_INC
+ do
+ if test -d $i ; then
+ TCL_INC=$i
+@@ -330,7 +330,7 @@
+ SAVED_LIBS=$LIBS
+ LIBS=""
+ FOUND_TCL_LIB=no
+-AC_SEARCH_LIBS(Tcl_Init, tcl8.0 tcl80,
++AC_SEARCH_LIBS(Tcl_Init, tcl8.2 tcl82,
+ FOUND_TCL_LIB=yes,
+ ,
+ -L${TCL_LIB} ${SAVED_LIBS} -lm)
+@@ -346,8 +346,8 @@
+ exit
+ fi
+-TK_INC=${PARENT}/tk-8.0
+-TK_LIB=${PARENT}/tk-8.0
++TK_INC=${PARENT}/tk-8.2
++TK_LIB=${PARENT}/tk-8.2
+
+ AC_ARG_WITH(tk,
+ [ --with-tk=DIR specify location of Tk installation],
+@@ -359,7 +359,7 @@
+ # include tcl.h, Xlib.h, Xutil.h before tk.h.
+ #-----------------------------------------------------------------------------
+ FOUND_TK_INC=0
+-for i in $TK_INC/generic $TK_INC/include/tk8.0 $TK_INC/include $TK_INC
++for i in $TK_INC/generic $TK_INC/include/tk8.2 $TK_INC/include $TK_INC
+ do
+ AC_MSG_CHECKING(for $i/tk.h)
+ if test -r $i/tk.h ; then
+@@ -391,7 +391,7 @@
+ SAVED_LIBS=$LIBS
+ LIBS=""
+ FOUND_TK_LIB=no
+-AC_SEARCH_LIBS(Tk_Init, tk8.0 tk80,
++AC_SEARCH_LIBS(Tk_Init, tk8.2 tk82,
+ FOUND_TK_LIB=yes,
+ ,
+ -L${TK_LIB} ${TCL_LIB} $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS ${SAVED_LIBS} -lm)
+@@ -466,20 +466,8 @@
+ COMMON_LIB=${COMMON_LIB}/lib
+ fi
+
+-AC_CHECK_LIB(uclmmbase,
+- mbus_init,
+- [
+- EXTERNAL_DEP="${EXTERNAL_DEP} ${COMMON_LIB}/libuclmmbase.a"
+- COMMON_LIB="-L${COMMON_LIB} -luclmmbase"
+- ],
+- [
+- echo "Could not find libuclmmbase.a. One of the following halted progess:"
+- echo " (a) Library is not installed."
+- echo " (b) Library is not built or not in expected location (--with-common=DIR)."
+- echo " (c) this script failed to see it (please inform rat-trap@cs.ucl.ac.uk)."
+- exit
+- ],
+- -L${COMMON_LIB})
++EXTERNAL_DEP="${EXTERNAL_DEP} ${COMMON_LIB}/libuclmmbase.a"
++COMMON_LIB="-L${COMMON_LIB} -luclmmbase"
+
+ AC_SUBST(COMMON_INC)
+ AC_SUBST(COMMON_LIB)
diff --git a/audio/rat/files/patch-ad b/audio/rat/files/patch-ad
index b1756adb31a2..aa499c0f54ab 100644
--- a/audio/rat/files/patch-ad
+++ b/audio/rat/files/patch-ad
@@ -1,13 +1,11 @@
---- common/net_udp.c.orig Tue Jun 22 10:54:05 1999
-+++ common/net_udp.c Mon Jan 24 17:14:12 2000
-@@ -335,6 +335,10 @@
- }
- }
+--- rat/Makefile.in.orig Sat Sep 16 20:45:21 2000
++++ rat/Makefile.in Sat Sep 16 20:45:29 2000
+@@ -15,7 +15,7 @@
+ ECHO = echo
-+#ifndef IPV6_ADD_MEMBERSHIP
-+#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
-+#endif
-+
- if (IN6_IS_ADDR_MULTICAST(&(s->addr6))) {
- unsigned int loop = 1;
- struct ipv6_mreq imr;
+ VERSION = @VERSION@
+-RATVER = rat-$(VERSION)
++RATVER = rat
+
+ AU_OBJ = @AU_OBJ@
+ AU_INC = @AU_INC@
diff --git a/audio/rat/files/patch-af b/audio/rat/files/patch-af
new file mode 100644
index 000000000000..f6f25611a616
--- /dev/null
+++ b/audio/rat/files/patch-af
@@ -0,0 +1,41 @@
+--- rat/Makefile.in.prefix Fri Sep 8 21:02:41 2000
++++ rat/Makefile.in Sun Sep 17 03:00:53 2000
+@@ -13,6 +13,7 @@
+ AR = ar
+ RANLIB = @RANLIB@
+ ECHO = echo
++STRIP = strip
+
+ VERSION = @VERSION@
+ RATVER = rat-$(VERSION)
+@@ -122,7 +123,7 @@
+ @${ECHO} "Generating version.h"
+ @sed -e 's/.*/#define RAT_VERSION "&"/' VERSION > version.h
+
+-sdr2.plugin.S02.audio.rtp.-.rat-$(VERSION): sdr2.plugin.in
++sdr2.plugin.S02.audio.rtp.-.$(RATVER): sdr2.plugin.in
+ @${ECHO} "Generating sdr plugin"
+ @${ECHO} "# Generated automatically from sdr2.plugin.in" > $@
+ @${ECHO} "# DO NOT EDIT THIS FILE" >> $@
+@@ -147,9 +148,9 @@
+ -rm -rf core core-$(RATVER)-media core-$(RATVER)-ui
+
+ install: all
+- ./install-sh -m 555 -c $(RATVER) $(bindir)
+- ./install-sh -m 555 -c $(RATVER)-media $(bindir)
+- ./install-sh -m 555 -c $(RATVER)-ui $(bindir)
++ ./install-sh -m 555 -s $(STRIP) -c $(RATVER) $(bindir)
++ ./install-sh -m 555 -s $(STRIP) -c $(RATVER)-media $(bindir)
++ ./install-sh -m 555 -s $(STRIP) -c $(RATVER)-ui $(bindir)
+ ./install-sh -m 444 -c man/man1/rat.1 $(mandir)/man1/rat.1
+ ./install-sh -m 444 -c sdr2.plugin.S02.audio.rtp.-.$(RATVER) $(prefix)/etc/sdr/plugins
+
+@@ -180,7 +181,7 @@
+ cvs tag release-`cat VERSION | sed "s/\./-/g"`
+
+ $(RATVER)-$(OSTYPE).tar.gz: $(RATVER) $(RATVER)-ui $(RATVER)-media
+- tar cf $(RATVER)-$(OSTYPE).tar README.* MODS COPYRIGHT INSTALL.TXT VERSION $(RATVER) $(RATVER)-ui $(RATVER)-media sdr2.plugin.S02.audio.rtp.-.rat-$(VERSION)
++ tar cf $(RATVER)-$(OSTYPE).tar README.* MODS COPYRIGHT INSTALL.TXT VERSION $(RATVER) $(RATVER)-ui $(RATVER)-media sdr2.plugin.S02.audio.rtp.-.$(RATVER)
+ rm -f $(RATVER)-$(OSTYPE).tar.gz
+ gzip -9 $(RATVER)-$(OSTYPE).tar
+
diff --git a/audio/rat/files/patch-ag b/audio/rat/files/patch-ag
new file mode 100644
index 000000000000..66d4d30c2beb
--- /dev/null
+++ b/audio/rat/files/patch-ag
@@ -0,0 +1,13 @@
+--- rat/main_control.c.brokenbin Sun Sep 17 02:26:19 2000
++++ rat/main_control.c Sun Sep 17 02:26:38 2000
+@@ -34,8 +34,8 @@
+ #define ENGINE_NAME "ratmedia.exe"
+ #define CONTROL_NAME "rat.exe"
+ #else
+-#define UI_NAME "rat-"##RAT_VERSION##"-ui"
+-#define ENGINE_NAME "rat-"##RAT_VERSION##"-media"
++#define UI_NAME "rat-ui"
++#define ENGINE_NAME "rat-media"
+ #endif
+
+ #define DEFAULT_RTP_PORT 5004