Skip to content

Commit

Permalink
Fix bug whereby encoding large ogg vorbis files caused a segfault
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnVinyard committed Nov 27, 2018
1 parent 238c5bd commit 1d81c44
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
17 changes: 16 additions & 1 deletion zounds/timeseries/audiosamples.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,22 @@ def encode(self, flo=None, fmt='WAV', subtype='PCM_16'):
format=fmt,
subtype=subtype,
samplerate=self.samples_per_second) as f:
f.write(self)

if fmt == 'OGG':
# KLUDGE: Trying to write too-large chunks to an ogg file seems
# to cause a segfault in libsndfile
# KLUDGE: This logic is very similar to logic in the OggVorbis
# processing node, and should probably be factored into a common
# location
factor = 20
chunksize = self.samples_per_second * factor
for i in xrange(0, len(self), chunksize):
chunk = self[i: i + chunksize]
f.write(chunk)
else:
# write everything in one chunk
f.write(self)

flo.seek(0)
return flo

Expand Down
11 changes: 10 additions & 1 deletion zounds/timeseries/test_audiosamples.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from zounds.timeseries import TimeDimension, TimeSlice
from zounds.core import IdentityDimension
from audiosamples import AudioSamples
from zounds.synthesize import SineSynthesizer
from zounds.synthesize import SineSynthesizer, SilenceSynthesizer


class AudioSamplesTest(unittest2.TestCase):
Expand Down Expand Up @@ -188,3 +188,12 @@ def test_sum_along_second_axis(self):
self.assertIsInstance(result, AudioSamples)
self.assertEqual(1, len(result.dimensions))
self.assertIsInstance(result.dimensions[0], TimeDimension)

def test_encode_large_ogg(self):
sr = SR11025()
synth = SilenceSynthesizer(sr)
samples = synth.synthesize(Seconds(190))
raw = samples.encode(fmt='OGG', subtype='VORBIS')
# prior to this test, the line above caused a segfault, so the assertion
# below is fairly worthless, and mostly a formality
self.assertIsNotNone(raw)

0 comments on commit 1d81c44

Please sign in to comment.