[Vorbis-dev] endian problems with AIFF and WAV

Erik de Castro Lopo mle+la at mega-nerd.com
Wed Dec 4 11:28:09 PST 2013


dave at 661.org wrote:

> I have a test program that loads an AIFF or WAV file with libsndfile and 
> plays then using libao.  After running around in circles for a while, I 
> found and fixed the problem, but I'm still confused as to why the solution 
> works.  Would someone please explain this to me so I don't trip over this 
> again later in my project?
> 
> I used sf_open_fd() to get a SNDFILE* pointer and an AF_INFO struct.  In 
> that struct I find out what bit resolution the samples are.  I put that 
> number into ao_sample_format format.bits, fill a buffer using 
> sf_read_int() and then call ao_play().  Doing this with a file containing 
> 8-bit samples, the result was the file playing at at half-pitch and twice 
> as long as normal.  But, if I manually plug in format.bits = 32, the files 
> play fine.

I suggest you read the libsndfile documentation here:

    http://www.mega-nerd.com/libsndfile/api.html

taking specific note of this paragraph:


    During read and write operations, formats are seamlessly converted
    between the format the application program has requested or supplied
    and the file's data format. The application programmer can remain
    blissfully unaware of issues such as file endian-ness and data format.

It means that regardless of what the data format is in the actual file,
when you read the file using sf_read_int() you get CPU native ints.

>      if ((sf_info.format & SF_ENDIAN_LITTLE) == SF_ENDIAN_LITTLE) format.byte_format = AO_FMT_LITTLE;
>      if ((sf_info.format & SF_ENDIAN_BIG) == SF_ENDIAN_BIG) format.byte_format = AO_FMT_BIG;
>      if ((sf_info.format & SF_FORMAT_PCM_S8) == SF_FORMAT_PCM_S8) format.bits = 8;
>      if ((sf_info.format & SF_FORMAT_PCM_16) == SF_FORMAT_PCM_16) format.bits = 16;
>      if ((sf_info.format & SF_FORMAT_PCM_24) == SF_FORMAT_PCM_24) format.bits = 24;
>      if ((sf_info.format & SF_FORMAT_PCM_32) == SF_FORMAT_PCM_32) format.bits = 32;
>      if ((sf_info.format & SF_FORMAT_PCM_U8) == SF_FORMAT_PCM_U8) format.bits = 8;

All of the above is wrong. If you are using sf_read_int() this should be:

     format.byte_format = AO_FMT_NATIVE
     format.bits = 32;

and if you read sf_read_short() it should be:

     format.byte_format = AO_FMT_NATIVE
     format.bits = 16;

Erik
-- 
----------------------------------------------------------------------
Erik de Castro Lopo
http://www.mega-nerd.com/


More information about the Vorbis-dev mailing list