Index: uspace/srv/audio/hound/audio_device.c
===================================================================
--- uspace/srv/audio/hound/audio_device.c	(revision bee53490fd25b6b457f36535f0c58753255c9d6c)
+++ uspace/srv/audio/hound/audio_device.c	(revision 4eff63c6227688ae1de2299f2c9c78d7b2618abf)
@@ -55,5 +55,5 @@
 static int get_buffer(audio_device_t *dev);
 static int release_buffer(audio_device_t *dev);
-static void fill_buffer(audio_device_t *dev, size_t size);
+static void advance_buffer(audio_device_t *dev, size_t size);
 static inline bool is_running(audio_device_t *dev)
 {
@@ -167,5 +167,9 @@
 		pcm_format_silence(dev->buffer.base, dev->buffer.size,
 		    &dev->sink.format);
-		fill_buffer(dev, dev->buffer.fragment_size * 2);
+		//TODO add underrun detection.
+		const size_t size = dev->buffer.fragment_size * 2;
+		/* We never cross the end of the buffer here */
+		audio_sink_mix_inputs(&dev->sink, dev->buffer.position, size);
+		advance_buffer(dev, size);
 
 		const unsigned frames = dev->buffer.fragment_size /
@@ -280,5 +284,9 @@
 			struct timeval time1;
 			getuptime(&time1);
-			fill_buffer(dev, dev->buffer.fragment_size);
+			//TODO add underrun detection.
+			/* We never cross the end of the buffer here */
+			audio_sink_mix_inputs(&dev->sink, dev->buffer.position,
+			    dev->buffer.fragment_size);
+			advance_buffer(dev, dev->buffer.fragment_size);
 			struct timeval time2;
 			getuptime(&time2);
@@ -290,7 +298,12 @@
 			log_verbose("Playback terminated!");
 			return;
-		case PCM_EVENT_FRAMES_CAPTURED:
-			//TODO implement
+		case PCM_EVENT_FRAMES_CAPTURED: {
+			const int ret = audio_source_push_data(&dev->source,
+			    dev->buffer.position, dev->buffer.fragment_size);
+			advance_buffer(dev, dev->buffer.fragment_size);
+			if (ret != EOK)
+				log_warning("Failed to push recorded data");
 			break;
+		}
 		case PCM_EVENT_CAPTURE_TERMINATED:
 			log_verbose("Recording terminated!");
@@ -372,16 +385,13 @@
 
 /**
- * Mix data from all connections and add it to the device buffer.
+ * Move buffer position pointer.
  * @param dev Audio device.
- * @param size portion of the device buffer to fill.
- */
-static void fill_buffer(audio_device_t *dev, size_t size)
+ * @param size number of bytes to move forward
+ */
+static void advance_buffer(audio_device_t *dev, size_t size)
 {
 	assert(dev);
 	assert(dev->buffer.position >= dev->buffer.base);
 	assert(dev->buffer.position < (dev->buffer.base + dev->buffer.size));
-
-	//TODO add underrun detection.
-	audio_sink_mix_inputs(&dev->sink, dev->buffer.position, size);
 	dev->buffer.position += size;
 	if (dev->buffer.position == (dev->buffer.base + dev->buffer.size))
Index: uspace/srv/audio/hound/audio_source.c
===================================================================
--- uspace/srv/audio/hound/audio_source.c	(revision bee53490fd25b6b457f36535f0c58753255c9d6c)
+++ uspace/srv/audio/hound/audio_source.c	(revision 4eff63c6227688ae1de2299f2c9c78d7b2618abf)
@@ -41,6 +41,8 @@
 #include <str_error.h>
 
+#include "audio_data.h"
 #include "audio_source.h"
 #include "audio_sink.h"
+#include "connection.h"
 #include "log.h"
 
@@ -87,4 +89,32 @@
 	source->name = NULL;
 }
+/**
+ * Push data to all connections.
+ * @param source The source of the data.
+ * @param dest Destination buffer.
+ * @param size size of the @p dest buffer.
+ * @return Error code.
+ */
+int audio_source_push_data(audio_source_t *source, const void *data,
+    size_t size)
+{
+	assert(source);
+	assert(data);
+
+	audio_data_t *adata = audio_data_create(data, size, source->format);
+	if (!adata)
+		return ENOMEM;
+
+	list_foreach(source->connections, it) {
+		connection_t *conn = connection_from_source_list(it);
+		const int ret = connection_push_data(conn, adata);
+		if (ret != EOK) {
+			log_warning("Failed push data to %s: %s",
+			    connection_sink_name(conn), str_error(ret));
+		}
+	}
+	audio_data_unref(adata);
+	return EOK;
+}
 
 /**
Index: uspace/srv/audio/hound/audio_source.h
===================================================================
--- uspace/srv/audio/hound/audio_source.h	(revision bee53490fd25b6b457f36535f0c58753255c9d6c)
+++ uspace/srv/audio/hound/audio_source.h	(revision 4eff63c6227688ae1de2299f2c9c78d7b2618abf)
@@ -75,4 +75,6 @@
     const pcm_format_t *f);
 void audio_source_fini(audio_source_t *source);
+int audio_source_push_data(audio_source_t *source, const void *data,
+    size_t size);
 static inline const pcm_format_t *audio_source_format(const audio_source_t *s)
 {
