# Buggy code
def get_frame(self, tt):
    buffersize = self.buffersize
    if isinstance(tt, np.ndarray):
        # lazy implementation, but should not cause problems in
        # 99.99 %  of the cases

        # elements of t that are actually in the range of the
        # audio file.

        in_time = (tt >= 0) & (tt < self.duration)

        # The np.round in the next line is super-important.
        # Removing it results in artifacts in the noise.
        frames = np.round((self.fps * tt)).astype(int)[in_time]
        fr_min, fr_max = frames.min(), frames.max()

        if not (0 <= (fr_min - self.buffer_startframe) < len(self.buffer)):
            self.buffer_around(fr_min)
        elif not (0 <= (fr_max - self.buffer_startframe) < len(self.buffer)):
            self.buffer_around(fr_max)

        try:
            result = np.zeros((len(tt), self.nchannels))
            indices = frames - self.buffer_startframe
            result[in_time] = self.buffer[indices]
            return result
        except IndexError as error:
            if indices.max() > len(self.buffer):
                raise IOError(
                    "Error reading file '%s', " % self.filename
                    + "trying to access beyond the end of the file"
                )
            else:
                raise IOError(
                    "Error in file %s, " % (self.filename)
                    + "At time t=%.02f-%.02f seconds, " % (tt[0], tt[-1])
                    + "indices wanted: %d-%d, " % (indices.min(), indices.max())
                    + "but len(buffer)=%d\n" % (len(self.buffer))
                    + str(error)
                )

    else:
        ind = int(self.fps * tt)
        if ind < 0 or ind > self.nframes:  # out of time: return 0
            return np.zeros(self.nchannels)

        if not (0 <= (ind - self.buffer_startframe) < len(self.buffer)):
            # out of the buffer: recenter the buffer
            self.buffer_around(ind)

        # read the frame in the buffer
        return self.buffer[ind - self.buffer_startframe]


# Traceback (IndexError)
IndexError                                Traceback (most recent call last)
/home/xxx/venv/lib/python3.4/site-packages/moviepy/audio/io/readers.py in get_frame(self, tt)
186                 indices = frames - self.buffer_startframe
--> 187                 result[in_time] = self.buffer[indices]
188                 return result

IndexError: index 120575 is out of bounds for axis 0 with size 120575

During handling of the above exception, another exception occurred:

OSError                                   Traceback (most recent call last)
<ipython-input-2-7b8ec45b76f0> in <module>()
2
3 sound = AudioFileClip("sample_mono_short.flac")
----> 4 samples = sound.to_soundarray()

<decorator-gen-194> in to_soundarray(self, tt, fps, quantize, nbytes, buffersize)

/home/xxx/venv/lib/python3.4/site-packages/moviepy/decorators.py in requires_duration(f, clip, *a, **k)
52         raise ValueError("Attribute 'duration' not set")
53     else:
---> 54         return f(clip, *a, **k)
55
56

/home/xxx/venv/lib/python3.4/site-packages/moviepy/audio/AudioClip.py in to_soundarray(self, tt, fps, quantize, nbytes, buffersize)
112             if self.duration>max_duration:
113                 return stacker(self.iter_chunks(fps=fps, quantize=quantize, nbytes=2,
--> 114                                                  chunksize=buffersize))
115             else:
116                 tt = np.arange(0, self.duration, 1.0/fps)

/home/xxx/venv/lib/python3.4/site-packages/numpy/core/shape_base.py in vstack(tup)
228
229     """
--> 230     return _nx.concatenate([atleast_2d(_m) for _m in tup], 0)
231
232 def hstack(tup):

/home/xxx/venv/lib/python3.4/site-packages/numpy/core/shape_base.py in <listcomp>(.0)
228
229     """
--> 230     return _nx.concatenate([atleast_2d(_m) for _m in tup], 0)
231
232 def hstack(tup):

/home/xxx/venv/lib/python3.4/site-packages/moviepy/audio/AudioClip.py in generator()
79                 tt = (1.0/fps)*np.arange(pospos[i],pospos[i+1])
80                 yield self.to_soundarray(tt, nbytes= nbytes, quantize=quantize, fps=fps,
---> 81                                          buffersize=chunksize)
82
83         if progress_bar:

<decorator-gen-194> in to_soundarray(self, tt, fps, quantize, nbytes, buffersize)

