SoundStream.st
changeset 1583 a45ac92afbc8
parent 1556 8a78c9a5a8f7
child 1839 c10cd58ec334
--- a/SoundStream.st	Thu Dec 22 17:14:07 2005 +0100
+++ b/SoundStream.st	Thu Dec 22 17:55:51 2005 +0100
@@ -13,7 +13,7 @@
 "{ Package: 'stx:libbasic2' }"
 
 FileStream subclass:#SoundStream
-	instanceVariableNames:'sampleRate numberOfChannels bitsPerSample audioFormat alPort
+	instanceVariableNames:'sampleRate numberOfChannels bitsPerSample audioFormat
 		handle1 handle2 bufferOffset bufferSize'
 	classVariableNames:'UnsupportedOperationSignal'
 	poolDictionaries:''
@@ -23,68 +23,92 @@
 !SoundStream primitiveDefinitions!
 %{
 
+#ifdef WIN32
+# define xxxUSE_WIN32_DIRECTSOUND
+#endif
 
 #ifdef IRIS
 # ifndef IRIX5
-#  define IRIS_AUDIO
+#  define USE_IRIS_AUDIO
+# endif
+#endif
+
+#ifndef USE_IRIS_AUDIO
+# ifndef USE_ALSA_AUDIO
+#  ifdef LINUX
+#   define USE_DEV_AUDIO
+#  endif
+# endif
+#endif
+
+#ifdef USE_IRIS_AUDIO
+# define IRIS_AUDIO
+# include <audio.h>
+# define __ALportVal(o)  (ALport)(__externalAddressVal(o))
+# define alPort handle1
+#endif
+
+#ifdef USE_ALSA_AUDIO
+# ifdef LINUX
+#  define ALSA_AUDIO
+#  include <alsa/asoundlib.h>
+#  define MAX_NR_OF_CHANNELS 8
+#  define DEBUG_SOUND
+#  define readHandle handle1
+#  define writeHandle handle2
 # endif
 #endif
 
-#ifdef IRIS_AUDIO
-# include <audio.h>
-# define __ALportVal(o)  (ALport)(__externalAddressVal(o))
-#endif
+#ifdef USE_DEV_AUDIO
+# ifdef LINUX
+#  include <stdio.h>
+#  include <sys/soundcard.h>
+#  define DEV_AUDIO_DEFAULT_FREQ (8000)
+#  define DEV_AUDIO_DEFAULT_BUFFERSIZE (16384)
+#  define DEV_AUDIO
+# endif
 
-#ifdef LINUX
-# include <stdio.h>
-# include <sys/soundcard.h>
-# define DEV_AUDIO_DEFAULT_FREQ (8000)
-# define DEV_AUDIO_DEFAULT_BUFFERSIZE (16384)
-# define DEV_AUDIO
-#endif
-
-#ifdef FREEBSD
-# include <stdio.h>
-# include <sys/time.h>
-# include <sys/ioctl.h>
-# include <machine/pcaudioio.h>
-# define DEV_AUDIO_DEFAULT_FREQ (8000)
-# define DEV_AUDIO_DEFAULT_BUFFERSIZE (16384)
-# define DEV_AUDIO
-#endif
+# ifdef FREEBSD
+#  include <stdio.h>
+#  include <sys/time.h>
+#  include <sys/ioctl.h>
+#  include <machine/pcaudioio.h>
+#  define DEV_AUDIO_DEFAULT_FREQ (8000)
+#  define DEV_AUDIO_DEFAULT_BUFFERSIZE (16384)
+#  define DEV_AUDIO
+# endif
 
-#if defined(sunos) || defined(solaris)
-# include <stdio.h>
-# ifdef solaris
-#  include <sys/audioio.h>
-# else
-#  include <sun/audioio.h>
+# if defined(sunos) || defined(solaris)
+#  include <stdio.h>
+#  ifdef solaris
+#   include <sys/audioio.h>
+#  else
+#   include <sun/audioio.h>
+#  endif
+#  define DEV_AUDIO_DEFAULT_FREQ (8000)
+#  define DEV_AUDIO_DEFAULT_BUFFERSIZE (16384)
+#  define DEV_AUDIO
 # endif
-# define DEV_AUDIO_DEFAULT_FREQ (8000)
-# define DEV_AUDIO_DEFAULT_BUFFERSIZE (16384)
-# define DEV_AUDIO
-#endif
 
-#if defined(hpux)
-# include <stdio.h>
-# include <sys/ioctl.h>
-# include <sys/inode.h>
-# include <sys/audio.h>
-# include <sys/time.h>
-# include <unistd.h>
-# define DEV_AUDIO_DEFAULT_FREQ (22050)
-# define DEV_AUDIO_DEFAULT_BUFFERSIZE (16384)
-# define DEV_AUDIO
-#endif
+# if defined(hpux)
+#  include <stdio.h>
+#  include <sys/ioctl.h>
+#  include <sys/inode.h>
+#  include <sys/audio.h>
+#  include <sys/time.h>
+#  include <unistd.h>
+#  define DEV_AUDIO_DEFAULT_FREQ (22050)
+#  define DEV_AUDIO_DEFAULT_BUFFERSIZE (16384)
+#  define DEV_AUDIO
+# endif
+#endif /* USE_DEV_AUDIO */
 
 #ifndef WIN32
 # ifndef O_WRONLY
 #  include <sys/fcntl.h>
 # endif
 
-# ifndef EINTR
-#  include <errno.h>
-# endif
+# include <errno.h>
 #endif
 
 #ifdef WIN32
@@ -112,7 +136,8 @@
 # include <stdio.h> /* */
 # include <windows.h>
 
-# ifdef USE_DIRECTSOUND
+# ifdef USE_WIN32_DIRECTSOUND
+#  define WIN32_DIRECTSOUND
 #  define CINTERFACE
 #  include "dsound.h"
 #  define __DirectSoundVal(o) (LPDIRECTSOUND)(__externalAddressVal(o))
@@ -126,6 +151,7 @@
 
 # else /* USE WAVE... */
 
+#  define WIN32_WAVE
 #  define __WaveHandleVal(o)    (HWAVEOUT)(__externalAddressVal(o))
 #  define MAXBUF      10        /* Maximum number of buffers */
 #  define DATALEN     2048      /* Size of wave data buffer */
@@ -193,13 +219,18 @@
 
 #endif /* WIN32 */
 
+#ifdef DEBUG_SOUND
+# define DPRINTF(x) printf x
+#else
+# define DPRINTF(x) /* as nothing */
+#endif
+
 %}
 ! !
 
 !SoundStream primitiveFunctions!
 %{
-#ifdef WIN32
-# ifndef USE_DIRECTSOUND
+#ifdef WIN32_WAVE
 
 static void CALLBACK
 waveCallBack(HWAVE waveHandle, UINT msg, DWORD inst, DWORD p1, DWORD p2)
@@ -215,8 +246,7 @@
     }
 }
 
