Skip to content

GH-60729: Add IEEE format wave audio support#145384

Open
mbeijen wants to merge 8 commits intopython:mainfrom
mbeijen:GH-60729-add-ieee-wave-audio-support
Open

GH-60729: Add IEEE format wave audio support#145384
mbeijen wants to merge 8 commits intopython:mainfrom
mbeijen:GH-60729-add-ieee-wave-audio-support

Conversation

@mbeijen
Copy link
Contributor

@mbeijen mbeijen commented Mar 1, 2026

This is an updated version of #102574, the original PR where @lkoenig added support for IEEE Wave Audio.

As requested by @encukou

I've

  • Renamed the new 'getencoding/setencoding' to 'getformat/setformat' - format is the term used in the specifications
  • Added format to getparams
  • Added FACT chunk to written non-PCM wave files, which is required by the spec (and is what Audacity does)
  • Added documentation!

Closes: #102574


📚 Documentation preview 📚: https://cpython-previews--145384.org.readthedocs.build/

lkoenig and others added 5 commits March 1, 2026 09:54
This adds support for floating point wav files and fix python#60729.
'format' is the term used in the wave audio specification
Per the RIFF/WAVE Rev. 3 documentation, non-PCM formats require a fact chunk, while PCM does not.
This is also what libsdnfile/audacity do

Reference: https://mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html (see the 'fact Chunk' section and linked Rev. 3 RIFF docs).
These methods are public but were previously not documented. This caused
the unit tests to fail when I mentioned changes to getparams() in the
whats new ;-)
@mbeijen mbeijen requested a review from aisk March 1, 2026 15:49
Copy link

@lkoenig lkoenig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pushing that forward.

Copy link
Member

@encukou encukou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the PR!
I didn't finish reviewing today; sending the comments I have.

Comment on lines +110 to +111
This is one of ``WAVE_FORMAT_PCM``, ``WAVE_FORMAT_IEEE_FLOAT``, or
``WAVE_FORMAT_EXTENSIBLE``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you document these using .. data::, and link to them using :data:?

Comment on lines +128 to +129
framerate, nframes, comptype, compname, format)``, equivalent to output
of the ``get*()`` methods.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a backwards-incompatible change: before someone could write:

    nc, sw, fr, nf, ct, cn = wav.getparams()

This could be solved by adding format as a named-only attribute (which, unfortunately, isn't easy with namedtuple), or maybe an argument to getparams.
You might want to leave getparams alone for now & tackle this in a focused follow-up PR.

Comment on lines +197 to +199
.. method:: getnchannels()

Return the number of channels.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind sending docs for existing methods in a separate PR, so they can be backported separately?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I just did that in #145451

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!
Please merge (don't rebase) the main branch; pushing a rebase tends to mess PRs up.

class MiscTestCase(unittest.TestCase):
def test__all__(self):
not_exported = {'WAVE_FORMAT_PCM', 'WAVE_FORMAT_EXTENSIBLE', 'KSDATAFORMAT_SUBTYPE_PCM'}
not_exported = {'WAVE_FORMAT_PCM', 'WAVE_FORMAT_IEEE_FLOAT', 'WAVE_FORMAT_EXTENSIBLE', 'KSDATAFORMAT_SUBTYPE_PCM'}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please export the WAVE_FORMAT_ ones (add to __all__) instead, and remove them here.
No point in hiding them; they're needed for documented functionality.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I'd keep KSDATAFORMAT_SUBTYPE_PCM hidden until it's documented; that seems out of scope for this PR.)

Comment on lines +650 to +653
try:
self._fact_sample_count_pos = self._file.tell()
except (AttributeError, OSError):
self._fact_sample_count_pos = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, what's the story about supporting files without tell?

Co-authored-by: Petr Viktorin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants