bastibe / python-soundfile

SoundFile is an audio library based on libsndfile, CFFI, and NumPy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Writing OGG produces an empty file

mgeier opened this issue · comments

I don't know if I'm doing something wrong, but this produces an OGG file with zero frames:

import soundfile as sf
import numpy as np
a = np.empty(100000)
sf.write(a, 'delme.ogg', 44100)

This doesn't seem to depend on my libsndfile binary, since the same error happens both on Debian Linux and on Windows XP 32bit.
To be sure, I compiled a little test program in C, which correctly writes a non-empty OGG file (this I tried only on Linux), so it cannot really be related to my installed version of libsndfile, or can it?

Any ideas what's wrong?

Can anybody write OGG files with PySoundFile?

Reading OGGs works perfectly, BTW ...
Writing other formats, too ...

I can confirm this on OS X. Ideally, our tests should have caught this!

Thanks for confirming this ... I have still no clue what's going on here ...

I originally thought it was enough to test only one format and rely on libsndfile that all others work, too.
But it looks like this isn't libsndfile's fault ... does that mean we have to test every single supported file format?
I think this would be quite tedious ...
See also #52.

Regardless of this bug, we should probably add tests for FLAC and OGG anyway, since those could mistakenly be disabled in the shared library file.

I guess a test for writing and afterwards reading FLAC is simple, since it's lossless, but I'm not sure how to test the contents of an OGG file.
But even checking only the length of the stored data would have exposed the current issue.

More experiments:

import numpy as np
import soundfile as sf
f = sf.SoundFile('delme.ogg', 'w', 44100, 1)
f.write(np.random.randn(10000)) 

works fine on my machine (Linux, libsndfile 1.0.25-9.1, pysoundfile HEAD).

However, if I write more than a few seconds, I get a SIGSEGV instead.

Furthermore, if I write less than 10000 frames or so, subsequent long writes segfault as well.

Yet, if I first write something between 10000 frames and a few seconds, then subsequent writes work perfectly fine, but do not write the last half second or so to the file. flush does not help with the last second.

And then all audio data vanishes from the file on close.

To be honest, it seems very unlikely that this is a problem on our end.

That's very interesting!

When I replace np.empty() with np.random.randn() in my original example, the written file is not empty anymore! But there are still a few samples missing, I was writing 100000 frames and only 77504 ended up in the OGG file. However, if I try the same thing in C, I get exactly 100000 frames in the OGG file.

The thing with the segmentation fault is also interesting ... I couldn't find a fixed size where this happens, I had a crash with 1.500.000 samples once, but another time it just worked.
This crash also happens in the C version, so this definitely doesn't have anything to do with us.

Here's the C test file ogg_problem.c:

#include <stdlib.h>
#include <sndfile.h>

static const unsigned int LENGTH = 100000;

int main() {
  float data[LENGTH];
  SNDFILE* sf;
  SF_INFO sfinfo;
  sfinfo.samplerate = 44100;
  sfinfo.channels = 1;
  sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;
  sf = sf_open("delme.ogg", SFM_WRITE, &sfinfo);
  if (!sf)
  {
    printf("error!\n");
    exit(99);
  }
  sf_count_t written = sf_writef_float(sf, data, LENGTH);
  printf("written: %d\n", written);
  sf_close(sf);
}

And a Makefile:

LDLIBS = -lsndfile

all: ogg_problem

Have you tried libsndfile-1.0.26pre6 from here http://www.mega-nerd.com/tmp/ ? I can't reproduce the bug (empty OGG) with this pre on Win x64.

Hello,
Does the issue get fixed please ? I just downloaded the last version of libsndfile 1.0.28, but I always get the .ogg bug.
Cheers,
Louis

I believe we are currently shipping libsndfile 1.0.27 in the Windows and macOS wheels.

At what version was this supposed to be fixed?

I believe we are currently shipping libsndfile 1.0.27 in the Windows and macOS wheels.

Exactly, that's why I tested with the lastest version but with no success.

At what version was this supposed to be fixed?

No one, but since the topic is 2 years old I wanted to know if there was any news.
Anyway thanks for your lib, which is very clean to use.
Cheers,
Louis

It appears that the problem still exists today with libsndfile 1.0.27.

Unfortunately yes, and still with libsndfile 1.0.28.

Still broken apparently.

No ideas to fix this?

This still seems to be broken. I haven't experienced seg faults, but when I write ogg files, the ends are very often cut off, which makes it sort of unusable. We care considering switching back to wav, but that would be unfortunate since ogg really saves a lot of space.

I can confirm that this issue depends on the libsndfile version used.
I tested it by creating ogg files with a duration of 1s using different sampling rates and number of channels. Under libsndfile 1.0.27-3 on Debian it works as expected. With libsndfile 1.0.25-10ubuntu0.16.04.1 on Ubuntu I got the following strange results that show even an interaction with the number of channels:

Number of samples Number of channels Written number of samples in ogg file
48000 1 0
8000 1 0
48000 2 0
8000 2 0
48000 8 32320
8000 8 0
48000 255 43584
8000 255 5888

@lcouka and @bastibe: as I was not able to reproduce the error under libsndfile 1.0.27 what did you do to get the error there?

commented

I have this same error.
For me, soundfile even crashes the Python kernel - both when running on Google colab or locally on OSX (via Spyder).
A file is written to disk before the crash, but it's empty: the channels contain no data at all.
So far it only happened with files of a certain length.

/Edit:
How can I find out which libsoundfile version my soundfile module is using?
Which would be the correct libsoundfile version to use?

You can query soundfile.__libsndfile_version__ to get the version of soundfile you are using.

By the way, you say you are using "PySoundFile", which is severely outdated. Please install "soundfile" instead, which is the current version.

commented

Thanks for the advice!
I am using soundfile not PySoundfile. I corrected that typo.

commented

Any updates on this issue? Using Python 3.7 with the latest version of soundfile and anytime I try to write a sample numpy array to .ogg I always get an empty file.

Which version of libsndfile and file are you using?
As stated above for me it did work with 1.0.27, but not 1.0.25

I seem to have the same problem using libsndfile1 1.0.28-7ubuntu0.1 with soundfile.__version__: 0.10.3.post1.

I see no easy option for downgrading libsndfile1 to 1.0.27.

i just tested with libsndfile-1.2.0 (as packaged in Debian, and afaict, the issue is gone)

That's wonderful news, thank you for following up on this issue!