-# endif
-#endif
+#endif /* WIN32_WAVE */
 
 %}
 ! !
@@ -856,58 +886,55 @@
 
     if (0) {
     }
+    else if (__INST(audioFormat) == @symbol(MU_LAW)) {
 #  ifdef AFMT_MU_LAW
-    else if (__INST(audioFormat) == @symbol(MU_LAW)) {
 	__format = AFMT_MU_LAW;
+#  endif
     }
-#  endif
+    else if (__INST(audioFormat) == @symbol(A_LAW)) {
 #  ifdef AFMT_A_LAW
-    else if (__INST(audioFormat) == @symbol(A_LAW)) {
 	__format = AFMT_A_LAW;
+#  endif
     }
-#  endif
+    else if (__INST(audioFormat) == @symbol(IMA_ADPCM)) {
 #  ifdef AFMT_IMA_ADPCM
-    else if (__INST(audioFormat) == @symbol(IMA_ADPCM)) {
 	__format = AFMT_IMA_ADPCM;
+#  endif
     }
-#  endif
+    else if (__INST(audioFormat) == @symbol(U8)) {
 #  ifdef AFMT_U8
-    else if (__INST(audioFormat) == @symbol(U8)) {
 	__format = AFMT_U8;
+#  endif
     }
-#  endif
+    else if (__INST(audioFormat) == @symbol(S16_LE)) {
 #  ifdef AFMT_S16_LE
-    else if (__INST(audioFormat) == @symbol(S16_LE)) {
 	__format = AFMT_S16_LE;
+#  endif
     }
-#  endif
+    else if (__INST(audioFormat) == @symbol(S16_BE)) {
 #  ifdef AFMT_S16_BE
-    else if (__INST(audioFormat) == @symbol(S16_BE)) {
 	__format = AFMT_S16_BE;
+#  endif
     }
-#  endif
-#  ifdef AFMT_S8
     else if (__INST(audioFormat) == @symbol(S8)) {
+#  ifdef AFMT_S8
 	__format = AFMT_S8;
-    }
 #  endif
-#  ifdef AFMT_U16_LE
-    else if (__INST(audioFormat) == @symbol(U16_LE)) {
-	__format = AFMT_U16_LE;
     }
+    else if (__INST(audioFormat) == @symbol(U16_LE)) {
+#  ifdef AFMT_U16_LE
+	__format = AFMT_U16_LE;
 #  endif
-#  ifdef AFMT_U16_BE
+    }
     else if (__INST(audioFormat) == @symbol(U16_BE)) {
+#  ifdef AFMT_U16_BE
 	__format = AFMT_U16_BE;
+#  endif
     }
-#  endif
+    else if (__INST(audioFormat) == @symbol(MPEG)) {
 #  ifdef AFMT_MPEG
-    else if (__INST(audioFormat) == @symbol(MPEG)) {
 	__format = AFMT_MPEG;
-    }
 #  endif
-    else {
-	__format = -1;
     }
 
 #if defined(DEV_AUDIO)
@@ -1070,7 +1097,7 @@
 	}
 # endif
     }
-#endif
+#endif /* DEV_AUDIO */
 %}.
     ^ UnsupportedOperationSignal raise
 
@@ -1547,11 +1574,9 @@
 	ALcloseport(__ALportVal(port));
     }
     RETURN (self);
-#endif
+#endif /* IRIS_AUDIO */
 
-#ifdef WIN32
-# ifdef USE_DIRECTSOUND
-
+#ifdef WIN32_DIRECTSOUND
     OBJ oDirectSound, oDSBuffer;
     LPDIRECTSOUND       t_pDirectSound;
     LPDIRECTSOUNDBUFFER t_pDSBuffer;
@@ -1571,7 +1596,10 @@
 	    IDirectSound_Release(t_pDirectSound);
 	}
     }
-# else
+    RETURN (self);
+#endif /* WIN32_DIRECTSOUND */
+
+#ifdef WIN32_WAVE
     struct buf *bp, *next;
     int r;
     HWAVEOUT t_waveHandle;
@@ -1580,20 +1608,20 @@
     if ((oWaveHandle = __INST(waveHandle)) != nil) {
 	t_waveHandle = __WaveHandleVal(oWaveHandle);
 
-#  ifdef NO_WAIT_IN_CLOSE
+# ifdef NO_WAIT_IN_CLOSE
 	/* Force cancellation of any pending buffers */
 	(void)waveOutReset(t_waveHandle);
-#  endif
+# endif
 
 	/* Wait until all pending buffers have been freed */
 	while (free_buffers < total_buffers) {
 	    WaitForSingleObject(free_buffer_event, INFINITE);
 	}
 
-#  ifndef NO_WAIT_IN_CLOSE
+# ifndef NO_WAIT_IN_CLOSE
 	/* Force cancellation of any pending buffers */
 	(void)waveOutReset(t_waveHandle);
-#  endif
+# endif
 
 	/* Close the device */
 	if ((r = waveOutClose(t_waveHandle)) != 0) {
@@ -1614,9 +1642,8 @@
 
 	__INST(waveHandle) = nil;
     }
-# endif
     RETURN (self);
-#endif
+# endif /* WIN32_WAVE */
 
 #if defined(DEV_AUDIO)
     OBJ fp;
@@ -1667,22 +1694,22 @@
 	}
     }
     RETURN(self);
