### Example Output on macOS Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/checking-hardware.md This is an example of the output you might see when querying audio devices on a macOS system. ```python >>> sd.query_devices() 0 Built-in Line Input, Core Audio (2 in, 0 out) > 1 Built-in Digital Input, Core Audio (2 in, 0 out) < 2 Built-in Output, Core Audio (0 in, 2 out) 3 Built-in Line Output, Core Audio (0 in, 2 out) 4 Built-in Digital Output, Core Audio (0 in, 2 out) ``` -------------------------------- ### Example Output on GNU/Linux Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/checking-hardware.md This is an example of the output you might see when querying audio devices on a GNU/Linux system. ```python >>> import sounddevice as sd >>> sd.query_devices() 0 HDA Intel: ALC662 rev1 Analog (hw:0,0), ALSA (2 in, 2 out) 1 HDA Intel: ALC662 rev1 Digital (hw:0,1), ALSA (0 in, 2 out) 2 HDA Intel: HDMI 0 (hw:0,3), ALSA (0 in, 8 out) 3 sysdefault, ALSA (128 in, 128 out) 4 front, ALSA (0 in, 2 out) 5 surround40, ALSA (0 in, 2 out) 6 surround51, ALSA (0 in, 2 out) 7 surround71, ALSA (0 in, 2 out) 8 iec958, ALSA (0 in, 2 out) 9 spdif, ALSA (0 in, 2 out) 10 hdmi, ALSA (0 in, 8 out) * 11 default, ALSA (128 in, 128 out) 12 dmix, ALSA (0 in, 2 out) 13 /dev/dsp, OSS (16 in, 16 out) ``` -------------------------------- ### Display Help Text for Play File Example Source: https://github.com/spatialaudio/python-sounddevice/blob/master/examples/README.rst Shows how to display the help text for the `play_file.py` example program using the `--help` argument. This is useful for understanding available command-line options. ```bash python play_file.py --help ``` -------------------------------- ### Install sounddevice using pip Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/installation.md Install the latest release of the sounddevice module using pip after activating a virtual environment. ```bash python -m pip install sounddevice ``` -------------------------------- ### Install Documentation Dependencies Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/contributing.md Install Sphinx and other required packages for building documentation using pip in editable mode with the 'doc' extra. ```shell python -m pip install -e . --group doc ``` -------------------------------- ### Main Execution with Audio Wire Example Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/examples.md This main function orchestrates the audio wire example. It first shows input information and then activates the audio routing coroutine for a set duration before cancelling it. Requires Python 3.7+. ```Python async def main(**kwargs): print('Some information about the input signal:') try: await asyncio.wait_for(print_input_infos(), timeout=2) except asyncio.TimeoutError: pass print('\nEnough of that, activating wire ...\n') audio_task = asyncio.create_task(wire_coro(**kwargs)) for i in range(10, 0, -1): print(i) await asyncio.sleep(1) audio_task.cancel() try: await audio_task except asyncio.CancelledError: print('\nwire was cancelled') if __name__ == "__main__": try: asyncio.run(main(blocksize=1024)) except KeyboardInterrupt: sys.exit('\nInterrupted by user') ``` -------------------------------- ### Install Development Version from GitHub Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/contributing.md Clone the repository and install the latest development version using pip in editable mode. This command also triggers the build process. ```shell git clone --recursive https://github.com/spatialaudio/python-sounddevice.git cd python-sounddevice python -m pip install -e . python sounddevice_build.py ``` -------------------------------- ### Install NumPy using pip Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/installation.md Install the NumPy library using pip, which is required for playing back and recording NumPy arrays with sounddevice. ```bash python -m pip install numpy ``` -------------------------------- ### Install sounddevice using conda Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/installation.md Install the sounddevice module from the conda-forge channel using the conda package manager. ```bash conda install -c conda-forge python-sounddevice ``` -------------------------------- ### Display All Audio Devices Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/checking-hardware.md This example shows how to import the sounddevice library and query all available audio devices. The output lists each device with its ID, name, host API, and channel information. ```python import sounddevice as sd print(sd.query_devices()) ``` -------------------------------- ### Example Python Code for Reporting Bugs Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/contributing.md Provide a minimal, runnable Python code example when reporting bugs. Ensure all necessary imports are included. ```python import sounddevice as sd fs = 48000 duration = 1.5 data = sd.rec(int(duration * fs), channels=99) sd.wait() print(data.shape) ``` -------------------------------- ### Set ASIO Input and Output Channels Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/platform-specific-settings.md Configure both input and output channels for ASIO devices. This example demonstrates setting default input and output settings for playrec(). ```python asio_in = sd.AsioSettings(channel_selectors=[8]) sd.default.extra_settings = asio_in, asio_out sd.playrec(..., channels=1, ...) ``` -------------------------------- ### Running a Script and Error Output Source: https://github.com/spatialaudio/python-sounddevice/blob/master/CONTRIBUTING.rst Example of how to run a Python script and the expected error output when encountering an issue, such as an invalid number of channels. Provide the full command and output when reporting problems. ```bash $ python my_script.py Expression 'parameters->channelCount <= maxChans' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1514 Expression 'ValidateParameters( inputParameters, hostApi, StreamDirection_In )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2818 Traceback (most recent call last): File "my_script.py", line 6, in data = sd.rec(int(duration * fs), channels=99) ... sounddevice.PortAudioError: Error opening InputStream: Invalid number of channels [PaErrorCode -9998] ``` -------------------------------- ### Configure Core Audio Input and Output Channels Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/platform-specific-settings.md Example of configuring specific input and output channels for Mac Core Audio devices. Input uses a direct channel map, while output uses a map with -1 for unused channels. ```python import sounddevice as sd ca_in = sd.CoreAudioSettings(channel_map=[1, 3]) ca_out = sd.CoreAudioSettings(channel_map=[-1, -1, 0, -1, 1, -1]) sd.playrec(..., channels=2, extra_settings=(ca_in, ca_out)) ``` -------------------------------- ### Example Error Output for Bug Reports Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/contributing.md Include the full command invocation and the complete output when reporting errors. This helps diagnose the problem effectively. ```shell $ python my_script.py Expression 'parameters->channelCount <= maxChans' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1514 Expression 'ValidateParameters( inputParameters, hostApi, StreamDirection_In )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2818 Traceback (most recent call last): File "my_script.py", line 6, in data = sd.rec(int(duration * fs), channels=99) ... sounddevice.PortAudioError: Error opening InputStream: Invalid number of channels [PaErrorCode -9998] ``` -------------------------------- ### Enable ASIO support in sounddevice Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/installation.md Enable ASIO support by setting the SD_ENABLE_ASIO environment variable to '1' before importing the sounddevice module. This is only applicable when sounddevice is installed via pip on Windows. ```python import os # Set environment variable before importing sounddevice. Value is not important. os.environ["SD_ENABLE_ASIO"] = "1" import sounddevice as sd print(sd.query_hostapis()) ``` -------------------------------- ### Upgrade sounddevice using pip Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/installation.md Upgrade an existing installation of the sounddevice module to the newest release using pip with the --upgrade flag. ```bash python -m pip install --upgrade sounddevice ``` -------------------------------- ### Plot Microphone Signal in Real-Time Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/examples.md This script visualizes live audio input from the microphone using matplotlib. It requires matplotlib and numpy to be installed. Configure input channels, device, window size, update interval, block size, and sample rate via command-line arguments. ```python #!/usr/bin/env python3 """Plot the live microphone signal(s) with matplotlib. Matplotlib and NumPy have to be installed. """ import argparse import queue import sys from matplotlib.animation import FuncAnimation import matplotlib.pyplot as plt import numpy as np import sounddevice as sd def int_or_str(text): """Helper function for argument parsing.""" try: return int(text) except ValueError: return text parser = argparse.ArgumentParser(add_help=False) parser.add_argument( '-l', '--list-devices', action='store_true', help='show list of audio devices and exit') args, remaining = parser.parse_known_args() if args.list_devices: print(sd.query_devices()) parser.exit(0) parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, parents=[parser]) parser.add_argument( 'channels', type=int, default=[1], nargs='*', metavar='CHANNEL', help='input channels to plot (default: the first)') parser.add_argument( '-d', '--device', type=int_or_str, help='input device (numeric ID or substring)') parser.add_argument( '-w', '--window', type=float, default=200, metavar='DURATION', help='visible time slot (default: %(default)s ms)') parser.add_argument( '-i', '--interval', type=float, default=30, help='minimum time between plot updates (default: %(default)s ms)') parser.add_argument( '-b', '--blocksize', type=int, help='block size (in samples)') parser.add_argument( '-r', '--samplerate', type=float, help='sampling rate of audio device') parser.add_argument( '-n', '--downsample', type=int, default=10, metavar='N', help='display every Nth sample (default: %(default)s)') args = parser.parse_args(remaining) if any(c < 1 for c in args.channels): parser.error('argument CHANNEL: must be >= 1') mapping = [c - 1 for c in args.channels] # Channel numbers start with 1 q = queue.Queue() def audio_callback(indata, frames, time, status): """This is called (from a separate thread) for each audio block.""" if status: print(status, file=sys.stderr) # Fancy indexing with mapping creates a (necessary!) copy: q.put(indata[::args.downsample, mapping]) def update_plot(frame): """This is called by matplotlib for each plot update. Typically, audio callbacks happen more frequently than plot updates, therefore the queue tends to contain multiple blocks of audio data. """ global plotdata while True: try: data = q.get_nowait() except queue.Empty: break shift = len(data) plotdata = np.roll(plotdata, -shift, axis=0) plotdata[-shift:, :] = data for column, line in enumerate(lines): line.set_ydata(plotdata[:, column]) return lines try: if args.samplerate is None: device_info = sd.query_devices(args.device, 'input') args.samplerate = device_info['default_samplerate'] length = int(args.window * args.samplerate / (1000 * args.downsample)) plotdata = np.zeros((length, len(args.channels))) fig, ax = plt.subplots() lines = ax.plot(plotdata) if len(args.channels) > 1: ax.legend([f'channel {c}' for c in args.channels], loc='lower left', ncol=len(args.channels)) ax.axis((0, len(plotdata), -1, 1)) ax.set_yticks([0]) ax.yaxis.grid(True) ax.tick_params(bottom=False, top=False, labelbottom=False, right=False, left=False, labelleft=False) fig.tight_layout(pad=0) stream = sd.InputStream( device=args.device, channels=max(args.channels), samplerate=args.samplerate, callback=audio_callback) ani = FuncAnimation(fig, update_plot, interval=args.interval, blit=True) with stream: plt.show() except Exception as e: parser.exit(1, type(e).__name__ + ': ' + str(e)) ``` -------------------------------- ### sounddevice.playrec Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/convenience-functions.md Simultaneously plays back and records audio data using NumPy arrays. It handles stream creation, starting, and optionally waiting for completion. ```APIDOC ## sounddevice.playrec(data, samplerate=None, channels=None, dtype=None, out=None, input_mapping=None, output_mapping=None, blocking=False, **kwargs) ### Description Simultaneous playback and recording of NumPy arrays. This function does the following steps internally: * Call [`stop()`](#sounddevice.stop) to terminate any currently running invocation of [`play()`](#sounddevice.play), [`rec()`](#sounddevice.rec) and [`playrec()`](#sounddevice.playrec). * Create a [`Stream`](streams.md#sounddevice.Stream) and a callback function for taking care of the actual playback and recording. * Start the stream. * If `blocking=True` was given, wait until playback/recording is done. If not, return immediately (to start waiting at a later point, [`wait()`](#sounddevice.wait) can be used). If you need more control (e.g. block-wise gapless playback and recording, realtime processing, …), you should explicitly create a [`Stream`](streams.md#sounddevice.Stream) yourself. If NumPy is not available, you can use a [`RawStream`](raw-streams.md#sounddevice.RawStream). ### Parameters * **data** (*array_like*) – Audio data to be played back. See [`play()`](#sounddevice.play). * **channels** (*int, sometimes optional*) – Number of input channels, see [`rec()`](#sounddevice.rec). The number of output channels is obtained from *data.shape*. * **dtype** (*str or numpy.dtype, optional*) – Input data type, see [`rec()`](#sounddevice.rec). If *dtype* is not specified, it is taken from *data.dtype* (i.e. [`default.dtype`](module-defaults.md#sounddevice.default.dtype) is ignored). The output data type is obtained from *data.dtype* anyway. * **input_mapping, output_mapping** (*array_like, optional*) – See the parameter *mapping* of [`rec()`](#sounddevice.rec) and [`play()`](#sounddevice.play), respectively. * **blocking** (*bool, optional*) – If `False` (the default), return immediately (but continue playback/recording in the background), if `True`, wait until playback/recording is finished. A non-blocking invocation can be stopped with [`stop()`](#sounddevice.stop) or turned into a blocking one with [`wait()`](#sounddevice.wait). ### Returns *numpy.ndarray or type(out)* – The recorded data. See [`rec()`](#sounddevice.rec). ### Other Parameters * **out** (*numpy.ndarray or subclass, optional*) – See [`rec()`](#sounddevice.rec). * **samplerate, **kwargs** – All parameters of [`Stream`](streams.md#sounddevice.Stream) – except *channels*, *dtype*, *callback* and *finished_callback* – can be used. ### Notes If you don’t specify the correct sampling rate (either with the *samplerate* argument or by assigning a value to [`default.samplerate`](module-defaults.md#sounddevice.default.samplerate)), the audio data will be played back, but it might be too slow or too fast! #### SEE ALSO [`play`](#sounddevice.play), [`rec`](#sounddevice.rec) ``` -------------------------------- ### Recording Audio with Arbitrary Duration Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/examples.md This script records audio from an input device for an arbitrary duration until interrupted. It requires the soundfile module to be installed. The recording is saved to a WAV file. ```python #!/usr/bin/env python3 """Create a recording with arbitrary duration. The soundfile module (https://python-soundfile.readthedocs.io/) has to be installed! """ import argparse import tempfile import queue import sys import sounddevice as sd import soundfile as sf import numpy # Make sure NumPy is loaded before it is used in the callback assert numpy # avoid "imported but unused" message (W0611) def int_or_str(text): """Helper function for argument parsing.""" try: return int(text) except ValueError: return text parser = argparse.ArgumentParser(add_help=False) parser.add_argument( '-l', '--list-devices', action='store_true', help='show list of audio devices and exit') args, remaining = parser.parse_known_args() if args.list_devices: print(sd.query_devices()) parser.exit(0) parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, parents=[parser]) parser.add_argument( 'filename', nargs='?', metavar='FILENAME', help='audio file to store recording to') parser.add_argument( '-d', '--device', type=int_or_str, help='input device (numeric ID or substring)') parser.add_argument( '-r', '--samplerate', type=int, help='sampling rate') parser.add_argument( '-c', '--channels', type=int, default=1, help='number of input channels') parser.add_argument( '-t', '--subtype', type=str, help='sound file subtype (e.g. "PCM_24")') args = parser.parse_args(remaining) q = queue.Queue() def callback(indata, frames, time, status): """This is called (from a separate thread) for each audio block.""" if status: print(status, file=sys.stderr) q.put(indata.copy()) try: if args.samplerate is None: device_info = sd.query_devices(args.device, 'input') # soundfile expects an int, sounddevice provides a float: args.samplerate = int(device_info['default_samplerate']) if args.filename is None: args.filename = tempfile.mktemp(prefix='delme_rec_unlimited_', suffix='.wav', dir='') # Make sure the file is opened before recording anything: with sf.SoundFile(args.filename, mode='x', samplerate=args.samplerate, channels=args.channels, subtype=args.subtype) as file: with sd.InputStream(samplerate=args.samplerate, device=args.device, channels=args.channels, callback=callback): print('#' * 80) print('press Ctrl+C to stop the recording') print('#' * 80) while True: file.write(q.get()) except KeyboardInterrupt: print('\nRecording finished: ' + repr(args.filename)) parser.exit(0) except Exception as e: parser.exit(1, type(e).__name__ + ': ' + str(e)) ``` -------------------------------- ### Play a Web Stream Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/examples.md This script plays an audio stream from a given URL using ffmpeg-python and sounddevice. Ensure ffmpeg-python is installed and provide a valid stream URL. The script allows specifying the output device, block size, and buffer size. ```Python #!/usr/bin/env python3 """Play a web stream. ffmpeg-python (https://github.com/kkroening/ffmpeg-python) has to be installed. If you don't know a stream URL, try http://icecast.spc.org:8000/longplayer (see https://longplayer.org/ for a description). """ import argparse import queue import sys import ffmpeg import sounddevice as sd def int_or_str(text): """Helper function for argument parsing.""" try: return int(text) except ValueError: return text parser = argparse.ArgumentParser(add_help=False) parser.add_argument( '-l', '--list-devices', action='store_true', help='show list of audio devices and exit') args, remaining = parser.parse_known_args() if args.list_devices: print(sd.query_devices()) parser.exit(0) parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, parents=[parser]) parser.add_argument( 'url', metavar='URL', help='stream URL') parser.add_argument( '-d', '--device', type=int_or_str, help='output device (numeric ID or substring)') parser.add_argument( '-b', '--blocksize', type=int, default=1024, help='block size (default: %(default)s)') parser.add_argument( '-q', '--buffersize', type=int, default=20, help='number of blocks used for buffering (default: %(default)s)') args = parser.parse_args(remaining) if args.blocksize == 0: parser.error('blocksize must not be zero') if args.buffersize < 1: parser.error('buffersize must be at least 1') q = queue.Queue(maxsize=args.buffersize) print('Getting stream information ...') try: info = ffmpeg.probe(args.url) except ffmpeg.Error as e: sys.stderr.buffer.write(e.stderr) parser.exit(1, str(e)) streams = info.get('streams', []) if len(streams) != 1: parser.exit(1, 'There must be exactly one stream available') stream = streams[0] if stream.get('codec_type') != 'audio': parser.exit(1, 'The stream must be an audio stream') channels = stream['channels'] samplerate = float(stream['sample_rate']) def callback(outdata, frames, time, status): assert frames == args.blocksize if status.output_underflow: print('Output underflow: increase blocksize?', file=sys.stderr) raise sd.CallbackAbort assert not status try: data = q.get_nowait() except queue.Empty as e: print('Buffer is empty: increase buffersize?', file=sys.stderr) raise sd.CallbackAbort from e assert len(data) == len(outdata) outdata[:] = data try: print('Opening stream ...') process = ffmpeg.input( args.url ).output( 'pipe:', format='f32le', acodec='pcm_f32le', ac=channels, ar=samplerate, loglevel='quiet', ).run_async(pipe_stdout=True) stream = sd.RawOutputStream( samplerate=samplerate, blocksize=args.blocksize, device=args.device, channels=channels, dtype='float32', callback=callback) read_size = args.blocksize * channels * stream.samplesize print('Buffering ...') for _ in range(args.buffersize): q.put_nowait(process.stdout.read(read_size)) print('Starting Playback ...') with stream: timeout = args.blocksize * args.buffersize / samplerate while True: q.put(process.stdout.read(read_size), timeout=timeout) except KeyboardInterrupt: parser.exit(1, '\nInterrupted by user') except queue.Full: # A timeout occurred, i.e. there was an error in the callback parser.exit(1) except Exception as e: parser.exit(1, type(e).__name__ + ': ' + str(e)) ``` -------------------------------- ### Stream.start Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Commence audio processing for the stream. ```APIDOC ## start() ### Description Commence audio processing. ### SEE ALSO [`stop`](convenience-functions.md#sounddevice.stop), [`abort`](#sounddevice.Stream.abort) ``` -------------------------------- ### Stream.samplerate Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Get the sampling frequency of the stream in Hertz. ```APIDOC ## samplerate ### Description The sampling frequency in Hertz (= frames per second). In cases where the hardware sampling frequency is inaccurate and PortAudio is aware of it, the value of this field may be different from the *samplerate* parameter passed to [`Stream()`](#sounddevice.Stream). If information about the actual hardware sampling frequency is not available, this field will have the same value as the *samplerate* parameter passed to [`Stream()`](#sounddevice.Stream). ``` -------------------------------- ### Stream.latency Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Get the input/output latency of the stream in seconds. ```APIDOC ## latency ### Description The input/output latency of the stream in seconds. This value provides the most accurate estimate of input/output latency available to the implementation. It may differ significantly from the *latency* value(s) passed to [`Stream()`](#sounddevice.Stream). ``` -------------------------------- ### Stream.samplesize Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Get the size in bytes of a single sample for the stream. ```APIDOC ## samplesize ### Description The size in bytes of a single sample. ### SEE ALSO [`dtype`](#sounddevice.Stream.dtype) ``` -------------------------------- ### Stream.dtype Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Get the data type of the audio samples in the stream. ```APIDOC ## dtype ### Description Data type of the audio samples. ### SEE ALSO [`default.dtype`](module-defaults.md#sounddevice.default.dtype), [`samplesize`](#sounddevice.Stream.samplesize) ``` -------------------------------- ### sounddevice._initialize() Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/expert-mode.md Initializes PortAudio, the underlying audio library. This is usually called automatically on import but can be invoked manually if needed. It temporarily redirects stderr to /dev/null on supported systems. ```APIDOC ## sounddevice._initialize() ### Description Initialize PortAudio. This temporarily forwards messages from stderr to `/dev/null` (where supported). In most cases, this doesn’t have to be called explicitly, because it is automatically called with the `import sounddevice` statement. ### Method N/A (Function Call) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response N/A ``` -------------------------------- ### Stream.device Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Get the IDs of the input and output devices for the stream. ```APIDOC ## device ### Description IDs of the input/output device. ``` -------------------------------- ### Record Audio with Default Settings Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/usage.md Record audio using the pre-configured default sampling rate and channel count. ```python myrecording = sd.rec(int(duration * fs)) ``` -------------------------------- ### Stream.channels Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Get the number of input and output channels for the stream. ```APIDOC ## channels ### Description The number of input/output channels. ``` -------------------------------- ### Check Available Sound Devices Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/contributing.md Run this command to list all available sound devices, which can be useful for diagnosing hardware-related issues. ```shell python -m sounddevice ``` -------------------------------- ### Stream.read_available Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Get the number of frames that can be read from the stream without waiting. ```APIDOC ## read_available ### Description The number of frames that can be read without waiting. Returns a value representing the maximum number of frames that can be read from the stream without blocking or busy waiting. ``` -------------------------------- ### Select Audio Device by Name Substring Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/usage.md Configure the default audio device by providing a substring of its name. This allows for flexible device selection without needing the exact ID. ```python import sounddevice as sd sd.default.samplerate = 44100 sd.default.device = 'digital output' sd.play(myarray) ``` -------------------------------- ### Build and Serve Documentation with Sphinx Autobuild Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/contributing.md Use sphinx-autobuild to automatically rebuild HTML documentation on changes and reload the browser. This command also opens the documentation in a browser. ```shell python -m sphinx_autobuild doc _build --open-browser ``` -------------------------------- ### Miscellaneous Functions Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/index.md Utility functions for sleeping, getting PortAudio version, and handling callback events. ```APIDOC ## Miscellaneous Functions and Classes ### Description A collection of utility functions and constants for tasks such as pausing execution, retrieving PortAudio version information, and handling callback events during stream operations. ### Functions - `sleep(seconds)`: Pause execution for the specified number of seconds. - `get_portaudio_version()`: Return the version of the PortAudio library. ### Classes - `CallbackFlags`: Flags used in stream callbacks. - `CallbackStop`: Exception raised to stop a stream callback. - `CallbackAbort`: Exception raised to abort a stream callback. ``` -------------------------------- ### Build HTML Documentation with Sphinx Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/contributing.md Re-create the HTML documentation pages locally using Sphinx. The generated files will be in the `_build/` directory. ```shell python -m sphinx doc _build ``` -------------------------------- ### Stream.blocksize Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Get the number of frames per block for the stream. A value of 0 means the blocksize can change. ```APIDOC ## blocksize ### Description Number of frames per block. The special value 0 means that the blocksize can change between blocks. See the *blocksize* argument of [`Stream`](#sounddevice.Stream). ``` -------------------------------- ### Get Default Device Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/module-defaults.md Retrieve the currently set default audio device indices for input and output. ```python >>> sd.default.device [5, 5] ``` -------------------------------- ### sounddevice.Stream Constructor Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Initializes a new audio stream with various configuration options. The callback function is central to real-time audio processing, handling input and output buffers. ```APIDOC ## sounddevice.Stream Constructor ### Description Initializes a new audio stream with various configuration options. The callback function is central to real-time audio processing, handling input and output buffers. ### Parameters * **samplerate** (int, optional) - The sampling frequency in Hertz. * **blocksize** (int, optional) - The number of frames in each block. * **device** (int or str or tuple, optional) - The audio device to use. * **channels** (int, optional) - The number of audio channels. * **dtype** (numpy.dtype or str, optional) - The data type of the audio samples. * **latency** (float, optional) - The desired latency in seconds. * **extra_settings** (dict, optional) - Additional device-specific settings. * **callback** (callable, optional) - User-supplied function to process audio data. * **finished_callback** (callable, optional) - User-supplied function to be called when the stream becomes inactive. * **clip_off** (bool, optional) - See [`default.clip_off`](module-defaults.md#sounddevice.default.clip_off). * **dither_off** (bool, optional) - See [`default.dither_off`](module-defaults.md#sounddevice.default.dither_off). * **never_drop_input** (bool, optional) - See [`default.never_drop_input`](module-defaults.md#sounddevice.default.never_drop_input). * **prime_output_buffers_using_stream_callback** (bool, optional) - See [`default.prime_output_buffers_using_stream_callback`](module-defaults.md#sounddevice.default.prime_output_buffers_using_stream_callback). ### Callback Behavior The *callback* function is called synchronously with the time base used by [`time`](#sounddevice.Stream.time). It receives information about buffer status and potential issues like underflow or overflow. Exceptions raised within the callback have specific behaviors: [`CallbackAbort`](misc.md#sounddevice.CallbackAbort) stops the stream, [`CallbackStop`](misc.md#sounddevice.CallbackStop) allows playback to complete, and other exceptions are printed to `sys.stderr` without propagating to the main thread. The callback must always fill the output buffer completely. The PortAudio stream callback operates at high priority and should avoid blocking operations or memory allocations. ``` -------------------------------- ### Stream.active Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Check if the stream is currently active. A stream is active after a successful call to start() until it becomes inactive. ```APIDOC ## active ### Description `True` when the stream is active, `False` otherwise. A stream is active after a successful call to [`start()`](#sounddevice.Stream.start), until it becomes inactive either as a result of a call to [`stop()`](convenience-functions.md#sounddevice.stop) or [`abort()`](#sounddevice.Stream.abort), or as a result of an exception raised in the stream callback. In the latter case, the stream is considered inactive after the last buffer has finished playing. ``` -------------------------------- ### Stream.cpu_load Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Get CPU usage information for the stream. This is a fraction of total CPU time consumed by audio processing routines. ```APIDOC ## cpu_load ### Description CPU usage information for the stream. The “CPU Load” is a fraction of total CPU time consumed by a callback stream’s audio processing routines including, but not limited to the client supplied stream callback. This function does not work with blocking read/write streams. This may be used in the stream callback function or in the application. It provides a floating point value, typically between 0.0 and 1.0, where 1.0 indicates that the stream callback is consuming the maximum number of CPU cycles possible to maintain real-time operation. A value of 0.5 would imply that PortAudio and the stream callback was consuming roughly 50% of the available CPU time. The value may exceed 1.0. A value of 0.0 will always be returned for a blocking read/write stream, or if an error occurs. ``` -------------------------------- ### sounddevice.query_devices Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/checking-hardware.md Returns information about available audio devices. This function can be used to get details about a specific device or a list of all devices. ```APIDOC ## sounddevice.query_devices(device=None, kind=None) ### Description Return information about available devices, including their capabilities for input and output. ### Method Python Function Call ### Parameters #### Parameters - **device** (int or str, optional) - Numeric device ID or device name substring(s). If specified, information about only the given *device* is returned in a single dictionary. - **kind** (str, optional) - If *device* is not specified and *kind* is 'input' or 'output', a single dictionary is returned with information about the default input or output device, respectively. ### Returns *dict or DeviceList* – A dictionary with information about the given *device* or – if no arguments were specified – a [`DeviceList`](#sounddevice.DeviceList) containing one dictionary for each available device. The dictionaries have the following keys: `'name'` (str): The name of the device. `'index'` (int): The device index. `'hostapi'` (int): The ID of the corresponding host API. `'max_input_channels'` (int): The maximum number of input channels supported by the device. `'max_output_channels'` (int): The maximum number of output channels supported by the device. `'default_low_input_latency'` (float): Default latency value for interactive input performance. `'default_low_output_latency'` (float): Default latency value for interactive output performance. `'default_high_input_latency'` (float): Default latency value for non-interactive input applications. `'default_high_output_latency'` (float): Default latency value for non-interactive output applications. `'default_samplerate'` (float): The default sampling frequency of the device. ### Notes The list of devices can also be displayed in a terminal by running `python3 -m sounddevice`. ### Examples ```python import sounddevice as sd # Get information about all available devices print(sd.query_devices()) # Get information about a specific device by name substring print(sd.query_devices(device='Built-in Output')) # Get information about the default input device print(sd.query_devices(kind='input')) ``` ``` -------------------------------- ### Get PortAudio Library Information Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/contributing.md Execute this script to retrieve the library name and version of PortAudio, essential for debugging PortAudio-specific problems. ```python import sounddevice as sd print(sd._libname) print(sd.get_portaudio_version()) ``` -------------------------------- ### Get Default Dtype Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/module-defaults.md Retrieve the default data type for audio samples. This indicates the format used for input and output if not specified otherwise. ```python >>> sd.default.dtype ['float32', 'float32'] ``` -------------------------------- ### sounddevice.Stream Initialization Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/streams.md Initializes an audio stream with various configurable parameters. Users can specify sample rate, block size, audio device, number of channels, data type, latency, and host-API-specific settings. A callback function can be provided for real-time audio processing. ```APIDOC ## class sounddevice.Stream ### Description Initializes an audio stream with various configurable parameters. ### Parameters * **samplerate** (float or None, optional) - The sample rate in samples per second per channel. If `None`, the default value is used. See [`default.samplerate`](module-defaults.md#sounddevice.default.samplerate). * **blocksize** (int or None, optional) - The number of frames per stream בכל callback invocation. If `None`, the default value is used. See [`default.blocksize`](module-defaults.md#sounddevice.default.blocksize). * **device** (int or str or None, optional) - The audio device to be used. If `None`, the default input or output device is used. See [`default.device`](module-defaults.md#sounddevice.default.device). * **channels** (int or pair thereof or None, optional) - The number of channels for input and output. If `None`, the default value is used. See [`default.channels`](module-defaults.md#sounddevice.default.channels). * **dtype** (numpy.dtype or str or pair thereof, optional) - The data type for NumPy arrays used for input and output. Supported types include `'f32'`, `'f64'`, `'i8'`, `'i16'`, `'i24'`, `'i32'`, `'u8'`. See [`numpy.dtype`](https://numpy.org/doc/stable/reference/generated/numpy.dtype.html). * **latency** (float or {'low', 'high'} or pair thereof, optional) - The desired latency in seconds. `'low'` and `'high'` select the device’s default low and high latency, respectively. `'high'` is typically more robust but may have higher latency. * **extra_settings** (settings object or pair thereof, optional) - Host-API-specific input/output settings. * **callback** (callable, optional) - User-supplied function to process or generate audio data. If `None`, the stream operates in blocking read/write mode. * **finished_callback** (callable, optional) - User-supplied function to be called when the stream is stopped or finished. * **clip_off** (bool, optional) - If `True`, disables clipping of output samples that are out of range. * **dither_off** (bool, optional) - If `True`, disables dithering. * **never_drop_input** (bool, optional) - If `True`, prevents input data from being discarded due to buffer underflows. * **prime_output_buffers_using_stream_callback** (bool, optional) - If `True`, the output buffers are filled using the stream callback before the stream is started. ``` -------------------------------- ### sounddevice.AsioSettings Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/platform-specific-settings.md ASIO-specific input/output settings. This class allows users to specify which channels to use for ASIO devices, supporting opening only specific channels. ```APIDOC ## sounddevice.AsioSettings ### Description ASIO-specific input/output settings. Objects of this class can be used as *extra_settings* argument to [`Stream()`](streams.md#sounddevice.Stream) (and variants) or as [`default.extra_settings`](module-defaults.md#sounddevice.default.extra_settings). ### Parameters * **channel_selectors** (*list of int*) – Support for opening only specific channels of an ASIO device. *channel_selectors* is a list of integers specifying the (zero-based) channel numbers to use. The length of *channel_selectors* must match the corresponding *channels* parameter of [`Stream()`](streams.md#sounddevice.Stream) (or variants), otherwise a crash may result. The values in the *channel_selectors* array must specify channels within the range of supported channels. ### Examples Setting output channels when calling [`play()`](convenience-functions.md#sounddevice.play): ```pycon >>> import sounddevice as sd >>> asio_out = sd.AsioSettings(channel_selectors=[12, 13]) >>> sd.play(..., extra_settings=asio_out) ``` Setting default output channels: ```pycon >>> sd.default.extra_settings = asio_out >>> sd.play(...) ``` Setting input channels as well: ```pycon >>> asio_in = sd.AsioSettings(channel_selectors=[8]) >>> sd.default.extra_settings = asio_in, asio_out >>> sd.playrec(..., channels=1, ...) ``` ``` -------------------------------- ### Convenience Functions Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/index.md Functions for easily playing and recording NumPy arrays, along with utilities for managing playback and recording status. ```APIDOC ## Convenience Functions ### Description Provides high-level functions to play, record, and play-and-record audio using NumPy arrays. Includes utilities to wait for completion, stop ongoing operations, and check the status of audio streams. ### Functions - `play(data, samplerate=None, blocksize=None, latency=None, dtype=None, out=None, mapping=None, cliplimit=None, neverdrop=None, rotate=None, callback=None, finished_callback=None, **kwargs)`: Play NumPy array `data`. - `rec(frames, samplerate=None, blocksize=None, latency=None, dtype=None, out=None, mapping=None, cliplimit=None, neverdrop=None, rotate=None, callback=None, finished_callback=None, **kwargs)`: Record `frames` audio frames. - `playrec(data, samplerate=None, blocksize=None, latency=None, dtype=None, out=None, mapping=None, cliplimit=None, neverdrop=None, rotate=None, callback=None, finished_callback=None, **kwargs)`: Play NumPy array `data` and record audio. - `wait()`: Wait until all currently playing audio is finished. - `stop()`: Stop the currently playing or recording audio. - `get_status()`: Return the status of the currently active stream. - `get_stream()`: Return the currently active stream. ``` -------------------------------- ### Get PortAudio Version Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/misc.md Retrieves version information for the PortAudio library. This function returns a tuple containing the release number and a textual description of the PortAudio build. ```default (1899, 'PortAudio V19-devel (built Feb 15 2014 23:28:00)') ``` -------------------------------- ### Simultaneous Playback and Recording with Defaults Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/usage.md Perform simultaneous playback and recording using default samplerate and channel settings. ```python sd.default.samplerate = fs sd.default.channels = 2 myrecording = sd.playrec(myarray) ``` -------------------------------- ### List Audio Devices in Terminal Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/api/checking-hardware.md This command-line instruction allows you to list all available audio devices directly from your terminal without running a Python script. ```shell python3 -m sounddevice ``` -------------------------------- ### Play an Audio File with Callback Stream Source: https://github.com/spatialaudio/python-sounddevice/blob/master/doc/examples.md Loads an entire audio file into memory and plays its contents using a callback stream. Requires NumPy and soundfile. For very long files, use play_long_file.py instead. ```python #!/usr/bin/env python3 """Load an audio file into memory and play its contents. NumPy and the soundfile module (https://python-soundfile.readthedocs.io/) must be installed for this to work. This example program loads the whole file into memory before starting playback. To play very long files, you should use play_long_file.py instead. This example could simply be implemented like this:: import sounddevice as sd import soundfile as sf data, fs = sf.read('my-file.wav') sd.play(data, fs) sd.wait() ... but in this example we show a more low-level implementation using a callback stream. """ import argparse import threading import sounddevice as sd import soundfile as sf def int_or_str(text): """Helper function for argument parsing.""" try: return int(text) except ValueError: return text parser = argparse.ArgumentParser(add_help=False) parser.add_argument( '-l', '--list-devices', action='store_true', help='show list of audio devices and exit') args, remaining = parser.parse_known_args() if args.list_devices: print(sd.query_devices()) parser.exit(0) parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, parents=[parser]) parser.add_argument( 'filename', metavar='FILENAME', help='audio file to be played back') parser.add_argument( '-d', '--device', type=int_or_str, help='output device (numeric ID or substring)') args = parser.parse_args(remaining) event = threading.Event() try: data, fs = sf.read(args.filename, always_2d=True) current_frame = 0 def callback(outdata, frames, time, status): global current_frame if status: print(status) chunksize = min(len(data) - current_frame, frames) outdata[:chunksize] = data[current_frame:current_frame + chunksize] if chunksize < frames: outdata[chunksize:] = 0 raise sd.CallbackStop() current_frame += chunksize stream = sd.OutputStream( samplerate=fs, device=args.device, channels=data.shape[1], callback=callback, finished_callback=event.set) with stream: event.wait() # Wait until playback is finished except KeyboardInterrupt: parser.exit(1, '\nInterrupted by user') except Exception as e: parser.exit(1, type(e).__name__ + ': ' + str(e)) ```