/home/xxx/venv/lib/python3.4/site-packages/moviepy/decorators.py in requires_duration(f, clip, *a, **k)
52         raise ValueError("Attribute 'duration' not set")
53     else:
---> 54         return f(clip, *a, **k)
55
56

/home/xxx/venv/lib/python3.4/site-packages/moviepy/audio/AudioClip.py in to_soundarray(self, tt, fps, quantize, nbytes, buffersize)
125         #print tt.max() - tt.min(), tt.min(), tt.max()
126
--> 127         snd_array = self.get_frame(tt)
128
129         if quantize:

<decorator-gen-136> in get_frame(self, t)

/home/xxx/venv/lib/python3.4/site-packages/moviepy/decorators.py in wrapper(f, *a, **kw)
87         new_kw = {k: fun(v) if k in varnames else v
88                  for (k,v) in kw.items()}
---> 89         return f(*new_a, **new_kw)
90     return decorator.decorator(wrapper)
91

/home/xxx/venv/lib/python3.4/site-packages/moviepy/Clip.py in get_frame(self, t)
93                 return frame
94         else:
---> 95             return self.make_frame(t)
96
97     def fl(self, fun, apply_to=[] , keep_duration=True):

/home/xxx/venv/lib/python3.4/site-packages/moviepy/audio/io/AudioFileClip.py in <lambda>(t)
69
70
---> 71         self.make_frame =  lambda t: reader.get_frame(t)
72         self.nchannels = reader.nchannels
73

/home/xxx/venv/lib/python3.4/site-packages/moviepy/audio/io/readers.py in get_frame(self, tt)
191                        "At time t=%.02f-%.02f seconds, "%(tt[0], tt[-1])+
192                        "indices wanted: %d-%d, "%(indices.min(), indices.max())+
--> 193                        "but len(buffer)=%d\n"%(len(self.buffer))+ str(error))
194
195         else:

OSError: Error in file sample_mono_short.flac, At time t=27.21-27.68 seconds, indices wanted: 100000-120687, but len(buffer)=120575
index 120575 is out of bounds for axis 0 with size 120575

# Fixed code
def get_frame(self, tt):
    buffersize = self.buffersize
    if isinstance(tt, np.ndarray):
        # lazy implementation, but should not cause problems in
        # 99.99 %  of the cases

        # elements of t that are actually in the range of the
        # audio file.
        in_time = (tt >= 0) & (tt < self.duration)

        # Check that the requested time is in the valid range
        if not in_time.any():
            raise IOError(
                "Error in file %s, " % (self.filename)
                + "Accessing time t=%.02f-%.02f seconds, " % (tt[0], tt[-1])
                + "with clip duration=%d seconds, " % self.duration
            )

        # The np.round in the next line is super-important.
        # Removing it results in artifacts in the noise.
        frames = np.round((self.fps * tt)).astype(int)[in_time]
        fr_min, fr_max = frames.min(), frames.max()

        if not (0 <= (fr_min - self.buffer_startframe) < len(self.buffer)):
            self.buffer_around(fr_min)
        elif not (0 <= (fr_max - self.buffer_startframe) < len(self.buffer)):
            self.buffer_around(fr_max)

        try:
            result = np.zeros((len(tt), self.nchannels))
            indices = frames - self.buffer_startframe
            result[in_time] = self.buffer[indices]
            return result

        except IndexError as error:
            warnings.warn(
                "Error in file %s, " % (self.filename)
                + "At time t=%.02f-%.02f seconds, " % (tt[0], tt[-1])
                + "indices wanted: %d-%d, " % (indices.min(), indices.max())
                + "but len(buffer)=%d\n" % (len(self.buffer))
                + str(error),
                UserWarning,
            )

            # repeat the last frame instead
            indices[indices >= len(self.buffer)] = len(self.buffer) - 1
            result[in_time] = self.buffer[indices]
            return result

    else:
        ind = int(self.fps * tt)
        if ind < 0 or ind > self.nframes:  # out of time: return 0
            return np.zeros(self.nchannels)

        if not (0 <= (ind - self.buffer_startframe) < len(self.buffer)):
            # out of the buffer: recenter the buffer
            self.buffer_around(ind)

        # read the frame in the buffer
        return self.buffer[ind - self.buffer_startframe]