-#endif
+#endif /* IRIS_AUDIO */
 
 #if defined(DEV_AUDIO)
     if (__isSmallInteger(fd)) {
 	int f = __intVal(fd);
 	/* ... */
     }
-#endif
+#endif /* DEV_AUDIO */
 %}.
     "dont know how to wait on non-iris systems"
     ^ self
 !
 
 isOpen
-    alPort notNil ifTrue:[^ true].
     handle1 notNil ifTrue:[^ true].
+    handle2 notNil ifTrue:[^ true].
     ^ filePointer notNil
 !
 
@@ -1720,10 +1747,9 @@
 	}
     }
   }
-#endif
+#endif /* IRIS_AUDIO */
 
 #if defined(DEV_AUDIO)
-#include <errno.h>
    /*
     * redefine to work around a bug in the linux sound driver;
     * if a write is interrupted (EINTR), it is not defined, how many
@@ -1782,7 +1808,7 @@
 	    }
 	}
     }
-#endif
+#endif /* DEV_AUDIO */
 
 %}.
     OperatingSystem getOSType = 'irix' ifFalse:[
@@ -1834,94 +1860,95 @@
 	}
     }
   }
-#endif /* SGI_AUDIO */
+#endif /* IRIS_AUDIO */
 
-#ifdef WIN32
-# ifdef USE_DIRECTSOUND
+#ifdef WIN32_DIRECTSOUND
   {
-      HRESULT hr;
-      DWORD status;
-      LPVOID lpbuf1 = NULL;
-      LPVOID lpbuf2 = NULL;
-      DWORD dwsize1 = 0;
-      DWORD dwsize2 = 0;
-      DWORD playPos, safePos, endWrite;
-      DWORD millis;
-      OBJ oDirectSound, oDSBuffer;
-      LPDIRECTSOUND       t_pDirectSound = (LPDIRECTSOUND)0;
-      LPDIRECTSOUNDBUFFER t_pDSBuffer = (LPDIRECTSOUNDBUFFER)0;
-      int t_cbBufOffset, t_cbBufSize;
-      short *buf;
-      int cnt, offs;
+    HRESULT hr;
+    DWORD status;
+    LPVOID lpbuf1 = NULL;
+    LPVOID lpbuf2 = NULL;
+    DWORD dwsize1 = 0;
+    DWORD dwsize2 = 0;
+    DWORD playPos, safePos, endWrite;
+    DWORD millis;
+    OBJ oDirectSound, oDSBuffer;
+    LPDIRECTSOUND       t_pDirectSound = (LPDIRECTSOUND)0;
+    LPDIRECTSOUNDBUFFER t_pDSBuffer = (LPDIRECTSOUNDBUFFER)0;
+    int t_cbBufOffset, t_cbBufSize;
+    short *buf;
+    int cnt, offs;
 
-      if ((oDSBuffer = __INST(pDSBuffer)) != nil) {
-	  t_pDSBuffer = __DSBufferVal(oDSBuffer);
-      }
-      if ((oDirectSound = __INST(pDirectSound)) != nil) {
-	  t_pDirectSound = __DirectSoundVal(oDirectSound);
-      }
+    if ((oDSBuffer = __INST(pDSBuffer)) != nil) {
+	t_pDSBuffer = __DSBufferVal(oDSBuffer);
+    }
+    if ((oDirectSound = __INST(pDirectSound)) != nil) {
+	t_pDirectSound = __DirectSoundVal(oDirectSound);
+    }
 
-      if (!t_pDSBuffer || !t_pDirectSound) {
-	  fprintf(stderr, "SoundStream not open!\n");
-	  RETURN (0);
-      }
-      t_cbBufOffset = __intVal(__INST(bufferOffset));
-      t_cbBufSize = __intVal(__INST(bufferSize));
+    if (!t_pDSBuffer || !t_pDirectSound) {
+	fprintf(stderr, "SoundStream not open!\n");
+	RETURN (0);
+    }
+    t_cbBufOffset = __intVal(__INST(bufferOffset));
+    t_cbBufSize = __intVal(__INST(bufferSize));
 
-      cnt = __intVal(count);
-      offs = __intVal(start) - 1;
-      buf = (short *)__InstPtr(anObject) + OHDR_SIZE + offs;
+    cnt = __intVal(count);
+    offs = __intVal(start) - 1;
+    buf = (short *)__InstPtr(anObject) + OHDR_SIZE + offs;
+
+    // Should be playing, right?
+    hr = IDirectSoundBuffer_GetStatus(t_pDSBuffer, &status );
+    if (!(status && DSBSTATUS_PLAYING)) {
+	fprintf(stderr, "Buffer not playing!\n");
+	RETURN (0);
+    }
 
-      // Should be playing, right?
-      hr = IDirectSoundBuffer_GetStatus(t_pDSBuffer, &status );
-      if (!(status && DSBSTATUS_PLAYING)) {
-	  fprintf(stderr, "Buffer not playing!\n");
-	  RETURN (0);
-      }
+    // Sleep until we have enough room in buffer.
+    hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
+    if( hr != DS_OK ) {
+	fprintf(stderr, "Cannot get position!\n");
+	RETURN (0);
+    }
+    if( playPos < t_cbBufOffset ) playPos += t_cbBufSize;
 
-      // Sleep until we have enough room in buffer.
-      hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
-      if( hr != DS_OK ) {
-	  fprintf(stderr, "Cannot get position!\n");
-	  RETURN (0);
-      }
-      if( playPos < t_cbBufOffset ) playPos += t_cbBufSize;
+    endWrite = t_cbBufOffset + (cnt * sizeof(short));
+    while ( playPos < endWrite ) {
+	// Calculate number of milliseconds until we will have room, as
+	// time = distance * (milliseconds/second) / ((bytes/sample) * (samples/second)),
+	// rounded up.
+	millis = (DWORD) (1.0 + ((endWrite - playPos) * 1000.0) / ( sizeof(short) * __intVal(__INST(sampleRate))));
 
-      endWrite = t_cbBufOffset + (cnt * sizeof(short));
-      while ( playPos < endWrite ) {
-	  // Calculate number of milliseconds until we will have room, as
-	  // time = distance * (milliseconds/second) / ((bytes/sample) * (samples/second)),
-	  // rounded up.
-	  millis = (DWORD) (1.0 + ((endWrite - playPos) * 1000.0) / ( sizeof(short) * __intVal(__INST(sampleRate))));
-
-	  // Sleep for that long
-	  Sleep( millis );
+	// Sleep for that long
+	Sleep( millis );
 
-	  // Wake up, find out where we are now
-	  hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
-	  if( hr != DS_OK ) {
-	      fprintf(stderr, "Cannot get position!\n");
-	      RETURN (0);
-	  }
-	  if( playPos < t_cbBufOffset ) playPos += t_cbBufSize; // unwrap offset
-      }
+	// Wake up, find out where we are now
+	hr = IDirectSoundBuffer_GetCurrentPosition(t_pDSBuffer, &playPos, &safePos );
+	if( hr != DS_OK ) {
+	    fprintf(stderr, "Cannot get position!\n");
+	    RETURN (0);
+	}
+	if( playPos < t_cbBufOffset ) playPos += t_cbBufSize; // unwrap offset
+    }
 
-      // Lock free space in the DS
-      hr = IDirectSoundBuffer_Lock(t_pDSBuffer, t_cbBufOffset, cnt * sizeof(short), &lpbuf1, &dwsize1, &lpbuf2, &dwsize2, 0);
-      if (hr == DS_OK) {
-	  // Copy the buffer into the DS
-	  CopyMemory(lpbuf1, buf, dwsize1);
-	  if(NULL != lpbuf2) CopyMemory(lpbuf2, buf+dwsize1, dwsize2);
+    // Lock free space in the DS
+    hr = IDirectSoundBuffer_Lock(t_pDSBuffer, t_cbBufOffset, cnt * sizeof(short), &lpbuf1, &dwsize1, &lpbuf2, &dwsize2, 0);
+    if (hr == DS_OK) {
+	// Copy the buffer into the DS
+	CopyMemory(lpbuf1, buf, dwsize1);
+	if(NULL != lpbuf2) CopyMemory(lpbuf2, buf+dwsize1, dwsize2);
 
-	  // Update our buffer offset and unlock sound buffer
-	  t_cbBufOffset = (t_cbBufOffset + dwsize1 + dwsize2) % t_cbBufSize;
-	  IDirectSoundBuffer_Unlock(t_pDSBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
-      }
-      __INST(buffferOffset) = __MKSMALLINT(t_cbBufOffset);
+	// Update our buffer offset and unlock sound buffer
+	t_cbBufOffset = (t_cbBufOffset + dwsize1 + dwsize2) % t_cbBufSize;
+	IDirectSoundBuffer_Unlock(t_pDSBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
+    }
+    __INST(buffferOffset) = __MKSMALLINT(t_cbBufOffset);
 
-      RETURN (count);
+    RETURN (count);
   }
-# else
+#endif /* WIN32_DIRECTSOUND */
+
+#ifdef WIN32_WAVE
   {
     struct buf *bp;
     int len, i, r;
@@ -1988,11 +2015,9 @@
     }
     RETURN (count);
   }
-# endif
-#endif /* WIN32 */
+#endif /* WIN32_WAVE */
 
 #if defined(DEV_AUDIO)
-#include <errno.h>
    /*
     * redefine to work around a bug in the linux sound driver;
     * if a write is interrupted (EINTR), it is not defined, how many
@@ -2052,7 +2077,7 @@
 	    }
 	}
     }
-#endif
+#endif /* DEV_AUDIO */
 
 %}.
     ^ super nextPutBytes:count from:anObject startingAt:start
