[Flac-dev] libFLAC bitbuffer optimizations

Eric Wong eric at petta-tech.com
Tue Dec 28 02:30:00 PST 2004

Pulled from my Arch archive, this following patch seems to have made
quite a difference in getting my ARM7TDMI chip to play FLAC (compression
levels 0-2) on my ipod.  I don't have benchmarks with hard numbers, but
playing with skips vs playing without skips is a fairly noticeable

memcpy and memset on uClibc are optimized in asm for the ARM7TDMI in
uClibc. Other hardware/libc combinations may not benefit as much, but
most C libraries should have optimized versions of these functions.

I'm also using Miroslav Lichvar's patch from Jan/Feb 2003 (that was
posted here), which I retrieved and hand-merged from the archives.  I
made a few minor changes to that, too, and managed to reduce it by a few
ops (nothing major).  I can repost both his patch and mine on top of it,

I also have some alternate lpc_restore_signal implementations (in C) I
can extract and post (don't really have a clean changeset), but I
haven't been able to get lpc-enabled FLACs to play at normal speeds,
yet.  I'll try to find some time in the next few months and learn enough
asm tricks to make this one faster for the ARM.  Help would be greatly
appreciated.  Right now I'm just looking at compiler output in asm, and
counting ops (especially branch calls).

Anyways, here goes the patch I described in my first paragraph:

* added files

    {arch}/flac/flac--ipod/flac--ipod--1.1.0/eric at petta-tech.com--2004b-ordinary/patch-log/patch-27

* modified files

--- orig/src/libFLAC/bitbuffer.c
+++ mod/src/libFLAC/bitbuffer.c
@@ -233,11 +233,26 @@
 	/* first shift the unconsumed buffer data toward the front as much as possible */
 	if(bb->total_consumed_bits >= FLAC__BITS_PER_BLURB) {
+		/*
+		 * memset and memcpy are usually implemented in assembly language
+		 * by the system libc, and they can be much faster
+		 */
+		unsigned r_end = (bb->blurbs + (bb->bits? 1:0)),
+		         r = bb->consumed_blurbs, l = r_end - r;
+		FLAC__blurb * rbuffer = &bb->buffer[r];
+		memcpy(&bb->buffer[0], rbuffer, r_end/4 + r_end%4);
+		memset(++rbuffer, 0, l/4 + l%4);
+#elif FLAC__BITS_PER_BLURB == 32
+		/* the original version */
 		unsigned l = 0, r = bb->consumed_blurbs, r_end = bb->blurbs + (bb->bits? 1:0);
 		for( ; r < r_end; l++, r++)
 			bb->buffer[l] = bb->buffer[r];
 		for( ; l < r_end; l++)
 			bb->buffer[l] = 0;
+	FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
+#endif /* FLAC__BITS_PER_BLURB == 32 or 8 */
 		bb->blurbs -= bb->consumed_blurbs;
 		bb->total_bits -= FLAC__BLURBS_TO_BITS(bb->consumed_blurbs);
 		bb->consumed_blurbs = 0;

Eric Wong / normalperson on freenode
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.xiph.org/pipermail/flac-dev/attachments/20041228/5e3896e1/attachment.pgp

More information about the Flac-dev mailing list