Index: osxaudio/gstosxaudiosrc.c
===================================================================
--- osxaudio/gstosxaudiosrc.c	(revision 695)
+++ osxaudio/gstosxaudiosrc.c	(working copy)
@@ -87,6 +87,8 @@
   ARG_DEVICE
 };
 
+// FIXME: for now, hardcode channels to 1 until someone cares to really test
+//   multichannel audio capture
 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
@@ -95,7 +97,9 @@
         "signed = (boolean) { TRUE }, "
         "width = (int) 32, "
         "depth = (int) 32, "
-        "rate = (int) [1, MAX], " "channels = (int) [1, MAX]")
+        "rate = (int) [1, MAX], "
+        //"channels = (int) [1, MAX]")
+        "channels = (int) 1")
     );
 
 static void gst_osx_audio_src_set_property (GObject * object, guint prop_id,
@@ -181,6 +185,7 @@
   gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
 
   src->device_id = kAudioDeviceUnknown;
+  src->deviceRate = -1;
   src->deviceChannels = -1;
 }
 
@@ -223,35 +228,55 @@
   GstOsxAudioSrc *osxsrc;
   GstPadTemplate *pad_template;
   GstCaps *caps;
-  gint min, max;
+  gint rate; //, cmin, cmax;
 
   gstelement_class = GST_ELEMENT_GET_CLASS (src);
   osxsrc = GST_OSX_AUDIO_SRC (src);
 
+  if (osxsrc->deviceRate == -1) {
+    /* -1 means we don't know the hardware sample rate yet.  for now, return
+     * template caps.
+     */
+    return NULL;
+  }
+
+#if 0
   if (osxsrc->deviceChannels == -1) {
     /* -1 means we don't know the number of channels yet.  for now, return
      * template caps.
      */
     return NULL;
   }
+#endif
 
-  max = osxsrc->deviceChannels;
-  if (max < 1)
-    max = 1;                    /* 0 channels means 1 channel? */
+  rate = osxsrc->deviceRate;
 
-  min = MIN (1, max);
+#if 0
+  // FIXME: for now, hardcode channels to 1 until someone cares to really test
+  //   multichannel audio capture
+  //cmax = osxsrc->deviceChannels;
+  cmax = 1;
+  if (cmax < 1)
+    cmax = 1;                    /* 0 channels means 1 channel? */
 
+  cmin = MIN (1, cmax);
+#endif
+
   pad_template = gst_element_class_get_pad_template (gstelement_class, "src");
   g_return_val_if_fail (pad_template != NULL, NULL);
 
   caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
 
+  gst_caps_set_simple (caps, "rate", G_TYPE_INT, rate, NULL);
+
+#if 0
   if (min == max) {
-    gst_caps_set_simple (caps, "channels", G_TYPE_INT, max, NULL);
+    gst_caps_set_simple (caps, "channels", G_TYPE_INT, cmax, NULL);
   } else {
-    gst_caps_set_simple (caps, "channels", GST_TYPE_INT_RANGE, min, max,
+    gst_caps_set_simple (caps, "channels", GST_TYPE_INT_RANGE, cmin, cmax,
         NULL);
   }
+#endif
 
   return caps;
 }
Index: osxaudio/gstosxringbuffer.c
===================================================================
--- osxaudio/gstosxringbuffer.c	(revision 695)
+++ osxaudio/gstosxringbuffer.c	(working copy)
@@ -73,7 +73,8 @@
     const AudioTimeStamp * inTimeStamp, unsigned int inBusNumber,
     unsigned int inNumberFrames, AudioBufferList * ioData);
 
-static AudioBufferList *buffer_list_alloc (int channels, int size);
+static AudioBufferList *buffer_list_alloc (int channels, int frames
+    int bytesPerChannel, gboolean interleaved);
 static void buffer_list_free (AudioBufferList * list);
 
 static void
@@ -258,6 +259,19 @@
       return FALSE;
     }
 
+    GST_LOG_OBJECT (osxbuf, "Device format: %x, %f, %u, %x, %d, %d, %d, %d,"
+        " %d",
+        (unsigned int) asbd_in.mFormatID,
+        asbd_in.mSampleRate,
+        (unsigned int) asbd_in.mChannelsPerFrame,
+        (unsigned int) asbd_in.mFormatFlags,
+        (unsigned int) asbd_in.mBytesPerFrame,
+        (unsigned int) asbd_in.mBitsPerChannel,
+        (unsigned int) asbd_in.mBytesPerPacket,
+        (unsigned int) asbd_in.mFramesPerPacket,
+        (unsigned int) asbd_in.mReserved);
+
+    src->deviceRate = (int) asbd_in.mSampleRate;
     src->deviceChannels = asbd_in.mChannelsPerFrame;
   } else {
     sink = GST_OSX_AUDIO_SINK (GST_OBJECT_PARENT (buf));
@@ -334,6 +348,7 @@
   GstStructure *structure;
   GstAudioChannelPosition *positions;
   UInt32 frameSize;
+  Boolean isWritable;
 
   osxbuf = GST_OSX_RING_BUFFER (buf);
 
@@ -382,7 +397,7 @@
     positions = NULL;
   }
 
