Skip to content

Commit

Permalink
Add open(), read() and write() functions
Browse files Browse the repository at this point in the history
This is the combination of a few commits from #18, plus a few more
things.
See also #14.
  • Loading branch information
mgeier committed May 29, 2014
1 parent 7b0d0cb commit 0ca0eb3
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions pysoundfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,74 @@ def write(self, data):
self.seek(curr, SEEK_SET, 'w')


def open(*args, **kwargs):
"""Return a new SoundFile object.
Takes the same arguments as SoundFile.__init__().
"""
return SoundFile(*args, **kwargs)


def read(file, frames=-1, start=None, stop=None, **kwargs):
"""Read a sound file and return its contents as NumPy array.
The number of frames to read can be specified with frames, the
position to start reading can be specified with start.
By default, the whole file is read from the beginning.
Alternatively, a range can be specified with start and stop.
Both start and stop accept negative indices to specify positions
relative to the end of the file.
The keyword arguments out, dtype, fill_value and always_2d are
forwarded to SoundFile.read().
All further arguments are forwarded to SoundFile.__init__().
"""
from inspect import getargspec

if frames >= 0 and stop is not None:
raise RuntimeError("Only one of {frames, stop} may be used")

read_kwargs = {}
for arg in getargspec(SoundFile.read).args:
if arg in kwargs:
read_kwargs[arg] = kwargs.pop(arg)
with SoundFile(file, 'r', **kwargs) as f:
start, stop, _ = slice(start, stop).indices(f.frames)
if stop < start:
stop = start
if frames < 0:
frames = stop - start
f.seek(start, SEEK_SET)
data = f.read(frames, **read_kwargs)
return data, f.sample_rate


def write(data, file, sample_rate, *args, **kwargs):
"""Write data from a NumPy array into a sound file.
If file exists, it will be overwritten!
If data is one-dimensional, a mono file is written.
For two-dimensional data, the columns are interpreted as channels.
All further arguments are forwarded to SoundFile.__init__().
Example usage:
import pysoundfile as sf
sf.write(myarray, 'myfile.wav', 44100, 'PCM_24')
"""
data = _np.asarray(data)
if data.ndim == 1:
channels = 1
else:
channels = data.shape[1]
with SoundFile(file, 'w', sample_rate, channels, *args, **kwargs) as f:
f.write(data)


def default_subtype(format):
"""Return default subtype for given format."""
return _default_subtypes.get(str(format).upper())
Expand Down

0 comments on commit 0ca0eb3

Please sign in to comment.