def __init__(self, device_index: int = None, channels: int = 1, sample_format: int = PA_INT16, sample_rate: int = None): device_info = Devices.get_device_info_by_index(device_index) if sample_rate is None: sample_rate = device_info.default_sample_rate super().__init__(AudioSettings(channels, sample_format, sample_rate)) self._loop = get_event_loop() self._lock = Lock() self._waiter = None self._need_buffers = None # 5 sec self._audio_buffer = deque(maxlen=500) settings = self.get_settings() msg = 'Param "channel" must be less than {}'.format( device_info.max_input_channels + 1) assert settings.channels <= device_info.max_input_channels, msg arguments = { 'rate': settings.sample_rate, 'channels': settings.channels, 'format': settings.sample_format, 'input': True, 'output': False, 'input_device_index': device_info.index, 'output_device_index': None, 'frames_per_buffer': settings.get_frames_count_by_duration_ms(10), 'stream_callback': self._audio_callback } self._stream = pa.open(**arguments) self._is_started = False
def __init__(self, PA_manager, rate, channels, format, input=False, output=False, input_device_index=None, output_device_index=None, frames_per_buffer=1024, start=True, input_host_api_specific_stream_info=None, output_host_api_specific_stream_info=None, stream_callback=None): """ Initialize a stream; this should be called by :py:func:`PyAudio.open`. A stream can either be input, output, or both. :param PA_manager: A reference to the managing :py:class:`PyAudio` instance :param rate: Sampling rate :param channels: Number of channels :param format: Sampling size and format. See |PaSampleFormat|. :param input: Specifies whether this is an input stream. Defaults to ``False``. :param output: Specifies whether this is an output stream. Defaults to ``False``. :param input_device_index: Index of Input Device to use. Unspecified (or ``None``) uses default device. Ignored if `input` is ``False``. :param output_device_index: Index of Output Device to use. Unspecified (or ``None``) uses the default device. Ignored if `output` is ``False``. :param frames_per_buffer: Specifies the number of frames per buffer. :param start: Start the stream running immediately. Defaults to ``True``. In general, there is no reason to set this to ``False``. :param input_host_api_specific_stream_info: Specifies a host API specific stream information data structure for input. .. only:: pamac See :py:class:`PaMacCoreStreamInfo`. :param output_host_api_specific_stream_info: Specifies a host API specific stream information data structure for output. .. only:: pamac See :py:class:`PaMacCoreStreamInfo`. :param stream_callback: Specifies a callback function for *non-blocking* (callback) operation. Default is ``None``, which indicates *blocking* operation (i.e., :py:func:`Stream.read` and :py:func:`Stream.write`). To use non-blocking operation, specify a callback that conforms to the following signature: .. code-block:: python callback(in_data, # recorded data if input=True; else None frame_count, # number of frames time_info, # dictionary status_flags) # PaCallbackFlags ``time_info`` is a dictionary with the following keys: ``input_buffer_adc_time``, ``current_time``, and ``output_buffer_dac_time``; see the PortAudio documentation for their meanings. ``status_flags`` is one of |PaCallbackFlags|. The callback must return a tuple: .. code-block:: python (out_data, flag) ``out_data`` is a byte array whose length should be the (``frame_count * channels * bytes-per-channel``) if ``output=True`` or ``None`` if ``output=False``. ``flag`` must be either :py:data:`paContinue`, :py:data:`paComplete` or :py:data:`paAbort` (one of |PaCallbackReturnCodes|). When ``output=True`` and ``out_data`` does not contain at least ``frame_count`` frames, :py:data:`paComplete` is assumed for ``flag``. **Note:** ``stream_callback`` is called in a separate thread (from the main thread). Exceptions that occur in the ``stream_callback`` will: 1. print a traceback on standard error to aid debugging, 2. queue the exception to be thrown (at some point) in the main thread, and 3. return `paAbort` to PortAudio to stop the stream. **Note:** Do not call :py:func:`Stream.read` or :py:func:`Stream.write` if using non-blocking operation. **See:** PortAudio's callback signature for additional details: http://portaudio.com/docs/v19-doxydocs/portaudio_8h.html#a8a60fb2a5ec9cbade3f54a9c978e2710 :raise ValueError: Neither input nor output are set True. """ # no stupidity allowed if not (input or output): raise ValueError("Must specify an input or output " + "stream.") # remember parent self._parent = PA_manager # remember if we are an: input, output (or both) self._is_input = input self._is_output = output # are we running? self._is_running = start # remember some parameters self._rate = rate self._channels = channels self._format = format self._frames_per_buffer = frames_per_buffer arguments = { 'rate': rate, 'channels': channels, 'format': format, 'input': input, 'output': output, 'input_device_index': input_device_index, 'output_device_index': output_device_index, 'frames_per_buffer': frames_per_buffer } if input_host_api_specific_stream_info: _l = input_host_api_specific_stream_info arguments[ 'input_host_api_specific_stream_info'] = _l._get_host_api_stream_object( ) if output_host_api_specific_stream_info: _l = output_host_api_specific_stream_info arguments[ 'output_host_api_specific_stream_info'] = _l._get_host_api_stream_object( ) if stream_callback: arguments['stream_callback'] = stream_callback # calling pa.open returns a stream object self._stream = pa.open(**arguments) self._input_latency = self._stream.inputLatency self._output_latency = self._stream.outputLatency if self._is_running: pa.start_stream(self._stream)
def __init__(self, PA_manager, rate, channels, format, input=False, output=False, input_device_index=None, output_device_index=None, frames_per_buffer=1024, start=True, input_host_api_specific_stream_info=None, output_host_api_specific_stream_info=None): """ Initialize a stream; this should be called by `PyAudio.open`. A stream can either be input, output, or both. :param `PA_manager`: A reference to the managing `PyAudio` instance :param `rate`: Sampling rate :param `channels`: Number of channels :param `format`: Sampling size and format. See `PaSampleFormat`. :param `input`: Specifies whether this is an input stream. Defaults to False. :param `output`: Specifies whether this is an output stream. Defaults to False. :param `input_device_index`: Index of Input Device to use. Unspecified (or None) uses default device. Ignored if `input` is False. :param `output_device_index`: Index of Output Device to use. Unspecified (or None) uses the default device. Ignored if `output` is False. :param `frames_per_buffer`: Specifies the number of frames per buffer. :param `start`: Start the stream running immediately. Defaults to True. In general, there is no reason to set this to false. :param `input_host_api_specific_stream_info`: Specifies a host API specific stream information data structure for input. See `PaMacCoreStreamInfo`. :param `output_host_api_specific_stream_info`: Specifies a host API specific stream information data structure for output. See `PaMacCoreStreamInfo`. :raise ValueError: Neither input nor output are set True. """ # no stupidity allowed if not (input or output): raise ValueError, \ "Must specify an input or output " +\ "stream." # remember parent self._parent = PA_manager # remember if we are an: input, output (or both) self._is_input = input self._is_output = output # are we running? self._is_running = start # remember some parameters self._rate = rate self._channels = channels self._format = format self._frames_per_buffer = frames_per_buffer arguments = { 'rate': rate, 'channels': channels, 'format': format, 'input': input, 'output': output, 'input_device_index': input_device_index, 'output_device_index': output_device_index, 'frames_per_buffer': frames_per_buffer } if input_host_api_specific_stream_info: _l = input_host_api_specific_stream_info arguments[ 'input_host_api_specific_stream_info'] = _l._get_host_api_stream_object( ) if output_host_api_specific_stream_info: _l = output_host_api_specific_stream_info arguments[ 'output_host_api_specific_stream_info'] = _l._get_host_api_stream_object( ) # calling pa.open returns a stream object self._stream = pa.open(**arguments) self._input_latency = self._stream.inputLatency self._output_latency = self._stream.outputLatency if self._is_running: pa.start_stream(self._stream)
def __init__(self, PA_manager, rate, channels, format, input = False, output = False, input_device_index = None, output_device_index = None, frames_per_buffer = 1024, start = True, input_host_api_specific_stream_info = None, output_host_api_specific_stream_info = None, stream_callback = None): """ Initialize a stream; this should be called by `PyAudio.open`. A stream can either be input, output, or both. :param `PA_manager`: A reference to the managing `PyAudio` instance. :param `rate`: Sampling rate. :param `channels`: Number of channels. :param `format`: Sampling size and format. See `PaSampleFormat`. :param `input`: Specifies whether this is an input stream. Defaults to False. :param `output`: Specifies whether this is an output stream. Defaults to False. :param `input_device_index`: Index of Input Device to use. Unspecified (or None) uses default device. Ignored if `input` is False. :param `output_device_index`: Index of Output Device to use. Unspecified (or None) uses the default device. Ignored if `output` is False. :param `frames_per_buffer`: Specifies the number of frames per buffer. :param `start`: Start the stream running immediately. Defaults to True. In general, there is no reason to set this to false. :param `input_host_api_specific_stream_info`: Specifies a host API specific stream information data structure for input. See `PaMacCoreStreamInfo`. :param `output_host_api_specific_stream_info`: Specifies a host API specific stream information data structure for output. See `PaMacCoreStreamInfo`. :param `stream_callback`: Specifies a callback function. The callback function must conform to the following signature: ``callback(in_data, frame_count, time_info, flags)`` The function will be called whenever PyAudio needs new audio data to play or has new data available from its inputs. ``in_data`` contains the input data (if available). ``frame_count`` is the number of frames available/required. ``time_info`` is a dictionary containing the current time, the time the ADC recorded the last sample, and the time the ADC will output the first sample. ``flags`` contains a bitwise and of some callback error flags. These are ``paInputOverflow``, ``paInputUnderflow``, ``paOutputOverflow``, ``paOutputUnderflow``, and ``paPrimingOutput``. The function must return either a tuple containing the frames to play and a status flag or just the audio data. If given a tuple, the flag can be either `paContinue` (normal playback/recording), `paComplete` (stop playing/recording after this block) or `paAbort` (error). If given just the audio data, returning an exactly the right number of frames implies ``paContinue``, while returning less than the right number of frames implies ``paComplete``. Returning nothing implies ``paError``. :raise ValueError: Neither input nor output are set True. """ # no stupidity allowed if not (input or output): raise ValueError("Must specify an input or output " + "stream.") # remember parent self._parent = PA_manager # remember if we are an: input, output (or both) self._is_input = input self._is_output = output # are we running? self._is_running = start # remember some parameters self._rate = rate self._channels = channels self._format = format self._frames_per_buffer = frames_per_buffer arguments = { 'rate' : rate, 'channels' : channels, 'format' : format, 'input' : input, 'output' : output, 'input_device_index' : input_device_index, 'output_device_index' : output_device_index, 'frames_per_buffer' : frames_per_buffer} if input_host_api_specific_stream_info: _l = input_host_api_specific_stream_info arguments[ 'input_host_api_specific_stream_info' ] = _l._get_host_api_stream_object() if output_host_api_specific_stream_info: _l = output_host_api_specific_stream_info arguments[ 'output_host_api_specific_stream_info' ] = _l._get_host_api_stream_object() if stream_callback: arguments[ 'stream_callback' ] = stream_callback # calling pa.open returns a stream object self._stream = pa.open(**arguments) self._input_latency = self._stream.inputLatency self._output_latency = self._stream.outputLatency if self._is_running: pa.start_stream(self._stream)
FORMAT = _portaudio.paInt16 CHANNELS = 2 RATE = 44100 RECORD_SECONDS = 5 # poor PPC macs... if sys.platform == 'darwin': CHANNELS = 1 print "* initializing" _portaudio.initialize() print "* opening" stream_input = _portaudio.open(format = FORMAT, channels = CHANNELS, rate = RATE, input = True, frames_per_buffer = chunk) stream_output = _portaudio.open(format = FORMAT, channels = CHANNELS, rate = RATE, output = True, frames_per_buffer = chunk) print "* starting stream" _portaudio.start_stream(stream_input) _portaudio.start_stream(stream_output) print "* recording"
def __init__(self, PA_manager, rate, channels, format, input=False, output=False, input_device_index=None, output_device_index=None, frames_per_buffer=1024, start=True, input_host_api_specific_stream_info=None, output_host_api_specific_stream_info=None, stream_callback=None): """ Initialize a stream; this should be called by `PyAudio.open`. A stream can either be input, output, or both. :param `PA_manager`: A reference to the managing `PyAudio` instance. :param `rate`: Sampling rate. :param `channels`: Number of channels. :param `format`: Sampling size and format. See `PaSampleFormat`. :param `input`: Specifies whether this is an input stream. Defaults to False. :param `output`: Specifies whether this is an output stream. Defaults to False. :param `input_device_index`: Index of Input Device to use. Unspecified (or None) uses default device. Ignored if `input` is False. :param `output_device_index`: Index of Output Device to use. Unspecified (or None) uses the default device. Ignored if `output` is False. :param `frames_per_buffer`: Specifies the number of frames per buffer. :param `start`: Start the stream running immediately. Defaults to True. In general, there is no reason to set this to false. :param `input_host_api_specific_stream_info`: Specifies a host API specific stream information data structure for input. See `PaMacCoreStreamInfo`. :param `output_host_api_specific_stream_info`: Specifies a host API specific stream information data structure for output. See `PaMacCoreStreamInfo`. :param `stream_callback`: Specifies a callback function. The callback function must conform to the following signature: ``callback(in_data, frame_count, time_info, flags)`` The function will be called whenever PyAudio needs new audio data to play or has new data available from its inputs. ``in_data`` contains the input data (if available). ``frame_count`` is the number of frames available/required. ``time_info`` is a dictionary containing the current time, the time the ADC recorded the last sample, and the time the ADC will output the first sample. ``flags`` contains a bitwise and of some callback error flags. These are ``paInputOverflow``, ``paInputUnderflow``, ``paOutputOverflow``, ``paOutputUnderflow``, and ``paPrimingOutput``. The function must return either a tuple containing the frames to play and a status flag or just the audio data. If given a tuple, the flag can be either `paContinue` (normal playback/recording), `paComplete` (stop playing/recording after this block) or `paAbort` (error). If given just the audio data, returning an exactly the right number of frames implies ``paContinue``, while returning less than the right number of frames implies ``paComplete``. Returning nothing implies ``paError``. :raise ValueError: Neither input nor output are set True. """ # no stupidity allowed if not (input or output): raise ValueError("Must specify an input or output " + "stream.") # remember parent self._parent = PA_manager # remember if we are an: input, output (or both) self._is_input = input self._is_output = output # are we running? self._is_running = start # remember some parameters self._rate = rate self._channels = channels self._format = format self._frames_per_buffer = frames_per_buffer arguments = { 'rate': rate, 'channels': channels, 'format': format, 'input': input, 'output': output, 'input_device_index': input_device_index, 'output_device_index': output_device_index, 'frames_per_buffer': frames_per_buffer } if input_host_api_specific_stream_info: _l = input_host_api_specific_stream_info arguments[ 'input_host_api_specific_stream_info'] = _l._get_host_api_stream_object( ) if output_host_api_specific_stream_info: _l = output_host_api_specific_stream_info arguments[ 'output_host_api_specific_stream_info'] = _l._get_host_api_stream_object( ) if stream_callback: arguments['stream_callback'] = stream_callback # calling pa.open returns a stream object self._stream = pa.open(**arguments) self._input_latency = self._stream.inputLatency self._output_latency = self._stream.outputLatency if self._is_running: pa.start_stream(self._stream)
def __init__(self, PA_manager, rate, channels, format, input=False, output=False, input_device_index=None, output_device_index=None, frames_per_buffer=1024, start=True, input_host_api_specific_stream_info=None, output_host_api_specific_stream_info=None, stream_callback=None): """ Initialize a stream; this should be called by :py:func:`PyAudio.open`. A stream can either be input, output, or both. :param PA_manager: A reference to the managing :py:class:`PyAudio` instance :param rate: Sampling rate :param channels: Number of channels :param format: Sampling size and format. See |PaSampleFormat|. :param input: Specifies whether this is an input stream. Defaults to ``False``. :param output: Specifies whether this is an output stream. Defaults to ``False``. :param input_device_index: Index of Input Device to use. Unspecified (or ``None``) uses default device. Ignored if `input` is ``False``. :param output_device_index: Index of Output Device to use. Unspecified (or ``None``) uses the default device. Ignored if `output` is ``False``. :param frames_per_buffer: Specifies the number of frames per buffer. :param start: Start the stream running immediately. Defaults to ``True``. In general, there is no reason to set this to ``False``. :param input_host_api_specific_stream_info: Specifies a host API specific stream information data structure for input. .. only:: pamac See :py:class:`PaMacCoreStreamInfo`. :param output_host_api_specific_stream_info: Specifies a host API specific stream information data structure for output. .. only:: pamac See :py:class:`PaMacCoreStreamInfo`. :param stream_callback: Specifies a callback function for *non-blocking* (callback) operation. Default is ``None``, which indicates *blocking* operation (i.e., :py:func:`Stream.read` and :py:func:`Stream.write`). To use non-blocking operation, specify a callback that conforms to the following signature: .. code-block:: python callback(in_data, # recorded data if input=True; else None frame_count, # number of frames time_info, # dictionary status_flags) # PaCallbackFlags ``time_info`` is a dictionary with the following keys: ``input_buffer_adc_time``, ``current_time``, and ``output_buffer_dac_time``; see the PortAudio documentation for their meanings. ``status_flags`` is one of |PaCallbackFlags|. The callback must return a tuple: .. code-block:: python (out_data, flag) ``out_data`` is a byte array whose length should be the (``frame_count * channels * bytes-per-channel``) if ``output=True`` or ``None`` if ``output=False``. ``flag`` must be either :py:data:`paContinue`, :py:data:`paComplete` or :py:data:`paAbort` (one of |PaCallbackReturnCodes|). When ``output=True`` and ``out_data`` does not contain at least ``frame_count`` frames, :py:data:`paComplete` is assumed for ``flag``. **Note:** ``stream_callback`` is called in a separate thread (from the main thread). Exceptions that occur in the ``stream_callback`` will: 1. print a traceback on standard error to aid debugging, 2. queue the exception to be thrown (at some point) in the main thread, and 3. return `paAbort` to PortAudio to stop the stream. **Note:** Do not call :py:func:`Stream.read` or :py:func:`Stream.write` if using non-blocking operation. **See:** PortAudio's callback signature for additional details: http://portaudio.com/docs/v19-doxydocs/portaudio_8h.html#a8a60fb2a5ec9cbade3f54a9c978e2710 :raise ValueError: Neither input nor output are set True. """ # no stupidity allowed if not (input or output): raise ValueError("Must specify an input or output " + "stream.") # remember parent self._parent = PA_manager # remember if we are an: input, output (or both) self._is_input = input self._is_output = output # are we running? self._is_running = start # remember some parameters self._rate = rate self._channels = channels self._format = format self._frames_per_buffer = frames_per_buffer arguments = { 'rate' : rate, 'channels' : channels, 'format' : format, 'input' : input, 'output' : output, 'input_device_index' : input_device_index, 'output_device_index' : output_device_index, 'frames_per_buffer' : frames_per_buffer} if input_host_api_specific_stream_info: _l = input_host_api_specific_stream_info arguments[ 'input_host_api_specific_stream_info' ] = _l._get_host_api_stream_object() if output_host_api_specific_stream_info: _l = output_host_api_specific_stream_info arguments[ 'output_host_api_specific_stream_info' ] = _l._get_host_api_stream_object() if stream_callback: arguments['stream_callback'] = stream_callback # calling pa.open returns a stream object self._stream = pa.open(**arguments) self._input_latency = self._stream.inputLatency self._output_latency = self._stream.outputLatency if self._is_running: pa.start_stream(self._stream)
def __init__(self, PA_manager, rate, channels, format, input = False, output = False, input_device_index = None, output_device_index = None, frames_per_buffer = 1024, start = True, input_host_api_specific_stream_info = None, output_host_api_specific_stream_info = None, stream_callback = None): """ Initialize a stream; this should be called by `PyAudio.open`. A stream can either be input, output, or both. :param `PA_manager`: A reference to the managing `PyAudio` instance :param `rate`: Sampling rate :param `channels`: Number of channels :param `format`: Sampling size and format. See `PaSampleFormat`. :param `input`: Specifies whether this is an input stream. Defaults to False. :param `output`: Specifies whether this is an output stream. Defaults to False. :param `input_device_index`: Index of Input Device to use. Unspecified (or None) uses default device. Ignored if `input` is False. :param `output_device_index`: Index of Output Device to use. Unspecified (or None) uses the default device. Ignored if `output` is False. :param `frames_per_buffer`: Specifies the number of frames per buffer. :param `start`: Start the stream running immediately. Defaults to True. In general, there is no reason to set this to false. :param `input_host_api_specific_stream_info`: Specifies a host API specific stream information data structure for input. See `PaMacCoreStreamInfo`. :param `output_host_api_specific_stream_info`: Specifies a host API specific stream information data structure for output. See `PaMacCoreStreamInfo`. :param `stream_callback1: Specifies a callback function the callback function must conform to the following signature: callback(frame_count, input_time, current_time, output_time, in_data) and it must return a tuple (out_data, flag), where flag must be either paContinue, paComplete or paAbort. If out_data does not contain at least frame_count frames, paComplete will be assumed. :raise ValueError: Neither input nor output are set True. """ # no stupidity allowed if not (input or output): raise ValueError, \ "Must specify an input or output " +\ "stream." # remember parent self._parent = PA_manager # remember if we are an: input, output (or both) self._is_input = input self._is_output = output # are we running? self._is_running = start # remember some parameters self._rate = rate self._channels = channels self._format = format self._frames_per_buffer = frames_per_buffer arguments = { 'rate' : rate, 'channels' : channels, 'format' : format, 'input' : input, 'output' : output, 'input_device_index' : input_device_index, 'output_device_index' : output_device_index, 'frames_per_buffer' : frames_per_buffer} if input_host_api_specific_stream_info: _l = input_host_api_specific_stream_info arguments[ 'input_host_api_specific_stream_info' ] = _l._get_host_api_stream_object() if output_host_api_specific_stream_info: _l = output_host_api_specific_stream_info arguments[ 'output_host_api_specific_stream_info' ] = _l._get_host_api_stream_object() if stream_callback: arguments[ 'stream_callback' ] = stream_callback # calling pa.open returns a stream object self._stream = pa.open(**arguments) self._input_latency = self._stream.inputLatency self._output_latency = self._stream.outputLatency if self._is_running: pa.start_stream(self._stream)
raise ValueError("Invalid width: %d" % width) if len(sys.argv) < 2: print("Usage: %s filename.wav" % sys.argv[0]) sys.exit(-1) wf = wave.open(sys.argv[1], 'rb') print("* initializing") _portaudio.initialize() print("* opening") stream = _portaudio.open(format=get_format_from_width(wf.getsampwidth()), channels=wf.getnchannels(), rate=wf.getframerate(), input=True, output=True) data = wf.readframes(chunk) print("* starting stream") _portaudio.start_stream(stream) while data != '': _portaudio.write_stream(stream, data, chunk) data = wf.readframes(chunk) # OK... _portaudio.close(stream)
chunk = 1024 if len(sys.argv) < 2: print "Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0] sys.exit(-1) wf = wave.open(sys.argv[1], 'rb') print "* initializing" _portaudio.initialize() print "* opening" stream = _portaudio.open(rate = wf.getframerate(), channels = wf.getnchannels(), format = get_format_from_width(wf.getsampwidth()), output = True) data = wf.readframes(chunk) print "* starting stream" _portaudio.start_stream(stream) print "available: %d" % _portaudio.get_stream_write_available(stream) while data != '': _portaudio.write_stream(stream, data, chunk) data = wf.readframes(chunk) print "* stopping stream" _portaudio.stop_stream(stream)