Update to Speex

Jean-Marc Valin jean-marc.valin at usherbrooke.ca
Tue Mar 18 21:26:11 UTC 2008


> If the last 'official' release had been 1.0, which is what I understood
> you were 'guaranteeing' compatibility with, then indeed 1.0 -> 1.2.0
> (or whatever beta release we decide before then) would not require an
> soname change, as things built with libspeex.so.1 (1.0) will always work
> perfectly if the system suddenly gives them libspeex.so.1 (1.2).

That's indeed the case. I've been using the Linux version numbering
scheme, so 1.0 was the stable branch and 1.1.x was the unstable branch.
I still encouraged people to use the codec from 1.1.x because 1) it was
API/ABI compatible with 1.0 and 2) The code was much better.

> In that situation, the problem would have been a social one, you had not
> promised compatibility for 1.1 users, so any promises we made when
> distributing it are our obligation to honour.  We'd have dug a hole it
> was entirely our problem to get out of.

I never promised compatibility for 1.1 users for anything else than the
codec part. So I don't see any problem here.

> As I understand it now though, the promise was a bit more complex.
> You were promising libspeex 1.1+ as better and compatible, but there
> were extra bits included in it, where all bets were still off as to
> what might have to change in them.

More or less correct. Considering that I broke the "new stuff" so many
times in 1.1.x, nobody could ever have assumed it was supposed to be
stable. Plus, if you look at all the versions debian included in 1.1.x,
you'll see that you already broke that stuff several times.

> I think that is where this first became a technical problem.  And why
> I'm not sure a purely social answer is the best one to choose.
> 
> 
> Assuming conservatively, that everyone who used the extra bits
> understood perfectly what they were getting into by doing that:
> still the only way to use them for some time was to link with
> libspeex.so.1.

And most of them would actually include their own copy exactly because
it was breaking far too often.

> We now have some number of applications in the wild, with naive users
> happily using them.  When libspeex was updated in the past, all users
> of the stable api had no problems at all.  Some of the dsp users had
> a few problems that went away with a rebuild or a patch from upstream.
> But even the latter was a dice roll, many of them probably had no
> problems either, because the bits you were still changing were the
> most bleeding edge and they weren't using those yet anyway ...
> 
> At least that's how I surmise we've heard little about this to date.

But now that I've split the libraries, at least the problem won't be
subtle. *Regardless* of what we do with the soname, the users of the dsp
stuff as included from previous versions will get an error at start
time. If we bump the soname, they'll get "can't find libspeex", while if
we don't bump the soname, we'll get "unresolved symbols". The first is
slightly better, but not worth annoying all the *other* users, who are
just using libspeex and who would see things breaking for no reason.

> 
> What will happen when we split speexdsp out though is a bit different.
> All of those applications are now guaranteed to break.  Worst of all,
> with lazy linking, they might not break until some point well into the
> running when the missing feature is actually used -- at which point
> the whole application will ungracefully die.

Most will have non-lazy linking as my experience goes.

> Worse than that, we're not really sure which (of many) applications
> is going to fall into which camp yet.  And without quite a bit of
> analysis, we may not know until people's apps crash which ones we
> had missed.  Knowing which aren't affected becomes a bit like the
> halting problem, though it does have a rough bound.

Well if we bump the soname, we break *everything*. Not really any
better. Plus it should be fairly easy to see if something uses the dsp
stuff. Not that many do anyway (any even less actually know how to use
it properly!).

> The only reliable fix for this again becomes a social problem ...
> Every maintainer of a dependent package needs to rebuild their code
> with the new libspeex and -z defs, fix and re-upload any that break.

Well, the code will simply not link if they don't link with libspeexdsp.
Period.

> The downside of that means that from the time we upload the new
> libspeex to the time that all the affected packages are fixed,
> they are all immediately broken for all users.

I don't see why you can't fix everything in one go.

> I think using the technical solution is superior in this case,
> because we can effect the same transition without any interruption
> to the existing users at all.

I think you're assuming that the "new stuff" was ever stable before. It
was not. These changes happened between ever single 1.1.x version
shipped with and it didn't cause any riots. I know that Debian shipped
with at least 1.1.6, 1.1.10, 1.1.11, and 1.1.12. All of these were
totally incompatible when it came to the API of the DSP stuff. At least
now that we switch to two different libs, and break won't be subtle as
it would have been for the previous changes.

> If the soname were bumped, in line with the strict interpretation
> that public symbols have been removed from the library (the library
> does not know about the social contract you placed on some of them),
> then rather than forcing an all or nothing transition, we get a nice
> buffer, where old things work for as long as they need to, and
> everything gets updated to the newer version in its own good time.

But we annoy the hell out of everyone that actually understood that the
new stuff wasn't stable. i.e. we annoy the ones who do it right so that
we can annoy the others slightly less.

> libspeex2 will become the default, so as people upload new versions
> of their apps, they will have been fixed however they need to be.
> All the end user sees is one day their app gets updated, at no point
> it is ever broken because "nobody has updated it yet for the speex
> transition" ...

Whatever you do, do *NOT* call this libspeex2. I'll start getting lots
of emails asking what the hell libspeex2 is, why they only see version
1.2, and whether version 2 is compatible, ...

> Do you have a scenario where things do break unnecessarily if we
> bump the soname?  The only real downside I see is that apps which
> could automatically get the new lib won't get it until they are
> next rebuilt? 

Well, it would definitely make dependencies easier.

> Obviously we don't want to force that on people
> any more than ever necessary, but compared to the 'big bang' type
> transition, the cost does not seem high.

Note that the 'big bang' has happened (in a worse form than this)
before. Nobody died and you don't even seem to remember people complaining.

