Index: uspace/srv/audio/hound/hound_ctx.c
===================================================================
--- uspace/srv/audio/hound/hound_ctx.c	(revision d988ef2a47fc17216b02595ca71934247ff2ce63)
+++ uspace/srv/audio/hound/hound_ctx.c	(revision f1438e5b77d3cae999c82f40303ef03f3048cb5f)
@@ -101,10 +101,9 @@
 typedef struct hound_ctx_stream {
 	link_t link;
-	list_t fifo;
+	audio_pipe_t fifo;
 	hound_ctx_t *ctx;
 	pcm_format_t format;
 	int flags;
 	size_t allowed_size;
-	size_t current_size;
 } hound_ctx_stream_t;
 
@@ -120,5 +119,5 @@
 	hound_ctx_stream_t *stream = malloc(sizeof(hound_ctx_stream_t));
 	if (stream) {
-		list_initialize(&stream->fifo);
+		audio_pipe_init(&stream->fifo);
 		link_initialize(&stream->link);
 		stream->ctx = ctx;
@@ -126,5 +125,4 @@
 		stream->format = format;
 		stream->allowed_size = buffer_size;
-		stream->current_size = 0;
 		list_append(&stream->link, &ctx->streams);
 		log_verbose("CTX: %p added stream; flags:%#x ch: %u r:%u f:%s",
@@ -140,18 +138,12 @@
 		//TODO consider DRAIN FLAG
 		list_remove(&stream->link);
-		if (!list_empty(&stream->fifo))
+		if (audio_pipe_bytes(&stream->fifo))
 			log_warning("Destroying stream with non empty buffer");
-		while (!list_empty(&stream->fifo)) {
-			link_t *l = list_first(&stream->fifo);
-			audio_data_link_t *data =
-			    audio_data_link_list_instance(l);
-			list_remove(l);
-			audio_data_link_destroy(data);
-		}
+		audio_pipe_fini(&stream->fifo);
 		log_verbose("CTX: %p remove stream (%zu/%zu); "
 		    "flags:%#x ch: %u r:%u f:%s",
-		    stream->ctx, stream->current_size, stream->allowed_size,
-		    stream->flags, stream->format.channels,
-		    stream->format.sampling_rate,
+		    stream->ctx, audio_pipe_bytes(&stream->fifo),
+		    stream->allowed_size, stream->flags,
+		    stream->format.channels, stream->format.sampling_rate,
 		    pcm_sample_format_str(stream->format.sample_format));
 		free(stream);
@@ -170,16 +162,8 @@
 
 	if (stream->allowed_size &&
-	    (stream->current_size + size > stream->allowed_size))
+	    (audio_pipe_bytes(&stream->fifo) + size > stream->allowed_size))
 		return EBUSY;
 
-	audio_data_link_t *adatalink =
-	    audio_data_link_create_data(data, size, stream->format);
-	if (adatalink) {
-		list_append(&adatalink->link, &stream->fifo);
-		stream->current_size += size;
-		return EOK;
-	}
-	log_warning("Failed to enqueue %zu bytes of data.", size);
-	return ENOMEM;
+	return audio_pipe_push_data(&stream->fifo, data, size, stream->format);
 }
 
@@ -194,35 +178,9 @@
 {
 	assert(stream);
-	const size_t src_frame_size = pcm_format_frame_size(&stream->format);
-	const size_t dst_frame_size = pcm_format_frame_size(f);
-	//TODO consider sample rate
-	size_t needed_frames = size / dst_frame_size;
-	while (needed_frames > 0 && !list_empty(&stream->fifo)) {
-		link_t *l = list_first(&stream->fifo);
-		audio_data_link_t *alink = audio_data_link_list_instance(l);
-		/* Get actual audio data chunk */
-		const size_t available_frames =
-		    audio_data_link_available_frames(alink);
-		const size_t copy_frames = min(available_frames, needed_frames);
-		const size_t copy_size = copy_frames * dst_frame_size;
-
-		/* Copy audio data */
-		pcm_format_convert_and_mix(data, copy_size,
-		    audio_data_link_start(alink),
-		    audio_data_link_remain_size(alink),
-		    &alink->adata->format, f);
-
-		/* Update values */
-		needed_frames -= copy_frames;
-		data += copy_size;
-		alink->position += (copy_frames * src_frame_size);
-		if (audio_data_link_remain_size(alink) == 0) {
-			list_remove(&alink->link);
-			audio_data_link_destroy(alink);
-		} else {
-			assert(needed_frames == 0);
-		}
-	}
-	return ENOTSUP;
+	const ssize_t copied_size =
+	    audio_pipe_mix_data(&stream->fifo, data, size, f);
+	if (copied_size != (ssize_t)size)
+		log_warning("Not enough data in stream buffer");
+	return copied_size > 0 ? EOK : copied_size;
 }
 
@@ -230,5 +188,5 @@
 {
 	assert(stream);
-	while (!list_empty(&stream->fifo))
+	while (audio_pipe_bytes(&stream->fifo))
 		async_usleep(10000);
 }
