Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Doc/c-api/bytes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -371,13 +371,17 @@ Getters
Get the writer size.
The function cannot fail.
.. c:function:: void* PyBytesWriter_GetData(PyBytesWriter *writer)
Get the writer data: start of the internal buffer.
The pointer is valid until :c:func:`PyBytesWriter_Finish` or
:c:func:`PyBytesWriter_Discard` is called on *writer*.
The function cannot fail.
Low-level API
^^^^^^^^^^^^^
Expand Down
69 changes: 7 additions & 62 deletions Doc/library/wave.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,14 @@
--------------

The :mod:`!wave` module provides a convenient interface to the Waveform Audio
"WAVE" (or "WAV") file format.

The module supports uncompressed PCM and IEEE floating-point WAV formats.
"WAVE" (or "WAV") file format. Only uncompressed PCM encoded wave files are
supported.

.. versionchanged:: 3.12

Support for ``WAVE_FORMAT_EXTENSIBLE`` headers was added, provided that the
extended format is ``KSDATAFORMAT_SUBTYPE_PCM``.

.. versionchanged:: next

Support for reading and writing ``WAVE_FORMAT_IEEE_FLOAT`` files was added.

The :mod:`!wave` module defines the following function and exception:


Expand Down Expand Up @@ -65,21 +60,6 @@ The :mod:`!wave` module defines the following function and exception:
specification or hits an implementation deficiency.


.. data:: WAVE_FORMAT_PCM

Format code for uncompressed PCM audio.


.. data:: WAVE_FORMAT_IEEE_FLOAT

Format code for IEEE floating-point audio.


.. data:: WAVE_FORMAT_EXTENSIBLE

Format code for WAVE extensible headers.


.. _wave-read-objects:

Wave_read Objects
Expand Down Expand Up @@ -118,14 +98,6 @@ Wave_read Objects
Returns number of audio frames.


.. method:: getformat()

Returns the frame format code.

This is one of :data:`WAVE_FORMAT_PCM`,
:data:`WAVE_FORMAT_IEEE_FLOAT`, or :data:`WAVE_FORMAT_EXTENSIBLE`.


.. method:: getcomptype()

Returns compression type (``'NONE'`` is the only supported type).
Expand All @@ -140,8 +112,8 @@ Wave_read Objects
.. method:: getparams()

Returns a :func:`~collections.namedtuple` ``(nchannels, sampwidth,
framerate, nframes, comptype, compname)``, equivalent to output
of the ``get*()`` methods.
framerate, nframes, comptype, compname)``, equivalent to output of the
``get*()`` methods.


.. method:: readframes(n)
Expand Down Expand Up @@ -218,9 +190,6 @@ Wave_write Objects

Set the sample width to *n* bytes.

For :data:`WAVE_FORMAT_IEEE_FLOAT`, only 4-byte (32-bit) and
8-byte (64-bit) sample widths are supported.


.. method:: getsampwidth()

Expand Down Expand Up @@ -269,32 +238,11 @@ Wave_write Objects
Return the human-readable compression type name.


.. method:: setformat(format)

Set the frame format code.

Supported values are :data:`WAVE_FORMAT_PCM` and
:data:`WAVE_FORMAT_IEEE_FLOAT`.

When setting :data:`WAVE_FORMAT_IEEE_FLOAT`, the sample width must be
4 or 8 bytes.


.. method:: getformat()

Return the current frame format code.


.. method:: setparams(tuple)

The *tuple* should be
``(nchannels, sampwidth, framerate, nframes, comptype, compname, format)``,
with values valid for the ``set*()`` methods. Sets all parameters.

For backwards compatibility, a 6-item tuple without *format* is also
accepted and defaults to :data:`WAVE_FORMAT_PCM`.

For ``format=WAVE_FORMAT_IEEE_FLOAT``, *sampwidth* must be 4 or 8.
The *tuple* should be ``(nchannels, sampwidth, framerate, nframes, comptype,
compname)``, with values valid for the ``set*()`` methods. Sets all
parameters.


.. method:: getparams()
Expand Down Expand Up @@ -331,6 +279,3 @@ Wave_write Objects
Note that it is invalid to set any parameters after calling :meth:`writeframes`
or :meth:`writeframesraw`, and any attempt to do so will raise
:exc:`wave.Error`.

