? COPYING
? darwin.patch
? esound-0.2.23-4.patch
? INSTALL
? install-sh
? missing
? mkinstalldirs
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/esound/Makefile.am,v
retrieving revision 1.56
diff -u -r1.56 Makefile.am
--- Makefile.am	13 May 2002 09:31:03 -0000	1.56
+++ Makefile.am	19 Jun 2002 17:29:04 -0000
@@ -73,6 +73,7 @@
 
 esd_SOURCES = 	\
 	esd.c 		\
+	esd_audio.c	\
 	clients.c	\
 	filter.c	\
 	mix.c		\
@@ -111,7 +112,7 @@
 
 LDADD = libesd.la $(AUDIOFILE_LIBS)
 
-esd_LDADD = $(WRAP_LIB) $(LDADD)
+esd_LDADD = $(WRAP_LIB) $(SOUND_LIBS) $(LDADD)
 
 m4datadir = $(datadir)/aclocal
 m4data_DATA = esd.m4
Index: acconfig.h
===================================================================
RCS file: /cvs/gnome/esound/acconfig.h,v
retrieving revision 1.18
diff -u -r1.18 acconfig.h
--- acconfig.h	23 Apr 2002 10:06:38 -0000	1.18
+++ acconfig.h	19 Jun 2002 17:29:04 -0000
@@ -9,6 +9,7 @@
 #undef DRIVER_NEWALSA
 #undef DRIVER_ALSA_09
 #undef DRIVER_DART
+#undef DRIVER_COREAUDIO
 #undef DRIVER_NONE
 #undef HAVE_INET_ATON
 #undef HAVE_NANOSLEEP
Index: audio.c
===================================================================
RCS file: /cvs/gnome/esound/audio.c,v
retrieving revision 1.17
diff -u -r1.17 audio.c
--- audio.c	23 Apr 2002 10:06:38 -0000	1.17
+++ audio.c	19 Jun 2002 17:29:05 -0000
@@ -20,6 +20,8 @@
 /*******************************************************************/
 /* returns audio_fd for use by main prog - platform dependent */
 
+#if defined(INSIDE_ESD)
+
 /* ALSA before OSS as ALSA is OSS compatible */
 #if defined(DRIVER_ALSA) || defined(DRIVER_NEWALSA) 
 #  include "audio_alsa.c"
@@ -41,9 +43,16 @@
 #  include "audio_mklinux.c"
 #elif defined(DRIVER_DART)
 #  include "audio_dart.c"
+#elif defined(DRIVER_COREAUDIO)
+#  include "audio_coreaudio.c"
 #else
 #  include "audio_none.c"
 #endif
+
+#else
+#define DRIVER_NONE 1
+#include "audio_none.c"
+#endif /* INSIDE_ESD */
 
 /*******************************************************************/
 /* display available devices */
