Re: [ecasound] lossless conversion broken?

From: Kai Vehmanen <kvehmanen@email-addr-hidden>
Date: Sun Dec 12 2010 - 19:33:44 EET

Hi all,

finally some news about this:

On Wed, 3 Nov 2010, Dan Muresan wrote:
>> So this is basicly the "asymmetric" method in:
>> http://blog.bjornroche.com/2009/12/linearity-and-dynamic-range-in-int.html
>
> I agree with the jackit threads -- introducing a nonlinear
> transformation in a chain is not a good thing (from a signals &
> systems POV). Sounds like 0x8000, symmetrical would be best for the
> future. I assume this breaks existing files, which is why you'd have
> to wait for a major release.

This turned out to be fairly complicated thing to fix/implement, even
after taking another close look at how other projects are handling this.

The 0x8000/2^N conversion seems to be the right thing to do. In practise
it causes tricky complications to the float-to-fixed case. When fed 0dBFS
signals generated in floating point domain (e.g. a full scale sine coming
from another JACK client), scaling with 0x8000 would cause an overflow
(1.0 x 0x8000 -> 32768.0f which doesn't fit a int16_t value).

So what to do? We can't tell JACK clients to use a different 0dbFS point.
This is the reason why libsndfile has different scaling for int-to-float
and float-to-int (which again cause bit errors for fixed-float-fixed
conversion). See:
       http://www.mega-nerd.com/libsndfile/FAQ.html#Q010
.. for the rationale.

What I ended up doing was to scale with 0x8000/2^N always, and
additionally, clip the extreme positive values when converting from float
to fixed (so for 16bit, +1.0f -> 32767). This in practise seems to the
best option overall.

I've now made a fix to the unit tests and another patch to change the
conversion routines to be symmetric (with 2^N scaling).

I just pushed the patches to git master branch, and these will be
in 2.8.0 ecasound release. You can now get some increased verbosity
by running the unit test with:

sh> cd ecasound.git/libecasound
sh> V=1 ./libecasound_tester "Unit test for eca-sample-conversion"

To see the difference, you can run the above with and without the most
recent git commit (that changes the conversion routines). This will show
the issues you've raised with s32-f32 conversion for positive values.

Any comments about the reasoning and/or implementation are much welcome
(preferably now rathar than after 2.8.0 release ;)).

My draft text to release mail is:
--cut--
* The int-float conversion routines have been modified to be symmetric
   (previously asymmetric). As this impacts all use-cases involving fixed
   point audio, the minor version was bumped to reflect the change.
   Ecasound now scales with 2^N for both int-to-float and float-to-int.
   For 0dBFS signals created in floating point domain, and normalized
   to [-1,1] range, the positive values are clipped just before 0dbFS to
   avoid overflow (positive values exceeding 2^N-1).

   Pointers to how other projects handle this issue:
     - Case for symmetric conversions:
       http://lists.apple.com/archives/coreaudio-api/2009/Dec/msg00120.html
     - Blog entry to which the above is a response:
       http://blog.bjornroche.com/2009/12/int-float-int-its-jungle-out-there.html
     - libsndfile FAQ covering the problem:
       http://www.mega-nerd.com/libsndfile/FAQ.html#Q010
     - Discussion around the topic on JACK devel list:
       http://comments.gmane.org/gmane.comp.audio.jackit/20499
--cut--

Thanks Dan and Sergei for reporting the issue!

------------------------------------------------------------------------------
Oracle to DB2 Conversion Guide: Learn learn about native support for PL/SQL,
new data types, scalar functions, improved concurrency, built-in packages,
OCI, SQL*Plus, data movement tools, best practices and more.
http://p.sf.net/sfu/oracle-sfdev2dev
_______________________________________________
Ecasound-list mailing list
Ecasound-list@email-addr-hidden
https://lists.sourceforge.net/lists/listinfo/ecasound-list
Received on Sun Dec 12 20:15:09 2010

This archive was generated by hypermail 2.1.8 : Sun Dec 12 2010 - 20:15:09 EET