Giter VIP home page Giter VIP logo

Comments (11)

Whistler7 avatar Whistler7 commented on July 19, 2024

My goals:

  1. Interface to fractional 64-bit NumPy arrays
  2. Support the complete range of values available in PCM and floating-point WAV formats
  3. No quantization distortion (transparent interface for in-range values, reading a PCM WAV file and then writing it back is bit-exact)
  4. Truncation and two's-complement saturation on write to PCM WAV format (convenient handling of out-of-range values)
  5. Compatibility with Python 2.7 and Python 3
  6. Windows and Linux OS compatibility

Less important to me:
7) Limiting PySoundFile to the API of libsndfile (especially when doing so conflicts with the above goals).
8) Support every feature of libsndfile
9) Big-endian WAV formats
10) Speed

PySoundFile 0.5.0 meets all my goals except 2) through 4). If the next version of PySoundFile doesn't accommodate these goals, I will create a Python wrapper around PySoundFile's integer interface that does meet all my goals. Either way, once I start using PySoundFile in my projects, backwards compatibility will be important to me.

Since PySoundFile supports all the popular WAV formats, for either block processing or whole-file access, I suspect that it will become more popular in the Python community than the WAV interfaces in SciPy and the standard Python library, which have a number of serious limitations. PySoundFile's popularity would increase greatly as soon as it is included in the main scientific Python distributions: Python(x,y), WinPython and Anaconda. Currently, these distributions have no WAV file I/O except WinPython (and scikits.audiolab is only included in the Python 2.7 version). So there is a great need, and backwards compatibility will be important to more users.

