diff --git a/sys/i386/isa/sound/dmabuf.c b/sys/i386/isa/sound/dmabuf.c index ee7e1368970..aaf57a66f0f 100644 --- a/sys/i386/isa/sound/dmabuf.c +++ b/sys/i386/isa/sound/dmabuf.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: dmabuf.c,v 1.13 1995/03/05 08:10:23 jkh Exp $ + * $Id: dmabuf.c,v 1.14 1995/03/18 20:01:10 swallace Exp $ */ #include "sound_config.h" @@ -299,7 +299,7 @@ DMAbuf_release (int dev, int mode) return 0; } -static int +int DMAbuf_start_input(int dev) { unsigned long flags; diff --git a/sys/i386/isa/sound/sound_calls.h b/sys/i386/isa/sound/sound_calls.h index 3618f29989c..dea28e3babd 100644 --- a/sys/i386/isa/sound/sound_calls.h +++ b/sys/i386/isa/sound/sound_calls.h @@ -1,7 +1,7 @@ /* * DMA buffer calls * - * $Id: sound_calls.h,v 1.10 1995/03/12 23:34:06 swallace Exp $ + * $Id: sound_calls.h,v 1.11 1995/03/28 07:56:13 bde Exp $ */ #ifndef _MACHINE_ISA_SOUND_H_ @@ -14,6 +14,7 @@ int DMAbuf_release(int dev, int mode); int DMAbuf_getwrbuffer(int dev, char **buf, int *size); int DMAbuf_getrdbuffer(int dev, char **buf, int *len); int DMAbuf_rmchars(int dev, int buff_no, int c); +int DMAbuf_start_input(int dev); int DMAbuf_start_output(int dev, int buff_no, int l); int DMAbuf_ioctl(int dev, unsigned int cmd, unsigned int arg, int local); long DMAbuf_init(long mem_start); diff --git a/sys/i386/isa/sound/vat_audio.c b/sys/i386/isa/sound/vat_audio.c index e520905269f..c056657151d 100644 --- a/sys/i386/isa/sound/vat_audio.c +++ b/sys/i386/isa/sound/vat_audio.c @@ -1,14 +1,55 @@ +/* + * Minimally compliant SunOS compatible audio driver front-end + * for use with VAT. + * + * This is a front end for the voxware based drivers that form the standard + * audio driver system for FreeBSD. It will not operate without the voxware + * package. + * + * This is not a full implementation of the SunOS audio driver, don't + * expect anything other than vat to operate with it. + * + * ---WARNING + * ---WARNING this work is not complete, it still doesn't work + * ---WARNING + * + * Copyright (C) 1993-1994 Amancio Hasty. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation. + * + * This software is provided `as-is'. The author disclaims all + * warranties with regard to this software, including without + * limitation all implied warranties of merchantability, fitness for + * a particular purpose, or noninfringement. In no event shall the + * author be liable for any damages whatsoever, including + * special, incidental or consequential damages, including loss of + * use, data, or profits, even if advised of the possibility thereof, + * and regardless of whether in an action in contract, tort or + * negligence, arising out of or in connection with the use or + * performance of this software. + * + */ + #include "vat_audio.h" -#if NVAT_AUDIO > 0 +#include "snd.h" /* Generic Sound Driver (voxware) */ + +#if (NVAT_AUDIO > 0) && (NSND > 0) #include "sound_config.h" #include "os.h" #include "vat_audioio.h" +#define splaudio splclock -#define PAS_AUDIO (SND_DEV_AUDIO | 0x10) -#define SB_AUDIO (SND_DEV_AUDIO ) -#define MIXER (SND_DEV_CTL) +extern int sndopen (dev_t dev, int flags); +extern int sndclose (dev_t dev, int flags); +extern int sndioctl (dev_t dev, int cmd, void *arg, int mode); +extern int sndread (int dev, struct uio *uio); +extern int sndwrite (int dev, struct uio *uio); struct va_softc { dev_t rdev; /* record device */ @@ -19,123 +60,140 @@ struct va_softc { int rlevel; int plevel; int open; -} va_softc = { PAS_AUDIO, SB_AUDIO, MIXER, {0, 0}, {0, 0}, 0, 0, 0 } ; +} va_softc; #define DEF_SAMPLE_RATE 8007 #ifndef AUDIOBLOCKSIZE #define AUDIOBLOCKSIZE 160 /* 20ms at 8khz */ #endif -static int iblocksize=AUDIOBLOCKSIZE; -static int oblocksize=1024; -#define splaudio splclock +static int iblocksize = AUDIOBLOCKSIZE; +static int oblocksize = 1024; -static void -setpgain(int level) -{ -register struct va_softc *va = (struct va_softc *)&va_softc; -int arg; - - level = (level*100/255) & 0x7f; - arg = (level << 8) | level; - sndioctl(va->mixer, MIXER_WRITE(SOUND_MIXER_PCM), &arg); -} - -static void -setrgain(int level) -{ -register struct va_softc *va = (struct va_softc *)&va_softc; -int arg; -int arg1; - - level = (level*100/255) & 0x7f; - arg = (level << 8) | level; - - sndioctl(va->mixer, SOUND_MIXER_WRITE_LINE, &arg); - sndioctl(va->mixer, SOUND_MIXER_WRITE_MIC, &arg); - sndioctl(va->mixer, SOUND_MIXER_WRITE_CD, &arg); -} - -static int -setprate(int rate) -{ -register struct va_softc *va = (struct va_softc *)&va_softc; -register int dev; - - dev = va->pdev >> 4; - return(audio_devs[dev]->ioctl(dev, SOUND_PCM_WRITE_RATE, rate, 1)); -} - -static int -setrrate(int rate) -{ -register struct va_softc *va = (struct va_softc *)&va_softc; -register int dev; - - dev = va->rdev >> 4; - return(audio_devs[dev]->ioctl(dev, SOUND_PCM_WRITE_RATE, rate, 1)); - -} +static u_int record_devices = (SOUND_MASK_MIC|SOUND_MASK_LINE|SOUND_MASK_CD); static int default_level[SOUND_MIXER_NRDEVICES] = { /* max = 0x64 */ 0x3232, /* Master Volume */ 0x3232, /* Bass */ 0x3232, /* Treble */ - 0x0, /* FM */ + 0x0000, /* FM */ 0x6464, /* PCM */ - 0x0, /* PC Speaker */ + 0x0000, /* PC Speaker */ 0x6464, /* Ext Line */ 0x6464, /* Mic */ 0x4b4b, /* CD */ - 0x0, /* Recording monitor (input mixer) -- avoid feedback */ + 0x0000, /* Recording monitor (input mixer) -- avoid feedback */ 0x4b4b, /* SB PCM */ 0x6464, /* Record Level -- to ADC */ }; -static u_int record_devices = (SOUND_MASK_MIC|SOUND_MASK_LINE|SOUND_MASK_CD); + +static void +setpgain(int level) +{ + register struct va_softc *va = (struct va_softc *)&va_softc; + int arg; + + level = (level * 100 / 255) & 0x7f; + arg = (level << 8) | level; + + sndioctl(va->mixer, MIXER_WRITE(SOUND_MIXER_PCM), &arg, 0); +} + +static void +setrgain(int level) +{ + register struct va_softc *va = (struct va_softc *)&va_softc; + int arg, arg1; + + level = (level * 100 / 255) & 0x7f; + arg = (level << 8) | level; + + sndioctl(va->mixer, SOUND_MIXER_WRITE_LINE, &arg, 0); + sndioctl(va->mixer, SOUND_MIXER_WRITE_MIC, &arg, 0); + sndioctl(va->mixer, SOUND_MIXER_WRITE_CD, &arg, 0); +} + +static int +setprate(int rate) +{ + register struct va_softc *va = (struct va_softc *)&va_softc; + register int dev; + + dev = va->pdev >> 4; + return (audio_devs[dev]->ioctl(dev, SOUND_PCM_WRITE_RATE, rate, 1)); +} + +static int +setrrate(int rate) +{ + register struct va_softc *va = (struct va_softc *)&va_softc; + register int dev; + + dev = va->rdev >> 4; + return (audio_devs[dev]->ioctl(dev, SOUND_PCM_WRITE_RATE, rate, 1)); +} int vaopen(dev_t dev, int flags) { -register struct va_softc *va = (struct va_softc *)&va_softc; -int s; + register struct va_softc *va = (struct va_softc *)&va_softc; + int s; - if(va->open) + if (va->open) return(EBUSY); else - va->open = 1 ; + va->open = 1; - s=sndopen(va->rdev, FREAD); - if(s) { +#ifdef SND_BIDIR + va->rdev = SND_DEV_AUDIO | (1<<4); /* first and second device */ + va->pdev = SND_DEV_AUDIO | (0<<4); + va->mixer = SND_DEV_CTL; + + s = sndopen(va->rdev, FREAD); + if (s) { va->open = 0; return(s); } - s=sndopen(va->pdev, FWRITE); - if(s) { + + s = sndopen(va->pdev, FWRITE); + if (s) { va->open = 0; sndclose(va->rdev, FREAD); return(s); } +#else + va->rdev = SND_DEV_AUDIO | (0<<4); /* first attached device */ + va->pdev = SND_DEV_AUDIO | (0<<4); + va->mixer = SND_DEV_CTL; + + s = sndopen(va->rdev, flags); + if (s) { + va->open = 0; + return(s); + } +#endif /* set sample rates */ setprate(DEF_SAMPLE_RATE); setrrate(DEF_SAMPLE_RATE); /* set block size for I/O samples */ - sndioctl(va->rdev, SNDCTL_DSP_GETBLKSIZE, &iblocksize); - sndioctl(va->pdev, SNDCTL_DSP_GETBLKSIZE, &oblocksize); + sndioctl(va->rdev, SNDCTL_DSP_GETBLKSIZE, &iblocksize, 0); + sndioctl(va->pdev, SNDCTL_DSP_GETBLKSIZE, &oblocksize, 0); /* initialize mixer controls the way we want them */ - sndioctl(va->mixer, SOUND_MIXER_WRITE_RECSRC, &record_devices); - for(s=0; s< SOUND_MIXER_NRDEVICES; s++) - sndioctl(va->mixer, MIXER_WRITE(s), &default_level[s]); - va->rlevel=(default_level[SOUND_MASK_MIC]&0x7f) * 255 / 100; - va->plevel=(default_level[SOUND_MASK_PCM]&0x7f) * 255 / 100; + sndioctl(va->mixer, SOUND_MIXER_WRITE_RECSRC, &record_devices, 0); - if((flags & FREAD) != 0) { /* start the read process */ + for (s = 0; s < SOUND_MIXER_NRDEVICES; s++) + sndioctl(va->mixer, MIXER_WRITE(s), &default_level[s], 0); + + va->rlevel = (default_level[SOUND_MASK_MIC] & 0x7f) * 255 / 100; + va->plevel = (default_level[SOUND_MASK_PCM] & 0x7f) * 255 / 100; + + if (flags & FREAD) /* start the read process */ DMAbuf_start_input(va->rdev>>4); - } return(0); } @@ -143,47 +201,60 @@ int s; int vaclose(dev_t dev, int flags) { -register struct va_softc *va = (struct va_softc *)&va_softc; + register struct va_softc *va = (struct va_softc *)&va_softc; va->open = 0; - sndioctl(va->mixer, SNDCTL_DSP_RESET, 0); + + sndioctl(va->mixer, SNDCTL_DSP_RESET, NULL, 0); + +#ifdef SND_BIDIR sndclose(va->pdev, FWRITE); sndclose(va->rdev, FREAD); - return(0); +#else + sndclose(va->rdev, flags); +#endif + return (0); } int -varead(dev_t dev, struct uio *buf, int ioflag) +varead(dev_t dev, struct uio *buf) { -register struct va_softc *va = (struct va_softc *)&va_softc; + register struct va_softc *va = (struct va_softc *)&va_softc; - return(sndread(va->rdev, buf, ioflag)); + return sndread(va->rdev, buf); } int -vawrite(dev_t dev, struct uio *buf, int ioflag) +vawrite(dev_t dev, struct uio *buf) { -register struct va_softc *va = (struct va_softc *)&va_softc; + register struct va_softc *va = (struct va_softc *)&va_softc; - return(sndwrite(va->pdev, buf, ioflag)); + return sndwrite(va->pdev, buf); } void audio_get_info(struct va_softc *va, struct audio_info *ai) { -struct audio_prinfo *r, *p; -int rdev = va->rdev>>4; -int pdev = va->pdev>>4; + struct audio_prinfo *r, *p; + int rdev = va->rdev >> 4; + int pdev = va->pdev >> 4; r = &ai->record; p = &ai->play; - p->sample_rate = audio_devs[pdev]->ioctl(pdev, SOUND_PCM_READ_RATE, 0,1); - r->sample_rate = audio_devs[rdev]->ioctl(rdev, SOUND_PCM_READ_RATE, 0,1); - p->channels = audio_devs[pdev]->ioctl(pdev, SOUND_PCM_READ_CHANNELS, 0,1); - r->channels = audio_devs[rdev]->ioctl(rdev, SOUND_PCM_READ_CHANNELS, 0,1); + p->sample_rate = + audio_devs[pdev]->ioctl(pdev, SOUND_PCM_READ_RATE, 0, 1); + r->sample_rate = + audio_devs[rdev]->ioctl(rdev, SOUND_PCM_READ_RATE, 0, 1); + + p->channels = + audio_devs[pdev]->ioctl(pdev, SOUND_PCM_READ_CHANNELS, 0, 1); + r->channels = + audio_devs[rdev]->ioctl(rdev, SOUND_PCM_READ_CHANNELS, 0, 1); + p->precision = audio_devs[pdev]->ioctl(pdev, SOUND_PCM_READ_BITS, 0, 1); r->precision = audio_devs[rdev]->ioctl(rdev, SOUND_PCM_READ_BITS, 0, 1); + p->encoding = r->encoding = AUDIO_ENCODING_ULAW; ai->monitor_gain = 0; @@ -195,45 +266,45 @@ int pdev = va->pdev>>4; p->port = AUDIO_SPEAKER; p->open = r->open = va->open; - - return; - } void audio_set_info(struct va_softc *va, struct audio_info *ai) { -struct audio_prinfo *r, *p; -int rdev = va->rdev>>4; -int pdev = va->pdev>>4; + struct audio_prinfo *r, *p; + int rdev = va->rdev >> 4; + int pdev = va->pdev >> 4; r = &ai->record; p = &ai->play; - /* Only set gains if mode == -1, I think this is a bug in vat. */ - if(ai->mode == ~0) { - if(p->gain != ~0) { + /* Only set gains if mode == -1, I think this is a bug in vat. */ + + if (ai->mode == ~0) { + if (p->gain != ~0) { va->plevel = p->gain; setpgain(va->plevel); } - if(r->gain != ~0) { + if (r->gain != ~0) { va->rlevel = r->gain; setrgain(va->rlevel); } } - if(p->sample_rate != ~0) + + if (p->sample_rate != ~0) p->sample_rate = setprate(p->sample_rate); - if(r->sample_rate != ~0) + if (r->sample_rate != ~0) r->sample_rate = setrrate(r->sample_rate); DMAbuf_start_input(rdev); } + int vaioctl(dev_t dev, int cmd, caddr_t arg, int mode) { -register struct va_softc *va = (struct va_softc *)&va_softc; -int s; + register struct va_softc *va = (struct va_softc *)&va_softc; + int s; switch(cmd) { case FIONBIO: @@ -248,8 +319,10 @@ int s; printf("vaioctl: cmd=0x%x, '%c', num = %d, len=%d, %s\n", cmd, IOCGROUP(cmd), cmd & 0xff, IOCPARM_LEN(cmd), cmd&IOC_IN ? "in" : "out"); + s = sndioctl(va->rdev, cmd, arg, mode); - if(s == 0) + + if (s == 0) s = sndioctl(va->pdev, cmd, arg, mode); break; } @@ -259,59 +332,55 @@ int s; int vaselect(dev_t dev, int rw, struct proc *p) { -register struct va_softc *va = (struct va_softc *)&va_softc; -int s; -int r; + register struct va_softc *va = (struct va_softc *)&va_softc; + int s, r; - s = splaudio(); r = 0; - switch(rw) { + s = splaudio(); + + switch (rw) { case FREAD: - if(DMAbuf_input_ready(va->rdev>>4)) + if (DMAbuf_input_ready(va->rdev>>4)) r = 1; else selrecord(p, &va->rsel); break; case FWRITE: - if(DMAbuf_output_ready(va->pdev>>4)) + if (DMAbuf_output_ready(va->pdev>>4)) r = 1; else selrecord(p, &va->wsel); - break; } + splx(s); return(r); } void -audio_rint() +audio_rint(void) { -register struct va_softc *va = (struct va_softc *)&va_softc; -register u_char *tp; -register int cc; + register struct va_softc *va = (struct va_softc *)&va_softc; + + if (!va->open) + return; - if(!va->open) return; selwakeup(&va->rsel); } void -audio_pint() +audio_pint(void) { -register struct va_softc *va = (struct va_softc *)&va_softc; -register u_char *tp; -register int cc; + register struct va_softc *va = (struct va_softc *)&va_softc; + + if (!va->open) + return; - if(!va->open) return; selwakeup(&va->wsel); } #else -void -audio_rint() -{ -} -void -audio_pint() -{ -} -#endif /* NVAT_AUDIO */ + +void audio_rint(void) {} +void audio_pint(void) {} + +#endif /* NVAT_AUDIO && NSND */