Index: audio_coreaudio.c
===================================================================
RCS file: audio_coreaudio.c
diff -N audio_coreaudio.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ audio_coreaudio.c	19 Jun 2002 17:29:05 -0000
@@ -0,0 +1,451 @@
+
+/*
+ * for CoreAudio
+ *
+ * If the playback/recording sound device is not stereo and its sample
+ * size is not float (32 bit), this will not work.
+ *
+ * Please let me know if there is such a case.
+ *
+ * Shawn Hsiao <phsiao@mac.com>
+ * Some enhancement by Masanori Sekino <m-sekino@mb.kcom.ne.jp>
+ */
+
+#include <CoreAudio/CoreAudio.h>
+#include <machine/limits.h>
+#include <pthread.h>
+
+#define BUF_SIZE ESD_BUF_SIZE
+
+static AudioDeviceID gOutputDeviceID, gInputDeviceID;
+
+static float OutputDataBuf[BUF_SIZE];
+static float InputDataBuf[BUF_SIZE];
+static int OutputWroteSamples = 0;
+static int InputReadSamples = 0;
+
+static pthread_mutex_t mutexOutput, mutexInput;
+static pthread_cond_t condOutput, condInput;
+
+static int audioPlaybackStarted = 0, audioRecordStarted = 0;
+static int coreaudio_has_output_device = 0;
+static int coreaudio_has_input_device = 0;
+static int coreaudio_init = 0;
+
+OSStatus PlaybackIOProc(AudioDeviceID inDevice,
+			const AudioTimeStamp *inNow,
+			const AudioBufferList *inInputData,
+			const AudioTimeStamp *inInputTime,
+			AudioBufferList *outOutputData,
+			const AudioTimeStamp *inOutputTime,
+			void *inClientData)
+{
+  float *bufPtr = outOutputData->mBuffers[0].mData;
+  int i;
+
+  pthread_mutex_lock(&mutexOutput);
+
+  for (i = 0; i < OutputWroteSamples; i++)
+    bufPtr[i] = OutputDataBuf[i];
+  for ( ; i < BUF_SIZE; i++)
+    bufPtr[i] = 0;
+  OutputWroteSamples = 0;
+
+  pthread_mutex_unlock(&mutexOutput);
+  pthread_cond_signal(&condOutput);
+
+  return (kAudioHardwareNoError);
+}
+
+OSStatus RecordIOProc(AudioDeviceID inDevice,
+		      const AudioTimeStamp *inNow,
+		      const AudioBufferList *inInputData,
+		      const AudioTimeStamp *inInputTime,
+		      AudioBufferList *outOutputData,
+		      const AudioTimeStamp *inOutputTime,
+		      void *inClientData)
+{
+  float *bufPtr = inInputData->mBuffers[0].mData;
+  int i;
+
+  pthread_mutex_lock(&mutexInput);
+
+  for (i = 0; i < BUF_SIZE; i++)
+    InputDataBuf[i] = bufPtr[i];
+  InputReadSamples = 0;
+
+  pthread_mutex_unlock(&mutexInput);
+  pthread_cond_signal(&condInput);
+
+  return (kAudioHardwareNoError);
+}
+
+#define ARCH_esd_audio_devices
+const char *esd_audio_devices()
+{
+    return "coreaudio API only";
+}
+
+/*
+ * This is called to reset the device status.
+ * Returns -2 to indicate the device failed to initialize;
+ * returns  -1 means any of rate/size/{mono,stereo} mismatched.
+ */
+#define ARCH_esd_audio_open
+int esd_audio_open()
+{
+#define LEN_DEVICE_NAME 64
+  OSStatus status;
+  UInt32 propertySize, bufferByteCount;
+  char deviceName[LEN_DEVICE_NAME];
+  struct AudioStreamBasicDescription streamDesc;
+  int rval;
+
+  /*
+   * We only need to do this once, the rest are taken cared by
+   * disable/enable calback.
+   */
+  if (coreaudio_init) {
+    return (0);
+  }
+
+  /********************** playback section ***************************/
+  /* get default output device */
+  propertySize = sizeof(gOutputDeviceID);
+  status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
+	                            &propertySize,
+				    &gOutputDeviceID);
+  if (status) {
+    fprintf(stderr, "get default output device failed, status = %d\n",
+	    (int)status);
+    return (-2);
+  }
+
+  if (gOutputDeviceID != kAudioDeviceUnknown) {
+    /* got default output device */
+    coreaudio_has_output_device = 1;
+
+    /* get output device name */
+    propertySize = sizeof(char)*LEN_DEVICE_NAME;
+    status = AudioDeviceGetProperty(gOutputDeviceID,
+				    1,
+				    0,
+				    kAudioDevicePropertyDeviceName,
+				    &propertySize,
+				    deviceName);
+    if (status) {
+      fprintf(stderr, "get device name failed, status = %d\n",
+	      (int)status);
+      return (-2);
+    }
+
+    /* get output format */
+    propertySize = sizeof(struct AudioStreamBasicDescription);
+    status = AudioDeviceGetProperty(gOutputDeviceID,
+				    1,
+				    0,
+				    kAudioDevicePropertyStreamFormat,
+				    &propertySize,
+				    &streamDesc);
+    if (status) {
+      fprintf(stderr, "get device property failed, status = %d\n",
+	      (int)status);
+      return (-2);
+    }
+
+    if ((streamDesc.mSampleRate != 44100.0) ||
+        (streamDesc.mFormatID != kAudioFormatLinearPCM) ||
+       !(streamDesc.mFormatFlags & kLinearPCMFormatFlagIsFloat) ||
+        (streamDesc.mChannelsPerFrame != 2))
+    {
+      fprintf (stderr, "unsupported device.\n");
+      return (-2);
+    }
+
+    /* set buffer size */
+    bufferByteCount = BUF_SIZE * sizeof(float);
+    propertySize = sizeof(bufferByteCount);
+    status = AudioDeviceSetProperty(gOutputDeviceID,
+                                    0,
+                                    0,
+                                    0,
+                                    kAudioDevicePropertyBufferSize,
+                                    propertySize,
+                                    &bufferByteCount);
+    if (status) {
+      fprintf(stderr, "set device property failed, status = %d\n",
+              (int)status);
+    }
+
+    fprintf(stderr, "using device %s for output:\n", deviceName);
+    fprintf(stderr, "\twith sample rate %f, %ld channels and %ld-bit sample\n",
+	    streamDesc.mSampleRate,
+	    streamDesc.mChannelsPerFrame,
+	    streamDesc.mBitsPerChannel);
+
+    rval = pthread_mutex_init(&mutexOutput, NULL);
+    if (rval) {
+      fprintf(stderr, "mutex init failed\n");
+      return (-1);
+    }
+    rval = pthread_cond_init(&condOutput, NULL);
+    if (rval) {
+      fprintf(stderr, "condition init failed\n");
+      return (-1);
+    }
+
+    /* Registers PlaybackIOProc with the device without activating it. */
+    status = AudioDeviceAddIOProc(gOutputDeviceID, PlaybackIOProc, (void *)1);
+  }
+
+  /********************** record section ***************************/
+  /* get default input device */
+  propertySize = sizeof(gInputDeviceID);
+  status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
+	                            &propertySize,
+				    &gInputDeviceID);
+  if (status) {
+    fprintf(stderr, "get default input device failed, status = %d\n",
+	    (int)status);
+    return (-2);
+  }
+
+  if (gInputDeviceID != kAudioDeviceUnknown) {
+    /* got default input device */
+    coreaudio_has_input_device = 1;
+
+    /* get input device name */
+    propertySize = sizeof(char)*64;
+    status = AudioDeviceGetProperty(gInputDeviceID,
+				    1,
+				    1,
+				    kAudioDevicePropertyDeviceName,
+				    &propertySize,
+				    deviceName);
+    if (status) {
+      fprintf(stderr, "get device name failed, status = %d\n",
+	      (int)status);
+      return (-2);
+    }
+
+    /* get input format */
+    propertySize = sizeof(struct AudioStreamBasicDescription);
+    status = AudioDeviceGetProperty(gInputDeviceID,
+				    1,
+				    1,
+				    kAudioDevicePropertyStreamFormat,
+				    &propertySize,
+				    &streamDesc);
+    if (status) {
+      fprintf(stderr, "get device property failed, status = %d\n",
+	      (int)status);
+      return (-2);
+    }
+
+    if ((streamDesc.mSampleRate != 44100.0) ||
+        (streamDesc.mFormatID != kAudioFormatLinearPCM) ||
+       !(streamDesc.mFormatFlags & kLinearPCMFormatFlagIsFloat) ||
+        (streamDesc.mChannelsPerFrame != 2))
+    {
+      fprintf (stderr, "unsupported device.\n");
+      return (-2);
+    }
+
+    /* set buffer size */
+    bufferByteCount = BUF_SIZE * sizeof(float);
+    propertySize = sizeof(bufferByteCount);
+    status = AudioDeviceSetProperty(gInputDeviceID,
+                                    0,
+                                    0,
+                                    1,
+                                    kAudioDevicePropertyBufferSize,
+                                    propertySize,
+                                    &bufferByteCount);
+    if (status) {
+      fprintf(stderr, "set device property failed, status = %d\n",
+              (int)status);
+    }
+
+    fprintf(stderr, "using device %s for input:\n", deviceName);
+    fprintf(stderr, "\twith sample rate %f, %ld channels and %ld-bit sample\n",
+	    streamDesc.mSampleRate,
+	    streamDesc.mChannelsPerFrame,
+	    streamDesc.mBitsPerChannel);
+
+    rval = pthread_mutex_init(&mutexInput, NULL);
+    if (rval) {
+      fprintf(stderr, "mutex init failed\n");
+      return (-1);
+    }
+    rval = pthread_cond_init(&condInput, NULL);
+    if (rval) {
+      fprintf(stderr, "condition init failed\n");
+      return (-1);
+    }
+
+    /* Registers PlaybackIOProc with the device without activating it. */
+    status = AudioDeviceAddIOProc(gInputDeviceID, RecordIOProc, (void *)1);
+  }
+
+  if (!coreaudio_has_output_device) {
+    fprintf(stderr, "unknown output device.\n");
+    return (-2);
+  }
+  /* Allow lack of recording device */
+  /*
+  if (!coreaudio_has_input_device) {
+    fprintf(stderr, "unknown input device.\n");
+    return (-2);
+  }
+  */
+
+  /* Indicates the initialization is done */
+  coreaudio_init = 1;
+
+  esd_audio_fd = 0; /* this is meaningless anyway */
+
+  return 0;
+}
+
+/*
+ * This is called to reset the device status.
+ * (before calls esd_audio_open again)
+ */
+#define ARCH_esd_audio_close
+void esd_audio_close()
+{
+  OSStatus status;
+
+  /* deactivate both of them */
+  if (coreaudio_has_output_device && audioPlaybackStarted) {
+    status = AudioDeviceStop(gOutputDeviceID, PlaybackIOProc);
+    audioPlaybackStarted = 0;
+  }
+
+  if (coreaudio_has_input_device && audioRecordStarted) {
+    status = AudioDeviceStop(gInputDeviceID, RecordIOProc);
+    audioRecordStarted = 0;
+  }
+
+  return;
+}
+
+
+#define ARCH_esd_audio_pause
+void esd_audio_pause()
+{
+  OSStatus status;
+
+  if (coreaudio_has_output_device && audioPlaybackStarted) {
+    status = AudioDeviceStop(gOutputDeviceID, PlaybackIOProc);
+    audioPlaybackStarted = 0;
+  }
+
+  if (coreaudio_has_input_device && audioRecordStarted) {
+    status = AudioDeviceStop(gInputDeviceID, RecordIOProc);
+    audioRecordStarted = 0;
+  }
+
+  return;
+}
+
+
+#define ARCH_esd_audio_write
+/*******************************************************************/
+/* dump a buffer to the sound device */
+int esd_audio_write( void *buffer, int buf_size )
+{
+  OSStatus status;
+  float scale = 1.0 / SHRT_MAX;
+  int remain_to_write = buf_size;
+
+  if (!coreaudio_has_output_device)
+    return -1;
+
+  if (!audioPlaybackStarted) {
+    status = AudioDeviceStart(gOutputDeviceID, PlaybackIOProc);
+    audioPlaybackStarted = 1;
+  }
+
+  while (remain_to_write)
+  {
+    pthread_mutex_lock(&mutexOutput);
+
+    while(OutputWroteSamples == BUF_SIZE)
+      pthread_cond_wait(&condOutput, &mutexOutput);
+
+    {
+      short *src_data = (short *)buffer + (buf_size - remain_to_write) / sizeof(short);
+      float *dst_data = OutputDataBuf + OutputWroteSamples;
+      int src_samples = remain_to_write / sizeof(short);
+      int dst_samples = BUF_SIZE - OutputWroteSamples;
+      int n = (dst_samples < src_samples) ? dst_samples : src_samples;
+      int i;
+
+      for (i = 0; i < n; i++)
+        dst_data[i] = scale * src_data[i];
+
+      OutputWroteSamples += n;
+      remain_to_write -= n * sizeof(short);
+    }
+
+    pthread_mutex_unlock(&mutexOutput);
+  }
+
+  return (buf_size);
+}
+
+#define ARCH_esd_audio_read
+/*******************************************************************/
+/* read a chunk from the sound device */
+int esd_audio_read( void *buffer, int buf_size )
+{
+  OSStatus status;
+  float scale = SHRT_MAX;
+  int remain_to_read = buf_size;
+
+  if (!coreaudio_has_input_device)
+    return -1;
+
+  if (!audioRecordStarted) {
+    status = AudioDeviceStart(gInputDeviceID, RecordIOProc);
+    audioRecordStarted = 1;
+  }
+
+  while (remain_to_read)
+  {
+    pthread_mutex_lock(&mutexInput);
+
+    while(InputReadSamples == BUF_SIZE)
+      pthread_cond_wait(&condInput, &mutexInput);
+
+    {
+      float *src_data = InputDataBuf + InputReadSamples;
+      short *dst_data = (short *)buffer + (buf_size - remain_to_read) / sizeof(short);
+      int src_samples = BUF_SIZE - InputReadSamples;
+      int dst_samples = remain_to_read / sizeof(short);
+      int n = (dst_samples < src_samples) ? dst_samples : src_samples;
+      int i;
+
+      for (i = 0; i < n; i++)
+        dst_data[i] = (short)(scale * src_data[i]);
+
+      InputReadSamples += n;
+      remain_to_read -= n * sizeof(short);
+    }
+
+    pthread_mutex_unlock(&mutexInput);
+  }
+
+  return (buf_size);
+}
+
+
+#define ARCH_esd_audio_flush
+/*******************************************************************/
+/* flush the audio buffer */
+void esd_audio_flush()
+{
+  /* nothing needed */
+  return;
+}
Index: configure.in
===================================================================
RCS file: /cvs/gnome/esound/configure.in,v
retrieving revision 1.82
diff -u -r1.82 configure.in
--- configure.in	19 Jun 2002 14:16:32 -0000	1.82
+++ configure.in	19 Jun 2002 17:29:05 -0000
@@ -156,6 +156,11 @@
       found_sound=yes
       AC_DEFINE(DRIVER_DART)
       ;;