If PySoundFile is to break backwards compatibility to solve my goals (issue #20) or any other, I propose to do it quickly, call the release version 1.0, and then be firm about preserving backwards compatibility with version 1.0.

from python-soundfile.

mgeier avatar mgeier commented on July 19, 2024

@bastibe: here my thoughts to the discussion ...

For my involvement in PySoundFile there are 2 different reasons:

  1. I need a library to read a few types of soundfiles into NumPy arrays (and vice versa) and it should have a very concise interface to be used (also) in an interactive Python (in my case IPython) session.
  2. I like programming in Python, I like open source. And probably I can help to make PySoundFile more useful to more people.

Some of my pull requests were mainly for the first point (especially the high-level read() and write() functions), others were purely for the second, regarding features which I myself will probably never use.

  • should we support every feature of libsndfile?

Probably not every single feature, but most of them.
If there is no reason against supporting a certain feature, we might as well support it.

I think every new feature we support potentially increases the number of users.
And even if nobody ever uses it, a few lines of code don't hurt (in the most cases).

  • should we focus on usability first, or speed first?

I guess we should decide this on a case-by-case basis.
But in general we should go the Python way, which I guess is usability first.

Of course we shouldn't unnecessarily slow things down.
I think we should try to avoid copying data as much as possible.

And if we add (potentially slow) features on top of libsndfile this should be made clear in the documentation.

And if there are several alternatives, the fast one should be the default.
E.g. we could add an option to return arrays in Fortran order, but C order should be the default because that's what libsndfile gives us.

  • should we focus on clean abstractions over convenience?

That's very abstract ... do you have a concrete example?

I guess in many cases those two don't contradict each other ...

  • should we break backwards compatibility?

Yes!

I really like PySoundFile since the moment I first saw it, but there are certain details which I find have potential for improvement. Some of those break backwards compatibility.

Especially the handling of formats and subtypes in dictionaries and the tuples of strings for combination of format/type/endian seems a bit clumsy to me.

As @Whistler7 mentioned, as long as we are below version 1.0 this isn't such a big deal. I also agree that PySoundFile can (and will) get much more popular in the future.
And I think it's better to break backwards compatibility now than have a not-so-nice API in version 1.0.

I also agree that Python 2.7 and 3.x and Win/Linux/OSX compatibility is important but I was counting on that anyway.

  • what about documentation and tests?

Yes!
I was missing unit tests when I was playing around with the code. I didn't mention anything, however, because don't really have experience with unit testing in Python.
I wouldn't know where to start, but I'd be willing to help as much as I can.

I also don't really have experience with documentation.
In my last Python project I used Doxygen because I also use it in C++, but of course it would be much better to do something closer to NumPy and use Sphinx and probably http://readthedocs.org ...?

This is all the more relevant since we have over a thousand downloads on PyPi every month, so these decisions probably affect quite a few people.

That's impressive, I wasn't aware of these numbers.
Still, I think some API changes are necessary and breaking backwards compatibility is the right thing to do in the current situation.

Here's my suggestion for further actions:

You should create a development branch. There we can experiment with breaking API changes. There we should also start to implement unit tests and probably re-structure the documentation somehow.
Then we should use this branch for some time to be sure that our decisions actually improved things and if we think so the development branch can be merged into master and be released as version 0.6.
Ideally, all breaking changes would be concentrated at this point in time.
After that we should wait and see how things are for the users and if there are no major complaints we could think about going into the direction of version 1.0, but I wouldn't rush into that.

from python-soundfile.

bastibe avatar bastibe commented on July 19, 2024

Thank you, @mgeier, these are very valuable points. Also thank you @Whistler7 for your viewpoints and use cases.

I think it is a great idea to create a development branch and start creating tests there. I have been thinking about how to test PySoundFile properly without merely testing libsndfile. I guess we will have to go for integration-test style testing where we mostly create temp files with certain attributes and read them back.

This should give us the confidence to push for new features without breaking old functionality. I also agree that we should probably go for a 1.0 with a stable API and good documentation. With all the great ideas raised here already, breaking backwards compatibility now is probably a very good thing, as it will allow us to go for a much nicer API for 1.0.

As for documentation, http://readthedocs.org is certainly the way to go. I especially like how cffi is doing its documentation and I think we should try to go down a similar route.

Personally, I use PySoundFile for scientific signal processing applications. Many of them use block processing, so accessing possibly overlapping blocks of audio data is very important to me. Reading whole files is convenient, but I find that I rarely need it. Also, I don't usually care about the data format as long as it is normalized floating point.

Another area I recently used is the virtual IO feature. Honestly, this is godsent and totally unique to PySoundFile! The reason is very simple: Web browsers allow access to file contents, but not their paths. Thus, the only way to open a local file from a web browser is to read the file content in Javascript. The virtual IO feature allows a python web server to read this binary data stream as if it were the local file. This opens up PySoundFile for web apps, which is awesome!

from python-soundfile.

mgeier avatar mgeier commented on July 19, 2024

I created a new issue for updating the documentation: #27.

from python-soundfile.

mgeier avatar mgeier commented on July 19, 2024

In my initial reply I didn't have an answer to this:

  • should we focus on clean abstractions over convenience?

I found an example in our discussion about file types (https://github.com/bastibe/PySoundFile/pull/22#issuecomment-39634137) and I think I understand the question now.

I would generally go for convenience.
There are many more users than developers, and the users should have it as convenient as possible.

Of course, we should still decide in each concrete case if a certain amount of convenience justifies the necessary amount of complexity and un-clean-ness in the code.

from python-soundfile.

peircej avatar peircej commented on July 19, 2024

Hi there,

I'm looking at PySoundFile/PySoundCard for the package for which I'm principal maintainer, PsychoPy. This is for presenting stimuli to subjects in psychology/neuroscience experiments and is already widely used (http://www.psychopy.org/usage.php). We're currently using pyo for sound, but not too happy with it because;

  • we have to compile it which doesn't always work (e.g. I've not yet succeeded on 64bit python 2.7 OSX)
  • it's big and unwieldy, so we can't go in and fix/alter things

For us the key issues are:

  • speed. In particular, users are sometimes measuring reaction times to their stimulus, so when they say play() they want the sound to start as fast as possible, or at least with a very consistent delay. The fact that it might take time to load the file initially is something we can def live with.
  • easy to build on all systems. Our users are spread across win32, linux and OSX and if we can't use all 3 it's a non-starter. We provide a 'standalone' package for win32 and mac so I want something I can wrap up with no external files needed if possible.
  • recording as well as playback and, again, knowing that recording started quickly is a big plus
  • python 2.7 and we will want 3.0 soon I guess

less important to us:

  • features like filtering aren't so interesting, but people might want to control apparent sound 'position'

thanks - your work looks very promising and we'll try to give it a test run.
Jon

from python-soundfile.

bastibe avatar bastibe commented on July 19, 2024

I'm glad you like the libraries!

PySoundFile and PySoundCard have libffi/portaudio/libsndfile as non-python dependencies. We bundle portaudio and libsndfile in the Windows installers, but since there are no binary installers for Mac and Linux, the user has to install these libraries manually there. It should be easy to incorporate these binaries into your standalone package though.

As for speed and startup time, we are doing very well I think. Starting to play a newly opened sound file is usually very fast. My machine takes about 0.025 seconds to open a stream, a sound file, and start playing. If both are already opened, it takes about 0.004 seconds. Note that pysoundfile can read sound files a chunk at a time, so loading large sound files is not an issue.

from python-soundfile.

peircej avatar peircej commented on July 19, 2024

A 4ms start would be great. 25ms to open a file is definitely no problem
either; that's something users know will always be an issue.

And I'm sure I can manage compiling the libs themselves and packaging
them. The problem usually comes when trying to link multiple compiled libs.

This looks brilliant. I'm excited! :-)

from python-soundfile.

bastibe avatar bastibe commented on July 19, 2024

As you probably noticed, both pysoundcard and pysoundfile rely on CFFI/libffi to load portaudio/libsndfile at runtime. There is no compiler required to load C libraries using CFFI. You just ship the C libraries and the python code, and libffi will do all the work. I love it!

from python-soundfile.

peircej avatar peircej commented on July 19, 2024

Out of interest, why this instead of ctypes?

from python-soundfile.

bastibe avatar bastibe commented on July 19, 2024

Eli Bendersky explained that very well. I find it much easier to write a C declaration in C and have CFFI parse that, than to build up the equivalent declaration from ctypes constructs in Python.

from python-soundfile.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.