def __init__(self, *, buffer_size_seconds: Union[int, float] = 60.0, input_device_index=None, sr=44100, width=2, frames_per_buffer=DFLT_FRM_PER_BUFFER, sleep_time_on_read_none_s: Optional[Union[int, float]] = 0.05, auto_drop=True): _info = device_info_by_index(input_device_index) sr = sr or int(_info['defaultSampleRate']) channels = _info['maxInputChannels'] super().__init__( source_reader=PyAudioSourceReader( input_device_index=input_device_index, rate=sr, width=width, channels=channels, frames_per_buffer=frames_per_buffer, unsigned=False, ), maxlen=PyAudioSourceReader.audio_buffer_size_seconds_to_maxlen( buffer_size_seconds=buffer_size_seconds, rate=sr, frames_per_buffer=frames_per_buffer, ), sleep_time_on_read_none_s=sleep_time_on_read_none_s, auto_drop=auto_drop)
def live_audio_chks(input_device_index=None, sr=DFLT_SR, sample_width=DFLT_SAMPLE_WIDTH, chk_size=DFLT_CHK_SIZE, stream_buffer_size_s=DFLT_STREAM_BUF_SIZE_S): """A generator of live chunks of audio bytes taken from a stream sourced from specified microphone. :param input_device_index: Index of Input Device to use. Unspecified (or None) uses default device. :param sr: Specifies the desired sample rate (in Hz) :param sample_bytes: Sample width in bytes (1, 2, 3, or 4) :param sample_width: Specifies the number of frames per buffer. :param stream_buffer_size_s: How many seconds of data to keep in the buffer (i.e. how far in the past you can see) """ input_device_index = ensure_source_input_device_index(input_device_index) seconds_per_read = chk_size / sr maxlen = int(stream_buffer_size_s / seconds_per_read) # print(maxlen) source_reader = PyAudioSourceReader(rate=sr, width=sample_width, unsigned=True, input_device_index=input_device_index, frames_per_buffer=chk_size) # _bytes_to_waveform = partial(audio_pokes_version_of_bytes_to_waveform, sr=sr, # sample_width=sample_width) with StreamBuffer(source_reader=source_reader, maxlen=maxlen) as stream_buffer: """keep open and save to file until stop event""" yield iter(stream_buffer)
def find_a_device_index(filt='microphone', dflt=None): if isinstance(filt, str): match_str = filt def filt(x): return match_str in x.get('name', match_str).lower() match = next(filter(filt, PyAudioSourceReader.list_device_info()), None) return (match is not None and match['index']) or dflt
def record_some_sound( save_to_file, input_device_index=None, sr=DFLT_SR, sample_width=DFLT_SAMPLE_WIDTH, chk_size=DFLT_CHK_SIZE, stream_buffer_size_s=DFLT_STREAM_BUF_SIZE_S, verbose=True, ): def get_write_file_stream(): if isinstance(save_to_file, str): return open(save_to_file, 'wb') else: return save_to_file # assume it's already a stream def clog(*args, **kwargs): if verbose: print(*args, **kwargs) seconds_per_read = chk_size / sr maxlen = int(stream_buffer_size_s / seconds_per_read) source_reader = PyAudioSourceReader(rate=sr, width=sample_width, unsigned=True, input_device_index=input_device_index, frames_per_buffer=chk_size) with StreamBuffer(source_reader=source_reader, maxlen=maxlen) as stream_buffer: """keep open and save to file until stop event""" clog("starting the recording...") with get_write_file_stream() as write_stream: while True: try: chk = source_reader.read() print(type(chk), len(chk)) except KeyboardInterrupt: clog("stopping the recording...") break clog('Done.')
def __post_init__(self): self.input_device_index = ensure_source_input_device_index( self.input_device_index) seconds_per_read = self.chk_size / self.sr self.maxlen = int(self.stream_buffer_size_s / seconds_per_read) self.source_reader = PyAudioSourceReader( rate=self.sr, width=self.sample_width, unsigned=True, input_device_index=self.input_device_index, frames_per_buffer=self.chk_size) super().__init__(source_reader=self.source_reader, maxlen=self.maxlen)
def audio_to_files(rate, width, channels, input_device_index, frames_per_buffer, interval, rootdir, logging_enabled): """Basically the main function to run the example. It will record audio with stream2py.sources.audio.PyAudioSourceReader and save to wav files with stream2py.examples.usage.record_audio_to_files.PyAudioSaver Check this source code to see how to put together the three components: SourceReader, StreamBuffer, BufferReader :param rate: Specifies the desired sample rate (in Hz) :param width: Sample width in bytes (1, 2, 3, or 4) :param channels: The desired number of input channels. Ignored if input_device is not specified (or None). :param input_device_index: Index of Input Device to use. Unspecified (or None) uses default device. :param frames_per_buffer: Specifies the number of frames per buffer. :param interval: seconds between reader_handler calls :param rootdir: folder path where files will be saved under :param logging_enabled: log debug messages using logging module """ from stream2py.utility.logger import set_logging_config set_logging_config(level=logging.DEBUG) seconds_per_read = frames_per_buffer / rate seconds_to_keep_in_stream_buffer = 60 maxlen = int(seconds_to_keep_in_stream_buffer / seconds_per_read) source_reader = PyAudioSourceReader(rate=rate, width=width, channels=channels, unsigned=True, input_device_index=input_device_index, frames_per_buffer=frames_per_buffer) with StreamBuffer(source_reader=source_reader, maxlen=maxlen) as stream_buffer: """keep open and save to file until stop event""" buffer_reader = stream_buffer.mk_reader() with PyAudioSaver(buffer_reader, interval=interval, rootdir=rootdir, logging_enabled=logging_enabled) as pasave: try: pasave.join() except KeyboardInterrupt: pass
def ensure_source_input_device_index(input_device_index=None): if input_device_index is None: input_device_index = find_a_default_input_device_index() if input_device_index is not None: if isinstance(input_device_index, int): return input_device_index elif isinstance(input_device_index, str): input_name = input_device_index for index, name in list_recording_device_index_names(): if name == input_name: return index raise ValueError( f"name not found in list of recording devices: {input_name}") elif isinstance(input_device_index, tuple) and len(input_device_index) == 2: index, name = input_device_index assert isinstance( index, int ), f"expecting first element of tuple to be an int: {input_device_index}" assert isinstance( name, str ), f"expecting second element of tuple to be a string: {input_device_index}" return index else: raise ValueError( f"couldn't resolve input_device_index: {input_device_index}") else: # TODO: Nicer way to print info (perhaps only relevant info, formated as table) print( "Need a valid input_device_index. Calling live_audio_chks.list_device_info() to information about the " "devices I can detect:\n") for item in PyAudioSourceReader.list_device_info(): print(item) print("") print( "---> Look in the list above and choose an input_device_index (it's called index in the printout above) " "that seems to be right for you!") raise ValueError("Need a valid input_device_index")
unsigned=True, input_device_index=input_device_index, frames_per_buffer=frames_per_buffer) with StreamBuffer(source_reader=source_reader, maxlen=maxlen) as stream_buffer: """keep open and save to file until stop event""" buffer_reader = stream_buffer.mk_reader() with PyAudioSaver(buffer_reader, interval=interval, rootdir=rootdir, logging_enabled=logging_enabled) as pasave: try: pasave.join() except KeyboardInterrupt: pass audio_to_files.list_device_info = lambda: PyAudioSourceReader.list_device_info( ) if __name__ == "__main__": audio_to_files(rate=44100, width=2, channels=1, input_device_index=6, frames_per_buffer=1024 * 4, interval=1, rootdir="~/odir/stream2py", logging_enabled=True)
def list_recording_device_index_names(): """List (index, name) of available recording devices""" return sorted((d['index'], d['name']) for d in PyAudioSourceReader.list_device_info() if d['maxInputChannels'] > 0)
def device_info_by_index(index): try: return next(d for d in PyAudioSourceReader.list_device_info() if d['index'] == index) except StopIteration: raise ValueError(f"Not found for input device index: {index}")
if __name__ == '__main__': # workon p3 # cd /Users/vmacari/projects/OtoBox/python/stream2py/stream2py/examples # export PYTHONPATH=/Users/vmacari/projects/OtoBox/python/stream2py/ preader = PlcReader('192.168.0.19', items_to_read=read_items, rack=0, slot=0, sleep_time=0) areader = PyAudioSourceReader(rate=44100, width=2, channels=1, input_device_index=1, frames_per_buffer=4096) try: areader.open() pprint(areader.info) except Exception as ex: loge(ex) exit(-1) try: if not preader.open(): preader.close() loge("ERROR: Failed to connect to PLC ?") exit(-1)