Chirp Connect Python SDK

The Chirp Connect Python SDK makes it easy to send and receive data over sound on many different platforms, including

  • macOS
  • Raspberry Pi
  • Linux

The latest stable version can be downloaded from the Chirp Admin Centre.

Compatible with all supported versions of Python 2 and 3. However for best performance it is recommended to use Python 3.

Getting Started

Step 1 - Install dependencies

For audio I/O, the SDK relies on the host having the PortAudio library installed.

macOS

brew install portaudio libsndfile

Debian/Ubuntu

sudo apt-get install python3-dev python3-setuptools portaudio19-dev libffi-dev libsndfile1

CentOS

sudo yum install gcc alsa-lib-devel python-devel python-setuptools libffi-devel libsndfile

Step 2 - Install SDK

Installing the SDK from source is as simple as

python setup.py install

Note: This may take a few minutes on some platforms.

Usage

See example.py for a full working demo.

To send data, instantiate the SDK with your app key and secret. These can be retrieved from the Chirp Admin Centre.

from chirp import ChirpConnect

sdk = ChirpConnect(app_key, app_secret)
sdk.start(send=True, receive=False)

payload = sdk.new_payload([80, 102, 42, 42, 128])
sdk.send(payload)

To receive data, you should implement your own subclass of the CallbackSet. See example.py for all available callbacks.

from chirp import ChirpConnect, CallbackSet

class Callbacks(CallbackSet):
    def on_received(self, payload):
        print(str(payload))

sdk = ChirpConnect(app_key, app_secret)

callbacks = Callbacks()
sdk.set_callbacks(callbacks)
sdk.start(send=False, receive=True)

To stop the SDK processing data, and finally close audio streams.

sdk.stop()
sdk.close()

Audio

The audio layer has several configurable options to suit your hardware requirements. These must be configured before the SDK is started.

Any changes to the audio configuration will only take effect if the SDK is not running.

The audio layer will use the default input/output device on the system. However you can explicitly define which device to use. This is particularly useful for Raspberry Pi’s, where an external USB microphone must be used, and many devices may be available. To check the available devices, run

sdk.audio.query_devices()

To set a specific input/output device, instruct the SDK to use the device using the index.

sdk.audio.input_device = 2
sdk.audio.output_device = 4

The block size of the audio buffer can also be configured. By default the audio layer will allow the system to decide how many samples to process per block.

sdk.audio.block_size = 4096  # samples per block

The SDK can process float32 or int16 samples. The SDK uses float32 by default but you can configure with int16s by running

sdk.audio.sample_size = 'int16'

The SDK can be instructed to process both mono/stereo output data

sdk.audio.output_channels = 2  # stereo

The sample rate can also be updated from the default value, which is typically 44.1kHz.

sdk.sample_rate = 48000  # Hz

Payloads

A Chirp payload is inherited from the built in type - bytearray. This means you can send data as a string or an iterable of integers. An array is typically used to access the full byte range of 0-255.

payload = sdk.new_payload([104, 101, 108, 108, 111])

To convert a received payload back to an array, just run

def on_received(self, payload):
    print(list(payload))

To print the payload encoded as a hex string

def on_received(self, payload):
    print(str(payload))

Licences

In offline mode (Enterprise users), licences can be loaded from file, retrieved from the network, or set directly from the licence string itself.

sdk.load_licence(licence_file)
sdk.set_licence(licence_string)
sdk.get_licence()
sdk.get_licence('ultrasonic')

The SDK can be instantiated directly with the path to the licence file.

from chirp import ChirpConnect
sdk = ChirpConnect(app_key, app_secret, licence_file)

Debugging

To check the quality of the input data from your microphone, you can run the SDK in debug mode. This will write the input audio data to a file called chirp_audio.wav. To do this, set the debug flag to True when instantiating the SDK. You can also specify an explicit path to save the wav file.


from chirp import ChirpConnect

sdk = ChirpConnect(app_key, app_secret, debug=True)

# Optionally specify wav file path
sdk.audio.wav_filename = '/path/to/wav'
sdk.start()

Advanced

The Python SDK uses sounddevice by default, however you can override this if you want to implement your own audio layer. This is achieved by subclassing the AudioSet class, then overriding the audio attribute before starting the SDK.

The raw audio data can be passed to the process_input and process_output functions inside your audio callback. See chirp/audio.py for a reference.

from chirp import AudioSet, ChirpConnect

class CustomAudio(AudioSet):
    """ Override init, start, stop, close methods """
    def __init__(self, sdk):
        self.sdk = sdk

    def start(self, send=True, receive=True):
        """ Start audio streams, and set up callbacks """
        pass

    def audio_callback(self, data):
        self.sdk.process_input(data)

sdk = ChirpConnect(key, secret)
sdk.audio = CustomAudio(sdk)
sdk.start(send=False, receive=True)

Troubleshooting

Audio device is not available

sounddevice.PortAudioError: Error querying device -1

Check the device is set up correctly, you may need to explicitly set the device index. See Audio section.

sdk.audio.query_devices()

Or if you have no input device, then you need to set receive=False when calling the start method.

Not receiving any data

First of all, put the SDK in debug mode (see Debug section) and check the audio data from your microphone is good quality. Also ensure that the SDK’s audio layer is set up exactly the same as your input device. The SDK is expecting single channel mono input data, and is usually configured with a sample rate of 44.1kHz.

Experiment with different block sizes, by default the SDK will use an adaptive block size but some platforms perform better with a fixed size. See Audio section.

sdk.audio.block_size = 4096

Audio output is stuttering

Ensure the SDK’s audio layer is set up exactly the same as your audio driver. Try experimenting with different settings. See Audio section.

sdk.audio.output_channels = 2