python-soundfile: OPUS support problems

Hi, I’ve been using pysoundfile for a long time for reading/writing Vorbis .ogg files, it’s working great, but it definitely lacks Opus support.

As I’ve discovered, libsndfile has already added support for opus, check out approved PR here: https://github.com/erikd/libsndfile/pull/406 . It’s not in an official release yet, but you can build a working version from source easily enough following CMake guide in readme.

Building libsndfile

I’ve managed to successfully build the library running these commands(some of them are redundant):

apt-get update
apt-get install cmake autoconf autogen automake build-essential libasound2-dev \
libflac-dev libogg-dev libtool libvorbis-dev libopus-dev pkg-config -y

cd /usr/local/lib
git clone https://github.com/erikd/libsndfile.git
cd libsndfile
mkdir -p build && cd build

cmake .. -DBUILD_SHARED_LIBS=ON
make && make install
cmake --build .

Linking is added for ctypes to help find the new version of libsoundfile

All native libsndfile examples are working fine from the command line: it reads/writes/etc .opus files without any errors/exceptions.

Changing source code to support Opus

Next is the interesting part. I’ve examined pysoundfile source code and it looks like just adding of an OPUS key to subtypes dictionary is enough to support .opus format.

Write

And yes, it’s working perfectly for write function. I’ve checked the generated audio by several different programs. It’s just fine.

import soundfile as sf
sf._subtypes['OPUS']=0x0064

data, sr = sf.read('example.wav')

sf.write('example.opus', data, sr, format='OGG', subtype='OPUS')

Read

Problems are starting with read function. Calling

sf.read('test.opus')

raises RuntimeError: Supported file format but file is malformed. It looks like a libsndfile bug, but as I mentioned above, clean libsndfile script reads .opus files without any exceptions.

I’ve solved this problem by installing pysoundfile from source with the following changes:

  1. Add
if format == 'opus':
    return 'OGG'

to get_format_from_file;

  1. Comment _error_check in seek and _cdata_io

Now, read is also working, but the commenting of _error_check doesn’t seem the proper way to fix this bug.

Do you know how to fix this error? Or maybe what exactly can be the problem?

In any case, thank you for the great work!

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 5
  • Comments: 16 (8 by maintainers)

Most upvoted comments

Now that libsndfile has added support for MP3, I am working on a new release. You can check my progress at https://github.com/bastibe/python-soundfile/issues/325