Index: uspace/app/drec/drec.c
===================================================================
--- uspace/app/drec/drec.c	(revision ed3816df9c8d9f9483b524e9564aa65c6fb406e4)
+++ uspace/app/drec/drec.c	(revision 92b638c034f15cb008344be39773f82ec6481376)
@@ -124,5 +124,5 @@
 	const unsigned frames = rec->buffer.size /
 	    (BUFFER_PARTS * channels * pcm_sample_format_size(format));
-	int ret = audio_pcm_start_capture(rec->device,
+	int ret = audio_pcm_start_capture_fragment(rec->device,
 	    frames, channels, sampling_rate, format);
 	if (ret != EOK) {
Index: uspace/app/wavplay/dplay.c
===================================================================
--- uspace/app/wavplay/dplay.c	(revision ed3816df9c8d9f9483b524e9564aa65c6fb406e4)
+++ uspace/app/wavplay/dplay.c	(revision 92b638c034f15cb008344be39773f82ec6481376)
@@ -113,5 +113,5 @@
 		   buffer_part, pb->source);
 		if (bytes == 0) {
-			audio_pcm_stop_playback(pb->device);
+			audio_pcm_last_playback_fragment(pb->device);
 		}
 		bzero(pb->buffer.position + bytes, buffer_part - bytes);
@@ -148,5 +148,5 @@
 	const unsigned frames = pb->buffer.size /
 	    (BUFFER_PARTS * channels * pcm_sample_format_size(format));
-	ret = audio_pcm_start_playback(pb->device, frames, channels,
+	ret = audio_pcm_start_playback_fragment(pb->device, frames, channels,
 	    sampling_rate, format);
 	if (ret != EOK) {
Index: uspace/drv/audio/sb16/dsp.c
===================================================================
--- uspace/drv/audio/sb16/dsp.c	(revision ed3816df9c8d9f9483b524e9564aa65c6fb406e4)
+++ uspace/drv/audio/sb16/dsp.c	(revision 92b638c034f15cb008344be39773f82ec6481376)
@@ -403,4 +403,7 @@
 		return EINVAL;
 
+	if (dsp->state != DSP_READY && dsp->state != DSP_STOPPED)
+		return EINVAL;
+
 	/* Check supported parameters */
 	ddf_log_debug("Requested playback: %u frames, %uHz, %s, %u channel(s).",
@@ -444,15 +447,27 @@
 }
 
-int sb_dsp_stop_playback(sb_dsp_t *dsp)
-{
-	assert(dsp);
-	if (dsp->state != DSP_PLAYBACK_NOEVENTS &&
-	    dsp->state != DSP_PLAYBACK_ACTIVE_EVENTS)
-		return EINVAL;
-
-	sb_dsp_write(dsp, DMA_16B_EXIT);
-	ddf_log_debug("Stopping playback on buffer.");
-	sb_dsp_change_state(dsp, DSP_PLAYBACK_TERMINATE);
-	return EOK;
+int sb_dsp_stop_playback(sb_dsp_t *dsp, bool immediate)
+{
+	assert(dsp);
+	if ((dsp->state == DSP_PLAYBACK_NOEVENTS ||
+	    dsp->state == DSP_PLAYBACK_ACTIVE_EVENTS) &&
+	    immediate)
+	{
+		sb_dsp_write(dsp, DMA_16B_PAUSE);
+		sb_dsp_reset(dsp);
+		ddf_log_debug("Stopped playback");
+		sb_dsp_change_state(dsp, DSP_STOPPED);
+		return EOK;
+	}
+	if (dsp->state == DSP_PLAYBACK_ACTIVE_EVENTS)
+	{
+		/* Stop after current fragment */
+		assert(!immediate);
+		sb_dsp_write(dsp, DMA_16B_EXIT);
+		ddf_log_debug("Last playback fragment");
+		sb_dsp_change_state(dsp, DSP_PLAYBACK_TERMINATE);
+		return EOK;
+	}
+	return EINVAL;
 }
 
@@ -462,4 +477,6 @@
 	assert(dsp);
 	if (!dsp->buffer.data)
+		return EINVAL;
+	if (dsp->state != DSP_READY && dsp->state != DSP_STOPPED)
 		return EINVAL;
 
@@ -503,15 +520,27 @@
 }
 
-int sb_dsp_stop_capture(sb_dsp_t *dsp)
-{
-	assert(dsp);
-	if (dsp->state != DSP_CAPTURE_NOEVENTS &&
-	    dsp->state != DSP_CAPTURE_ACTIVE_EVENTS)
-		return EINVAL;
-
-	sb_dsp_write(dsp, DMA_16B_EXIT);
-	ddf_log_debug("Stopped capture");
-	sb_dsp_change_state(dsp, DSP_CAPTURE_TERMINATE);
-	return EOK;
+int sb_dsp_stop_capture(sb_dsp_t *dsp, bool immediate)
+{
+	assert(dsp);
+	if ((dsp->state == DSP_CAPTURE_NOEVENTS ||
+	    dsp->state == DSP_CAPTURE_ACTIVE_EVENTS) &&
+	    immediate)
+	{
+		sb_dsp_write(dsp, DMA_16B_PAUSE);
+		sb_dsp_reset(dsp);
+		ddf_log_debug("Stopped capture fragment");
+		sb_dsp_change_state(dsp, DSP_STOPPED);
+		return EOK;
+	}
+	if (dsp->state == DSP_CAPTURE_ACTIVE_EVENTS)
+	{
+		/* Stop after current fragment */
+		assert(!immediate);
+		sb_dsp_write(dsp, DMA_16B_EXIT);
+		ddf_log_debug("Last capture fragment");
+		sb_dsp_change_state(dsp, DSP_CAPTURE_TERMINATE);
+		return EOK;
+	}
+	return EINVAL;
 }
 /**
Index: uspace/drv/audio/sb16/dsp.h
===================================================================
--- uspace/drv/audio/sb16/dsp.h	(revision ed3816df9c8d9f9483b524e9564aa65c6fb406e4)
+++ uspace/drv/audio/sb16/dsp.h	(revision 92b638c034f15cb008344be39773f82ec6481376)
@@ -90,8 +90,8 @@
 int sb_dsp_start_playback(sb_dsp_t *dsp, unsigned frames,
     unsigned channels, unsigned sample_rate, pcm_sample_format_t format);
-int sb_dsp_stop_playback(sb_dsp_t *dsp);
+int sb_dsp_stop_playback(sb_dsp_t *dsp, bool immediate);
 int sb_dsp_start_capture(sb_dsp_t *dsp, unsigned frames,
     unsigned channels, unsigned sample_rate, pcm_sample_format_t format);
-int sb_dsp_stop_capture(sb_dsp_t *dsp);
+int sb_dsp_stop_capture(sb_dsp_t *dsp, bool immediate);
 
 #endif
Index: uspace/drv/audio/sb16/pcm_iface.c
===================================================================
--- uspace/drv/audio/sb16/pcm_iface.c	(revision ed3816df9c8d9f9483b524e9564aa65c6fb406e4)
+++ uspace/drv/audio/sb16/pcm_iface.c	(revision 92b638c034f15cb008344be39773f82ec6481376)
@@ -96,7 +96,7 @@
 }
 
-static int sb_stop_playback(ddf_fun_t *fun)
+static int sb_stop_playback(ddf_fun_t *fun, bool immediate)
 {
-	return sb_dsp_stop_playback(fun_to_dsp(fun));
+	return sb_dsp_stop_playback(fun_to_dsp(fun), immediate);
 }
 
@@ -108,7 +108,7 @@
 }
 
-static int sb_stop_capture(ddf_fun_t *fun)
+static int sb_stop_capture(ddf_fun_t *fun, bool immediate)
 {
-	return sb_dsp_stop_capture(fun_to_dsp(fun));
+	return sb_dsp_stop_capture(fun_to_dsp(fun), immediate);
 }
 
Index: uspace/lib/drv/generic/remote_audio_pcm.c
===================================================================
--- uspace/lib/drv/generic/remote_audio_pcm.c	(revision ed3816df9c8d9f9483b524e9564aa65c6fb406e4)
+++ uspace/lib/drv/generic/remote_audio_pcm.c	(revision 92b638c034f15cb008344be39773f82ec6481376)
@@ -342,5 +342,5 @@
  * 0 to turn off event generation.
  */
-int audio_pcm_start_playback(audio_pcm_sess_t *sess, unsigned frames,
+int audio_pcm_start_playback_fragment(audio_pcm_sess_t *sess, unsigned frames,
     unsigned channels, unsigned sample_rate, pcm_sample_format_t format)
 {
@@ -357,7 +357,40 @@
 	return ret;
 }
-
-/**
- * Stop current playback.
+/**
+ * Stops playback after current fragment.
+ *
+ * @param sess Audio device session.
+ *
+ * @return Error code.
+ */
+int audio_pcm_last_playback_fragment(audio_pcm_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	const int ret = async_req_2_0(exch,
+	    DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
+	    IPC_M_AUDIO_PCM_STOP_PLAYBACK, false);
+	async_exchange_end(exch);
+	return ret;
+}
+
+/**
+ * Start playback on buffer from the current position.
+ *
+ * @param sess Audio device session.
+ * @param channels Number of channels.
+ * @param sample_rate Sampling rate (for one channel).
+ * @param format Sample format.
+ *
+ * @return Error code.
+ */
+int audio_pcm_start_playback(audio_pcm_sess_t *sess,
+    unsigned channels, unsigned sample_rate, pcm_sample_format_t format)
+{
+	return audio_pcm_start_playback_fragment(
+	    sess, 0, channels, sample_rate, format);
+}
+
+/**
+ * Immediately stops current playback.
  *
  * @param sess Audio device session.
@@ -368,13 +401,13 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	const int ret = async_req_1_0(exch,
-	    DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
-	    IPC_M_AUDIO_PCM_STOP_PLAYBACK);
-	async_exchange_end(exch);
-	return ret;
-}
-
-/**
- * Start capture on buffer from position 0.
+	const int ret = async_req_2_0(exch,
+	    DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
+	    IPC_M_AUDIO_PCM_STOP_PLAYBACK, true);
+	async_exchange_end(exch);
+	return ret;
+}
+
+/**
+ * Start capture on buffer from the current position.
  *
  * @param sess Audio device session.
@@ -389,5 +422,5 @@
  * 0 to turn off event generation.
  */
-int audio_pcm_start_capture(audio_pcm_sess_t *sess, unsigned frames,
+int audio_pcm_start_capture_fragment(audio_pcm_sess_t *sess, unsigned frames,
     unsigned channels, unsigned sample_rate, pcm_sample_format_t format)
 {
@@ -405,5 +438,40 @@
 
 /**
- * Stop current playback.
+ * Start capture on buffer from the current position.
+ *
+ * @param sess Audio device session.
+ * @param channels Number of channels.
+ * @param sample_rate Sampling rate (for one channel).
+ * @param format Sample format.
+ *
+ * @return Error code.
+ */
+int audio_pcm_start_capture(audio_pcm_sess_t *sess,
+    unsigned channels, unsigned sample_rate, pcm_sample_format_t format)
+{
+	return audio_pcm_start_capture_fragment(
+	    sess, 0, channels, sample_rate, format);
+}
+
+/**
+ * Stops capture at the end of current fragment.
+ *
+ * Won't work if capture was started with fragment size 0.
+ * @param sess Audio device session.
+ *
+ * @return Error code.
+ */
+int audio_pcm_last_capture_fragment(audio_pcm_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	const int ret = async_req_2_0(exch,
+	    DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
+	    IPC_M_AUDIO_PCM_STOP_CAPTURE, false);
+	async_exchange_end(exch);
+	return ret;
+}
+
+/**
+ * Immediately stops current capture.
  *
  * @param sess Audio device session.
@@ -414,6 +482,7 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	const int ret = async_req_1_0(exch,
-	    DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE), IPC_M_AUDIO_PCM_STOP_CAPTURE);
+	const int ret = async_req_2_0(exch,
+	    DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
+	    IPC_M_AUDIO_PCM_STOP_CAPTURE, true);
 	async_exchange_end(exch);
 	return ret;
@@ -648,7 +717,8 @@
 {
 	const audio_pcm_iface_t *pcm_iface = iface;
+	const bool immediate = DEV_IPC_GET_ARG1(*call);
 
 	const int ret = pcm_iface->stop_playback ?
-	    pcm_iface->stop_playback(fun) : ENOTSUP;
+	    pcm_iface->stop_playback(fun, immediate) : ENOTSUP;
 	async_answer_0(callid, ret);
 }
@@ -674,7 +744,8 @@
 {
 	const audio_pcm_iface_t *pcm_iface = iface;
+	const bool immediate = DEV_IPC_GET_ARG1(*call);
 
 	const int ret = pcm_iface->stop_capture ?
-	    pcm_iface->stop_capture(fun) : ENOTSUP;
+	    pcm_iface->stop_capture(fun, immediate) : ENOTSUP;
 	async_answer_0(callid, ret);
 }
Index: uspace/lib/drv/include/audio_pcm_iface.h
===================================================================
--- uspace/lib/drv/include/audio_pcm_iface.h	(revision ed3816df9c8d9f9483b524e9564aa65c6fb406e4)
+++ uspace/lib/drv/include/audio_pcm_iface.h	(revision 92b638c034f15cb008344be39773f82ec6481376)
@@ -81,9 +81,17 @@
 int audio_pcm_release_buffer(audio_pcm_sess_t *);
 
-int audio_pcm_start_playback(audio_pcm_sess_t *, unsigned,
+int audio_pcm_start_playback_fragment(audio_pcm_sess_t *, unsigned,
+    unsigned, unsigned, pcm_sample_format_t);
+int audio_pcm_last_playback_fragment(audio_pcm_sess_t *);
+
+int audio_pcm_start_playback(audio_pcm_sess_t *,
     unsigned, unsigned, pcm_sample_format_t);
 int audio_pcm_stop_playback(audio_pcm_sess_t *);
 
-int audio_pcm_start_capture(audio_pcm_sess_t *, unsigned,
+int audio_pcm_start_capture_fragment(audio_pcm_sess_t *, unsigned,
+    unsigned, unsigned, pcm_sample_format_t);
+int audio_pcm_last_capture_fragment(audio_pcm_sess_t *);
+
+int audio_pcm_start_capture(audio_pcm_sess_t *,
     unsigned, unsigned, pcm_sample_format_t);
 int audio_pcm_stop_capture(audio_pcm_sess_t *);
@@ -102,8 +110,8 @@
 	int (*start_playback)(ddf_fun_t *, unsigned,
 	    unsigned, unsigned, pcm_sample_format_t);
-	int (*stop_playback)(ddf_fun_t *);
+	int (*stop_playback)(ddf_fun_t *, bool);
 	int (*start_capture)(ddf_fun_t *, unsigned,
 	    unsigned, unsigned, pcm_sample_format_t);
-	int (*stop_capture)(ddf_fun_t *);
+	int (*stop_capture)(ddf_fun_t *, bool);
 } audio_pcm_iface_t;
 
Index: uspace/srv/audio/hound/audio_device.c
===================================================================
--- uspace/srv/audio/hound/audio_device.c	(revision ed3816df9c8d9f9483b524e9564aa65c6fb406e4)
+++ uspace/srv/audio/hound/audio_device.c	(revision 92b638c034f15cb008344be39773f82ec6481376)
@@ -112,5 +112,5 @@
 		const unsigned frames = dev->buffer.size /
 		    (BUFFER_PARTS * pcm_format_frame_size(&dev->sink.format));
-		ret = audio_pcm_start_playback(dev->sess, frames,
+		ret = audio_pcm_start_playback_fragment(dev->sess, frames,
 		    dev->sink.format.channels, dev->sink.format.sampling_rate,
 		    dev->sink.format.sample_format);
@@ -155,5 +155,5 @@
 		const unsigned frames = dev->buffer.size /
 		    (BUFFER_PARTS * pcm_format_frame_size(&dev->sink.format));
-		ret = audio_pcm_start_capture(dev->sess, frames,
+		ret = audio_pcm_start_capture_fragment(dev->sess, frames,
 		    dev->sink.format.channels, dev->sink.format.sampling_rate,
 		    dev->sink.format.sample_format);
