### start Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/playback-device.md Starts audio playback by consuming audio samples from a provided generator. ```APIDOC ## start(callback_generator: Generator[bytes | array.array, int, None]) -> None ### Description Starts audio playback. The generator is called with the number of frames needed and should yield audio samples. ### Method None (SDK Method) ### Endpoint None (SDK Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **callback_generator** (Generator) - Required - Generator that yields audio sample data. Should be pre-started with `next()`. Generator receives an int (frames needed) and yields bytes, array.array, memoryview, or numpy array with shape (numframes, numchannels). ### Request Example ```python import miniaudio def sample_generator(): frames_needed = yield b"" while True: audio_data = b"\x00" * (frames_needed * 2 * 2) frames_needed = yield audio_data device = miniaudio.PlaybackDevice() gen = sample_generator() next(gen) device.start(gen) ``` ### Response #### Success Response None #### Response Example None ### Raises - `MiniaudioError` — If device is already running or fails to start ``` -------------------------------- ### System Capability Check Example Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/utility-functions.md A comprehensive example demonstrating how to check system capabilities using miniaudio utility functions. It prints the library version and lists all available backends with their loopback support status. ```python import miniaudio def check_system_capabilities(): print(f"miniaudio version: {miniaudio.lib_version()}") backends = miniaudio.get_enabled_backends() print(f"\nAvailable backends ({len(backends)}):") for backend in sorted(backends, key=lambda b: b.name): supports_loopback = miniaudio.is_loopback_supported(backend) loopback_str = " (with loopback)" if supports_loopback else "" print(f" - {backend.name}{loopback_str}") check_system_capabilities() ``` -------------------------------- ### start Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/capture-device.md Starts the audio capture process. The provided callback generator will receive captured audio data. ```APIDOC ## start(callback_generator: Generator[None, bytes | array.array, None]) -> None ### Description Start audio capture. The generator receives audio samples as array.array with type matching the sample format. ### Parameters #### Path Parameters - **callback_generator** (Generator) - Required - Generator that receives captured audio. Pre-start with `next()`. Receives array.array (e.g., array('h') for SIGNED16, array('f') for FLOAT32) or bytes (for SIGNED24). Generator should be: `def gen(): _ = yield; while True: data = yield` ### Raises - `MiniaudioError` — If device is already running or fails to start ### Request Example ```python import miniaudio buffer = [] def record_callback(): _ = yield # Initialize while True: data = yield buffer.append(data) print(".", end="", flush=True) device = miniaudio.CaptureDevice(sample_rate=44100) gen = record_callback() next(gen) device.start(gen) # Recording... ``` ``` -------------------------------- ### PlaybackDevice as Context Manager Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/playback-device.md Demonstrates using PlaybackDevice as a context manager, which ensures the device is automatically closed after use. This example configures the sample rate and starts streaming a file. ```python with miniaudio.PlaybackDevice(sample_rate=44100) as device: stream = miniaudio.stream_file("music.mp3") next(stream) device.start(stream) import time time.sleep(10) # Device automatically closed ``` -------------------------------- ### Install PyMiniaudio Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/README.md Install the pyminiaudio library using pip. Ensure you are using Python 3.10+ or PyPy3. ```bash pip install miniaudio ``` -------------------------------- ### Start Audio Capture with Callback Generator Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/capture-device.md Starts recording audio using a generator. The generator receives captured audio data and should be initialized with `next()`. Ensure the generator handles the data format (array.array or bytes) correctly. ```python import miniaudio buffer = [] def record_callback(): _ = yield # Initialize while True: data = yield buffer.append(data) print(".", end="", flush=True) device = miniaudio.CaptureDevice(sample_rate=44100) gen = record_callback() next(gen) device.start(gen) # Recording... ``` -------------------------------- ### Start Playback with a Generator Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/playback-device.md Starts audio playback using a generator that yields audio samples. The generator must be pre-started with `next()` and will be called with the number of frames needed. ```python import miniaudio def sample_generator(): frames_needed = yield b"" # Initialize while True: # Generate or fetch frames_needed frames of audio audio_data = b"\x00" * (frames_needed * 2 * 2) # 2 channels, 16-bit frames_needed = yield audio_data device = miniaudio.PlaybackDevice() gen = sample_generator() next(gen) # Start the generator device.start(gen) # Audio is now playing device.stop() device.close() ``` -------------------------------- ### Start DuplexStream with Callback Generator Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/duplex-stream.md Starts simultaneous audio playback and capture using a generator. The generator receives captured audio and yields playback audio. Ensure the generator is initialized before starting. ```python import miniaudio def duplex_callback(): captured = yield b"" # Initialize while True: # captured contains input from microphone (array) # Echo the input back through speakers captured = yield captured device = miniaudio.DuplexStream() gen = duplex_callback() next(gen) device.start(gen) # Audio is now echoing ``` -------------------------------- ### Play an Audio File Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/playback-device.md Plays an audio file by first getting its information to configure the PlaybackDevice and stream, then starting playback and sleeping for the duration of the file. ```python import miniaudio import time # Get file info to match format info = miniaudio.get_file_info("music.mp3") # Create playback device matching file format with miniaudio.PlaybackDevice( output_format=miniaudio.SampleFormat.SIGNED16, nchannels=info.nchannels, sample_rate=info.sample_rate ) as device: # Stream the file stream = miniaudio.stream_file( "music.mp3", output_format=miniaudio.SampleFormat.SIGNED16, nchannels=info.nchannels, sample_rate=info.sample_rate ) next(stream) device.start(stream) # Play for the duration of the file time.sleep(info.duration) ``` -------------------------------- ### Convert and Save Audio Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/decoded-sound-file.md This example demonstrates decoding an audio file with specific output parameters (format, channels, sample rate) and then saving the processed audio to a WAV file. ```python import miniaudio # Decode audio file sound = miniaudio.decode_file( "input.mp3", output_format=miniaudio.SampleFormat.SIGNED16, nchannels=2, sample_rate=44100 ) # Save to WAV file miniaudio.wav_write_file("output.wav", sound) ``` -------------------------------- ### Select Specific Input and Output Devices for DuplexStream Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/duplex-stream.md This example shows how to list available playback and capture devices and then create a DuplexStream using specific device IDs. This is useful when you need to ensure audio is processed through particular hardware. ```python import miniaudio # List devices devices = miniaudio.Devices() playbacks = devices.get_playbacks() captures = devices.get_captures() print("Playback devices:") for i, d in enumerate(playbacks): print(f" {i}: {d['name']}") print("Capture devices:") for i, d in enumerate(captures): print(f" {i}: {d['name']}") # Create duplex with specific devices device = miniaudio.DuplexStream( playback_device_id=playbacks[0]["id"], capture_device_id=captures[0]["id"] ) # ... use device ``` -------------------------------- ### get_enabled_backends() Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/utility-functions.md Get the set of all available audio backends on this system. ```APIDOC ## get_enabled_backends() ### Description Get the set of all available audio backends on this system. ### Returns - **Set[Backend]** - Set of available backends ### Raises - **MiniaudioError** - If unable to determine backends ### Example ```python import miniaudio backends = miniaudio.get_enabled_backends() print(f"Available backends: {[b.name for b in backends]}") if miniaudio.Backend.PULSEAUDIO in backends: print("PulseAudio is available") ``` ``` -------------------------------- ### Record and Save Audio Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/README.md This snippet demonstrates how to record audio for a specified duration using the CaptureDevice and save it as a WAV file. Ensure the miniaudio library is installed. ```python import miniaudio from time import sleep chunks = [] def record(): _ = yield while True: data = yield chunks.append(data) device = miniaudio.CaptureDevice() gen = record() next(gen) device.start(gen) sleep(5) device.stop() # Save recording samples = miniaudio.array.array('h') for chunk in chunks: samples.extend(chunk) sound = miniaudio.DecodedSoundFile( "recording", 2, 44100, miniaudio.SampleFormat.SIGNED16, samples ) miniaudio.wav_write_file("recording.wav", sound) ``` -------------------------------- ### DuplexStream.start Source: https://github.com/irmen/pyminiaudio/blob/master/README.md Starts the duplex audio stream, initiating both playback and capture. The provided callback generator handles audio data. ```APIDOC ## DuplexStream.start ### Description Start the audio device: playback and capture begin. The audio data for playback is provided by the given callback generator, which is sent the recorded audio data as an array.array whose type matches the chosen capture format (e.g. array('h') for SIGNED16, array('f') for FLOAT32). (it should already be started before passing it in) ### Method POST ### Endpoint `/stream/duplex/start` ### Parameters #### Request Body - **callback_generator** (Generator[bytes | array.array, bytes | array.array, NoneType]) - Required - A generator that provides audio data for playback and receives recorded data. ### Request Example ```python # Assuming 'duplex_stream' is an instance of DuplexStream # and 'my_generator' is a generator function duplex_stream.start(my_generator()) ``` ### Response #### Success Response (200) - **status** (string) - Indicates successful start of the stream. ``` -------------------------------- ### NetworkSource Implementation Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/streamable-source.md Example of a StreamableSource that reads from a network connection. Implements read and close. ```python class NetworkSource(miniaudio.StreamableSource): def __init__(self, url): self.connection = open_network_connection(url) def read(self, num_bytes: int): return self.connection.recv(num_bytes) def close(self): self.connection.close() ``` -------------------------------- ### Get Enabled Audio Backends Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/utility-functions.md Retrieves a set of all audio backends that are currently available on the system. This helps in understanding the audio hardware and software configuration. ```python import miniaudio backends = miniaudio.get_enabled_backends() print(f"Available backends: {[b.name for b in backends]}") if miniaudio.Backend.PULSEAUDIO in backends: print("PulseAudio is available") ``` -------------------------------- ### lib_version() Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/utility-functions.md Get the version string of the underlying miniaudio C library. ```APIDOC ## lib_version() ### Description Get the version string of the underlying miniaudio C library. ### Returns - **str** - Version string (e.g., "0.11.25") ### Example ```python import miniaudio version = miniaudio.lib_version() print(f"miniaudio library version: {version}") ``` ``` -------------------------------- ### Stream Audio File with Configuration Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/configuration.md Stream an audio file with custom output format, channel count, and sample rate. Configure buffer size, dithering, and starting position. ```python stream = miniaudio.stream_file( "music.mp3", output_format=miniaudio.SampleFormat.SIGNED16, nchannels=2, sample_rate=44100, frames_to_read=1024, dither=miniaudio.DitherMode.NONE, seek_frame=0 ) ``` -------------------------------- ### width_from_format(sampleformat: SampleFormat) Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/utility-functions.md Get the sample width in bytes for a given sample format. ```APIDOC ## width_from_format(sampleformat: SampleFormat) ### Description Get the sample width in bytes for a given sample format. ### Parameters #### Path Parameters - **sampleformat** (SampleFormat) - Required - Sample format enum ### Returns - **int** - Number of bytes per sample (0, 1, 2, 3, or 4) ### Raises - **MiniaudioError** - If format is unsupported ### Example ```python import miniaudio for fmt in [miniaudio.SampleFormat.SIGNED16, miniaudio.SampleFormat.FLOAT32]: width = miniaudio.width_from_format(fmt) print(f"{fmt.name}: {width} bytes/sample") ``` ``` -------------------------------- ### FileSource Implementation Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/streamable-source.md Example of a StreamableSource that reads from a local file. Implements the required read and close methods. ```python class FileSource(miniaudio.StreamableSource): def __init__(self, filename): self.file = open(filename, "rb") def read(self, num_bytes: int): return self.file.read(num_bytes) def close(self): self.file.close() ``` -------------------------------- ### Generator Pattern for Audio Callbacks Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/README.md Demonstrates the generator pattern for audio callbacks in pyminiaudio. This includes examples for playback (yielding audio data), capture (receiving audio data), and duplex (both directions). ```python # Playback: yield audio data def playback(): frames_needed = yield b"" while True: audio_data = b"..." frames_needed = yield audio_data # Capture: receive audio data def capture(): _ = yield while True: data = yield # Duplex: both directions def duplex(): captured = yield b"" while True: playback_data = b"..." captured = yield playback_data ``` -------------------------------- ### Get Capture Devices Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/devices.md Retrieves a list of all available audio input devices on the system. Each device entry includes its name, type, supported formats, and an ID for further use. ```python import miniaudio devices = miniaudio.Devices() captures = devices.get_captures() for device in captures: print(f"Recording device: {device['name']}") print(f" Channels: {[f['channels'] for f in device['formats']]}") ``` -------------------------------- ### Streaming WAV over HTTP Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/wav-file-read-stream.md Provides an example of serving a WAV audio stream over HTTP using Python's http.server. This allows clients to stream the WAV content directly from the server. ```python import miniaudio from http.server import HTTPServer, BaseHTTPRequestHandler class WAVStreamHandler(BaseHTTPRequestHandler): def do_GET(self): if self.path == "/stream.wav": # Create WAV stream stream = miniaudio.stream_file("music.mp3") next(stream) wav_stream = miniaudio.WavFileReadStream( stream, sample_rate=44100, nchannels=2, output_format=miniaudio.SampleFormat.SIGNED16 ) # Send WAV file self.send_response(200) self.send_header("Content-Type", "audio/wav") self.end_headers() while True: chunk = wav_stream.read(4096) if not chunk: break self.wfile.write(chunk) else: self.send_response(404) self.end_headers() # Run server if __name__ == "__main__": server = HTTPServer(("localhost", 8000), WAVStreamHandler) print("Server running at http://localhost:8000/stream.wav") server.serve_forever() ``` -------------------------------- ### Get Playback Devices Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/devices.md Retrieves a list of all available audio output devices on the system. Each device entry includes its name, type, supported formats, and an ID for further use. ```python import miniaudio devices = miniaudio.Devices() playbacks = devices.get_playbacks() for device in playbacks: print(f"Device: {device['name']}") print(f" Formats: {device['formats']}") ``` -------------------------------- ### Apply Voice Modulation (Pitch Shift) with DuplexStream Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/duplex-stream.md This example shows how to modulate the pitch of captured audio in real-time using a DuplexStream. It implements a simple pitch shifting algorithm by doubling or skipping samples. Ensure the audio_buffer is handled correctly for the desired sample format. ```python import miniaudio import time import array def pitch_shifter(factor=1.5): captured = yield b"" # Simple pitch shift using sample doubling/skipping audio_buffer = array.array('h') while True: captured = yield captured if isinstance(captured, bytes): captured = array.array('h', captured) # Pitch shift by changing playback rate shifted = array.array('h') for i, sample in enumerate(captured): if int(i * factor) < len(captured): shifted.append(captured[int(i * factor)]) captured = shifted device = miniaudio.DuplexStream() gen = pitch_shifter(factor=0.8) # Lower pitch next(gen) device.start(gen) print("Pitch shift active (lower). Press Ctrl+C to stop...") try: time.sleep(10) except KeyboardInterrupt: pass device.stop() device.close() ``` -------------------------------- ### Configure Playback Device with File Info Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/sound-file-info.md Shows how to use `SoundFileInfo` properties to configure a `PlaybackDevice` and stream an audio file with matching parameters. ```python import miniaudio info = miniaudio.get_file_info("music.flac") # Create a playback device matching the file's properties with miniaudio.PlaybackDevice( output_format=info.sample_format, nchannels=info.nchannels, sample_rate=info.sample_rate ) as device: stream = miniaudio.stream_file( "music.flac", output_format=info.sample_format, nchannels=info.nchannels, sample_rate=info.sample_rate ) next(stream) device.start(stream) # Play for duration import time time.sleep(info.duration) ``` -------------------------------- ### Choose Audio Backend at Runtime Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/utility-functions.md Create a playback device, optionally specifying a preferred audio backend. If the preferred backend is unavailable, a warning is printed, and a default backend is used. ```python import miniaudio def create_device_with_backend(backend_preference=None): """Create a playback device with optional backend preference""" backends = miniaudio.get_enabled_backends() if backend_preference and backend_preference not in backends: print(f"Warning: {backend_preference.name} not available") backend_preference = None if backend_preference: preferred_backends = [backend_preference] else: preferred_backends = None device = miniaudio.PlaybackDevice(backends=preferred_backends) print(f"Using {device.backend} backend") return device device = create_device_with_backend(miniaudio.Backend.PULSEAUDIO) # ... use device ``` -------------------------------- ### Playback and Capture Device Initialization Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/README.md Demonstrates initializing PlaybackDevice and CaptureDevice with a specified sample rate. The playback device streams a file, while the capture device processes incoming audio data. ```python # Playback device = miniaudio.PlaybackDevice(sample_rate=44100) stream = miniaudio.stream_file("music.mp3") next(stream) device.start(stream) # Capture device = miniaudio.CaptureDevice(sample_rate=44100) def callback(): _ = yield while True: data = yield # Process captured audio device_gen = callback() next(device_gen) device.start(device_gen) ``` -------------------------------- ### Configure Playback Device with Backend Priority Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/configuration.md Instantiate a playback device, prioritizing PulseAudio, then ALSA, then JACK. ```python device = miniaudio.PlaybackDevice( backends=[ miniaudio.Backend.PULSEAUDIO, miniaudio.Backend.ALSA, miniaudio.Backend.JACK ] ) ``` -------------------------------- ### Get General File Info Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/file-info-functions.md Query properties of any supported audio file format. Use this to get metadata like duration, sample rate, and channel count before decoding. ```python import miniaudio info = miniaudio.get_file_info("music.mp3") print(f"Duration: {info.duration:.2f} seconds") print(f"Sample rate: {info.sample_rate} Hz") print(f"Channels: {info.nchannels}") print(f"Format: {info.sample_format.name}") ``` -------------------------------- ### CaptureDevice Constructor Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/capture-device.md Initializes a CaptureDevice instance. Configure input format, channels, sample rate, buffer size, and other audio parameters. ```python class CaptureDevice(AbstractDevice): def __init__( self, input_format: SampleFormat = SampleFormat.SIGNED16, nchannels: int = 2, sample_rate: int = 44100, buffersize_msec: int = 200, device_id: Union[ffi.CData, None] = None, callback_periods: int = 0, backends: Optional[List[Backend]] = None, thread_prio: ThreadPriority = ThreadPriority.HIGHEST, app_name: str = "", ) -> None: ... ``` -------------------------------- ### List Playback and Capture Devices Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/README.md Initializes the `Devices` class and iterates through available playback devices, printing their names and supported formats. ```python import miniaudio devices = miniaudio.Devices() for dev in devices.get_playbacks(): print(f"{dev['name']}: {dev['formats']}") ``` -------------------------------- ### WavFileReadStream Source: https://github.com/irmen/pyminiaudio/blob/master/README.md An IO stream that reads as a .wav file, and which gets its pcm samples from the provided producer. ```APIDOC ## Class WavFileReadStream ### Description An IO stream that reads as a .wav file, and which gets its pcm samples from the provided producer. ### Methods #### `close()` * **Description**: Close the file. #### `read(amount: int = 9223372036854775807)` * **Description**: Read up to the given amount of bytes from the file. * **Parameters**: - **amount** (int) - Optional - The maximum number of bytes to read. Defaults to a very large number. * **Returns**: Bytes or None if the end of the file is reached. ``` -------------------------------- ### SoundFileInfo Constructor Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/sound-file-info.md Initializes a SoundFileInfo object with details about an audio file. ```APIDOC ## SoundFileInfo Constructor ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | name | str | Yes | — | File name or identifier | | file_format | FileFormat | Yes | — | Audio file format (WAV, FLAC, MP3, VORBIS) | | nchannels | int | Yes | — | Number of audio channels (mono=1, stereo=2, etc.) | | sample_rate | int | Yes | — | Sample rate in Hz (e.g., 44100, 48000) | | sample_format | SampleFormat | Yes | — | Sample format in memory | | duration | float | Yes | — | Duration of audio in seconds | | num_frames | int | Yes | — | Total number of audio frames | | sub_format | int | No | None | Sub-format identifier (codec-specific) | ``` -------------------------------- ### Select and Use a Specific Capture Device Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/capture-device.md Demonstrates how to list available audio input devices and select a specific one for recording by its ID. This allows for targeted audio capture when multiple devices are present. ```python import miniaudio # List available input devices devices = miniaudio.Devices() captures = devices.get_captures() print("Recording devices:") for dev in captures: print(f" {dev['name']}") print(f" Formats: {dev['formats']}") # Use the first capture device if captures: device_id = captures[0]["id"] device = miniaudio.CaptureDevice( device_id=device_id, sample_rate=48000, nchannels=1 ) # ... record audio using this specific device ``` -------------------------------- ### Configure CaptureDevice Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/configuration.md Instantiate a CaptureDevice with specific audio input settings. This allows control over sample format, channels, rate, buffer size, and device selection for audio capture. ```python capture = miniaudio.CaptureDevice( input_format=miniaudio.SampleFormat.SIGNED16, # Sample format nchannels=2, # Stereo sample_rate=44100, # CD quality buffersize_msec=200, # Buffer size device_id=None, # Default device callback_periods=0, # Default periods backends=None, # Auto-detect backend thread_prio=miniaudio.ThreadPriority.HIGHEST, # High priority app_name="MyApp" # App name ) ``` -------------------------------- ### DuplexStream Methods Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/duplex-stream.md Provides methods to control the audio stream, including starting, stopping, closing, and managing volume. ```APIDOC ## DuplexStream Methods ### `start(callback_generator: Generator[bytes | array.array, bytes | array.array, None]) -> None` #### Description Start simultaneous audio playback and capture. #### Parameters - **callback_generator** (Generator) - Required - Generator that both receives and yields audio. Receives captured audio as array.array (type matches capture_format), and yields playback audio as bytes, array.array, memoryview, or numpy array. Generator pattern: `def gen(): audio = yield b"""; while True: audio = yield playback_data` #### Raises - `MiniaudioError` — If device is already running or fails to start #### Example ```python import miniaudio def duplex_callback(): captured = yield b"" # Initialize while True: # captured contains input from microphone (array) # Echo the input back through speakers captured = yield captured device = miniaudio.DuplexStream() gen = duplex_callback() next(gen) device.start(gen) # Audio is now echoing ``` ### `stop() -> None` #### Description Stop both playback and capture. #### Example ```python device.stop() ``` ### `close() -> None` #### Description Close the audio device and free resources. Automatically called when used as context manager. #### Example ```python device.close() ``` ### `set_master_volume(volume: float) -> None` #### Description Set the master volume for both playback and capture. #### Parameters - **volume** (float) - Required - Volume level between 0.0 (silent) and 1.0 (full) #### Raises - `MiniaudioError` — If volume is outside [0.0, 1.0] range or device is closed #### Example ```python device.set_master_volume(0.75) ``` ### `get_master_volume() -> float` #### Description Get the master volume for the device. #### Returns float — Current volume between 0.0 and 1.0 #### Example ```python volume = device.get_master_volume() ``` ``` -------------------------------- ### CaptureDevice Constructor Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/capture-device.md Initializes a CaptureDevice for recording audio. Allows configuration of sample format, channels, sample rate, buffer size, and other advanced settings. ```APIDOC ## CaptureDevice Constructor ### Description Initializes a CaptureDevice for recording audio. Allows configuration of sample format, channels, sample rate, buffer size, and other advanced settings. ### Parameters #### Constructor Parameters - **input_format** (SampleFormat) - Optional - Default: SIGNED16 - Sample format for recording - **nchannels** (int) - Optional - Default: 2 - Number of audio channels (1=mono, 2=stereo) - **sample_rate** (int) - Optional - Default: 44100 - Sample rate in Hz (e.g., 44100, 48000) - **buffersize_msec** (int) - Optional - Default: 200 - Audio buffer size in milliseconds - **device_id** (ffi.CData or None) - Optional - Default: None - Specific device to use (from Devices.get_captures()) - **callback_periods** (int) - Optional - Default: 0 - Number of callback periods (0 = use default) - **backends** (List[Backend] or None) - Optional - Default: None - List of preferred backends to try - **thread_prio** (ThreadPriority) - Optional - Default: HIGHEST - Priority for audio thread - **app_name** (str) - Optional - Default: "" - Application name for audio subsystem **Note:** SIGNED24 format is not supported and will raise `MiniaudioError`. ``` -------------------------------- ### Configure PlaybackDevice Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/configuration.md Instantiate a PlaybackDevice with specific audio output settings. Use this to control sample format, channels, rate, buffer size, and device selection. ```python playback = miniaudio.PlaybackDevice( output_format=miniaudio.SampleFormat.SIGNED16, # Sample format nchannels=2, # Stereo sample_rate=44100, # CD quality buffersize_msec=200, # Buffer size device_id=None, # Default device callback_periods=0, # Default periods backends=None, # Auto-detect backend thread_prio=miniaudio.ThreadPriority.HIGHEST, # High priority app_name="MyApp" # App name ) ``` -------------------------------- ### Get Master Volume Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/playback-device.md Retrieves the current master volume level of the playback device, returned as a float between 0.0 and 1.0. ```python current_volume = device.get_master_volume() print(f"Current volume: {current_volume * 100:.0f}%") ``` -------------------------------- ### PlaybackDevice Constructor Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/playback-device.md Initializes a PlaybackDevice for audio output. Allows configuration of sample format, channels, sample rate, buffer size, and backend preferences. ```APIDOC ## PlaybackDevice() ### Description Initializes an audio output device for playback. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Constructor Parameters - **output_format** (SampleFormat) - Optional - Default: SIGNED16 - Sample format for playback. - **nchannels** (int) - Optional - Default: 2 - Number of audio channels (1=mono, 2=stereo). - **sample_rate** (int) - Optional - Default: 44100 - Sample rate in Hz (e.g., 44100, 48000). - **buffersize_msec** (int) - Optional - Default: 200 - Audio buffer size in milliseconds. - **device_id** (ffi.CData or None) - Optional - Default: None - Specific device to use (from Devices.get_playbacks()). - **callback_periods** (int) - Optional - Default: 0 - Number of callback periods (0 = use default). - **backends** (List[Backend] or None) - Optional - Default: None - List of preferred backends to try. - **thread_prio** (ThreadPriority) - Optional - Default: HIGHEST - Priority for audio thread. - **app_name** (str) - Optional - Default: "" - Application name for audio subsystem. ``` -------------------------------- ### SeekableSource Implementation Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/streamable-source.md Example of a StreamableSource that supports seeking within in-memory byte data. Implements read, seek, and close. ```python class SeekableSource(miniaudio.StreamableSource): def __init__(self, data: bytes): self.data = data self.position = 0 def read(self, num_bytes: int): chunk = self.data[self.position:self.position + num_bytes] self.position += len(chunk) return chunk def seek(self, offset: int, origin: miniaudio.SeekOrigin) -> bool: if origin == miniaudio.SeekOrigin.START: new_pos = offset elif origin == miniaudio.SeekOrigin.CURRENT: new_pos = self.position + offset elif origin == miniaudio.SeekOrigin.END: new_pos = len(self.data) + offset else: return False if 0 <= new_pos <= len(self.data): self.position = new_pos return True return False ``` -------------------------------- ### Get miniaudio Library Version Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/utility-functions.md Retrieves the version string of the underlying miniaudio C library. This is useful for compatibility checks or logging. ```python import miniaudio version = miniaudio.lib_version() print(f"miniaudio library version: {version}") ``` -------------------------------- ### Select and Initialize Playback Device Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/devices.md Allows the user to select a playback device from a list and initializes a PlaybackDevice object with a specified sample rate. This is useful for directing audio output to a specific hardware device. ```python import miniaudio devices = miniaudio.Devices() playbacks = devices.get_playbacks() print("Available playback devices:") for i, device in enumerate(playbacks): print(f"{i}: {device['name']}") choice = int(input("Select device: ")) selected_device = playbacks[choice] # Create playback device with specific hardware device = miniaudio.PlaybackDevice( device_id=selected_device["id"], sample_rate=44100 ) print(f"Using: {selected_device['name']}") ``` -------------------------------- ### Get Master Volume Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/capture-device.md Retrieves the current master volume level of the capture device. The returned value is a float between 0.0 and 1.0. ```python current_volume = device.get_master_volume() print(f"Recording level: {current_volume * 100:.0f}%") ``` -------------------------------- ### Use Specific Audio Backend Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/devices.md Initializes the miniaudio Devices with a specific backend, such as PulseAudio on Linux. This is useful for ensuring compatibility or performance with a particular audio system. ```python import miniaudio # Try PulseAudio on Linux devices = miniaudio.Devices([miniaudio.Backend.PULSEAUDIO]) print(f"Active backend: {devices.backend}") playbacks = devices.get_playbacks() for device in playbacks: print(f" {device['name']}") ``` -------------------------------- ### Handle MiniaudioError for Playback Device Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/exceptions.md Example of catching MiniaudioError when initializing a PlaybackDevice. This is useful for handling general audio device issues. ```python import miniaudio try: device = miniaudio.PlaybackDevice() except miniaudio.MiniaudioError as e: print(f"Audio device error: {e}") ``` -------------------------------- ### Get DuplexStream Master Volume Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/duplex-stream.md Retrieves the current master volume level of the DuplexStream device, which ranges from 0.0 (silent) to 1.0 (full). ```python volume = device.get_master_volume() ``` -------------------------------- ### Select and Initialize Capture Device for Recording Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/devices.md Enables selection of a capture device for recording audio. It sets up a callback to capture audio data and stores it in a buffer. The recording runs for a specified duration. ```python import miniaudio from time import sleep devices = miniaudio.Devices() captures = devices.get_captures() print("Available recording devices:") for i, device in enumerate(captures): print(f"{i}: {device['name']}") choice = int(input("Record from which device? ")) selected_device = captures[choice] buffer = [] def record_callback(): _ = yield while True: data = yield buffer.append(data) print(".", end="", flush=True) device = miniaudio.CaptureDevice( device_id=selected_device["id"], sample_rate=44100 ) gen = record_callback() next(gen) device.start(gen) print("Recording for 5 seconds...") sleep(5) device.stop() print(f"\nRecorded from: {selected_device['name']}") ``` -------------------------------- ### Check System Capabilities Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/README.md Retrieve library version, list enabled backends, and check for loopback support on a specific backend. ```python import miniaudio print(f"Library version: {miniaudio.lib_version()}") print(f"Backends: {miniaudio.get_enabled_backends()}") print(f"Loopback support: {miniaudio.is_loopback_supported(miniaudio.Backend.WASAPI)}") ``` -------------------------------- ### Batch Process Audio Files Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/file-info-functions.md Iterate through audio files in a directory, get their info, and sum their durations. Handles unsupported formats gracefully. ```python import miniaudio import pathlib audio_dir = pathlib.Path("./audio") total_duration = 0 for audio_file in audio_dir.glob("*.*"): try: info = miniaudio.get_file_info(str(audio_file)) total_duration += info.duration print(f"{audio_file.name}: {info.duration:.1f}s @ {info.sample_rate} Hz") except miniaudio.DecodeError: print(f"{audio_file.name}: Unsupported format") print(f"\nTotal duration: {total_duration / 3600:.2f} hours") ``` -------------------------------- ### Define SeekOrigin Enum Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/enums.md Defines the SeekOrigin enumeration with members START, CURRENT, and END, representing different reference points for seeking in audio streams. ```python class SeekOrigin(Enum): START = 0 CURRENT = 1 END = 2 ``` -------------------------------- ### Query Available Audio Devices Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/README.md Use the `Devices` class to list available playback and capture hardware, including their supported audio formats. A specific device can be selected by its ID. ```python devices = miniaudio.Devices() # List playback devices for dev in devices.get_playbacks(): print(f"{dev['name']}: {dev['formats']}") # List capture devices for dev in devices.get_captures(): print(f"{dev['name']}: {dev['formats']}") # Use specific device device = miniaudio.PlaybackDevice(device_id=playbacks[0]["id"]) ``` -------------------------------- ### Get Sample Width from Format Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/conversion-functions.md Use `width_from_format` to determine the byte width of a given `SampleFormat`. This is useful for understanding data size per sample. ```python import miniaudio for fmt in [miniaudio.SampleFormat.SIGNED16, miniaudio.SampleFormat.FLOAT32]: width = miniaudio.width_from_format(fmt) print(f"{fmt.name}: {width} bytes/sample") ``` -------------------------------- ### Configure Playback Device Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/README.md Configure a `PlaybackDevice` with specific audio format, channel count, sample rate, buffer size, thread priority, and preferred backends. Also demonstrates decoding configuration with output format, channels, sample rate, and dithering. ```python # Device configuration device = miniaudio.PlaybackDevice( output_format=miniaudio.SampleFormat.SIGNED16, nchannels=2, sample_rate=44100, buffersize_msec=200, thread_prio=miniaudio.ThreadPriority.HIGHEST, backends=[miniaudio.Backend.PULSEAUDIO], app_name="MyApp" ) # Decoding configuration sound = miniaudio.decode_file( "music.mp3", output_format=miniaudio.SampleFormat.FLOAT32, nchannels=2, sample_rate=48000, dither=miniaudio.DitherMode.TRIANGLE ) # Streaming configuration stream = miniaudio.stream_file( "music.flac", output_format=miniaudio.SampleFormat.SIGNED16, frames_to_read=2048, dither=miniaudio.DitherMode.NONE ) ``` -------------------------------- ### Get WAV File Info Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/file-info-functions.md Query WAV file properties from a file path or from in-memory bytes. Useful for specific WAV metadata extraction. ```python import miniaudio # From file info = miniaudio.wav_get_file_info("audio.wav") # From memory with open("audio.wav", "rb") as f: info = miniaudio.wav_get_info(f.read()) ``` -------------------------------- ### Check Backend Availability Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/utility-functions.md Determines if a specific audio backend is available on the current system. Iterate through potential backends to find compatible ones. ```python import miniaudio # Check which backends are available for backend in [miniaudio.Backend.WASAPI, miniaudio.Backend.PULSEAUDIO, miniaudio.Backend.COREAUDIO, miniaudio.Backend.ALSA]: if miniaudio.is_backend_enabled(backend): print(f"{backend.name} is available") ``` -------------------------------- ### Linux Backend Selection for Playback Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/configuration.md Attempts to use PulseAudio first, falling back to ALSA for playback on Linux systems. ```python # Try specific backend on Linux device = miniaudio.PlaybackDevice( backends=[ miniaudio.Backend.PULSEAUDIO, # Try PulseAudio first miniaudio.Backend.ALSA # Fallback to ALSA ] ) ``` -------------------------------- ### Robust Playback Device Initialization with Sample Rate Fallback Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/errors.md Attempts to initialize a playback device with a list of preferred sample rates, falling back to the next rate if initialization fails. ```python import miniaudio def create_playback_device(): """Create playback device with fallback""" sample_rates = [44100, 48000, 22050] for sr in sample_rates: try: device = miniaudio.PlaybackDevice(sample_rate=sr) print(f"Opened device at {sr} Hz") return device except miniaudio.MiniaudioError as e: print(f"Failed at {sr} Hz: {e}") continue raise miniaudio.MiniaudioError("Cannot open audio device") device = create_playback_device() ``` -------------------------------- ### Memory-Efficient Audio Streaming Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/decoding-functions.md Shows how to use streaming functions for large audio files to maintain constant memory usage. Includes examples for playback and chunk-based analysis. ```python import miniaudio # For large files, use streaming instead # stream_file() keeps memory usage constant stream = miniaudio.stream_file("large_file.mp3") next(stream) chunk_count = 0 with miniaudio.PlaybackDevice() as device: device.start(stream) # Only current chunk in memory import time time.sleep(300) # 5 minutes # For analysis, decode and process chunks stream = miniaudio.stream_memory(open("audio.mp3", "rb").read()) next(stream) for chunk in stream: # Process chunk (max 1024 frames at a time) pass ``` -------------------------------- ### Convert Sample Format and Rate Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/decoded-sound-file.md Demonstrates converting audio data to a different sample format and sample rate using `convert_frames`, then creating a new DecodedSoundFile object with the converted data and saving it. ```python import miniaudio # Load in original format first sound = miniaudio.read_file("music.flac") print(f"Original: {sound.sample_rate} Hz, {sound.sample_format.name}") # Convert to different format and sample rate converted_bytes = miniaudio.convert_frames( sound.sample_format, sound.nchannels, sound.sample_rate, sound.samples.tobytes(), miniaudio.SampleFormat.SIGNED16, sound.nchannels, 22050 ) # Create DecodedSoundFile with converted data converted_samples = miniaudio.array.array('h') converted_samples.frombytes(converted_bytes) converted = miniaudio.DecodedSoundFile( sound.name, sound.nchannels, 22050, miniaudio.SampleFormat.SIGNED16, converted_samples ) print(f"Converted: {converted.sample_rate} Hz, {converted.sample_format.name}") # Save converted version miniaudio.wav_write_file("output.wav", converted) ``` -------------------------------- ### Verify Audio File Integrity Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/file-info-functions.md A function to verify audio file integrity by attempting to get file info and catching DecodeErrors. It prints various file properties if successful. ```python import miniaudio def verify_audio_file(filename): try: info = miniaudio.get_file_info(filename) checks = { "Readable": True, "Format": info.file_format.name, "Duration": f"{info.duration:.2f}s", "Sample rate": f"{info.sample_rate} Hz", "Channels": info.nchannels, "Sample format": info.sample_format.name, } for check, result in checks.items(): print(f"{check}: {result}") return True except miniaudio.DecodeError as e: print(f"Error: {e}") return False verify_audio_file("audio.flac") ``` -------------------------------- ### Select Optimal Backend for Loopback Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/utility-functions.md Provides a function to find and select an optimal audio backend that supports loopback for audio capture. It prioritizes common backends across different operating systems. ```python import miniaudio def find_loopback_backend(): """Find a backend that supports loopback for audio capture""" backends = miniaudio.get_enabled_backends() # Prefer specific backends preferred = [ miniaudio.Backend.WASAPI, # Windows miniaudio.Backend.COREAUDIO, # macOS miniaudio.Backend.PULSEAUDIO, # Linux miniaudio.Backend.ALSA, # Linux fallback ] for backend in preferred: if backend in backends and miniaudio.is_loopback_supported(backend): return backend return None loopback_backend = find_loopback_backend() if loopback_backend: print(f"Using {loopback_backend.name} for loopback") else: print("No loopback-capable backend found") ``` -------------------------------- ### Query Specific Format Properties Source: https://github.com/irmen/pyminiaudio/blob/master/_autodocs/api-reference/file-info-functions.md Demonstrates querying properties specific to WAV, FLAC, and MP3 files using their respective get_file_info functions. ```python import miniaudio # Get WAV-specific info wav_info = miniaudio.wav_get_file_info("audio.wav") print(f"WAV: {wav_info.nchannels} ch @ {wav_info.sample_rate} Hz") # Get FLAC-specific info flac_info = miniaudio.flac_get_file_info("audio.flac") if flac_info.sample_format == miniaudio.SampleFormat.SIGNED32: print("24-bit FLAC detected") # Get MP3-specific info mp3_info = miniaudio.mp3_get_file_info("audio.mp3") print(f"MP3: {mp3_info.sample_format.name}") ```