Index: uspace/lib/riff/src/chunk.c
===================================================================
--- uspace/lib/riff/src/chunk.c	(revision 57d923e19864415b1436334a3232fabd0f3f23da)
+++ uspace/lib/riff/src/chunk.c	(revision 266ec54acdd67b4f0e7d168c473eb06cef24b0c7)
@@ -213,4 +213,6 @@
 	}
 
+	rr->pos = 0;
+
 	rr->f = fopen(fname, "rb");
 	if (rr->f == NULL) {
@@ -302,14 +304,7 @@
 {
 	errno_t rc;
-	long pos;
-
-	pos = ftell(parent->riffr->f);
-	if (pos < 0) {
-		rc = EIO;
-		goto error;
-	}
 
 	rchunk->riffr = parent->riffr;
-	rchunk->ckstart = pos + 8;
+	rchunk->ckstart = parent->riffr->pos + 8;
 	rc = riff_read_uint32(parent, &rchunk->ckid);
 	if (rc != EOK)
@@ -402,5 +397,4 @@
 errno_t riff_rchunk_seek(riff_rchunk_t *rchunk, long offset, int whence)
 {
-	long pos;
 	long dest;
 	int rv;
@@ -414,8 +408,5 @@
 		break;
 	case SEEK_CUR:
-		pos = ftell(rchunk->riffr->f);
-		if (pos < 0)
-			return EIO;
-		dest = pos + offset;
+		dest = rchunk->riffr->pos + offset;
 		break;
 	default:
@@ -432,4 +423,5 @@
 		return EIO;
 
+	rchunk->riffr->pos = dest;
 	return EOK;
 }
@@ -482,8 +474,27 @@
 {
 	long ckend;
+	uint8_t byte;
+	size_t nread;
+	errno_t rc;
 
 	ckend = riff_rchunk_get_ndpos(rchunk);
-	if (fseek(rchunk->riffr->f, ckend, SEEK_SET) < 0)
-		return EIO;
+	if (rchunk->riffr->pos < ckend &&
+	    ckend <= rchunk->riffr->pos + 512) {
+		/* (Buffered) reading is faster than seeking */
+		while (rchunk->riffr->pos < ckend) {
+			rc = riff_read(rchunk, &byte, sizeof(byte), &nread);
+			if (rc != EOK)
+				return rc;
+
+			if (nread != sizeof(byte))
+				return EIO;
+		}
+
+	} else if (rchunk->riffr->pos != ckend) {
+		/* Need to seek (backwards or too far) */
+		if (fseek(rchunk->riffr->f, ckend, SEEK_SET) < 0)
+			return EIO;
+		rchunk->riffr->pos = ckend;
+	}
 
 	return EOK;
@@ -511,7 +522,5 @@
 	long toread;
 
-	pos = ftell(rchunk->riffr->f);
-	if (pos < 0)
-		return EIO;
+	pos = rchunk->riffr->pos;
 
 	ckend = riff_rchunk_get_end(rchunk);
@@ -529,4 +538,5 @@
 		return EIO;
 
+	rchunk->riffr->pos += *nread;
 	return EOK;
 }