-  GST_LOG_OBJECT (osxbuf, "Format: %x, %f, %u, %x, %d, %d, %d, %d, %d",
+  GST_LOG_OBJECT (osxbuf, "Desired format: %x, %f, %u, %x, %d, %d, %d, %d, %d",
       (unsigned int) format.mFormatID,
       format.mSampleRate,
       (unsigned int) format.mChannelsPerFrame,
@@ -397,7 +412,16 @@
   scope = osxbuf->is_src ? kAudioUnitScope_Output : kAudioUnitScope_Input;
   element = osxbuf->is_src ? 1 : 0;
 
-  propertySize = sizeof (format);
+  status = AudioUnitGetPropertyInfo (osxbuf->audiounit,
+      kAudioUnitProperty_StreamFormat, scope, element, &propertySize,
+      &isWritable);
+
+  if (status) {
+    GST_WARNING_OBJECT (osxbuf, "Failed to get stream format info: %lx",
+        (gulong) status);
+    goto done;
+  }
+
   status = AudioUnitSetProperty (osxbuf->audiounit,
       kAudioUnitProperty_StreamFormat, scope, element, &format, propertySize);
 
@@ -407,15 +431,39 @@
     goto done;
   }
 
-  status = AudioUnitSetProperty (osxbuf->audiounit,
-      kAudioUnitProperty_AudioChannelLayout,
-      scope, element, layout, layoutSize);
+  status = AudioUnitGetProperty (osxbuf->audiounit,
+      kAudioUnitProperty_StreamFormat, scope, element, &format, &propertySize);
+
   if (status) {
-    GST_WARNING_OBJECT (osxbuf, "Failed to set output channel layout: %lx",
-        (gulong) status);
+    GST_WARNING_OBJECT (osxbuf, "Failed to get audio description: %lx",
+        status);
     goto done;
   }
 
+  // afaik, if we set our own format then this will always be the same
+  /*GST_LOG_OBJECT (osxbuf, "Actual format: %x, %f, %u, %x, %d, %d, %d, %d, %d",
+      (unsigned int) format.mFormatID,
+      format.mSampleRate,
+      (unsigned int) format.mChannelsPerFrame,
+      (unsigned int) format.mFormatFlags,
+      (unsigned int) format.mBytesPerFrame,
+      (unsigned int) format.mBitsPerChannel,
+      (unsigned int) format.mBytesPerPacket,
+      (unsigned int) format.mFramesPerPacket,
+      (unsigned int) format.mReserved);*/
+
+  // FIXME: consider channel layout for src element, not just sink
+  if (!osxbuf->is_src) {
+    status = AudioUnitSetProperty (osxbuf->audiounit,
+        kAudioUnitProperty_AudioChannelLayout,
+        scope, element, layout, layoutSize);
+    if (status) {
+      GST_WARNING_OBJECT (osxbuf, "Failed to set channel layout: %lx",
+          (gulong) status);
+      goto done;
+    }
+  }
+
   spec->segsize =
       (spec->latency_time * spec->rate / G_USEC_PER_SEC) *
       spec->bytes_per_sample;
@@ -434,7 +482,7 @@
     }
 
     osxbuf->recBufferList = buffer_list_alloc (format.mChannelsPerFrame,
-        frameSize * format.mBytesPerFrame);
+        frameSize, format.mBitsPerChannel / 8, TRUE);
   }
 
   buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize);
@@ -656,18 +704,32 @@
 }
 
 static AudioBufferList *
-buffer_list_alloc (int channels, int size)
+buffer_list_alloc (int channels, int frames, int bytesPerChannel,
+    gboolean interleaved)
 {
   AudioBufferList *list;
-  int total_size;
+  int buffer_count;
+  int size, total_size;
   int n;
 
-  total_size = sizeof (AudioBufferList) + 1 * sizeof (AudioBuffer);
+  if (interleaved)
+    buffer_count = 1;
+  else
+    buffer_count = channels;
+
+  total_size = sizeof (AudioBufferList) + buffer_count * sizeof (AudioBuffer);
   list = (AudioBufferList *) g_malloc (total_size);
 
-  list->mNumberBuffers = 1;
-  for (n = 0; n < (int) list->mNumberBuffers; ++n) {
-    list->mBuffers[n].mNumberChannels = channels;
+  list->mNumberBuffers = buffer_count;
+  for (n = 0; n < buffer_count; ++n) {
+    if (interleaved) {
+      list->mBuffers[n].mNumberChannels = channels;
+      size = bytesPerChannel * channels * frames;
+    } else {
+      list->mBuffers[n].mNumberChannels = 1;
+      size = bytesPerChannel * frames;
+    }
+
     list->mBuffers[n].mDataByteSize = size;
     list->mBuffers[n].mData = g_malloc (size);
   }
Index: osxaudio/gstosxaudiosrc.h
===================================================================
--- osxaudio/gstosxaudiosrc.h	(revision 695)
+++ osxaudio/gstosxaudiosrc.h	(working copy)
@@ -66,7 +66,8 @@
 
   AudioDeviceID device_id;
 
-  /* actual number of channels reported by input device */
+  /* properties reported by the hardware */
+  int deviceRate;
   int deviceChannels;
 };
 
