cournape / audiolab

A python package for reading/writing audio files from numpy array
http://cournape.github.com/audiolab
GNU Lesser General Public License v2.1
141 stars 46 forks source link

Can't read data from file with unknown number of frames #14

Open njsmith opened 11 years ago

njsmith commented 11 years ago

I want to read the audio out of a .mov file, so I'm doing

child = subprocess.Popen(["avconv", "-i", "myfile.mov", "-f", "au", "-"], stdout=subprocess.PIPE)
my_sndfile = Sndfile(child.stdout.fileno())

This calls avconv (from ffmpeg) to feed the data directly into my process (no need for temporary files), and that's great. But:

In [76]: d = s.read_frames(10000000)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-76-cb9a61676b12> in <module>()
----> 1 d = s.read_frames(10000000)

/home/njs/.user-python2.7-64bit/local/lib/python2.7/site-packages/scikits.audiolab-0.11.0-py2.7-linux-x86_64.egg/scikits/audiolab/pysndfile/_sndfile.so in scikits.audiolab.pysndfile._sndfile.Sndfile.read_frames (scikits/audiolab/pysndfile/_sndfile.c:5361)()

/home/njs/.user-python2.7-64bit/local/lib/python2.7/site-packages/scikits.audiolab-0.11.0-py2.7-linux-x86_64.egg/scikits/audiolab/pysndfile/_sndfile.so in scikits.audiolab.pysndfile._sndfile.Sndfile.read_frames_double (scikits/audiolab/pysndfile/_sndfile.c:5749)()

RuntimeError: Asked 10000000 frames, read 573440

Sort of frustrating... it's telling me it managed to read the frames, but... then it threw them away and raised an exception. So the frames are there, but it's impossible for me to get at them. I expected this to allow for a shorter return value, like POSIX read or Python file.read.

The only solution I can see is to call read_frames(1) in a loop, which is silly, but there you go.

cournape commented 11 years ago

libsndfile has some facility to read from a PIPE (http://www.mega-nerd.com/libsndfile/FAQ.html#Q017), but I have never tried it. There may be a way to make this more friendly in python.

njsmith commented 11 years ago

Right, the libsndfile part is fine, the problem is that the python wrapper api has no way to say " please give me N frames... or if the file ends before you've read N frames, then just give me what you got". The wrapper considers it a hard error if the file ends before all N frames are read.

(Compare the length argument to file.read, which is just an upper bound and you may get fewer bytes than requested.) On 16 Jan 2013 07:55, "David Cournapeau" notifications@github.com wrote:

libsndfile has some facility to read from a PIPE ( http://www.mega-nerd.com/libsndfile/FAQ.html#Q017), but I have never tried it. There may be a way to make this more friendly in python.

— Reply to this email directly or view it on GitHubhttps://github.com/cournape/audiolab/issues/14#issuecomment-12324696.