From 43366d974aef4c10215b8f8783c5a511c2cbf0b3 Mon Sep 17 00:00:00 2001 From: Bastian Bechtold Date: Mon, 8 Dec 2014 10:45:14 +0100 Subject: [PATCH 1/6] updated installation instructions --- README.rst | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/README.rst b/README.rst index 9d2bbee..e3de438 100644 --- a/README.rst +++ b/README.rst @@ -18,18 +18,29 @@ interface for Python calling C code. CFFI is supported for CPython 2.6+, Installation ------------ -On the Python side, you need to have CFFI and Numpy in order to use -PySoundFile. Additionally, You need the library libsndfile installed on -your computer. On Unix, use your package manager to install libsndfile. -Then just install PySoundFile using pip or ``python setup.py install``. - -If you are running Windows, I recommend using -`WinPython `__ or some similar -distribution. This should set you up with Numpy. However, you also need -CFFI and it's dependency, PyCParser. A good place to get these are the -`Unofficial Windows Binaries for -Python `__. Having installed -those, you can download the Windows installers for PySoundFile: +PySoundFile depends on the Python packages CFFI and Numpy, and the +system library libsndfile. + +To install the Python dependencies, I recommend using the `Anaconda +`__ Distribution of Python. Anaconda +provides the ``conda`` package manager, which will install all +dependencies using ``conda install cffi numpy`` (conda is also +independently available on pip). + +You will also need to install `libsndfile +`__. On Windows, libsndfile is +included in the binary installers (see below). On OS X, `homebrew +`__ can install libsndfile using +``brew install libsndfile``. On Linux, use your distribution's package +manager, for example ``sudo apt-get install libsndfile``. + +With CFFI, Numpy, and libsndfile installed, you can use `pip +`__ to install +`PySoundFile `__ with +``pip install pysoundfile`` or ``pip install pysoundfile --user`` if you +don't have administrator privileges. If you are running Windows you +should download the Windows installers for PySoundFile instead (which +also include libsndfile): | `PySoundFile-0.5.0.win-amd64-py2.7 `__ | `PySoundFile-0.5.0.win-amd64-py3.3 `__ From f8c8ba16698d38840ae7a6598b9aa817eac42306 Mon Sep 17 00:00:00 2001 From: Bastian Bechtold Date: Mon, 8 Dec 2014 11:27:07 +0100 Subject: [PATCH 2/6] updated licensing information --- README.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index e3de438..4dbf0ab 100644 --- a/README.rst +++ b/README.rst @@ -1,18 +1,21 @@ PySoundFile =========== -PySoundFile is an audio library based on libsndfile, CFFI and Numpy +`PySoundFile `__ is an audio +library based on libsndfile, CFFI and Numpy. Full documentation is +available on `pysoundfile.readthedocs.org +`__. PySoundFile can read and write sound files. File reading/writing is supported through `libsndfile `__, -which is a free, cross-platform, open-source library for reading and -writing many different sampled sound file formats that runs on many +which is a free, cross-platform, open-source (LGPL) library for reading +and writing many different sampled sound file formats that runs on many platforms including Windows, OS X, and Unix. It is accessed through `CFFI `__, which is a foreign function interface for Python calling C code. CFFI is supported for CPython 2.6+, 3.x and PyPy 2.0+. PySoundFile represents audio data as NumPy arrays. -| PySoundFile is BSD licensed. +| PySoundFile is BSD licensed (BSD 3-Clause License). | (c) 2013, Bastian Bechtold Installation From 645f9e7f09c8f44c62154c430bb19606d2a1aff5 Mon Sep 17 00:00:00 2001 From: Bastian Bechtold Date: Mon, 8 Dec 2014 11:28:35 +0100 Subject: [PATCH 3/6] updated code examples and text --- README.rst | 108 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 36 deletions(-) diff --git a/README.rst b/README.rst index 4dbf0ab..3665363 100644 --- a/README.rst +++ b/README.rst @@ -50,55 +50,91 @@ also include libsndfile): | `PySoundFile-0.5.0.win32-py2.7 `__ | `PySoundFile-0.5.0.win32-py3.3 `__ -Usage ------ +Read/Write Functions +-------------------- + +Data can be written to the file using ``write()``, or read from the file +using ``read()``. PySoundFile can open all file formats that `libsndfile +supports `__, for example +WAV, FLAC, OGG and MAT files. + +Here is an example for a program that reads a wave file and copies it +into an ogg-vorbis file: + +.. code:: python + + import pysoundfile as sf + + data, samplerate = sf.read('existing_file.wav') + sf.write(data, 'new_file.ogg', samplerate=samplerate) + +Block Processing +---------------- + +Sound files can also be read in short, overlapping blocks. For example, +this calculates the signal level for a long file: + +.. code:: python + + import numpy as np + import pysoundfile as sf + + rms = [np.sqrt(np.mean(block**2)) for block in + sf.blocks('myfile.wav', blocksize=1024, overlap=512)] + +SoundFile Objects +----------------- -Each SoundFile can either open a sound file on the disk, or a file-like -object (using ``libsndfile``'s `virtual file -interface `__). -Every sound file has a specific samplerate, data format and a set number -of channels. +Sound file can also be opened as SoundFile objects. Every SoundFile has +a specific sample rate, data format and a set number of channels. -You can read and write any file that -`libsndfile `__ can -open. This includes Microsoft WAV, OGG, FLAC and Matlab MAT files. +If a file is opened, it is kept open for as long as the SoundFile object +exists and closes automatically when it goes out of scope. +Alternatively, there is a context managers, which opens and closes the +file automatically: -If a file on disk is opened, it is kept open for as long as the -SoundFile object exists and closes automatically when it goes out of -scope. Alternatively, the SoundFile object can be used as a context -manager, which closes the file when it exits. +.. code:: python + + import pysoundfile as sf + + with sf.SoundFile('myfile.wav', 'rw') as f: + while f.tell() < len(f)-1: + pos = f.tell() + data = f.read(1024) + f.seek(pos) + f.write(data*2) All data access uses frames as index. A frame is one discrete time-step in the sound file. Every frame contains as many samples as there are channels in the file. -Read/Write Functions -~~~~~~~~~~~~~~~~~~~~ +RAW Files +--------- -Data can be written to the file using ``write()``, or read from the -file using ``read()``. - -Here is an example for a program that reads a wave file and copies it -into an ogg-vorbis file: +Pysoundfile can usually auto-detect the file type of sound files. This +is not possible for RAW files, though. This is a useful idiom for +opening RAW files without having to provide all the format for every +file: .. code:: python - import pysoundfile as sf + import pysoundfile as sf - data, samplerate = sf.read('existing_file.wav') - sf.write(data, 'new_file.ogg', samplerate=samplerate) + format = {'format':'RAW', 'subtype':'FLOAT', 'endian':'FILE'} + data = sf.read('myfile.raw', dtype='float32', **format) + sf.write(data, 'otherfile.raw', **format) Virtual IO -~~~~~~~~~~ +---------- -If you have an open file-like object, you can use something similar to -this to decode it: +If you have an open file-like object, Pysoundfile can open it just like +regular files: .. code:: python - from pysoundfile import SoundFile - with SoundFile('filename.flac', 'rb') as fObj: - data, samplerate = sf.read(fObj) + import pysoundfile as sf + with open('filename.flac', 'rb') as f: + data, samplerate = sf.read(f) Here is an example using an HTTP request: @@ -108,19 +144,19 @@ Here is an example using an HTTP request: import pysoundfile as sf import requests - fObj = BytesIO() + f = BytesIO() response = requests.get('http://www.example.com/my.flac', stream=True) for data in response.iter_content(4096): if data: - fObj.write(data) - fObj.seek(0) - data, samplerate = sf.read(fObj) + f.write(data) + f.seek(0) + data, samplerate = sf.read(f) Accessing Text Data -~~~~~~~~~~~~~~~~~~~ +------------------- In addition to audio data, there are a number of text fields in every sound file. In particular, you can set a title, a copyright notice, a software description, the artist name, a comment, a date, the album -name, a license, a tracknumber and a genre. Note however, that not all +name, a license, a track number and a genre. Note however, that not all of these fields are supported for every file format. From e87e6d29d59b71283a28e97ea49246619b71c8c0 Mon Sep 17 00:00:00 2001 From: Bastian Bechtold Date: Wed, 10 Dec 2014 10:55:44 +0100 Subject: [PATCH 4/6] a few improvements, as suggested by @mgeier --- README.rst | 34 ++++++++++++++++++---------------- pysoundfile.py | 4 ++-- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/README.rst b/README.rst index 3665363..ca94a8e 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ PySoundFile `PySoundFile `__ is an audio library based on libsndfile, CFFI and Numpy. Full documentation is available on `pysoundfile.readthedocs.org -`__. +`__. PySoundFile can read and write sound files. File reading/writing is supported through `libsndfile `__, @@ -71,8 +71,9 @@ into an ogg-vorbis file: Block Processing ---------------- -Sound files can also be read in short, overlapping blocks. For example, -this calculates the signal level for a long file: +Sound files can also be read in short, optionally overlapping blocks. +For example, this calculates the signal level for each block of a long +file: .. code:: python @@ -85,20 +86,21 @@ this calculates the signal level for a long file: SoundFile Objects ----------------- -Sound file can also be opened as SoundFile objects. Every SoundFile has -a specific sample rate, data format and a set number of channels. +Sound files can also be opened as SoundFile objects. Every SoundFile +has a specific sample rate, data format and a set number of channels. -If a file is opened, it is kept open for as long as the SoundFile object -exists and closes automatically when it goes out of scope. -Alternatively, there is a context managers, which opens and closes the -file automatically: +If a file is opened, it is kept open for as long as the SoundFile +object exists and closes automatically when it goes out of scope. You +can also use the `close()` method to close SoundFile objects +explicitly. Alternatively, there is a context managers, which opens +and closes the file automatically: .. code:: python import pysoundfile as sf with sf.SoundFile('myfile.wav', 'rw') as f: - while f.tell() < len(f)-1: + while f.tell() < len(f): pos = f.tell() data = f.read(1024) f.seek(pos) @@ -152,11 +154,11 @@ Here is an example using an HTTP request: f.seek(0) data, samplerate = sf.read(f) -Accessing Text Data -------------------- +Accessing File Metadata +----------------------- -In addition to audio data, there are a number of text fields in every -sound file. In particular, you can set a title, a copyright notice, a +In addition to audio data, there are a number of text fields in some +sound files. In particular, you can set a title, a copyright notice, a software description, the artist name, a comment, a date, the album -name, a license, a track number and a genre. Note however, that not all -of these fields are supported for every file format. +name, a license, a track number and a genre. Note however, that not +all of these fields are supported for every file format. diff --git a/pysoundfile.py b/pysoundfile.py index 948fa2e..475234b 100644 --- a/pysoundfile.py +++ b/pysoundfile.py @@ -5,7 +5,7 @@ To read a sound file in a block-wise fashion, use :func:`blocks`. Alternatively, sound files can be opened as :class:`SoundFile` objects. -For further information, see http://pysoundfile.rtfd.org/. +For further information, see http://pysoundfile.readthedocs.org/. """ __version__ = "0.5.0" @@ -521,7 +521,7 @@ class SoundFile(object): """A sound file. For more documentation see the __init__() docstring (which is also - used for the online documentation (http://pysoundfile.rtfd.org/). + used for the online documentation (http://pysoundfile.readthedocs.org/). """ From 8da1e2fc856bf658fd08aea3b4ac39693e8a129c Mon Sep 17 00:00:00 2001 From: Bastian Bechtold Date: Thu, 11 Dec 2014 14:12:08 +0100 Subject: [PATCH 5/6] improve wording of file closing --- README.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index ca94a8e..603b1b2 100644 --- a/README.rst +++ b/README.rst @@ -90,10 +90,9 @@ Sound files can also be opened as SoundFile objects. Every SoundFile has a specific sample rate, data format and a set number of channels. If a file is opened, it is kept open for as long as the SoundFile -object exists and closes automatically when it goes out of scope. You -can also use the `close()` method to close SoundFile objects -explicitly. Alternatively, there is a context managers, which opens -and closes the file automatically: +object exists and closes when the object is garbage collected. Use the +``close()`` method or the context manager to close the file +explicitly: .. code:: python From 8d9922ba8ff3ca2f9d4769a051fe0f198466cce5 Mon Sep 17 00:00:00 2001 From: Bastian Bechtold Date: Wed, 17 Dec 2014 11:21:32 +0100 Subject: [PATCH 6/6] improved wording on SoundFile closing behavior. --- README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 603b1b2..9a14a6a 100644 --- a/README.rst +++ b/README.rst @@ -90,9 +90,9 @@ Sound files can also be opened as SoundFile objects. Every SoundFile has a specific sample rate, data format and a set number of channels. If a file is opened, it is kept open for as long as the SoundFile -object exists and closes when the object is garbage collected. Use the -``close()`` method or the context manager to close the file -explicitly: +object exists. The file closes when the object is garbage collected, +but you should use the ``close()`` method or the context manager to +close the file explicitly: .. code:: python