[codec] Alternative CELT implementation

"Timothy B. Terriberry" <tterribe@xiph.org> Fri, 11 February 2011 05:21 UTC

Return-Path: <tterribe@xiph.org>
X-Original-To: codec@core3.amsl.com
Delivered-To: codec@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 88F3D3A6867 for <codec@core3.amsl.com>; Thu, 10 Feb 2011 21:21:16 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.599
X-Spam-Level:
X-Spam-Status: No, score=-2.599 tagged_above=-999 required=5 tests=[BAYES_00=-2.599]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id iseBgM-SYwxC for <codec@core3.amsl.com>; Thu, 10 Feb 2011 21:21:08 -0800 (PST)
Received: from mxip1i.isis.unc.edu (mxip1i.isis.unc.edu [152.2.0.74]) by core3.amsl.com (Postfix) with ESMTP id 35D343A6848 for <codec@ietf.org>; Thu, 10 Feb 2011 21:21:07 -0800 (PST)
X-IronPort-Anti-Spam-Filtered: true
X-IronPort-Anti-Spam-Result: ApwEAIJWVE2sGgRS/2dsb2JhbACEHaJLqxyQLoEngz92BIUBhnuDJgw
X-IronPort-AV: E=Sophos;i="4.60,453,1291611600"; d="scan'208";a="74222868"
Received: from mr1a.isis.unc.edu (HELO smtp.unc.edu) ([172.26.4.82]) by mxip1o.isis.unc.edu with ESMTP; 11 Feb 2011 00:21:21 -0500
X-UNC-Auth-As: tterribe
X-UNC-Auth-IP: 71.198.47.72
Received: from [172.17.0.5] ([71.198.47.72]) (authenticated bits=0) by smtp.unc.edu (8.14.4/8.14.3) with ESMTP id p1B5LGTM013908 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for <codec@ietf.org>; Fri, 11 Feb 2011 00:21:21 -0500 (EST)
Message-ID: <4D54C74C.5000903@xiph.org>
Date: Thu, 10 Feb 2011 21:21:16 -0800
From: "Timothy B. Terriberry" <tterribe@xiph.org>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.15) Gecko/20101120 Gentoo/2.0.10 SeaMonkey/2.0.10
MIME-Version: 1.0
To: codec@ietf.org
Content-Type: text/plain; charset="UTF-8"; format="flowed"
Content-Transfer-Encoding: 7bit
Subject: [codec] Alternative CELT implementation
X-BeenThere: codec@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: Codec WG <codec.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/codec>, <mailto:codec-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/codec>
List-Post: <mailto:codec@ietf.org>
List-Help: <mailto:codec-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/codec>, <mailto:codec-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 11 Feb 2011 05:21:16 -0000

As part of the development leading up to the latest milestone, I wrote 
an "independent" implementation of libcelt (at least, as independent as 
I could be as one of the original authors of libcelt). It can be 
obtained here:

http://people.xiph.org/~tterribe/celt/celtdec-0.008.tar.gz

I tried to make as many implementation choices differently from libcelt 
as possible, and strove for simplicity where I could. For example, PVQ 
decoding uses 5kB of ROM and just 17 lines of code (compared to over 700 
lines of code in libcelt's cwrs.c, though in libcelt's defense that does 
encoding, too). The range coder implements all of its specialized 
versions by calling the general-purpose functions, even though this 
costs more CPU. libcelt's enormous quant_band() has been implemented 
instead with no less than 5 different functions, with (what I think) is 
a much clearer control flow (only one of those five is recursive!). The 
calculations needed for folding are done (as much as they can be) 
just-in-time, instead of just-in-case, etc., etc. Some code still 
parallels libcelt very closely (such as the general-purpose range coder 
functions), but this is because doing so is basically required by the 
bitstream. In some places libcelt has been brought _more_ in-line with 
this code since I started writing it, so they are not as different as 
they originally were (see libcelt commit a093f4df from last Thursday).

This code only supports the standard Opus modes, though it could be made 
to support custom modes by adding static definitions for them 
(on-the-fly mode creation is not supported), but it does not support 
resampling. It does not implement any form of PLC (as I understand it, 
this is not required). It currently supports CELT only, and the 
simplistic test driver does not parse the Opus packet header (in fact, 
it requires raw, CBR CELT data, as it does not parse any kind of packet 
sizes at all). This will likely change at some point in the future. This 
effort has been invaluable in uncovering issues with both the libcelt 
code and the bitstream, but it is definitely only for tinkerers at the 
moment. There is no build system: just compile all the .c files.

Some numbers: sloccount claims there are 3,115 lines of code, though wc 
-l gives exactly 4,000. Running size on a 32-bit x86 executable 
optimized for space gives just under 36 kB (the actual file is 42 kB). 
It decodes to within +/-1 of libcelt on every sample I've tried. It 
passes Jean-Marc's compliance test, with far fewer differences than the 
fixed-point version (and in fact helped uncover some divide by zero 
issues in the test, for files with no errors over the threshold), though 
I have only checked a few files, since we do not have a formal set of 
test streams yet. The effort took about 2 weeks from initial code to 
first working version, though more effort has been expended to keep up 
with recent changes in libcelt (indeed, it was driving many of them).

Anyway, if anyone plays around with it and finds anything interesting, 
let me know.