+   darwin*)
+      found_sound=yes
+      AC_DEFINE(DRIVER_COREAUDIO)
+      SOUND_LIBS="-framework CoreAudio"
+      ;;
    esac
 
    if test "${ac_cv_header_dmedia_audio_h}" = "yes"; then
Index: esd.c
===================================================================
RCS file: /cvs/gnome/esound/esd.c,v
retrieving revision 1.63
diff -u -r1.63 esd.c
--- esd.c	17 Jun 2002 09:44:47 -0000	1.63
+++ esd.c	19 Jun 2002 17:29:05 -0000
@@ -21,6 +21,13 @@
 #define gethostbyname2(host, family) gethostbyname((host))
 #endif /* HAVE_GETHOSTBYNAME2 */
 
+#if defined (__APPLE__)
+#include <mach/mach.h>
+#include <mach/thread_policy.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#endif
+
 /*******************************************************************/
 /* esd.c - prototypes */
 void set_audio_buffer( void *buf, esd_format_t format, int magl, int magr,
@@ -514,6 +521,29 @@
 
     int default_format = ESD_BITS16 | ESD_STEREO;
     /* end test scaffolding parameters */
+
+#if defined (__APPLE__)
+    /* get realtime priority */
+    {
+	struct thread_time_constraint_policy ttcpolicy;
+	int bus_speed, mib [2] = { CTL_HW, HW_BUS_FREQ };
+	size_t len;   
+
+	len = sizeof (bus_speed);
+	sysctl (mib, 2, &bus_speed, &len, NULL, 0);
+
+	/* Is it enough? */
+	ttcpolicy.period = bus_speed / 120;
+	ttcpolicy.computation = bus_speed / 2400;
+	ttcpolicy.constraint = bus_speed / 1200;
+	ttcpolicy.preemptible = 1;
+
+	thread_policy_set (mach_thread_self (),
+			   THREAD_TIME_CONSTRAINT_POLICY,
+			   (int*)&ttcpolicy,
+			   THREAD_TIME_CONSTRAINT_POLICY_COUNT);
+    }
+#endif
 
     programname = *argv;
 
Index: esd.conf
===================================================================
RCS file: /cvs/gnome/esound/esd.conf,v
retrieving revision 1.2
diff -u -r1.2 esd.conf
--- esd.conf	19 Jun 1999 02:52:01 -0000	1.2
+++ esd.conf	19 Jun 2002 17:29:05 -0000
@@ -1,4 +1,4 @@
 [esd]
 auto_spawn=1
 spawn_options=-terminate -nobeeps -as 2
-spawn_wait_ms=100
+spawn_wait_ms=999
Index: esd_audio.c
===================================================================
RCS file: esd_audio.c
diff -N esd_audio.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ esd_audio.c	19 Jun 2002 17:29:05 -0000
@@ -0,0 +1,4 @@
+/* dirty trickery to reduce shared library dependencies */
+
+#define INSIDE_ESD
+#include "audio.c"
Index: esd_config.c
===================================================================
RCS file: /cvs/gnome/esound/esd_config.c,v
retrieving revision 1.5
diff -u -r1.5 esd_config.c
--- esd_config.c	4 Jun 2002 15:41:49 -0000	1.5
+++ esd_config.c	19 Jun 2002 17:29:05 -0000
@@ -16,7 +16,7 @@
 int esd_no_spawn=1; /* If we can't find even the system config file,
 		       things are screwed up - don't try to make things
 		       worse. */
-int esd_spawn_wait_ms=100; /* Time to wait trying to connect to an
+int esd_spawn_wait_ms=999; /* Time to wait trying to connect to an
 			      autospawned ESD, in milliseconds. */
 char esd_spawn_options[LINEBUF_SIZE] = "-terminate -nobeeps -as 2";
 
Index: esdlib.c
===================================================================
RCS file: /cvs/gnome/esound/esdlib.c,v
retrieving revision 1.78
diff -u -r1.78 esdlib.c
--- esdlib.c	19 Jun 2002 14:03:01 -0000	1.78
+++ esdlib.c	19 Jun 2002 17:29:05 -0000
@@ -681,8 +681,8 @@
 	FD_ZERO (&fdset);
 	FD_SET (esd_pipe[0], &fdset);
 	
-	timeout.tv_sec = 0;
-	timeout.tv_usec = esd_spawn_wait_ms * 1000;
+	timeout.tv_sec = (esd_spawn_wait_ms * 1000) / 1000000;
+	timeout.tv_usec = (esd_spawn_wait_ms * 1000) % 1000000;
 	
 	ret = select (esd_pipe[0] + 1, &fdset, NULL, NULL, &timeout);
 	