@@ -2134,8 +2159,7 @@
   }
 #endif /* IRIS_AUDIO */
 
-#ifdef WIN32
-# ifdef USE_DIRECTSOUND
+#ifdef WIN32_DIRECTSOUND
   {
     HRESULT result;
     LPDIRECTSOUND       t_pDirectSound;
@@ -2252,7 +2276,9 @@
     ok = true;
     goto out;
   }
-# else /* !USE_DIRECTSOUND */
+#endif /* WIN32_DIRECTSOUND */
+
+#ifdef WIN32_WAVE
   {
     PCMWAVEFORMAT waveFormat;
     int r;
@@ -2297,7 +2323,7 @@
 	t = __MKEXTERNALADDRESS(t_waveHandle); __INST(waveHandle) = t; __STORE(self, t);
     }
 
-#if 0
+# if 0
     /*
      * HACK: If we immediately start writing valid audio data to the device
      * then the sound is choppy in the beginning. Writing a null packet to
@@ -2312,67 +2338,66 @@
 	}
 	audioWrite(null, DATALEN);
     }
-#endif /* 0 */
+# endif /* 0 */
     ok = true;
     goto out;
   }
-# endif /* !USE_DIRECTSOUND */
-#endif /* WIN32 */
+#endif /* !WIN32_DIRECTSOUND */
 
 #ifdef DEV_AUDIO
