コード例 #1
0
 def rec(self, duration=None, channels=1, fs=96000, frames_per_buffer=1024, dtype=np.float32):
     """Record. If dropouts or buffer underruns occur try different
     values for the frames_per_buffer variable."""
     
     _Device.rec(self, duration=duration, channels=channels, fs=fs)
     self._validate(frames_per_buffer)
     
     missing_frames = self._get_missing_frames(frames_per_buffer, int(duration*fs))
     
     nofsamples = missing_frames+int(duration*fs)
     
     rec = Audio(channels=channels, fs=fs, nofsamples=nofsamples, dtype=dtype)
     
     assert len(rec)%frames_per_buffer == 0
     
     stream = self.pa.open(format                = self._data_format(rec),
                           channels              = rec.ch,
                           rate                  = rec.fs,
                           frames_per_buffer     = frames_per_buffer,
                           input_device_index    = self._index_in,
                           input                 = True,
                           output                = False,
                           )
     try:
         self._logger.info("rec: start")
         counter = 0
         
         # split the audio into chunks the size of one buffer, so we can
         # iterate over the audio in chunksizes of the same size as one buffer
         it_in = iter(np.split(rec.samples, len(rec)/frames_per_buffer))
         try:
             while True:
                 chunk_in    = it_in.next()
                 raw_1d      = np.fromstring(stream.read(frames_per_buffer),
                                             dtype=rec.samples.dtype)
                 # because we use an iterator chunk_in is a sliding window in the rec variable
                 chunk_in[:] = raw_1d.reshape((frames_per_buffer, rec.ch))
                 
                 counter += 1
                 
         except StopIteration:
             pass
             
         finally:
             stream.stop_stream()
             
         self._logger.debug("chunks recorded : %i" %counter)
         self._logger.debug("samples recorded: %i" %(counter*frames_per_buffer))
         self._logger.debug("duration        : %.3f" %(counter*frames_per_buffer/rec.fs))
         
     finally:
         self._logger.debug("rec: close stream")
         stream.close()
         
     # remove the padding (empty frames) added to fill the last buffer. Trim
     # at the start, since we can treat that as latency.
     rec.trim(start=missing_frames, end=None)
     
     self._logger.debug("rec: trimmed %i samples from the start" %missing_frames)
     self._check_if_clipped(rec)
     self._logger.info("rec: done")
     
     return rec
コード例 #2
0
 def play_rec(self, x, frames_per_buffer=1024):
     """Play audio and record from input. If dropouts or buffer underruns occur
     try different values for the frames_per_buffer variable."""
     
     _Device.play_rec(self, x)
     self._validate(frames_per_buffer)
     
     missing_frames = self._get_missing_frames(frames_per_buffer, len(x))
     
     # generate silence to fill up missing frames
     pad = Audio(channels=x.ch, fs=x.fs, nofsamples=missing_frames, dtype=x.samples.dtype)
     
     # append the missing frames to a copy of the audio to be played. We now have
     # audio that can be split into complete (full) buffers
     cpy = Audio(fs=x.fs, initialdata=x.samples)
     cpy.concat(pad)
     
     assert len(cpy)%frames_per_buffer == 0
     
     rec = Audio(channels=cpy.ch, fs=cpy.fs, nofsamples=len(cpy), dtype=cpy.samples.dtype)
     
     stream = self.pa.open(format                = self._data_format(x),
                           channels              = x.ch,
                           rate                  = x.fs,
                           frames_per_buffer     = frames_per_buffer,
                           input_device_index    = self._index_in,
                           output_device_index   = self._index_out,
                           input                 = True,
                           output                = True,
                           )
     try:
         self._logger.info("play_rec: start")
         counter = 0
         
         # split the audio into chunks the size of one buffer, so we can
         # iterate over the audio in chunksizes of the same size as one buffer
         it_out = iter(np.split(cpy.samples, len(cpy)/frames_per_buffer))
         it_in  = iter(np.split(rec.samples, len(rec)/frames_per_buffer))
         try:
             while True:
                 chunk_out   = it_out.next()
                 chunk_in    = it_in.next()
                 
                 stream.write(chunk_out.tostring(), num_frames=frames_per_buffer)
                 
                 raw_1d      = np.fromstring(stream.read(frames_per_buffer),
                                             dtype=rec.samples.dtype)
                 # because we use an iterator chunk_in is a sliding window in the rec variable
                 chunk_in[:] = raw_1d.reshape((frames_per_buffer, rec.ch))
                 
                 counter += 1
                 
         except StopIteration:
             pass
             
         finally:
             stream.stop_stream()
             
         self._logger.debug("chunks played  : %i"    %counter)
         self._logger.debug("samples played : %i"    %(counter*frames_per_buffer))
         self._logger.debug("duration       : %.3f"  %(counter*frames_per_buffer/x.fs))
         
     finally:
         self._logger.debug("play_rec: close stream")
         stream.close()
         
     # remove the padding (empty frames) added to fill the last buffer. Trim
     # at the start, since we can treat that as latency.
     rec.trim(start=missing_frames, end=None)
     
     self._logger.debug("play_rec: trimmed %i samples from the start" %missing_frames)
     self._check_if_clipped(rec)
     self._logger.info("play_rec: done")
     
     return rec