For :data:`WAVE_FORMAT_IEEE_FLOAT` output, a ``fact`` chunk is written as
required by the WAVE specification for non-PCM formats.
15 changes: 0 additions & 15 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1518,21 +1518,6 @@ typing
wave
----

* Added support for IEEE floating-point WAVE audio
(``WAVE_FORMAT_IEEE_FLOAT``) in :mod:`wave`.

* Added :meth:`wave.Wave_read.getformat`, :meth:`wave.Wave_write.getformat`,
and :meth:`wave.Wave_write.setformat` for explicit frame format handling.

* :meth:`wave.Wave_write.setparams` accepts both 7-item tuples including
``format`` and 6-item tuples for backwards compatibility (defaulting to
``WAVE_FORMAT_PCM``).

* ``WAVE_FORMAT_IEEE_FLOAT`` output now includes a ``fact`` chunk,
as required for non-PCM WAVE formats.

(Contributed by Lionel Koenig and Michiel W. Beijen in :gh:`60729`.)

* Removed the ``getmark()``, ``setmark()`` and ``getmarkers()`` methods
of the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes,
which were deprecated since Python 3.13.
Expand Down
Binary file removed Lib/test/audiodata/pluck-float32.wav
Binary file not shown.
16 changes: 4 additions & 12 deletions Lib/test/audiotests.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,17 @@ def tearDown(self):
unlink(TESTFN)

def check_params(self, f, nchannels, sampwidth, framerate, nframes,
comptype, compname, format):
comptype, compname):
self.assertEqual(f.getnchannels(), nchannels)
self.assertEqual(f.getsampwidth(), sampwidth)
self.assertEqual(f.getframerate(), framerate)
self.assertEqual(f.getnframes(), nframes)
self.assertEqual(f.getcomptype(), comptype)
self.assertEqual(f.getcompname(), compname)
self.assertEqual(f.getformat(), format)

params = f.getparams()
self.assertEqual(params,
(nchannels, sampwidth, framerate, nframes, comptype, compname))
(nchannels, sampwidth, framerate, nframes, comptype, compname))
self.assertEqual(params.nchannels, nchannels)
self.assertEqual(params.sampwidth, sampwidth)
self.assertEqual(params.framerate, framerate)
Expand All @@ -52,17 +51,13 @@ def check_params(self, f, nchannels, sampwidth, framerate, nframes,


class AudioWriteTests(AudioTests):
readonly = False

def create_file(self, testfile):
if self.readonly:
self.skipTest('Read only file format')
f = self.fout = self.module.open(testfile, 'wb')
f.setnchannels(self.nchannels)
f.setsampwidth(self.sampwidth)
f.setframerate(self.framerate)
f.setcomptype(self.comptype, self.compname)
f.setformat(self.format)
return f

def check_file(self, testfile, nframes, frames):
Expand All @@ -72,14 +67,13 @@ def check_file(self, testfile, nframes, frames):
self.assertEqual(f.getframerate(), self.framerate)
self.assertEqual(f.getnframes(), nframes)
self.assertEqual(f.readframes(nframes), frames)
self.assertEqual(f.getformat(), self.format)

def test_write_params(self):
f = self.create_file(TESTFN)
f.setnframes(self.nframes)
f.writeframes(self.frames)
self.check_params(f, self.nchannels, self.sampwidth, self.framerate,
self.nframes, self.comptype, self.compname, self.format)
self.nframes, self.comptype, self.compname)
f.close()

def test_write_context_manager_calls_close(self):
Expand Down Expand Up @@ -263,7 +257,7 @@ def test_read_params(self):
f = self.f = self.module.open(self.sndfilepath)
#self.assertEqual(f.getfp().name, self.sndfilepath)
self.check_params(f, self.nchannels, self.sampwidth, self.framerate,
self.sndfilenframes, self.comptype, self.compname, self.format)
self.sndfilenframes, self.comptype, self.compname)

def test_close(self):
with open(self.sndfilepath, 'rb') as testfile:
Expand Down Expand Up @@ -304,8 +298,6 @@ def test_read(self):
f.setpos(f.getnframes() + 1)

def test_copy(self):
if self.readonly:
self.skipTest('Read only file format')
f = self.f = self.module.open(self.sndfilepath)
fout = self.fout = self.module.open(TESTFN, 'wb')
fout.setparams(f.getparams())
Expand Down
Loading
Loading