Index: uspace/drv/audio/sb16/dsp.c
===================================================================
--- uspace/drv/audio/sb16/dsp.c	(revision b4970183584d3b011f21b3b9d7baa1d10beca9b6)
+++ uspace/drv/audio/sb16/dsp.c	(revision 57e8b3ba054d7a008b430e7b6b67994b03197240)
@@ -188,13 +188,16 @@
 {
 	assert(dsp);
+	dsp->active.frame_count +=
+	    dsp->active.samples / ((dsp->active.mode & DSP_MODE_STEREO) ? 2 : 1);
+
 	if (dsp->event_exchange) {
 		switch (dsp->status) {
 		case DSP_PLAYBACK:
-			async_msg_0(dsp->event_exchange,
-			    PCM_EVENT_PLAYBACK_DONE);
+			async_msg_1(dsp->event_exchange,
+			    PCM_EVENT_FRAMES_PLAYED, dsp->active.frame_count);
 			break;
 		case DSP_RECORDING:
-			async_msg_0(dsp->event_exchange,
-			    PCM_EVENT_RECORDING_DONE);
+			async_msg_1(dsp->event_exchange,
+			    PCM_EVENT_FRAMES_RECORDED, dsp->active.frame_count);
 			break;
 		default:
@@ -267,5 +270,5 @@
 }
 
-int sb_dsp_start_playback(sb_dsp_t *dsp, unsigned parts,
+int sb_dsp_start_playback(sb_dsp_t *dsp, unsigned frames,
     unsigned channels, unsigned sampling_rate, pcm_sample_format_t format)
 {
@@ -275,13 +278,7 @@
 		return EINVAL;
 
-	/* Play block size must be even number (we use DMA 16)*/
-	if (dsp->buffer.size % (parts * 2))
-		return EINVAL;
-
-	const unsigned play_block_size = dsp->buffer.size / parts;
-
 	/* Check supported parameters */
-	ddf_log_debug("Requested playback (%u parts): %uHz, %s, %u channel(s).",
-	    parts, sampling_rate, pcm_sample_format_str(format), channels);
+	ddf_log_debug("Requested playback: %u frames, %uHz, %s, %u channel(s).",
+	    frames, sampling_rate, pcm_sample_format_str(format), channels);
 	if (channels != 1 && channels != 2)
 		return ENOTSUP;
@@ -311,9 +308,11 @@
 #endif
 
-	dsp->active.mode = 0 |
-	    (sign ? DSP_MODE_SIGNED : 0) | (channels == 2 ? DSP_MODE_STEREO : 0);
+	dsp->active.mode = 0
+	    | (sign ? DSP_MODE_SIGNED : 0)
+	    | (channels == 2 ? DSP_MODE_STEREO : 0);
+	dsp->active.samples = frames * channels;
+	dsp->active.frame_count = 0;
+
 	sb_dsp_write(dsp, dsp->active.mode);
-
-	dsp->active.samples = sample_count(format, play_block_size);
 	sb_dsp_write(dsp, (dsp->active.samples - 1) & 0xff);
 	sb_dsp_write(dsp, (dsp->active.samples - 1) >> 8);
@@ -339,5 +338,5 @@
 }
 
-int sb_dsp_start_record(sb_dsp_t *dsp, unsigned parts,
+int sb_dsp_start_record(sb_dsp_t *dsp, unsigned frames,
     unsigned channels, unsigned sampling_rate, pcm_sample_format_t format)
 {
@@ -347,13 +346,7 @@
 		return EINVAL;
 
-	/* Play block size must be even number (we use DMA 16)*/
-	if (dsp->buffer.size % (parts * 2))
-		return EINVAL;
-
-	const unsigned play_block_size = dsp->buffer.size / parts;
-
 	/* Check supported parameters */
-	ddf_log_debug("Requested record (%u parts): %uHz, %s, %u channel(s).",
-	    parts, sampling_rate, pcm_sample_format_str(format), channels);
+	ddf_log_debug("Requested record: %u frames, %uHz, %s, %u channel(s).",
+	    frames, sampling_rate, pcm_sample_format_str(format), channels);
 	if (channels != 1 && channels != 2)
 		return ENOTSUP;
@@ -384,8 +377,10 @@
 
 	dsp->active.mode = 0 |
-	    (sign ? DSP_MODE_SIGNED : 0) | (channels == 2 ? DSP_MODE_STEREO : 0);
+	    (sign ? DSP_MODE_SIGNED : 0) |
+	    (channels == 2 ? DSP_MODE_STEREO : 0);
+	dsp->active.samples = frames * channels;
+	dsp->active.frame_count = 0;
+
 	sb_dsp_write(dsp, dsp->active.mode);
-
-	dsp->active.samples = sample_count(format, play_block_size);
 	sb_dsp_write(dsp, (dsp->active.samples - 1) & 0xff);
 	sb_dsp_write(dsp, (dsp->active.samples - 1) >> 8);
Index: uspace/drv/audio/sb16/dsp.h
===================================================================
--- uspace/drv/audio/sb16/dsp.h	(revision b4970183584d3b011f21b3b9d7baa1d10beca9b6)
+++ uspace/drv/audio/sb16/dsp.h	(revision 57e8b3ba054d7a008b430e7b6b67994b03197240)
@@ -57,4 +57,5 @@
 		uint8_t mode;
 		uint16_t samples;
+		unsigned frame_count;
 	} active;
 	enum {
@@ -75,8 +76,8 @@
 int sb_dsp_set_event_session(sb_dsp_t *dsp, async_sess_t *session);
 int sb_dsp_release_buffer(sb_dsp_t *dsp);
-int sb_dsp_start_playback(sb_dsp_t *dsp, unsigned parts,
+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_start_record(sb_dsp_t *dsp, unsigned parts,
+int sb_dsp_start_record(sb_dsp_t *dsp, unsigned frames,
     unsigned channels, unsigned sample_rate, pcm_sample_format_t format);
 int sb_dsp_stop_record(sb_dsp_t *dsp);
Index: uspace/drv/audio/sb16/pcm_iface.c
===================================================================
--- uspace/drv/audio/sb16/pcm_iface.c	(revision b4970183584d3b011f21b3b9d7baa1d10beca9b6)
+++ uspace/drv/audio/sb16/pcm_iface.c	(revision 57e8b3ba054d7a008b430e7b6b67994b03197240)
@@ -70,5 +70,5 @@
 }
 
-static int sb_start_playback(ddf_fun_t *fun, unsigned parts,
+static int sb_start_playback(ddf_fun_t *fun, unsigned frames,
     unsigned channels, unsigned sample_rate, pcm_sample_format_t format)
 {
@@ -77,5 +77,5 @@
 	sb_dsp_t *dsp = fun->driver_data;
 	return sb_dsp_start_playback(
-	    dsp, parts, channels, sample_rate, format);
+	    dsp, frames, channels, sample_rate, format);
 }
 
@@ -88,5 +88,5 @@
 }
 
-static int sb_start_record(ddf_fun_t *fun, unsigned parts,
+static int sb_start_record(ddf_fun_t *fun, unsigned frames,
     unsigned channels, unsigned sample_rate, pcm_sample_format_t format)
 {
@@ -95,5 +95,5 @@
 	sb_dsp_t *dsp = fun->driver_data;
 	return sb_dsp_start_record(
-	    dsp, parts, channels, sample_rate, format);
+	    dsp, frames, channels, sample_rate, format);
 }
 
