python-soundfile
python-soundfile copied to clipboard
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:
- Add
if format == 'opus':
return 'OGG'
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!
Thank you for your analysis!
I'd be grateful for a pull request, which we can merge once the new version of libsndfile has been released.
I believe the reading issue would be addressed once we added the appropriate code to _subtype (and possibly _format and _default_subtypes).
Hi, @bastibe, thanks for you answer!
I believe the reading issue would be addressed once we added the appropriate code to _subtype (and possibly _format and _default_subtypes).
If I got it right, you are planning to work on the code update. Where can I follow the progress just to stay in tune?
Actually, I was asking you whether you would like to try to implement it!
Oh, ok, I got it!
Then I'll make a PR as soon as I check the remaining assumptions about the problem with the read function.
Any progress on this? @bastibe @Islanna . Looking forward to be able to support OPUS files as well. If it is already supported, is there anything else that I need to add?
No progress that I know of. But I know libsndfile is working on MP3 support. Once that is released, I will prepare a new release of soundfile with OPUS support and MP3 support.
Until then, pull requests are welcome.
Any ETA? It has been a month...
That's entirely up to https://github.com/libsndfile/libsndfile.
That's entirely up to https://github.com/libsndfile/libsndfile.
libsndfile has supported MP3 and OPUS, any plan to python-soundfile? I tried to use soundfile with libsndfile(1.0.31) to read MP3 file successfully, but failed to open OPUS.
According to the documentation, libsndfile will support MP3 in 1.1.0, but that has not yet been released. As soon as it is, I'll update soundfile to support it as well. Opus should be available in 1.0.29.
can we read opus now?
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
Should we add to _formats 'OPUS': 0x200000 (*.opus file extension is typically reserved for Ogg container with Opus codec stream). There is already a _formats entry for 'OGG': 0x200000, so should opus format just reuse the same hex value. _subtypes should probably add OPUS: 0x0090and to _default_subtypes:'OPUS' : 'OPUS'`?
In general, Opus support should already be working. Ogg containers with Opus contents should already work. But you're right, I think we don't have the file extension registered yet. I think _formats['OPUS'] = 0x200000 should be correct. But just try it out and see if it does the right thing. The default subtype is correct, too, I think.
I've also just run into an issue reading opus files. It seems that reading the last block fails, but the first blocks work fine.
Here's an audio file where reading works fine until you hit the last block: Opus_long.opus.zip
Here's a short audio file that is short enough that also the first block fails. Opus_file.opus.zip
@tcwalther please forward this issue to https://github.com/libsndfile/libsndfile.
Hello guys, people said about reading opus but i am in doubt if it can write ogg based on opus codec, is it possible?