> The big unknown here though is still how big will the bang actually
> be in this case ...  a whimper we could suffer, but if we light the
> fuse blind, it may be bigger than we are hoping for.

Not really bad.

>>>   +#define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0}
>> The extra zeros just prevent something from being left uninitialised.
> 
> Cool.  If the size of the struct didn't change, that's fine.  It's just
> another thing they won't get the fix for until they recompile ;)

The size of the struct indeed did not change. At least it's in stereo,
which very few people use with Speex (for good reason -- it sucks).

> It's the already existing binaries that are the problem, they may link
> to the new lib and start up fine, only to crash 'mysteriously' later
> when the lazy linker goes looking for a speexdsp symbol.

Few libraries link with Speex *and* use the DSP stuff. The only one I'm
aware of is OPAL (and it doesn't use the DSP functions properly anyway
-- though that's besides the point).

> For any package that we could identify in advance, such as ekiga,
> we would have to make the libspeex1 (1.2beta3) package (and all
> future libspeex packages for at least two debian releases ... )
> conflict with ekiga <= $whatever_version_its_at_now.
> 
> That way the build of ekiga that cannot work with the replacement
> libspeex.so.1 will be forced off the system when speex 1.2beta3 +
> are installed.
> 
> If the user wants to keep ekiga they will either need to keep the
> old libspeex instead, or wait until a new version of ekiga is
> uploaded that does work with the new libspeex.
> 
> lather, rinse, repeat for any other apps that are reported to break.
> 
> It's usually an iterative process, that feeds off of users getting
> burned and reporting it, so we like to avoid this one where we can.

I think Ekiga is the main one here. The only apps that would use it are
the VoIP ones and even then only a few do. Might want to check wengo,
but I don't think they do.

> I think what is different is that the earlier changes rolled the dice
> and won, either nobody else noticed them at all, or they noticed them,
> remembered what you'd told them, fixed whatever broke and moved on.
> 
> This time, everyone is sure to notice.  They still may not grumble,
> but some otherwise innocent users are almost surely going to get
> caught up in the flak.  We've changed the equation from slim chance
> it will break something, to certainty it will break everything that
> currently touches speexdsp.

Why are people more likely to notice now. In the previous cases, it was
even worse because I might have added a single parameter and the app
would do all kinds of silly things before crashing and the user would
have no idea what the hell's going on (yes, Ekiga ships with the DSP
stuff enabled by default).

> If you still think that with all the above taken into account,
> then we'll call that final.  Whichever way it goes, we'll all
> learn something from how it unfolds  ;)

Yes, I still think that.
>> The resampler in beta2 was definitely broken, badly. It would produce
>> bad quality output in many cases and would crash in some corner cases.
> 
> Ahh, bad output I could have missed, up to this point I've largely been
> feeding pure tones through it and I don't expect them to perform well,
> it's not really what you're optimising for.  They were just good for
> spotting the sort of things I was looking for at the time.
> 
> The fidelity degraded heavily on some of those in 1.2beta2 relative
> to whatever I was using prior to that (probably 1.1.12?) -- if that
> shouldn't be, let me know and I'll dig up a test case.

The resampler's first release was in 1.2beta2. I hadn't even started it
when I released beta1. The problem is that I broke it just before
releasing beta2. The problem was quality degradation, but it only
happened for "simple" conversion ratios (e.g. 16kHz to 48kHz), but not
for complicated ones (e.g. 44.1 -> 48) that were using a different path.

>>> I guess with 20/20 hindsight libspeexdsp.so.0 might have been a better
>>> starting point, but the numbers themselves aren't particularly important
>>> so the law of least surprise would favour libspeexdsp1 for beta3.  The
>>> vast majority of users will expect libspeexdsp.so.1 to be provided by
>>> that, and a good number of them will get confused if its not.
>> The idea is that libspeexdsp.so.0 would be beta3 (or whatever). Then,
>> when 1.2 is released, we can have both libspeexdsp1 and libspeex1 to
>> make things less confusing.
> 
> If there really will be only one more API change (is there definitely
> at least one you have planned), that probably would make some sense,
> but it will diverge the first time either of them ever does change
> in future, and that might make it even more confusing again.

The plan so far is to have one last change. It might even be
backward-compatible, but I can't promise that (unlikely, but possible).

>> The current code is not very different from beta3 actually. You could
>> pretty much ship it as a bugfix version of beta3... or wait for the next
>> release.
> 
> Cool, I'll get beta3 ready to go, then we'll have another look at
> how the big picture is shaping up from there.  If you have a known
> api change coming in the pipeline as a certainty, we'll probably
> want to factor the anticipated timing of that into what we upload
> where and when.

If you want mumble to work, you'll need the current svn, which is pretty
much like beta3 except for the stuff that makes Mumble work.

>> 2) Documentation
> 
> Someone more concise than me please ? ;)

Well, I always get told I'm too concise!

>> 3) Need to convert the AGC to fixed-point
> 
> hrm...  its just one tiny little function...  but with some
> nasty, nasty, operations for fixed-point.  Do you really want
> to convert this, or is there some better algorithm we should be
> looking at for fixed-point AGC ?
> 
> ... after hrm'ing some more, I'll get back to you on this one,
> I need to rummage around in some old code first ...

Yes, I still want it converted. I think it might require the
pseudo-float code I wrote. I also already have approximations for exp()
and log(), which should make things easier.

>> 4) Need to put back a decent VAD.
> 
> We might have to define 'decent' before I can decide if I'll
> be of any help there ;-)

Well, I had one that sort of worked and that I had to remove. The
solutions are to either:
1) Being back the old one and convert it to fixed-point
2) Write one based on the same principles, but less messy

	Jean-Marc



More information about the Pkg-voip-maintainers mailing list