class_docstr: A class to read the audio in either video files or audio files
  using ffmpeg. ffmpeg will read any audio and transform them into
  raw data.
  
  Parameters
  ----------
  
  filename
    Name of any video or audio file, like ``video.mp4`` or
    ``sound.wav`` etc.
  
  buffersize
    The size of the buffer to use. Should be bigger than the buffer
    used by ``write_audiofile``
  
  print_infos
    Print the ffmpeg infos on the file being read (for debugging)
  
  fps
    Desired frames per second in the decoded signal that will be
    received from ffmpeg
  
  nbytes
    Desired number of bytes (1,2,4) in the signal that will be
    received from ffmpeg
docstr: TODO: add documentation
docstr_tok: ["TODO",":","add","documentation"]
code: def get_frame(self, tt):
      """TODO: add documentation"""
      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=%f 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.n_frames:  # 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]
  
file_path: moviepy/moviepy/audio/io/readers.py
imports: import subprocess
  import warnings
  import numpy
  from moviepy.config import FFMPEG_BINARY
  from moviepy.tools import cross_platform_popen_params
  from moviepy.video.io.ffmpeg_reader import ffmpeg_parse_infos
label_desc: Use image node_id 6 for calling the FFMPEG_AudioReader obj's underlying member method code with example usage: obj.get_frame(tt) and returns: self, result, np, result