Re: endian problems with AIFF and WAV
Erik de Castro Lopo <[email protected]> Thu, 5 Dec 2013 06:28:09 +1100
| Newsgroups | gmane.comp.multimedia.ogg.vorbis.devel |
|---|---|
| Organization | Erik Conspiracy Secret Labs |
| Message-ID | <[email protected]> |
[email protected] 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/