summaryrefslogtreecommitdiff
path: root/audio/vat/files/patch-ah
diff options
context:
space:
mode:
Diffstat (limited to 'audio/vat/files/patch-ah')
-rw-r--r--audio/vat/files/patch-ah577
1 files changed, 0 insertions, 577 deletions
diff --git a/audio/vat/files/patch-ah b/audio/vat/files/patch-ah
deleted file mode 100644
index 596513307334..000000000000
--- a/audio/vat/files/patch-ah
+++ /dev/null
@@ -1,577 +0,0 @@
---- audio-voxware.cc.orig Fri Apr 26 05:22:37 1996
-+++ audio-voxware.cc Sat May 10 00:15:51 2003
-@@ -1,4 +1,6 @@
- /*
-+ * Modifications (C) 1997-1998 by Luigi Rizzo and others.
-+ *
- * Copyright (c) 1991-1993 Regents of the University of California.
- * All rights reserved.
- *
-@@ -33,31 +35,43 @@
- static const char rcsid[] =
- "@(#) $Header: audio-voxware.cc,v 1.10 96/04/26 05:22:05 van Exp $ (LBL)";
-
--#include <string.h>
--#include <sys/fcntl.h>
--#include <errno.h>
--#if defined(sco) || defined(__bsdi__)
--#include <sys/socket.h>
--#endif
--#if defined(__FreeBSD__)
--#include <sys/types.h>
--#include <sys/uio.h>
--#include <unistd.h>
--#include <machine/soundcard.h>
-+
-+/*
-+ * Full Duplex audio module for the new sound driver and full duplex
-+ * cards. Luigi Rizzo, from original sources supplied by Amancio Hasty.
-+ *
-+ * This includes some enhancements:
-+ * - the audio device to use can be in the AUDIODEV env. variable.
-+ * It can be either a unit number or a full pathname;
-+ * - use whatever format is available from the card (included split
-+ * format e.g. for the sb16);
-+ * - limit the maximum size of the playout queue to approx 4 frames;
-+ * this is necessary if the write channel is slower than expected;
-+ * the fix is based on two new ioctls, AIOGCAP and AIONWRITE,
-+ * but the code should compile with the old driver as well.
-+ */
-+
-+#if !defined(__FreeBSD__) || (__FreeBSD__ < 4)
-+#include <osfcn.h>
- #else
--#include <sys/soundcard.h>
-+#include <fcntl.h>
- #endif
-+#include <sys/soundcard.h>
- #include "audio.h"
-+#include "mulaw.h"
- #include "Tcl.h"
-
- #define ULAW_ZERO 0x7f
-+
-+/* for use in the Voxware driver */
- #define ABUFLOG2 8
--#define ABUFLEN (1 << ABUFLOG2)
- #define NFRAG 5
-
--class VoxWareAudio : public Audio {
-+extern const u_char lintomulawX[];
-+
-+class VoxWare : public Audio {
- public:
-- VoxWareAudio();
-+ VoxWare();
- virtual int FrameReady();
- virtual u_char* Read();
- virtual void Write(u_char *);
-@@ -66,163 +80,415 @@
- virtual void OutputPort(int);
- virtual void InputPort(int);
- virtual void Obtain();
-+ virtual void Release();
- virtual void RMute();
- virtual void RUnmute();
- virtual int HalfDuplex() const;
- protected:
-+ int ext_fd; /* source for external file */
-
-- u_char* readptr;
-- u_char* readbufend;
- u_char* readbuf;
-+ u_short *s16_buf;
-+
-+ int play_fmt ;
-+ int is_half_duplex ;
-+
-+ // new sound driver
-+ int rec_fmt ; /* the sb16 has split format... */
-+ snd_capabilities soundcaps;
-
-- u_char* ubufptr;
-- u_char* ubufend;
-- u_char* ubuf;
--
-- u_char* writeptr;
-- u_char* writebufend;
-- u_char* writebuf;
- };
-
--static class VoxWareAudioMatcher : public Matcher {
-+static class VoxWareMatcher : public Matcher {
- public:
-- VoxWareAudioMatcher() : Matcher("audio") {}
-+ VoxWareMatcher() : Matcher("audio") {}
- TclObject* match(const char* fmt) {
- if (strcmp(fmt, "voxware") == 0)
-- return (new VoxWareAudio);
-- else
-+ return (new VoxWare);
- return (0);
- }
--} voxware_audio_matcher;
-+} linux_audio_matcher;
-
--VoxWareAudio::VoxWareAudio()
-+VoxWare::VoxWare()
- {
-- readbuf = new u_char[ABUFLEN];
-- readptr = readbufend = readbuf + ABUFLEN;
-+ readbuf = new u_char[blksize];
-+ s16_buf = new u_short[blksize];
-
-- writeptr = writebuf = new u_char[ABUFLEN];
-- writebufend = writebuf + ABUFLEN;
-+ memset(readbuf, ULAW_ZERO, blksize);
-
-- ubufptr = ubuf = new u_char[blksize];
-- ubufend = ubuf + blksize;
-- memset(ubuf, ULAW_ZERO, blksize);
-+ ext_fd = -1 ; /* no external audio */
-+ iports = 4; /* number of input ports */
- }
-
--int VoxWareAudio::HalfDuplex() const
-+void
-+VoxWare::Obtain()
- {
-- /*XXX change this if full duplex audio device available*/
-- return 1;
--}
-+ char *thedev;
-+ char buf[64];
-+ int d = -1;
-
--void VoxWareAudio::Obtain()
--{
- if (HaveAudio())
- abort();
--
-- fd = open("/dev/audio", O_RDWR|O_NDELAY);
-+ is_half_duplex = 0 ;
-+ /*
-+ * variable AUDIODEV has the name of the audio device.
-+ * With the new audio driver, the main device can also control
-+ * the mixer, so there is no need to carry two descriptors around.
-+ */
-+ thedev=getenv("AUDIODEV");
-+ if (thedev==NULL)
-+ thedev="/dev/audio";
-+ else if ( thedev[0] >= '0' && thedev[0] <= '9' ) {
-+ d = atoi(thedev);
-+ sprintf(buf,"/dev/audio%d", d);
-+ thedev = buf ;
-+ }
-+ fd = open(thedev, O_RDWR );
- if (fd >= 0) {
-- int on = 1;
-- ioctl(fd, FIONBIO, &on);
-+ int i = -1 ;
-+ u_long fmt = 0 ;
-+ int rate = 8000 ;
-+
-+ snd_chan_param pa;
-+ struct snd_size sz;
-+ i = ioctl(fd, AIOGCAP, &soundcaps);
-+ fmt = soundcaps.formats ; /* can be invalid, check later */
-+
-+ play_fmt = AFMT_MU_LAW ;
-+ rec_fmt = AFMT_MU_LAW ;
-+
-+ if (i == -1 ) { /* setup code for old voxware driver */
-+ i = ioctl(fd, SNDCTL_DSP_GETFMTS, &fmt);
-+ fmt &= AFMT_MU_LAW ; /* only use mu-law */
-+ fmt |= AFMT_FULLDUPLEX ;
-+ if ( i < 0 ) { /* even voxware driver failed, try with pcaudio */
-+ fmt = AFMT_MU_LAW | AFMT_WEIRD ;
-+ }
-+ }
-+ switch (soundcaps.formats & (AFMT_FULLDUPLEX | AFMT_WEIRD)) {
-+ case AFMT_FULLDUPLEX :
-+ /*
-+ * this entry for cards with decent full duplex. Use s16
-+ * preferably (some are broken in ulaw) or ulaw or u8 otherwise.
-+ */
-+ if (fmt & AFMT_S16_LE)
-+ play_fmt = rec_fmt = AFMT_S16_LE ;
-+ else if (soundcaps.formats & AFMT_MU_LAW)
-+ play_fmt = rec_fmt = AFMT_MU_LAW ;
-+ else if (soundcaps.formats & AFMT_U8)
-+ play_fmt = rec_fmt = AFMT_U8 ;
-+ else {
-+ printf("sorry, no supported formats\n");
-+ close(fd);
-+ fd = -1 ;
-+ return;
-+ }
-+ break ;
-+ case AFMT_FULLDUPLEX | AFMT_WEIRD :
-+ /* this is the sb16... */
-+ if (fmt & AFMT_S16_LE) {
-+ play_fmt = AFMT_U8 ;
-+ rec_fmt = AFMT_S16_LE;
-+ } else {
-+ printf("sorry, no supported formats\n");
-+ close(fd);
-+ fd = -1 ;
-+ return;
-+ }
-+ break ;
-+ default :
-+ printf("sorry don't know how to deal with this card\n");
-+ close (fd);
-+ fd = -1;
-+ return;
-+ }
-
-- int frag = (NFRAG << 16) | ABUFLOG2;
-- ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
--#ifdef fullduplex
-+ pa.play_format = play_fmt ;
-+ pa.rec_format = rec_fmt ;
-+ pa.play_rate = pa.rec_rate = rate ;
-+ ioctl(fd, AIOSFMT, &pa); /* if this fails, also AIOSSIZE will.. */
-+ sz.play_size = (play_fmt == AFMT_S16_LE) ? 2*blksize : blksize;
-+ sz.rec_size = (rec_fmt == AFMT_S16_LE) ? 2*blksize : blksize;
-+ i = ioctl(fd, AIOSSIZE, &sz);
-+
-+ /*
-+ * Set the line input level to 0 to avoid loopback if the mic
-+ * is connected to the line-in port (e.g. through an echo
-+ * canceller).
-+ */
-+ int v = 0;
-+ (void)ioctl(fd, MIXER_WRITE(SOUND_MIXER_LINE), &v);
-+ // restore hardware settings in case some other vat changed them
-+ InputPort(iport);
-+ SetRGain(rgain);
-+ SetPGain(pgain);
-+
-+ if ( i < 0 ) { // if AIOSSIZE fails, maybe this is a Voxware driver
-+ ioctl(fd, SNDCTL_DSP_SPEED, &rate);
-+ ioctl(fd, SNDCTL_DSP_SETFMT, &play_fmt); // same for play/rec
-+ d = (play_fmt == AFMT_S16_LE) ? 2*blksize : blksize;
-+ ioctl(fd, SNDCTL_DSP_SETBLKSIZE, &d);
-+ read(fd, &i, 1); /* dummy read to start read engine */
-+ }
- Audio::Obtain();
--#else
-- notify();
--#endif
-+ } else {
-+ fprintf(stderr, "failed to open rw...\n");
-+ fd = open(thedev, O_WRONLY );
-+ fprintf(stderr, "open wronly returns %d\n", fd);
-+ is_half_duplex = 1 ;
-+ play_fmt = rec_fmt = AFMT_MU_LAW ;
-+ notify(); /* XXX */
- }
- }
-
--void VoxWareAudio::Write(u_char *cp)
-+/*
-+ * note: HalfDuplex() uses a modified function of the new driver,
-+ * which will return AFMT_FULLDUPLEX set in SNDCTL_DSP_GETFMTS
-+ * for full-duplex devices. In the old driver this was 0 so
-+ * the default is to use half-duplex for them. Note also that I have
-+ * not tested half-duplex operation.
-+ */
-+int
-+VoxWare::HalfDuplex() const
- {
-- if (HaveAudio() && (rmute & 1) != 0) {
-- register u_char *cpend = cp + blksize;
-- register u_char *wbuf = writeptr;
-- register u_char *wend = writebufend;
-- for ( ; cp < cpend; cp += 4) {
-- wbuf[0] = cp[0];
-- wbuf[1] = cp[1];
-- wbuf[2] = cp[2];
-- wbuf[3] = cp[3];
-- wbuf += 4;
-- if (wbuf >= wend) {
-- wbuf = writebuf;
-- if (write(fd, (char*)wbuf, ABUFLEN) != ABUFLEN)
-- perror("aud write");
-- }
-- }
-- writeptr = wbuf;
-+ int i, probed_duplex = 0;
-+
-+ /* newpcm style */
-+#ifdef SNDCTL_DSP_GETCAPS
-+ ioctl(fd, SNDCTL_DSP_GETCAPS, &i);
-+ probed_duplex |= (i & DSP_CAP_DUPLEX);
-+#endif /* SNDCTL_DSP_GETCAPS */
-+
-+ /* pcm style */
-+#ifdef SNDCTL_DSP_GETFMTS
-+ ioctl(fd, SNDCTL_DSP_GETFMTS, &i);
-+ probed_duplex |= (i & AFMT_FULLDUPLEX);
-+#endif /* SNDCTL_DSP_GETFMTS */
-+
-+ if (is_half_duplex || (probed_duplex == 0)) {
-+ fprintf(stderr, "HalfDuplex returns 1\n");
-+ return 1 ;
- }
-+
-+ return 0;
- }
-
--int VoxWareAudio::FrameReady()
-+void VoxWare::Release()
- {
-- if ((rmute & 1) == 0) {
-- register u_char* cp = ubufptr;
-- register u_char* cpend = ubufend;
-- register u_char* rbuf = readptr;
-- register u_char* rend = readbufend;
--
-- for ( ; cp < cpend; cp += 4) {
-- if (rbuf >= rend) {
-- rbuf = readbuf;
-- int cc = read(fd, (char*)rbuf, ABUFLEN);
-- if (cc <= 0) {
-- ubufptr = cp;
-- readbufend = rbuf;
-- if (cc == -1 && errno != EAGAIN) {
-- Release();
-- Obtain();
-- }
-- return (0);
-+ if (HaveAudio()) {
-+ Audio::Release();
- }
-- readbufend = rend = rbuf + cc;
- }
-- cp[0] = rbuf[0];
-- cp[1] = rbuf[1];
-- cp[2] = rbuf[2];
-- cp[3] = rbuf[3];
-- rbuf += 4;
-+
-+void VoxWare::Write(u_char *cp)
-+{
-+ int i = blksize, l;
-+ if (play_fmt == AFMT_S16_LE) {
-+ for (i=0; i< blksize; i++)
-+ s16_buf[i] = mulawtolin[cp[i]] ;
-+ cp = (u_char *)s16_buf;
-+ i = 2 *blksize ;
-+ } else if (play_fmt == AFMT_S8) {
-+ for (i=0; i< blksize; i++) {
-+ int x = mulawtolin[cp[i]] ;
-+ x = (x >> 8 ) & 0xff;
-+ cp[i] = (u_char)x ;
-+ }
-+ i = blksize ;
-+ } else if (play_fmt == AFMT_U8) {
-+ for (i=0; i< blksize; i++) {
-+ int x = mulawtolin[cp[i]] ;
-+ /*
-+ * when translating to 8-bit formats, it would be useful to
-+ * implement AGC to avoid loss of resolution in the conversion.
-+ * This code is still incomplete...
-+ */
-+#if 0 /* AGC -- still not complete... */
-+ static int peak = 0;
-+ if (x < 0) x = -x ;
-+ if (x > peak) peak = ( peak*16 + x - peak ) / 16 ;
-+ else peak = ( peak*8192 + x - peak ) / 8192 ;
-+ if (peak < 128) peak = 128 ;
-+ /* at this point peak is in the range 128..32k
-+ * samples can be scaled and clipped consequently.
-+ */
-+ x = x * 32768/peak ;
-+ if (x > 32767) x = 32767;
-+ else if (x < -32768) x = -32768;
-+#endif
-+ x = (x >> 8 ) & 0xff;
-+ x = (x ^ 0x80) & 0xff ;
-+ cp[i] = (u_char)x ;
-+ }
-+ i = blksize ;
-+ }
-+#if 0
-+ // this code is meant to keep the queue short.
-+ int r, queued;
-+ r = ioctl(fd, AIONWRITE, &queued);
-+ queued = soundcaps.bufsize - queued ;
-+ if (play_fmt == AFMT_S16_LE) {
-+ if (queued > 8*blksize)
-+ i -= 8 ;
-+ } else {
-+ if (queued > 4*blksize)
-+ i -= 4 ;
- }
-- readptr = rbuf;
-+#endif
-+ for ( ; i > 0 ; i -= l) {
-+ l = write(fd, cp, i);
-+ cp += l;
- }
-- return (1);
- }
-
--u_char* VoxWareAudio::Read()
-+u_char* VoxWare::Read()
- {
-- u_char* cp = ubuf;
-- ubufptr = cp;
-- return (cp);
-+ u_char* cp;
-+ int l=0, l0 = blksize, i = blksize;
-+
-+ cp = readbuf;
-+
-+ if (rec_fmt == AFMT_S16_LE) {
-+ cp = (u_char *)s16_buf;
-+ l0 = i = 2 *blksize ;
-+ }
-+ for ( ; i > 0 ; i -= l ) {
-+ l = read(fd, cp, i);
-+ if (l<0) break;
-+ cp += l ;
-+ }
-+ if (rec_fmt == AFMT_S16_LE) {
-+ for (i=0; i< blksize; i++) {
-+#if 1 /* remove DC component... */
-+ static int smean = 0 ; /* smoothed mean to remove DC */
-+ int dif = ((short) s16_buf[i]) - (smean >> 13) ;
-+ smean += dif ;
-+ readbuf[i] = lintomulawX[ dif & 0x1ffff ] ;
-+#else
-+ readbuf[i] = lintomulaw[ s16_buf[i] ] ;
-+#endif
-+ }
-+ }
-+ else if (rec_fmt == AFMT_S8) {
-+ for (i=0; i< blksize; i++)
-+ readbuf[i] = lintomulaw[ readbuf[i]<<8 ] ;
-+ }
-+ else if (rec_fmt == AFMT_U8) {
-+ for (i=0; i< blksize; i++)
-+ readbuf[i] = lintomulaw[ (readbuf[i]<<8) ^ 0x8000 ] ;
-+ }
-+ if (iport == 3) {
-+ l = read(ext_fd, readbuf, blksize);
-+ if (l < blksize) {
-+ lseek(ext_fd, (off_t) 0, 0);
-+ read(ext_fd, readbuf+l, blksize - l);
-+ }
-+ }
-+ return readbuf;
- }
-
--void VoxWareAudio::SetRGain(int level)
-+/*
-+ * should check that I HaveAudio() before trying to set gain.
-+ *
-+ * In most mixer devices, there is only a master volume control on
-+ * the capture channel, so the following code does not really work
-+ * as expected. The only (partial) exception is the MIC line, where
-+ * there is generally a 20dB boost which can be enabled or not
-+ * depending on the type of device.
-+ */
-+void VoxWare::SetRGain(int level)
- {
-+ double x = level;
-+ level = (int) (x/2.56);
-+ int foo = (level<<8) | level;
-+ if (!HaveAudio())
-+ Obtain();
-+ switch (iport) {
-+ case 2:
-+ case 1:
-+ break;
-+ case 0:
-+ if (ioctl(fd, MIXER_WRITE(SOUND_MIXER_MIC), &foo) == -1)
-+ printf("failed to set mic volume \n");
-+ break;
-+ }
-+ /* IGAIN tends to be found on SB-like mixers, RECLEV on AC97 */
-+ if ((ioctl(fd, MIXER_WRITE(SOUND_MIXER_IGAIN), &foo) == -1) &&
-+ (ioctl(fd, MIXER_WRITE(SOUND_MIXER_RECLEV), &foo) == -1))
-+ printf("failed set input line volume \n");
- rgain = level;
- }
-
--void VoxWareAudio::SetPGain(int level)
-+void VoxWare::SetPGain(int level)
- {
-+ float x = level;
-+ level = (int) (x/2.56);
-+ int foo = (level<<8) | level;
-+ if (ioctl(fd, MIXER_WRITE(SOUND_MIXER_PCM), &foo) == -1) {
-+ printf("failed to output level %d \n", level);
-+ }
- pgain = level;
- }
-
--void VoxWareAudio::OutputPort(int p)
-+void VoxWare::OutputPort(int p)
- {
- oport = p;
- }
-
--void VoxWareAudio::InputPort(int p)
-+void VoxWare::InputPort(int p)
- {
-+ int src = 0;
-+
-+ if (ext_fd >= 0 && p != 3) {
-+ close(ext_fd);
-+ ext_fd = -1 ;
-+ }
-+
-+ switch(p) {
-+ case 3:
-+ if (ext_fd == -1)
-+ ext_fd = open(ext_fname, 0);
-+ if (ext_fd != -1)
-+ lseek(ext_fd, (off_t) 0, 0);
-+ break;
-+ case 2:
-+ src = 1 << SOUND_MIXER_LINE;
-+ break;
-+ case 1: /* cd ... */
-+ src = 1 << SOUND_MIXER_CD;
-+ break;
-+ case 0 :
-+ src = 1 << SOUND_MIXER_MIC;
-+ break;
-+ }
-+ if ( ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &src) == -1 ) {
-+ printf("failed to select input \n");
-+ p = 0;
-+ }
- iport = p;
- }
-
--void VoxWareAudio::RMute()
-+void VoxWare::RMute()
- {
- rmute |= 1;
- }
-
--void VoxWareAudio::RUnmute()
-+void VoxWare::RUnmute()
- {
- rmute &=~ 1;
- }
-+
-+/*
-+ * FrameReady must return 0 every so often, or the system will keep
-+ * processing mike data and not other events.
-+ */
-+int VoxWare::FrameReady()
-+{
-+ int i, l = 0;
-+ int lim = blksize;
-+
-+ i = ioctl(fd, FIONREAD, &l );
-+ if (rec_fmt == AFMT_S16_LE) lim = 2*blksize;
-+ return (l >= lim) ? 1 : 0 ;
-+}
-+/*** end of file ***/