WarrenWeckesser / wavio

A Python module for reading and writing WAV files using numpy arrays.
133 stars 19 forks source link

Lacks BytesIO support #20

Closed Quotatron3000 closed 6 months ago

Quotatron3000 commented 7 months ago

Python typically has it so BytesIO can be a 'placeholder' for an open file (both for read and write operations), especially if tasks are to be written in-memory rather than written to disk. Many standard python file operations will accept a BytesIO object in the place of a file, for example, in PIL:

from PIL import Image
SomeBinaryData = b'Placeholder'

with Image.open(io.BytesIO(SomeBinaryData)) as LoadedImage:
    #some normal file operations go here

Passing a BytesIO object to wavio.write in-place of a filepath currently throws an error.

Given many numpy operations will be in-memory, it would be reasonable to assume any .wav manipulation (E.G. by pydub) would also likely be in-memory too, prior to file export. BytesIO support would readily enable this and doesn't require much overhead to implement.

WarrenWeckesser commented 7 months ago

Passing a BytesIO object to wavio.write in-place of a filepath currently throws an error.

Could you give a simple example? It works for me, on a Mac laptop with Python 3.11.1 and 3.12.2, numpy 1.26.4 and wavio 0.0.8:

In [1]: import numpy as np

In [2]: from io import BytesIO

In [3]: import wavio

In [4]: a = np.array([1, 2, 3, 10, 12, 13, 0, 0, 99], dtype=np.uint8)

In [5]: f = BytesIO()

In [6]: wavio.write(f, a, rate=44100)  # Write to the BytesIO instance.

In [7]: f.getvalue()  # Inspect the bytes.
Out[7]: b'RIFF-\x00\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00D\xac\x00\x00D\xac\x00\x00\x01\x00\x08\x00data\t\x00\x00\x00\x01\x02\x03\n\x0c\r\x00\x00c'

In [8]: f.seek(0)
Out[8]: 0

In [9]: w = wavio.read(f)  # Read back the data from the BytesIO instance.

In [10]: w
Out[10]: Wav(data.shape=(9, 1), data.dtype=uint8, rate=44100, sampwidth=1)

In [11]: w.data
Out[11]: 
array([[ 1],
       [ 2],
       [ 3],
       [10],
       [12],
       [13],
       [ 0],
       [ 0],
       [99]], dtype=uint8)
WarrenWeckesser commented 6 months ago

wavio does work with a BytesIO instance, so I'm closing the issue. If you can provide sufficient details to reproduce any problem that you might have had, we can reopen the issue.