|
15 | 15 | getsampwidth() -- returns sample width in bytes |
16 | 16 | getframerate() -- returns sampling frequency |
17 | 17 | getnframes() -- returns number of audio frames |
| 18 | + getencoding() -- returns frame encoding (WAVE_FORMAT_PCM, WAVE_FORMAT_IEEE_FLOAT |
| 19 | + or WAVE_FORMAT_EXTENSIBLE) |
18 | 20 | getcomptype() -- returns compression type ('NONE' for linear samples) |
19 | 21 | getcompname() -- returns human-readable version of |
20 | 22 | compression type ('not compressed' linear samples) |
|
42 | 44 | setsampwidth(n) -- set the sample width |
43 | 45 | setframerate(n) -- set the frame rate |
44 | 46 | setnframes(n) -- set the number of frames |
| 47 | + setencoding(encoding) |
| 48 | + -- set the frame encoding. Only WAVE_FORMAT_PCM, |
| 49 | + WAVE_FORMAT_IEEE_FLOAT are supported. |
45 | 50 | setcomptype(type, name) |
46 | 51 | -- set the compression type and the |
47 | 52 | human-readable compression type |
@@ -80,6 +85,7 @@ class Error(Exception): |
80 | 85 | pass |
81 | 86 |
|
82 | 87 | WAVE_FORMAT_PCM = 0x0001 |
| 88 | +WAVE_FORMAT_IEEE_FLOAT = 0x0003 |
83 | 89 | WAVE_FORMAT_EXTENSIBLE = 0xFFFE |
84 | 90 | # Derived from uuid.UUID("00000001-0000-0010-8000-00aa00389b71").bytes_le |
85 | 91 | KSDATAFORMAT_SUBTYPE_PCM = b'\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x008\x9bq' |
@@ -226,6 +232,10 @@ class Wave_read: |
226 | 232 | available through the getsampwidth() method |
227 | 233 | _framerate -- the sampling frequency |
228 | 234 | available through the getframerate() method |
| 235 | + _encoding -- frame encoding |
| 236 | + One of WAVE_FORMAT_PCM, WAVE_FORMAT_IEEE_FLOAT |
| 237 | + or WAVE_FORMAT_EXTENSIBLE available through |
| 238 | + getencoding() method |
229 | 239 | _comptype -- the AIFF-C compression type ('NONE' if AIFF) |
230 | 240 | available through the getcomptype() method |
231 | 241 | _compname -- the human-readable AIFF-C compression type |
@@ -338,6 +348,9 @@ def getparams(self): |
338 | 348 | self.getframerate(), self.getnframes(), |
339 | 349 | self.getcomptype(), self.getcompname()) |
340 | 350 |
|
| 351 | + def getencoding(self): |
| 352 | + return self._encoding |
| 353 | + |
341 | 354 | def setpos(self, pos): |
342 | 355 | if pos < 0 or pos > self._nframes: |
343 | 356 | raise Error('position not in range') |
@@ -367,16 +380,16 @@ def readframes(self, nframes): |
367 | 380 |
|
368 | 381 | def _read_fmt_chunk(self, chunk): |
369 | 382 | try: |
370 | | - wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack_from('<HHLLH', chunk.read(14)) |
| 383 | + self._encoding, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack_from('<HHLLH', chunk.read(14)) |
371 | 384 | except struct.error: |
372 | 385 | raise EOFError from None |
373 | | - if wFormatTag != WAVE_FORMAT_PCM and wFormatTag != WAVE_FORMAT_EXTENSIBLE: |
374 | | - raise Error('unknown format: %r' % (wFormatTag,)) |
| 386 | + if self._encoding not in (WAVE_FORMAT_PCM, WAVE_FORMAT_IEEE_FLOAT, WAVE_FORMAT_EXTENSIBLE): |
| 387 | + raise Error('unknown format: %r' % (self._encoding,)) |
375 | 388 | try: |
376 | 389 | sampwidth = struct.unpack_from('<H', chunk.read(2))[0] |
377 | 390 | except struct.error: |
378 | 391 | raise EOFError from None |
379 | | - if wFormatTag == WAVE_FORMAT_EXTENSIBLE: |
| 392 | + if self._encoding == WAVE_FORMAT_EXTENSIBLE: |
380 | 393 | try: |
381 | 394 | cbSize, wValidBitsPerSample, dwChannelMask = struct.unpack_from('<HHL', chunk.read(8)) |
382 | 395 | # Read the entire UUID from the chunk |
@@ -419,6 +432,8 @@ class Wave_write: |
419 | 432 | set through the setsampwidth() or setparams() method |
420 | 433 | _framerate -- the sampling frequency |
421 | 434 | set through the setframerate() or setparams() method |
| 435 | + _encoding -- frame encoding |
| 436 | + set through setencoding() method |
422 | 437 | _nframes -- the number of audio frames written to the header |
423 | 438 | set through the setnframes() or setparams() method |
424 | 439 |
|
@@ -446,6 +461,7 @@ def initfp(self, file): |
446 | 461 | self._file = file |
447 | 462 | self._convert = None |
448 | 463 | self._nchannels = 0 |
| 464 | + self._encoding = WAVE_FORMAT_PCM |
449 | 465 | self._sampwidth = 0 |
450 | 466 | self._framerate = 0 |
451 | 467 | self._nframes = 0 |
@@ -518,6 +534,16 @@ def setcomptype(self, comptype, compname): |
518 | 534 | self._comptype = comptype |
519 | 535 | self._compname = compname |
520 | 536 |
|
| 537 | + def setencoding(self, encoding): |
| 538 | + if self._datawritten: |
| 539 | + raise Error('cannot change parameters after starting to write') |
| 540 | + if encoding not in (WAVE_FORMAT_IEEE_FLOAT, WAVE_FORMAT_PCM): |
| 541 | + raise Error('unsupported wave format') |
| 542 | + self._encoding = encoding |
| 543 | + |
| 544 | + def getencoding(self): |
| 545 | + return self._encoding |
| 546 | + |
521 | 547 | def getcomptype(self): |
522 | 548 | return self._comptype |
523 | 549 |
|
@@ -601,7 +627,7 @@ def _write_header(self, initlength): |
601 | 627 | self._form_length_pos = None |
602 | 628 | self._file.write(struct.pack('<L4s4sLHHLLHH4s', |
603 | 629 | 36 + self._datalength, b'WAVE', b'fmt ', 16, |
604 | | - WAVE_FORMAT_PCM, self._nchannels, self._framerate, |
| 630 | + self._encoding, self._nchannels, self._framerate, |
605 | 631 | self._nchannels * self._framerate * self._sampwidth, |
606 | 632 | self._nchannels * self._sampwidth, |
607 | 633 | self._sampwidth * 8, b'data')) |
|
0 commit comments