pkgsrc/audio/xamp/patches/patch-ag
rh e37e6d06d1 Update xamp to 0.8.10 (from PR 11250 by Rui-Xiang Guo
<rxg@ms25.url.com.tw>, the maintainer of this package).  Changes are
bugfixes, and use of the native NetBSD sound API instead of OSS emulation.
2000-10-18 11:22:42 +00:00

245 lines
6.4 KiB
Text

$NetBSD: patch-ag,v 1.3 2000/10/18 11:22:44 rh Exp $
--- ../audioIO_NetBSD.c.orig Tue Oct 17 17:50:54 2000
+++ ../audioIO_NetBSD.c Tue Oct 17 20:01:20 2000
@@ -0,0 +1,240 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+
+ Origional code by: tomislav uzelac
+ Modified by:
+ * Dan Nelson - BSD mods.
+ * Andrew Richards - moved code from audio.c and added mixer support etc
+ * Brett Lymn - NetBSD support & 8bit mode.
+ * Rui-Xiang Guo - NetBSD native API support.
+ */
+
+/* Support for NetBSD sound devices */
+
+#include "amp.h"
+#include "audioIO.h"
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/audioio.h>
+#include <sys/param.h>
+#include <sys/filio.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+/* optimal fragment size - if this is set too high you will get clicks
+ * in the audio output, below is near the upper limit for the sb sound driver
+ * on my machine (Toshiba 400CDT laptop).
+ */
+
+int AUSIZ = 20480;
+
+/* declare these static to effectively isolate the audio device */
+
+static int audio_fd;
+static int mixer_fd;
+
+static char *reduce;
+
+/* audioOpen() */
+/* should open the audio device, perform any special initialization */
+/* Set the frequency, no of channels and volume. Volume is only set if */
+/* it is not -1 */
+
+void
+audioOpen(int frequency, int stereo, int volume)
+{
+ audio_info_t audio_dev;
+
+ if ((audio_fd = open ("/dev/audio", O_WRONLY, 0)) == -1)
+ die("Unable to open the audio device\n");
+ DB(audio, msg("Audio device opened on %d\n", audio_fd));
+
+ ioctl(audio_fd, AUDIO_GETINFO, &audio_dev); /* get current settings */
+ AUDIO_INITINFO(&audio_dev);
+
+ /* Set 1 or 2 channels */
+ audio_dev.play.channels = (stereo ? 2 : 1);
+
+ /* Set the output frequency */
+ DB(audio, msg("Setting freq to %d Hz\n", frequency));
+ audio_dev.play.sample_rate = frequency;
+
+ if (volume != -1)
+ audioSetVolume(volume);
+
+ audio_dev.blocksize = AUSIZ;
+ audio_dev.play.encoding = AUDIO_ENCODING_SLINEAR;
+ audio_dev.hiwat = 20;
+ audio_dev.lowat = 1;
+ audio_dev.mode = AUMODE_PLAY;
+
+ if (ioctl(audio_fd, AUDIO_SETINFO, &audio_dev) < 0)
+ die("AUDIO_SETINFO failed\n");
+
+ /* ok - try running the sound system at 16 bits, if that does not
+ * work then try 8 bits, if that does not work, give up.
+ */
+ reduce = NULL;
+ audio_dev.play.precision = 16;
+ if (ioctl(audio_fd, AUDIO_SETINFO, &audio_dev) < 0) {
+ DB(audio,
+ msg("AUDIO_SETINFO for 16 bits failed, try 8 bits\n"));
+ if ((reduce = (char *) malloc(AUSIZ * sizeof(char))) == NULL)
+ die("Cannot malloc reduce buffer\n");
+ audio_dev.play.precision = 8;
+ if (ioctl(audio_fd, AUDIO_SETINFO, &audio_dev) < 0)
+ die("AUDIO_SETINFO failed both 16bit and 8bit\n");
+ AUSIZ = AUSIZ * sizeof(short);
+ }
+}
+
+
+/* audioSetVolume - only code this if your system can change the volume while playing */
+/* sets the output volume 0-100 */
+
+int device_id = 3;
+char *mixer_device;
+mixer_ctrl_t *values;
+mixer_devinfo_t *infos;
+
+void
+audioSetMixer()
+{
+ int i, ndev;
+ mixer_devinfo_t dinfo;
+
+ mixer_device = getenv("MIXERDEVICE");
+ if (mixer_device == NULL)
+ mixer_device = "/dev/mixer0";
+
+ if ((mixer_fd = open(mixer_device, O_RDWR)) < 0)
+ warn("Unable to open mixer device\n");
+ DB(audio, msg("Mixer device opened on %d\n", mixer_fd));
+
+ for (ndev = 0; ; ndev++) {
+ dinfo.index = ndev;
+ if (ioctl(mixer_fd, AUDIO_MIXER_DEVINFO, &dinfo) < 0)
+ break;
+ }
+ infos = calloc(ndev, sizeof *infos);
+ values = calloc(ndev, sizeof *values);
+
+ for (i = 0; i < ndev; i++) {
+ infos[i].index = i;
+ ioctl(mixer_fd, AUDIO_MIXER_DEVINFO, &infos[i]);
+ }
+
+ for (i = 0; i < ndev; i++) {
+ if (infos[i].type == AUDIO_MIXER_VALUE) {
+ values[i].dev = i;
+ values[i].type = infos[i].type;
+ }
+ }
+
+ values[device_id].un.value.num_channels = 2;
+}
+
+void
+audioSetVolume(int volume)
+{
+ mixer_ctrl_t *m;
+
+ DB(audio, msg("Setting volume to: %d\n", volume));
+ m = &values[device_id];
+
+ if (ioctl(mixer_fd, AUDIO_MIXER_WRITE, m) < 0)
+ warn("Unable to set sound volume\n");
+
+ m->un.value.level[0] = m->un.value.level[1] = volume * AUDIO_MAX_GAIN / 100;
+}
+
+void
+audioSetBalance(int volume, int balance)
+{
+ mixer_ctrl_t *m;
+
+ DB(audio, msg("Setting volume to: %d\n", volume));
+ DB(audio, msg("Setting balance to: %d\n", balance));
+ m = &values[device_id];
+
+ if (ioctl(mixer_fd, AUDIO_MIXER_WRITE, m) < 0)
+ warn("Unable to set sound volume\n");
+
+ if (balance < 0) {
+ m->un.value.level[0] = volume * AUDIO_MAX_GAIN / 100;
+ m->un.value.level[1] = m->un.value.level[0] * (20 + balance) / 20;
+ }
+ else {
+ m->un.value.level[1] = volume * AUDIO_MAX_GAIN / 100;
+ m->un.value.level[0] = m->un.value.level[1] * (20 - balance) / 20;
+ }
+}
+
+/* audioFlush() */
+/* should flush the audio device */
+
+inline void
+audioFlush()
+{
+ DB(audio, msg("audio: flush %d\n", audio_fd));
+}
+
+
+/* audioClose() */
+/* should close the audio device and perform any special shutdown */
+
+void
+audioClose()
+{
+ close(audio_fd);
+ if (mixer_fd != -1)
+ close(mixer_fd);
+ DB(audio, msg("audio: closed %d\n", audio_fd));
+}
+
+/* audioWrite */
+/* writes count bytes from buffer to the audio device */
+/* returns the number of bytes actually written */
+
+inline int
+audioWrite(char *buffer, int count)
+{
+ int i;
+ short *cast;
+
+ DB(audio, msg("audio: Writing %d bytes to audio descriptor %d\n",count,
+ getAudioFd()));
+
+ /* if the reduce buffer is allocated we need to do 8bit writes
+ * so munge the data buffer appropriately.
+ */
+ if (reduce != NULL) {
+ cast = (short *) buffer;
+
+ for (i=0; i < count/sizeof(short); i++) {
+ reduce[i] = cast[i] >> 8;
+ }
+ return (sizeof(short) * write(audio_fd, reduce,
+ count/sizeof(short)));
+ } else {
+ return (write(audio_fd,buffer,count));
+ }
+}
+
+/* Let buffer.c have the audio descriptor so it can select on it. This means */
+/* that the program is dependent on a file descriptor to work. Should really */
+/* move the select's etc (with inlines of course) in here so that this is the */
+/* ONLY file which has hardware dependent audio stuff in it */
+
+int
+getAudioFd()
+{
+ return (audio_fd);
+}