A python wrapper for the pulseaudio simple API. Supports playing and recording audio via PulseAudio and PipeWire.
This library is feature-complete, so there won't be much ongoing activity in this repository. Reported bugs will be fixed. PRs for improvements are always welcome.
libpulse-simple.so.0(part oflibpulse0on Debian orlibpulseon Arch)- A running PulseAudio/PipeWire server
There's a good chance your Linux distribution comes with PulseAudio or PipeWire preinstalled.
pip3 install pasimpleThere are two simple convenience functions for recording/playing audio to/from a .wav file:
from pasimple import record_wav, play_wav
# Record 5 seconds of audio from the default recording device
record_wav('/tmp/test_recording.wav', 5)
# Play the recording via the default output device
play_wav('/tmp/test_recording.wav')Both functions block until all audio has been recorded/played. The default encoding used by record_wav is PA_SAMPLE_S24LE, mono, 41kHz. The function play_wav can only recognize files encoded in one of the following formats: PA_SAMPLE_U8, PA_SAMPLE_S16LE, PA_SAMPLE_S24LE, PA_SAMPLE_S32LE. For more complex use cases, scroll down to the "Documentation" section.
A more extensive example for recording audio can be found in examples/record.py:
import wave
import pasimple
# Audio attributes for the recording
FORMAT = pasimple.PA_SAMPLE_S32LE
SAMPLE_WIDTH = pasimple.format2width(FORMAT)
CHANNELS = 1
SAMPLE_RATE = 41000
# Record 10 seconds of audio
with pasimple.PaSimple(pasimple.PA_STREAM_RECORD, FORMAT, CHANNELS, SAMPLE_RATE) as pa:
audio_data = pa.read(CHANNELS * SAMPLE_RATE * SAMPLE_WIDTH * 10)
# Save audio to a file
with wave.open('recording.wav', 'wb') as wave_file:
wave_file.setsampwidth(SAMPLE_WIDTH)
wave_file.setnchannels(CHANNELS)
wave_file.setframerate(SAMPLE_RATE)
wave_file.writeframes(audio_data)In this example we're explicity specifying the audio format to be used for recording. When the PaSimple object is created, it opens a PulseAudio stream with the specified format. Further parameters that can be used in the PaSimple constructor are described in more detail under "Documentation" below.
The recording starts as soon as the PaSimple object is created and audio data is buffered internally. Calls to read can retrieve the raw audio data, specifying the number of bytes to read as an argument. The function will block until the requested number of bytes is available. When done recording, the PaSimple object's audio stream should be closed with a call to close(). Alternatively, it can be used with python's context manager (the with statement in the example above).
Finally, the data is written to a .wav file. We specify the audio format again, so that a correct .wav file header can be written.
An example for playing audio can be found in examples/play.py:
import wave
import pasimple
# Read a .wav file with its attributes
with wave.open('recording.wav', 'rb') as wave_file:
format = pasimple.width2format(wave_file.getsampwidth())
channels = wave_file.getnchannels()
sample_rate = wave_file.getframerate()
audio_data = wave_file.readframes(wave_file.getnframes())
# Play the file via PulseAudio
with pasimple.PaSimple(pasimple.PA_STREAM_PLAYBACK, format, channels, sample_rate) as pa:
pa.write(audio_data)
pa.drain()To play a .wav file, we basically do the recording steps in reverse. First, we read the audio encoding together with the raw audio data from the file. When creating the PaSimple object, this time, we're opening a playback stream and specify the format of the audio we're going to play. It's then as simple as passing the raw audio data to the write function. Finally, we call drain to make sure all audio has played before closing the stream by leaving the with context.
An annotated example of how to stream audio from/to a source/sink can be found in examples/echo.py
This sections describes all constants/functions/classes available in the pasimple module.
Stream directions
The stream direction is used when creating a PaSimple object to specify whether the stream should be used for playing or recording audio.
| Constant | Description |
|---|---|
| PA_STREAM_PLAYBACK | Open a stream for playback |
| PA_STREAM_RECORD | Open a stream for recording |
Audio formats
Formats that can be used with PulseAudio to play or record audio. PulseAudio's documentation for these formats can be found here.
| Constant | Description |
|---|---|
| PA_SAMPLE_U8 | Unsigned 8 Bit PCM |
| PA_SAMPLE_ALAW | 8 Bit a-Law |
| PA_SAMPLE_ULAW | 8 Bit mu-Law |
| PA_SAMPLE_S16LE | Signed 16 Bit PCM, little endian (PC) |
| PA_SAMPLE_S16BE | Signed 16 Bit PCM, big endian |
| PA_SAMPLE_FLOAT32LE | 32 Bit IEEE floating point, little endian (PC), range -1.0 to 1.0 |
| PA_SAMPLE_FLOAT32BE | 32 Bit IEEE floating point, big endian, range -1.0 to 1.0 |
| PA_SAMPLE_S32LE | Signed 32 Bit PCM, little endian (PC) |
| PA_SAMPLE_S32BE | Signed 32 Bit PCM, big endian |
| PA_SAMPLE_S24LE | Signed 24 Bit PCM packed, little endian (PC) |
| PA_SAMPLE_S24BE | Signed 24 Bit PCM packed, big endian |
| PA_SAMPLE_S24_32LE | Signed 24 Bit PCM in LSB of 32 Bit words, little endian (PC) |
| PA_SAMPLE_S24_32BE | Signed 24 Bit PCM in LSB of 32 Bit words, big endian |
width2format(sample_width)
sample_width: Audio sample width to return a matching format for.
Returns one of PA_SAMPLE_U8, PA_SAMPLE_S16LE, PA_SAMPLE_S24LE or PA_SAMPLE_S32LE (common PCM audio formats), corresponding to the provided sample width or an error if none match.
format2width(audio_format)
audio_format: One of thePA_SAMPLE_*audio formats to return the width for.
Returns the sample width for an audio format.
play_wav(file_path)
file_path: Path to a.wavfile to be played.
Plays a .wav file via PulseAudio and blocks until all audio data has been played. The following formats are supported: PA_SAMPLE_U8, PA_SAMPLE_S16LE, PA_SAMPLE_S24LE, PA_SAMPLE_S32LE. Throws a wave.Error if the .wav file cannot be read or a PaSimpleError if the audio data cannot be played.
record_wav(file_path, length, format=PA_SAMPLE_S24LE, channels=1, sample_rate=41000)
file_path: Path to a.wavfile the recorded audio will be written to.length: The length of the recording in seconds.format: Audio format to be used for the recording (one ofPA_SAMPLE_U8,PA_SAMPLE_S16LE,PA_SAMPLE_S24LE,PA_SAMPLE_S32LE).channels: Number of channels to record (1=mono, 2=stereo).sample_rate: Sample rate for the recording in Hz.
Records a .wav file via PulseAudio and blocks until all audio data has been recorded. The following formats are supported: PA_SAMPLE_U8, PA_SAMPLE_S16LE, PA_SAMPLE_S24LE, PA_SAMPLE_S32LE. Throws a wave.Error if the .wav file cannot be written or a PaSimpleError if the audio data cannot be recorded.
An instance of PaSimple represents an audio stream for playing or recording audio via PulseAudio. On error, all functions throw a PaSimpleError.
PaSimple(direction, format, channels, rate, app_name='python', stream_name=None, server_name=None, device_name=None, maxlength=-1, tlength=-1, prebuf=-1, minreq=-1, fragsize=-1):
direction: EitherPA_STREAM_PLAYBACKorPA_STREAM_RECORD.format: The audio encoding (one ofPA_SAMPLE_*) for this stream.channels: Integer specifying the number of channels (1=mono, 2=stereo).rate: Integer specifying the sample rate in Hz.app_name: String specifying the name of the application that will be registered in PulseAudio.stream_name:None(useapp_name) or a string specifying the name of this stream that will be registered in PulseAudio.server_name:None(default) or a string specifying a PulseAudio server name.device_name:None(default) or a string specifying a specific PulseAudio device for recording or playback.maxlength:-1(default: max supported) or an integer specifying the buffer size limit in bytes.tlength:-1(default: about 2s) or an integer specifying how many bytes to keep in the playback buffer.prebuf:-1(usetlength) or an integer specifying how many bytes to buffer before starting playback.minreq:-1(default: about 2s) or an integer specifying the minimum size of chunks for refilling the playback buffer in bytes.fragsize:-1(default: about 2s) or an integer specifying the size of recording chunks in bytes.
Initialize a PulseAudio simple API stream for playing or recording audio data.
close()
Close the underlying stream and free resources.
direction()
Returns the direction specified in the constructor.
format()
Returns the audio format specified in the constructor.
channels()
Returns the number of audio channels specified in the constructor.
rate()
Returns the audio rate specified in the constructor.
read(num_bytes)
num_bytes: The number of bytes to read.
Record data from the PulseAudio server. PA_STREAM_RECORD must have been used during initialization. This function blocks and returns num_bytes bytes of audio data.
write(data)
data: Raw audio data to be played.
Play audio via the PulseAudio server. PA_STREAM_PLAYBACK must have been used during initialization. Encoding of data must match the one specified in the constructor.
drain()
Blocks until all remaining data in the buffer has been played.
flush()
Discards any data in the record/playback buffers.
get_latency()
Returns the record/playback latency reported by PulseAudio in microseconds.
This list of PulseAudio internal error codes has been taken from here.
| Error code | Description |
|---|---|
| 0 | No error |
| 1 | Access failure |
| 2 | Unknown command |
| 3 | Invalid argument |
| 4 | Entity exists |
| 5 | No such entity |
| 6 | Connection refused |
| 7 | Protocol error |
| 8 | Timeout |
| 9 | No authentication key |
| 10 | Internal error |
| 11 | Connection terminated |
| 12 | Entity killed |
| 13 | Invalid server |
| 14 | Module initialization failed |
| 15 | Bad state |
| 16 | No data |
| 17 | Incompatible protocol version |
| 18 | Data too large |
| 19 | Operation not supported |
| 20 | The error code was unknown to the client |
| 21 | Extension does not exist |
| 22 | Obsolete functionality |
| 23 | Missing implementation |
| 24 | The caller forked without calling execve() and tried to reuse the context |
| 25 | An IO error happened |
| 26 | Device or resource busy |
| 27 | Not really an error but the first invalid error code |