2000-12-18 01:03:37 +01:00
|
|
|
|
$NetBSD: patch-ab,v 1.2 2000/12/18 00:03:38 wiz Exp $
|
2000-12-18 00:32:09 +01:00
|
|
|
|
|
|
|
|
|
--- sys/NetBSD/audio.c.orig Sun May 23 10:29:13 1999
|
|
|
|
|
+++ sys/NetBSD/audio.c Sun May 23 10:55:39 1999
|
|
|
|
|
@@ -0,0 +1,298 @@
|
|
|
|
|
+/*
|
|
|
|
|
+ * NetBSD $B%5%&%s%I=hM}(B
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * Copyright (c) 1994 Kazuhiko Ishii.
|
|
|
|
|
+ * Copyright (c) 1995 Masanobu Saitoh.
|
|
|
|
|
+ *
|
|
|
|
|
+ * $BK\%=%U%H%&%'%"$N%=!<%9$d%P%$%J%j$r:FG[I[$9$k>l9g$O!"<!$N>r7o$r=e<i$7$F(B
|
|
|
|
|
+ * $B2<$5$$!#(B
|
|
|
|
|
+ *
|
|
|
|
|
+ * 1. $BK\%=%U%H%&%'%"$rF~<j$7$?J}$K$O!"(BX11$BHG(B Emi Clock $B$N;HMQ8"$H!"Bh;0<T(B
|
|
|
|
|
+ * $B$X$N:FG[I[8"$,G'$a$i$l$^$9!#$?$@$7!":FG[I[$K4X$7$F$O!"F~<j;~$N%*%j(B
|
|
|
|
|
+ * $B%8%J%k$N$^$^2~JQ$;$:$K9T$&$3$H$,>r7o$G$9!#(B
|
|
|
|
|
+ * 2. $BK\%=%U%H%&%'%"$N0lIt$^$?$OA4It$rCx:n8"<T$KL5CG$G2~JQ$7$FG[I[$9$k$3(B
|
|
|
|
|
+ * $B$H$O$G$-$^$;$s!#(B
|
|
|
|
|
+ * 3. $BK\%=%U%H%&%'%"$N0lIt$^$?$OA4It$rCx:n8"<T$KL5CG$GFs<!MxMQ$9$k$3$H$O(B
|
|
|
|
|
+ * $B$G$-$^$;$s!#(B
|
|
|
|
|
+ * 4. $BK\%=%U%H%&%'%"$r%7%9%F%`$K%P%s%I%k$7$?$j!"%7%9%F%`$NDI2C%Q%C%1!<%8(B
|
|
|
|
|
+ * $B$H$7$FBh;0<T$K:FG[I[$7$?$j$9$k>l9g$O!";vA0$KCx:n8"<T$K5v2D$,I,MW$G(B
|
|
|
|
|
+ * $B$9!#(B
|
|
|
|
|
+ * 5. $BK\%=%U%H%&%'%"$r>&MQ$K;HMQ$9$k>l9g(B($B6bA,E*Mx1W$rF@$k>l9g(B)$B$O!";vA0$K(B
|
|
|
|
|
+ * $BCx:n8"<T$K5v2D$,I,MW$G$9!#$3$N>l9g!"4pK\E*$KM-=~$H$J$j$^$9!#(B
|
|
|
|
|
+ * 6. $BK\%=%U%H%&%'%"$rMxMQ$9$k$3$H$K$h$C$FH/@8$7$?$$$+$J$kB;32$b!"Cx:n8"(B
|
|
|
|
|
+ * $B<T$OIi$o$J$$$b$N$H$7$^$9!#$3$l$K9g0U$G$-$J$$>l9g$O!";HMQ8"$,$J$$$b(B
|
|
|
|
|
+ * $B$N$H$7$^$9!#(B
|
|
|
|
|
+ * 7. $B!H(BEmi Clock$B!I$N>&I8$*$h$SK\%=%U%H%&%'%"$N2hA|$d%G%6%$%s$K4X$9$kCx:n(B
|
|
|
|
|
+ * $B8"$O!"(BMotosoft $B$3$H!HK\(B $B=SLi!I;a$,M-$7$^$9!#(B
|
|
|
|
|
+ * 8. $B!H(BEmi Clock$B!I$N>&I8$*$h$S2hA|$d%G%6%$%s$O!"(BX11$BHG(B Emi Clock $B3+H/$N$?(B
|
|
|
|
|
+ * $B$a!"(BMotosoft $B$h$j!H8E>l(B $B@59T!I$X8D?ME*$K%i%$%;%s%96!M?$5$l$F$^$9!#(B
|
|
|
|
|
+ * $BBh;0<T$XFs<!%i%$%;%s%96!M?$9$k$3$H$OG'$a$i$l$F$*$j$^$;$s!#(B
|
|
|
|
|
+ * 9. Motosoft $B$H8E>l$KL5CG$G!"K\%=%U%H%&%'%"$N2hA|%G!<%?$rFs<!MxMQ$9$k$3(B
|
|
|
|
|
+ * $B$H$r6X;_$7$^$9!#(B
|
|
|
|
|
+ * 10. $B$3$3$K5-=R$7$?0J30$N8"Mx$K$D$$$F$O!"F|K\9q$NCx:n8"K!$K$h$k$b$N$H$7(B
|
|
|
|
|
+ * $B$^$9!#(B
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/* $BDj?t(B */
|
|
|
|
|
+#define HAS_SOUND_CODE /* $B%5%&%s%I4X78$N%3!<%I$OM-8z!*(B */
|
|
|
|
|
+
|
|
|
|
|
+/* RCS ID */
|
2000-12-18 01:03:37 +01:00
|
|
|
|
+rcsId(audioId, "Id: audio.c,v 1.5 1994/05/31 06:28:21 masa-k Rel ")
|
2000-12-18 00:32:09 +01:00
|
|
|
|
+
|
|
|
|
|
+static int S_AuFileHeader();
|
|
|
|
|
+static void S_PlayInterval();
|
|
|
|
|
+
|
|
|
|
|
+static int AudioDevice;
|
|
|
|
|
+static audio_info_t AudioSaveConfig;
|
|
|
|
|
+static int SoundLeft;
|
|
|
|
|
+static int SoundPlayed;
|
|
|
|
|
+static int SoundTimeBytes;
|
|
|
|
|
+static char *SoundBufPtr;
|
|
|
|
|
+static char *SoundTmpBuffer = NULL;
|
|
|
|
|
+static struct timeval SoundStart;
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * $B%5%&%s%I4D6-$N=i4|2=(B
|
|
|
|
|
+ */
|
|
|
|
|
+static void
|
|
|
|
|
+S_SoundEnvInit()
|
|
|
|
|
+{
|
|
|
|
|
+ /* $B2?$b$7$J$$(B */
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * $B%5%&%s%I%G%P%$%9$NB8:_H=Dj(B
|
|
|
|
|
+ */
|
|
|
|
|
+static Boolean
|
|
|
|
|
+S_IsSoundAvailable()
|
|
|
|
|
+{
|
|
|
|
|
+ struct stat st;
|
|
|
|
|
+
|
|
|
|
|
+ /* $B%*!<%G%#%*#I!?#F$N%A%'%C%/(B */
|
|
|
|
|
+ if (stat(AUDIO_DEVICE, &st) < 0)
|
|
|
|
|
+ return False;
|
|
|
|
|
+ if (!S_ISCHR(st.st_mode))
|
|
|
|
|
+ return False;
|
|
|
|
|
+
|
|
|
|
|
+ return True;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * $B%5%&%s%I:F@8(B
|
|
|
|
|
+ */
|
|
|
|
|
+static int
|
|
|
|
|
+S_PlaySound(filename)
|
|
|
|
|
+char *filename;
|
|
|
|
|
+{
|
|
|
|
|
+ SoundCacheBuffer localCache;
|
|
|
|
|
+ int ret;
|
|
|
|
|
+
|
|
|
|
|
+ if ((ret = S_CacheSound(filename, &localCache)) != SOUND_NO_ERROR)
|
|
|
|
|
+ return ret;
|
|
|
|
|
+ SoundTmpBuffer = localCache.soundCacheBuffer;
|
|
|
|
|
+ if ((ret = S_PlayCacheSound(&localCache)) != SOUND_NO_ERROR) {
|
|
|
|
|
+ S_FreeCacheSound(&localCache);
|
|
|
|
|
+ return ret;
|
|
|
|
|
+ }
|
|
|
|
|
+ return SOUND_NO_ERROR;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * $B%5%&%s%I$N%-%c%C%7%e2=2DG=!?IT2DG=H=Dj(B
|
|
|
|
|
+ */
|
|
|
|
|
+static Boolean
|
|
|
|
|
+S_IsSoundCacheAvailable()
|
|
|
|
|
+{
|
|
|
|
|
+ return True;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * $B%5%&%s%I$N%-%c%C%7%e2=(B
|
|
|
|
|
+ */
|
|
|
|
|
+static int
|
|
|
|
|
+S_CacheSound(filename, cacheBufferPtr)
|
|
|
|
|
+char *filename;
|
|
|
|
|
+SoundCacheBuffer *cacheBufferPtr;
|
|
|
|
|
+{
|
|
|
|
|
+ int soundFile;
|
|
|
|
|
+
|
|
|
|
|
+ if ((soundFile = open(filename, O_RDONLY)) < 0)
|
|
|
|
|
+ return SOUND_OPEN_ERROR;
|
|
|
|
|
+ AUDIO_INITINFO(&(cacheBufferPtr->soundBParam));
|
|
|
|
|
+ if ((cacheBufferPtr->soundLength = S_AuFileHeader(soundFile,
|
|
|
|
|
+ &(cacheBufferPtr->soundBParam))) < 0) {
|
|
|
|
|
+ close(soundFile);
|
|
|
|
|
+ return SOUND_FILE_INVALID;
|
|
|
|
|
+ }
|
|
|
|
|
+ cacheBufferPtr->soundCacheBuffer =
|
|
|
|
|
+ (char *)XtMalloc(cacheBufferPtr->soundLength);
|
|
|
|
|
+ read(soundFile, cacheBufferPtr->soundCacheBuffer,
|
|
|
|
|
+ cacheBufferPtr->soundLength);
|
|
|
|
|
+ close(soundFile);
|
|
|
|
|
+ return SOUND_NO_ERROR;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * $B%-%c%C%7%e2=$5$l$?%5%&%s%I$N:F@8(B
|
|
|
|
|
+ */
|
|
|
|
|
+static int
|
|
|
|
|
+S_PlayCacheSound(cacheBufferPtr)
|
|
|
|
|
+SoundCacheBuffer *cacheBufferPtr;
|
|
|
|
|
+{
|
|
|
|
|
+ int tmpfd;
|
|
|
|
|
+ if ((tmpfd = open(AUDIO_DEVICE, O_WRONLY)) < 0) {
|
|
|
|
|
+ if (errno == EBUSY)
|
|
|
|
|
+ return SOUND_DEVICE_BUSY;
|
|
|
|
|
+ return SOUND_DEVICE_ERROR;
|
|
|
|
|
+ }
|
|
|
|
|
+ AudioDevice = tmpfd;
|
|
|
|
|
+ ioctl(AudioDevice, AUDIO_GETINFO, &AudioSaveConfig);
|
|
|
|
|
+ /* $B%*!<%G%#%*%U%!%$%k$K9g$o$;$F%G%P%$%9$r%;%C%H$9$k(B
|
|
|
|
|
+ $B%G%P%$%9L$%5%]!<%H$N7A<0$N%*!<%G%#%*%U%!%$%k$O%(%i!<(B */
|
|
|
|
|
+ if (ioctl(AudioDevice, AUDIO_SETINFO,
|
|
|
|
|
+ &(cacheBufferPtr->soundBParam)) < 0) {
|
|
|
|
|
+ close(AudioDevice);
|
|
|
|
|
+ return SOUND_DEVICE_ERROR;
|
|
|
|
|
+ }
|
|
|
|
|
+ /* $B%*!<%G%#%*%G%P%$%9$r%N%s%V%m%C%-%s%0%b!<%I$K@_Dj(B */
|
|
|
|
|
+ fcntl(AudioDevice, F_SETFL, fcntl(AudioDevice, F_GETFL, 0) | O_NDELAY);
|
|
|
|
|
+ SoundBufPtr = cacheBufferPtr->soundCacheBuffer;
|
|
|
|
|
+ SoundLeft = cacheBufferPtr->soundLength;
|
|
|
|
|
+ SoundPlayed = 0;
|
|
|
|
|
+ SoundTimeBytes = (cacheBufferPtr->soundBParam.play.precision / 8) *
|
|
|
|
|
+ cacheBufferPtr->soundBParam.play.channels *
|
|
|
|
|
+ cacheBufferPtr->soundBParam.play.sample_rate;
|
|
|
|
|
+ signal(SIGALRM, S_PlayInterval);
|
|
|
|
|
+ gettimeofday(&SoundStart, NULL);
|
|
|
|
|
+ S_PlayInterval();
|
|
|
|
|
+ return SOUND_NO_ERROR;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * $B%-%c%C%7%e2=$5$l$?%5%&%s%I$N3+J|(B
|
|
|
|
|
+ */
|
|
|
|
|
+static void
|
|
|
|
|
+S_FreeCacheSound(cacheBufferPtr)
|
|
|
|
|
+SoundCacheBuffer *cacheBufferPtr;
|
|
|
|
|
+{
|
|
|
|
|
+ XtFree(cacheBufferPtr->soundCacheBuffer);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * $B%5%&%s%I4D6-$N8e;OKv(B
|
|
|
|
|
+ */
|
|
|
|
|
+static void
|
|
|
|
|
+S_SoundEnvDispose()
|
|
|
|
|
+{
|
|
|
|
|
+ /* $B2?$b$7$J$$(B */
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * SIGALRM$B$G8F$P$l$k4X?t(B
|
|
|
|
|
+ */
|
|
|
|
|
+static void
|
|
|
|
|
+S_PlayInterval()
|
|
|
|
|
+{
|
|
|
|
|
+ int nbytes, timer;
|
|
|
|
|
+ struct itimerval t;
|
|
|
|
|
+ struct timeval now;
|
|
|
|
|
+
|
|
|
|
|
+ if (SoundLeft > 0) {
|
|
|
|
|
+ if ((nbytes = write(AudioDevice, SoundBufPtr, SoundLeft)) > 0) {
|
|
|
|
|
+ SoundPlayed += nbytes;
|
|
|
|
|
+ SoundLeft -= nbytes;
|
|
|
|
|
+ SoundBufPtr += nbytes;
|
|
|
|
|
+ timer = ((double)SoundPlayed / (double)SoundTimeBytes)
|
|
|
|
|
+ * 1000000;
|
|
|
|
|
+ gettimeofday(&now, NULL);
|
|
|
|
|
+ timer -= (now.tv_sec - SoundStart.tv_sec) * 1000000
|
|
|
|
|
+ + now.tv_usec - SoundStart.tv_usec;
|
|
|
|
|
+ if (timer <= 0)
|
|
|
|
|
+ timer = 1;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ timer = 1;
|
|
|
|
|
+ if (nbytes < 0 && errno != EBUSY)
|
|
|
|
|
+ SoundLeft = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ t.it_interval.tv_sec = 0;
|
|
|
|
|
+ t.it_interval.tv_usec = 0;
|
|
|
|
|
+ t.it_value.tv_sec = timer / 1000000;
|
|
|
|
|
+ t.it_value.tv_usec = timer % 1000000;
|
|
|
|
|
+ setitimer(ITIMER_REAL, &t, NULL);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (close(AudioDevice) == -1)
|
|
|
|
|
+ perror("nazo\n");
|
|
|
|
|
+ if (SoundTmpBuffer != NULL) {
|
|
|
|
|
+ XtFree(SoundTmpBuffer);
|
|
|
|
|
+ SoundTmpBuffer = NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ signal(SIGALRM, SIG_IGN);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#if BYTE_ORDER == LITTLE_ENDIAN
|
|
|
|
|
+# define BSWAP32(x) x = bswap32(x)
|
|
|
|
|
+#endif
|
|
|
|
|
+#if BYTE_ORDER == BIG_ENDIAN
|
|
|
|
|
+# define BSWAP32(x)
|
|
|
|
|
+#endif
|
|
|
|
|
+#if BYTE_ORDER == PDP_ENDIAN
|
|
|
|
|
+# error lose.
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+/*
|
|
|
|
|
+ * .au$B%U%!%$%k$N%X%C%@>pJs$rJV$94X?t(B
|
|
|
|
|
+ * $B%U%!%$%k0LCV$O%G!<%?It$N@hF,$K%;%C%H$5$l$k!#(B
|
|
|
|
|
+ */
|
|
|
|
|
+static int
|
|
|
|
|
+S_AuFileHeader(file, audio)
|
|
|
|
|
+int file;
|
|
|
|
|
+audio_info_t *audio;
|
|
|
|
|
+{
|
|
|
|
|
+ static int formattable[] = {
|
|
|
|
|
+ 0, 0, /* Not defined */
|
|
|
|
|
+ AUDIO_ENCODING_ULAW, 8, /* 8-bit ISDN u-law */
|
|
|
|
|
+ AUDIO_ENCODING_LINEAR, 8, /* 8-bit linear PCM */
|
|
|
|
|
+ AUDIO_ENCODING_LINEAR, 16, /* 16-bit linear PCM */
|
|
|
|
|
+ AUDIO_ENCODING_LINEAR, 24, /* 24-bit linear PCM */
|
|
|
|
|
+ AUDIO_ENCODING_LINEAR, 32 /* 32-bit linear PCM */
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ long magic, pos, size, format, rate, chan;
|
|
|
|
|
+ struct stat st;
|
|
|
|
|
+
|
|
|
|
|
+ read(file, &magic, sizeof(long));
|
|
|
|
|
+ BSWAP32(magic);
|
|
|
|
|
+ if (magic != AUDIOMAGICNUMBER)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ read(file, &pos, sizeof(long));
|
|
|
|
|
+ BSWAP32(pos);
|
|
|
|
|
+ read(file, &size, sizeof(long));
|
|
|
|
|
+ BSWAP32(size);
|
|
|
|
|
+ read(file, &format, sizeof(long));
|
|
|
|
|
+ BSWAP32(format);
|
|
|
|
|
+ read(file, &rate, sizeof(long));
|
|
|
|
|
+ BSWAP32(rate);
|
|
|
|
|
+ read(file, &chan, sizeof(long));
|
|
|
|
|
+ BSWAP32(chan);
|
|
|
|
|
+ if (format < 1 || format > 5)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ format = format * 2;
|
|
|
|
|
+ audio->play.encoding = formattable[format];
|
|
|
|
|
+ audio->play.precision = formattable[format + 1];
|
|
|
|
|
+ audio->play.sample_rate = rate;
|
|
|
|
|
+ audio->play.channels = chan;
|
|
|
|
|
+ lseek(file, pos, SEEK_SET);
|
|
|
|
|
+ fstat(file, &st);
|
|
|
|
|
+ return st.st_size - pos;
|
|
|
|
|
+}
|