-	{
-	    int __fd;
-	    int __mode;
-	    FILE *f;
+  {
+      int __fd;
+      int __mode;
+      FILE *f;
 
-	    if (strcmp(__stringVal(aMode), "w") == 0) {
-		__mode = O_WRONLY;
-	    } else if (strcmp(__stringVal(aMode), "r") == 0) {
-		__mode = O_RDONLY;
-	    } else {
-		__mode = O_RDWR;
-	    }
-	    do {
-		__BEGIN_INTERRUPTABLE__
-		__fd = open((char *) __stringVal(__INST(pathName)), __mode /* |O_NDELAY */);
-		__END_INTERRUPTABLE__
-	    } while ((__fd < 0) && (__threadErrno == EINTR));
+      if (strcmp(__stringVal(aMode), "w") == 0) {
+	  __mode = O_WRONLY;
+      } else if (strcmp(__stringVal(aMode), "r") == 0) {
+	  __mode = O_RDONLY;
+      } else {
+	  __mode = O_RDWR;
+      }
+      do {
+	  __BEGIN_INTERRUPTABLE__
+	  __fd = open((char *) __stringVal(__INST(pathName)), __mode /* |O_NDELAY */);
+	  __END_INTERRUPTABLE__
+      } while ((__fd < 0) && (__threadErrno == EINTR));
 
-	    if (__fd >= 0) {
-		/*
-		 * make it a FILE *
-		 */
-		f = fdopen(__fd, __stringVal(aMode));
-		if (! f) {
-		    __BEGIN_INTERRUPTABLE__
-		    close(__fd);
-		    __END_INTERRUPTABLE__
-		    ok = false;
-		    goto out;
-		}
-		setbuf(f, NULL);
-		__INST(buffered) = false;
-		__INST(filePointer) = __MKOBJ(f);
-		__STORESELF(filePointer);
+      if (__fd >= 0) {
+	  /*
+	   * make it a FILE *
+	   */
+	  f = fdopen(__fd, __stringVal(aMode));
+	  if (! f) {
+	      __BEGIN_INTERRUPTABLE__
+	      close(__fd);
+	      __END_INTERRUPTABLE__
+	      ok = false;
+	      goto out;
+	  }
+	  setbuf(f, NULL);
+	  __INST(buffered) = false;
+	  __INST(filePointer) = __MKOBJ(f);
+	  __STORESELF(filePointer);
 
 #if defined(PCM_ENABLE_OUTPUT) && defined(PCM_ENABLE_INPUT)
 # if defined(SNDCTL_DSP_SETTRIGGER)
-		if (__mode == O_RDWR) {
-		    int enable_bits = ~(PCM_ENABLE_OUTPUT|PCM_ENABLE_INPUT);
+	  if (__mode == O_RDWR) {
+	      int enable_bits = ~(PCM_ENABLE_OUTPUT|PCM_ENABLE_INPUT);
 
-		    if (ioctl(__fd, SNDCTL_DSP_SETTRIGGER, &enable_bits) == -1)
-		    {
-			fprintf(stderr, "can't request synchronous start of fullduplex operation");
-		    }
-		}
+	      if (ioctl(__fd, SNDCTL_DSP_SETTRIGGER, &enable_bits) == -1)
+	      {
+		  fprintf(stderr, "can't request synchronous start of fullduplex operation");
+	      }
+	  }
 # endif
 #endif
-		ok = true;
-		goto out;
-	    }
-	}
+	  ok = true;
+	  goto out;
+      }
+  }
+#endif /* DEV_AUDIO */
 
-#endif /* DEV_AUDIO */
 out:;
 %}.
     ok == false ifTrue:[
@@ -2662,7 +2687,7 @@
 !SoundStream class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/SoundStream.st,v 1.67 2005-05-31 18:49:10 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/SoundStream.st,v 1.68 2005-12-22 16:55:51 cg Exp $'
 ! !
 
 SoundStream initialize!