Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#4426 closed defect (invalid)

RIFF WAVE 24-bit WAVE_FORMAT_PCM files are not properly supported

Reported by: rsn10100 Owned by:
Priority: normal Component: ffmpeg
Version: unspecified Keywords: wav
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:
When converting 24-bit audio to a wav format it is down converted to 16-bit by default. You can force to output a WAVEFORMATEXTENSIBLE format with -acodec pcm_s24le but some older software does not support the extensible format.

I believe this down conversion is being done because of a rumor that the original spec did not allow for 24-bit files. I have looked through the August 1991 specification and although it never specifically mentions 24-bit it does state the following:

Each sample is contained in an integer i. The size of i is the smallest number of bytes required to contain the specified sample size.

It goes on and then gives a few examples, one of which mentions a WAVE_FORMAT_PCM 20-bit format.

Example of a PCM WAVE file with 44.1 kHz sampling rate, mono, 20 bits per sample:

RIFF( 'WAVE' INFO(INAM("O Canada"Z))
fmt(1, 1, 44100, 132300, 3, 20)
data( <wave-data> ) )

That is a WAVE_FORMAT_PCM(0x0001), 1 channel, 44.1KHz, 132300 bytes per second, 3 bytes per sample, 24-bit wave file with 20 valid bits...

This would indicate that 24-bit WAVE_FORMAT_PCM files are supported by the format and should be valid in conversions. Many applications also encode and decode this format, which is why I'm filing a bug here.

Source: http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf

The expected result: A 24-bit WAVE_FORMAT_PCM file should be created by default when the input format is 24-bit and the output format is wav.

How to reproduce:

% ffmpeg -f s24le -ar 44100 -ac 1 -i in.pcm out.wav
ffmpeg version N-71209-gd759844 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 4.9.2 (GCC)
  configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib}}}

Change History (5)

comment:1 Changed 5 years ago by heleppkes

WAVEFORMATEX is a Microsoft format, and they clearly define that bits per sample is only allowed to be 8 or 16 with WAVE_FORMAT_PCM, and only with WAVE_FORMAT_EXTENSIBLE higher bit depths are allowed. See https://msdn.microsoft.com/en-us/library/windows/desktop/dd390970(v=vs.85).aspx

FFmpeg should not be creating out of spec files, even if some occasional software can read it.
Just because a 24 year old spec once potentially allowed it doesn't mean that the spec wasn't refined later. Always go by the current active spec, not a long out-of-date and hundred times revised version.

Last edited 5 years ago by heleppkes (previous) (diff)

comment:2 in reply to: ↑ description Changed 5 years ago by cehoyos

  • Component changed from undetermined to ffmpeg
  • Keywords WAVEFORMATEX WAVE_FORMAT_PCM output 24bit removed
  • Resolution set to invalid
  • Status changed from new to closed

Replying to rsn10100:

When converting 24-bit audio to a wav format it is down converted to 16-bit by default.

Only if you requested encoding but did not specify an encoder.

I believe this down conversion is being done because of a rumor that the original spec did not allow for 24-bit files.

No, this is not the reason.
For every output format, a default codec is chosen for each supported codec_type if no codec was explicitely specified: For format wav and codec_type audio this is pcm_s16le.
So far, the developers have resisted to implement a heuristic that would change the behaviour for limited use. Note that such a change would not work for library users and would make the default behaviour for libary users and users of the ffmpeg application different.

comment:3 Changed 5 years ago by rsn10100

  • Component changed from ffmpeg to undetermined
  • Keywords WAVEFORMATEX WAVE_FORMAT_PCM output 24bit added

Ok, so the format picks its own default value when one is not specified? That's new information to me.

Well, you're right about WAVEFORMATEX. It is WAVEFORMATEX that does not support anything other then 8 or 16 bits. However, PCMWAVEFORMAT still does and is supported even though the structure has been superseded by WAVEFORMATEX.

https://msdn.microsoft.com/en-us/library/dd743663(v=vs.85).aspx

All wav files still using PCMWAVEFORMAT are still valid and supported with any number of channels in Windows and many applications. I believe PCMWAVEFORMAT should be the default PCM integer format for wav files when the number of channels is 1 or 2 regardless of the number of sample bits in the stream. You may disagree, but 24 years of files and software written in this way makes it an issue of backward compatibility. I see no reason that 1 and 2 channel 24-bit and 32-bit WAVE_FORMAT_PCM files can't be written using PCMWAVEFORMAT as they have been for more than 20 years.

comment:4 Changed 5 years ago by heleppkes

A modern software should not write a structure thats officially deprecated.

Version 0, edited 5 years ago by heleppkes (next)

comment:5 Changed 5 years ago by cehoyos

  • Component changed from undetermined to ffmpeg
  • Keywords WAVEFORMATEX WAVE_FORMAT_PCM output 24bit removed
Note: See TracTickets for help on using tickets.