Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot write Ogg files over 96 seconds long at 44.1 kHz #426

Open
carlthome opened this issue Jan 31, 2024 · 4 comments
Open

Cannot write Ogg files over 96 seconds long at 44.1 kHz #426

carlthome opened this issue Jan 31, 2024 · 4 comments

Comments

@carlthome
Copy link

Not entirely sure how this happens, but I've been observing program crashes with sf.write for any Ogg file over a duration of 95-96 seconds at 44.1 kHz.

This works:

sf.write("audio.ogg", np.zeros((44100*95, 2)), 44100)

While this crashes:

sf.write("audio.ogg", np.zeros((44100*96, 2)), 44100)

on 0.12.1 macOS M1, 32 GB RAM.

@bastibe
Copy link
Owner

bastibe commented Feb 1, 2024

Thank you for the bug report.

How did you install soundfile? Is there an error message?

@carlthome
Copy link
Author

I've done pipenv install librosa and got

librosa==0.10.1
  - audioread [required: >=2.1.9, installed: 3.0.1]
  - decorator [required: >=4.3.0, installed: 5.1.1]
  - joblib [required: >=0.14, installed: 1.3.2]
  - lazy-loader [required: >=0.1, installed: 0.3]
  - msgpack [required: >=1.0, installed: 1.0.7]
  - numba [required: >=0.51.0, installed: 0.59.0]
    - llvmlite [required: >=0.42.0dev0,<0.43, installed: 0.42.0]
    - numpy [required: >=1.22,<1.27, installed: 1.26.3]
  - numpy [required: >=1.20.3,!=1.22.2,!=1.22.1,!=1.22.0, installed: 1.26.3]
  - pooch [required: >=1.0, installed: 1.8.0]
    - packaging [required: >=20.0, installed: 23.2]
    - platformdirs [required: >=2.5.0, installed: 4.2.0]
    - requests [required: >=2.19.0, installed: 2.31.0]
      - certifi [required: >=2017.4.17, installed: 2023.11.17]
      - charset-normalizer [required: >=2,<4, installed: 3.3.2]
      - idna [required: >=2.5,<4, installed: 3.6]
      - urllib3 [required: >=1.21.1,<3, installed: 2.2.0]
  - scikit-learn [required: >=0.20.0, installed: 1.4.0]
    - joblib [required: >=1.2.0, installed: 1.3.2]
    - numpy [required: >=1.19.5,<2.0, installed: 1.26.3]
    - scipy [required: >=1.6.0, installed: 1.12.0]
      - numpy [required: >=1.22.4,<1.29.0, installed: 1.26.3]
    - threadpoolctl [required: >=2.0.0, installed: 3.2.0]
  - scipy [required: >=1.2.0, installed: 1.12.0]
    - numpy [required: >=1.22.4,<1.29.0, installed: 1.26.3]
  - soundfile [required: >=0.12.1, installed: 0.12.1]
    - cffi [required: >=1.0, installed: 1.16.0]
      - pycparser [required: Any, installed: 2.21]
  - soxr [required: >=0.3.2, installed: 0.3.7]
    - numpy [required: Any, installed: 1.26.3]
  - typing-extensions [required: >=4.1.1, installed: 4.9.0]

No error message that I can see, but perhaps it's librosa that misses a transitive dependency for soundfile?

@bastibe
Copy link
Owner

bastibe commented Feb 2, 2024

Thank you. This is probably an issue with upstream libsndfile.

You will need to check with them if they have a fix for this issue. They may already have fixed it actually, as soundfile is one version behind libsndfile at the moment.

@dernett
Copy link

dernett commented Jun 5, 2024

I ran into this issue, and after looking around a bit it seems that this limitation has existed since at least 2014. One workaround that I discovered from a GNU Octave bug report is to write the file out in chunks of size 2^20 instead of writing it out all at once with sf.write. So, I wrote this write_chunked function that can be used as an alternative for sf.write:

def write_chunked(file, data, samplerate, subtype=None, endian=None, format=None,
          closefd=True, chunk_size=0x100000):
    import numpy as np
    data = np.asarray(data)
    if data.ndim == 1:
        channels = 1
    else:
        channels = data.shape[1]
    with SoundFile(file, 'w', samplerate, channels,
                   subtype, endian, format, closefd) as f:
        num_chunks = (len(data) + chunk_size - 1) // chunk_size
        for chunk in np.array_split(data, num_chunks, axis=0):
            f.write(chunk)

From my limited testing it seems to work fine for writing vorbis files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants