├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── PLATFORMS.md ├── README.md ├── examples ├── ESP32Receive │ ├── ESP32Receive.ino │ └── credentials.h ├── ESP32Send │ ├── ESP32Send.ino │ └── credentials.h ├── MKRZeroSend │ ├── MKRZeroSend.ino │ └── credentials.h ├── MXChipSendReceive │ ├── MXChipSendReceive.ino │ └── credentials.h ├── Nano33SenseReceive │ ├── Nano33SenseReceive.ino │ └── credentials.h └── Nano33SenseSend │ ├── Nano33SenseSend.ino │ └── credentials.h ├── keywords.txt ├── library.properties └── src ├── chirp_sdk.h ├── chirp_sdk_errors.h ├── chirp_sdk_events.h ├── chirp_sdk_version.h ├── cortex-m0plus └── libChirpSDK.a ├── cortex-m4 └── libChirpSDK.a ├── esp32 └── libChirpSDK.a └── mk64fx512 └── libChirpSDK.a /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # ChirpSDK for Arduino Changelog 2 | 3 | Recent changes to the [Chirp Arduino SDK](https://developers.chirp.io/docs). 4 | 5 | ## v3.4.1 (09/12/2019) 6 | - Add support for Teensy boards (cortex-m4 hard float build) 7 | 8 | ## v3.4.0 (18/09/2019) 9 | - All functions have been renamed to `chirp_sdk*` from `chirp_connect*` 10 | - `chirp_sdk_get_heap_usage` has been added. This gives you the current dynamic memory allocated and used at any time by the SDK. 11 | - `chirp_connect_pause` has been removed. 12 | - `chirp_connect_as_string` has been removed. You can find alternatives on our [Payload](https://developers.chirp.io/docs/using-chirp/payloads) page. 13 | - `chirp_sdk_(set/get)_auto_mute` becomes `chirp_sdk_(set/get)_listen_to_self`. Be aware these are opposite meanings so don't forget to switch `true` by `false` and vice versa when updating your code. 14 | - `CHIRP_SDK_MEMORY_LEAK` error code has been added and is returned by `del_chirp_sdk` when some memory leaks occur when deleting the SDK. 15 | - `CHIRP_SDK_RECEIVING_NOT_AVAILABLE` error code has been added and is returned when trying to use decoding features with a library which is send only. 16 | - Core build v3.3.1 17 | 18 | ## v3.3.1 (22/08/2019) 19 | - Use high frequency oscillator in Nano 33 Sense examples 20 | 21 | ## v3.3.0 (09/08/2019) 22 | 23 | - Added support for cortex-m4 (Nano 33 Sense) 24 | - Added send-only support for cortex-m0plus (MKRZero, MKR Vidor 4000) 25 | - Build v3.3.0-rc1 26 | 27 | ## v3.2.0 (14/03/2019) 28 | 29 | - Build v3.2.9 30 | - Optimised DSP for ESP32 31 | 32 | ## v3.1.0 (11/03/2019) 33 | 34 | - Build v3.2.8 35 | - Significant memory improvements 36 | 37 | ## v3.0.0 (03/03/2019) 38 | 39 | - Build v3.2.5 40 | - cortex-m4 architectures for MXChip 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Chirp License 2 | 3 | This software is copyright © 2011-2019, Asio Ltd. All rights reserved. 4 | 5 | This software is provided under license from Asio Ltd. It is to be used only in accordance with our [Fair Use Policy](https://public.chirp.io/docs/Chirp+Fair+Use+Licence+Agreement.pdf) 6 | 7 | Chirp retains the right to revoke access or use of our technology without limitation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the software. 8 | 9 | Chirp acknowledges that the following third-party open source software is used and covered by these licenses (Apache-2.0 and BSD-3) 10 | 11 | - [Arm mBedTLS License](https://github.com/ARMmbed/mbedtls/blob/development/apache-2.0.txt) 12 | - [Arm CMSIS License](https://github.com/ARM-software/CMSIS_5/blob/develop/LICENSE.txt) 13 | - [ESP DSP License](https://github.com/espressif/esp-dsp/blob/master/LICENSE) 14 | - [libtomcrypt License](https://github.com/libtom/libtomcrypt/blob/develop/LICENSE) 15 | -------------------------------------------------------------------------------- /PLATFORMS.md: -------------------------------------------------------------------------------- 1 | # Chirp Arduino - Platforms 2 | 3 | Chirp is a library enabling Arduino-based devices to send and receive data using sound. You'll need: 4 | 5 | * A compatible Arduino board 6 | * A digital I2S MEMS microphone (if your board does not contain a microphone) 7 | * A digital I2S amplifier and compatible speaker 8 | 9 | See a full list of supported platforms at the [Chirp Developer Hub](https://developers.chirp.io/docs/using-chirp/platforms#arduino) 10 | 11 | For receiving data, you will need a digital MEMS microphone. Some boards (for example, the Nano 33 Sense and Microsoft MXChip) already include a MEMS mic so you are good to go. For others, you will need an external mic such as the [SPH0645](https://www.adafruit.com/product/3421) or [ICS-43434](https://www.mouser.co.uk/ProductDetail/TDK-InvenSense/ICS-43434?qs=u4fy%2FsgLU9PAgmWRI7%252BqXA%3D%3D). 12 | 13 | For sending data, we recommend using a digital I2S audio output such as the [UDA1334A](https://www.adafruit.com/product/3678) or [MAX98357A](https://www.adafruit.com/product/3006), connected to a compatible speaker. 14 | 15 | You can quickly test that your device is receiving chirps by playing some random test signals from the [Developer Hub](https://developers.chirp.io). 16 | 17 | To test whether your device is sending chirps OK, we recommend setting up the [Python command-line tools](https://developers.chirp.io/docs/tutorials/command-line) to receive data from the Arduino. 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chirp for Arduino 2 | 3 | Chirp for Arduino makes it quick and easy to integrate Chirp connectivity into your Arduino sketches. 4 | 5 | * For step-by-step instructions, follow the [Chirp Getting Started Guide for Arduino](https://developers.chirp.io/docs/getting-started/arduino). 6 | * For an overview of Chirp technology, see our [Chirp Overview](https://developers.chirp.io/docs/). 7 | * To get in touch directly, visit [Chirp Developer Support](https://developers.chirp.io/support). 8 | 9 | *** 10 | 11 | This software is copyright © 2011-2019, Asio Ltd. All rights reserved. -------------------------------------------------------------------------------- /examples/ESP32Receive/ESP32Receive.ino: -------------------------------------------------------------------------------- 1 | /**----------------------------------------------------------------------------- 2 | 3 | Example code using the Chirp SDK to receive data using ESP32 and 4 | SPH0645 microphone 5 | 6 | @file ESP32Receive.ino 7 | 8 | @brief Create a developer account at https://developers.chirp.io, 9 | and copy and paste your key, secret and config string for the 10 | "16khz-mono-embedded" protocol into the credentials.h file. 11 | 12 | This example will start listening for chirps and print to the terminal 13 | when anything is received. 14 | 15 | Note: this example can be used in conjunction with the send example, 16 | to send and receive data in the same application. 17 | 18 | Copyright © 2011-2019, Asio Ltd. 19 | All rights reserved. 20 | 21 | ----------------------------------------------------------------------------*/ 22 | #include 23 | 24 | #include "chirp_sdk.h" 25 | #include "credentials.h" 26 | 27 | #define I2SI_DATA 12 // I2S DATA IN on GPIO32 28 | #define I2SI_BCK 14 // I2S BCLK on GPIO14 29 | #define I2SI_LRCL 15 // I2S SELECT on GPIO15 30 | 31 | #define LED_PIN 2 // Pin number for on-board LED 32 | #define SWITCH_PIN 0 // Pin number for on-board switch 33 | 34 | #define BUFFER_SIZE 512 // Audio buffer size 35 | #define SAMPLE_RATE 16000 // Audio sample rate 36 | 37 | /** 38 | Convert I2S input data. 39 | Data is 18 bit signed, MSBit first, two's complement. 40 | The MIC_CALIBRATION value is determined using the Serial 41 | Plotter to centre the audio about zero. The below value 42 | should be correct for most ESP32 boards. 43 | */ 44 | #define MIC_CALIBRATION 13125 45 | #define CONVERT_INPUT(sample) (((int32_t)(sample) >> 14) + MIC_CALIBRATION) 46 | 47 | // Global variables ------------------------------------------------------------ 48 | 49 | static chirp_sdk_t *chirp = NULL; 50 | static chirp_sdk_state_t currentState = CHIRP_SDK_STATE_NOT_CREATED; 51 | static bool startTasks = false; 52 | 53 | // Function definitions -------------------------------------------------------- 54 | 55 | void setupChirp(); 56 | void chirpErrorHandler(chirp_sdk_error_code_t code); 57 | void setupAudioInput(int sample_rate); 58 | 59 | // Function declarations ------------------------------------------------------- 60 | 61 | void setup() 62 | { 63 | pinMode(LED_PIN, OUTPUT); 64 | digitalWrite(LED_PIN, LOW); 65 | 66 | Serial.begin(115200); 67 | Serial.printf("Heap size: %u\n", ESP.getFreeHeap()); 68 | 69 | xTaskCreate(initTask, "initTask", 16384, NULL, 1, NULL); 70 | } 71 | 72 | void loop() 73 | { 74 | esp_err_t audioError; 75 | chirp_sdk_error_code_t chirpError; 76 | 77 | if (startTasks) 78 | { 79 | xTaskCreate(processInputTask, "processInputTask", 16384, NULL, 5, NULL); 80 | startTasks = false; 81 | } 82 | } 83 | 84 | // RTOS Tasks ------------------------------------------------------------------ 85 | 86 | void initTask(void *parameter) 87 | { 88 | setupChirp(); 89 | 90 | chirp_sdk_error_code_t chirpError = chirp_sdk_set_input_sample_rate(chirp, SAMPLE_RATE); 91 | chirpErrorHandler(chirpError); 92 | setupAudioInput(SAMPLE_RATE); 93 | 94 | Serial.printf("Heap size: %u\n", ESP.getFreeHeap()); 95 | startTasks = true; 96 | vTaskDelete(NULL); 97 | } 98 | 99 | void processInputTask(void *parameter) 100 | { 101 | esp_err_t audioError; 102 | chirp_sdk_error_code_t chirpError; 103 | 104 | size_t bytesLength = 0; 105 | float buffer[BUFFER_SIZE] = {0}; 106 | int32_t ibuffer[BUFFER_SIZE] = {0}; 107 | 108 | while (currentState >= CHIRP_SDK_STATE_RUNNING) 109 | { 110 | audioError = i2s_read(I2S_NUM_0, ibuffer, BUFFER_SIZE * 4, &bytesLength, portMAX_DELAY); 111 | if (bytesLength) 112 | { 113 | for (int i = 0; i < bytesLength / 4; i++) 114 | { 115 | buffer[i] = (float) CONVERT_INPUT(ibuffer[i]); 116 | } 117 | 118 | chirpError = chirp_sdk_process_input(chirp, buffer, bytesLength / 4); 119 | chirpErrorHandler(chirpError); 120 | } 121 | } 122 | vTaskDelete(NULL); 123 | } 124 | 125 | // Chirp ----------------------------------------------------------------------- 126 | 127 | void onStateChangedCallback(void *chirp, chirp_sdk_state_t previous, chirp_sdk_state_t current) 128 | { 129 | currentState = current; 130 | Serial.printf("State changed from %d to %d\n", previous, current); 131 | } 132 | 133 | void onReceivingCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) 134 | { 135 | Serial.println("Receiving data..."); 136 | digitalWrite(LED_PIN, HIGH); 137 | } 138 | 139 | void onReceivedCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) 140 | { 141 | if (payload) 142 | { 143 | char *data = (char *)calloc(length + 1, sizeof(uint8_t)); 144 | memcpy(data, payload, length * sizeof(uint8_t)); 145 | Serial.print("Received data: "); 146 | Serial.println(data); 147 | free(data); 148 | } 149 | else 150 | { 151 | Serial.println("Decode failed."); 152 | } 153 | } 154 | 155 | void setupChirp() 156 | { 157 | chirp = new_chirp_sdk(CHIRP_APP_KEY, CHIRP_APP_SECRET); 158 | if (chirp == NULL) 159 | { 160 | Serial.println("Chirp initialisation failed."); 161 | return; 162 | } 163 | 164 | chirp_sdk_error_code_t err = chirp_sdk_set_config(chirp, CHIRP_APP_CONFIG); 165 | chirpErrorHandler(err); 166 | 167 | chirp_sdk_callback_set_t callbacks = {0}; 168 | callbacks.on_state_changed = onStateChangedCallback; 169 | callbacks.on_receiving = onReceivingCallback; 170 | callbacks.on_received = onReceivedCallback; 171 | 172 | err = chirp_sdk_set_callbacks(chirp, callbacks); 173 | chirpErrorHandler(err); 174 | 175 | err = chirp_sdk_set_callback_ptr(chirp, chirp); 176 | chirpErrorHandler(err); 177 | 178 | err = chirp_sdk_start(chirp); 179 | chirpErrorHandler(err); 180 | 181 | Serial.println("Chirp SDK initialised."); 182 | } 183 | 184 | void chirpErrorHandler(chirp_sdk_error_code_t code) 185 | { 186 | if (code != CHIRP_SDK_OK) 187 | { 188 | const char *error_string = chirp_sdk_error_code_to_string(code); 189 | Serial.println(error_string); 190 | exit(42); 191 | } 192 | } 193 | 194 | // I2S Audio ------------------------------------------------------------------- 195 | 196 | void setupAudioInput(int sample_rate) 197 | { 198 | /* 199 | Set up I2S audio for SPH0645 microphone 200 | */ 201 | esp_err_t err; 202 | Serial.println("Initialising audio input driver.."); 203 | 204 | const i2s_config_t i2s_config = 205 | { 206 | .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX), 207 | .sample_rate = sample_rate, 208 | .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, 209 | .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, 210 | .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), 211 | .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, 212 | .dma_buf_count = 8, 213 | .dma_buf_len = 64, 214 | .use_apll = true 215 | }; 216 | 217 | const i2s_pin_config_t pin_config = 218 | { 219 | .bck_io_num = I2SI_BCK, 220 | .ws_io_num = I2SI_LRCL, 221 | .data_out_num = I2S_PIN_NO_CHANGE, 222 | .data_in_num = I2SI_DATA 223 | }; 224 | 225 | err = i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); 226 | if (err != ESP_OK) 227 | { 228 | Serial.printf("Failed installing driver: %d\n", err); 229 | while (true); 230 | } 231 | 232 | err = i2s_set_pin(I2S_NUM_0, &pin_config); 233 | if (err != ESP_OK) 234 | { 235 | Serial.printf("Failed setting pin: %d\n", err); 236 | while (true); 237 | } 238 | 239 | err = i2s_set_sample_rates(I2S_NUM_0, sample_rate); 240 | if (err != ESP_OK) 241 | { 242 | Serial.printf("Failed to set sample rates: %d\n", err); 243 | while (true); 244 | } 245 | 246 | Serial.println("Audio input driver initalised."); 247 | } 248 | -------------------------------------------------------------------------------- /examples/ESP32Receive/credentials.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------ 2 | * 3 | * Credentials.h 4 | * 5 | * For full information on usage and licensing, see https://chirp.io/ 6 | * 7 | * Copyright © 2011-2019, Asio Ltd. 8 | * All rights reserved. 9 | * 10 | *----------------------------------------------------------------------------*/ 11 | 12 | #ifndef Credentials_h 13 | #define Credentials_h 14 | 15 | #error("Add your credentials below (from https://developers.chirp.io) and delete this line.") 16 | 17 | #define CHIRP_APP_KEY "YOUR_APP_KEY" 18 | #define CHIRP_APP_SECRET "YOUR_APP_SECRET" 19 | #define CHIRP_APP_CONFIG "YOUR_APP_CONFIG" 20 | 21 | #endif /* Credentials_h */ 22 | -------------------------------------------------------------------------------- /examples/ESP32Send/ESP32Send.ino: -------------------------------------------------------------------------------- 1 | /**----------------------------------------------------------------------------- 2 | 3 | Example code using the Chirp SDK to send data using ESP32 and UDA1334 4 | audio output 5 | 6 | @file ESP32Send.ino 7 | 8 | @brief Create a developer account at https://developers.chirp.io, 9 | and copy and paste your key, secret and config string for the 10 | "16khz-mono-embedded" protocol into the credentials.h file. 11 | 12 | When the EN switch is pressed on the board, a random chirp will be sent to 13 | the audio output. 14 | 15 | Note: this example can be used in conjunction with the receive example, 16 | to send and receive data in the same application. 17 | 18 | Copyright © 2011-2019, Asio Ltd. 19 | All rights reserved. 20 | 21 | ----------------------------------------------------------------------------*/ 22 | #include 23 | 24 | #include "chirp_sdk.h" 25 | #include "credentials.h" 26 | 27 | #define I2SO_DATA 23 // I2S DATA OUT on GPIO23 28 | #define I2SO_BCK 18 // I2S BCLK on GPIO18 29 | #define I2SO_WSEL 5 // I2S SELECT on GPIO5 30 | 31 | #define LED_PIN 2 // Pin number for on-board LED 32 | #define SWITCH_PIN 0 // Pin number for on-board switch 33 | 34 | #define VOLUME 0.5 // Between 0 and 1 35 | #define BUFFER_SIZE 512 36 | #define SAMPLE_RATE 16000 37 | 38 | // Global variables ------------------------------------------------------------ 39 | 40 | static chirp_sdk_t *chirp = NULL; 41 | static chirp_sdk_state_t currentState = CHIRP_SDK_STATE_NOT_CREATED; 42 | static volatile bool buttonPressed = false; 43 | static bool startTasks = false; 44 | 45 | // Function definitions -------------------------------------------------------- 46 | 47 | void IRAM_ATTR handleInterrupt(); 48 | void setupChirp(); 49 | void chirpErrorHandler(chirp_sdk_error_code_t code); 50 | void setupAudioOutput(int sample_rate); 51 | 52 | // Function declarations ------------------------------------------------------- 53 | 54 | void setup() 55 | { 56 | pinMode(LED_PIN, OUTPUT); 57 | digitalWrite(LED_PIN, LOW); 58 | pinMode(SWITCH_PIN, INPUT_PULLUP); 59 | attachInterrupt(digitalPinToInterrupt(SWITCH_PIN), handleInterrupt, FALLING); 60 | 61 | Serial.begin(115200); 62 | Serial.printf("Heap size: %u\n", ESP.getFreeHeap()); 63 | 64 | xTaskCreate(initTask, "initTask", 16384, NULL, 1, NULL); 65 | } 66 | 67 | void loop() 68 | { 69 | esp_err_t audioError; 70 | chirp_sdk_error_code_t chirpError; 71 | 72 | if (startTasks) 73 | { 74 | xTaskCreate(processOutputTask, "processOutputTask", 16384, NULL, 3, NULL); 75 | startTasks = false; 76 | } 77 | 78 | if (buttonPressed) 79 | { 80 | char *payload = "hello"; 81 | chirpError = chirp_sdk_send(chirp, (uint8_t *)payload, strlen(payload)); 82 | chirpErrorHandler(chirpError); 83 | Serial.print("Sending data: "); 84 | Serial.println(payload); 85 | buttonPressed = false; 86 | } 87 | } 88 | 89 | void IRAM_ATTR handleInterrupt() 90 | { 91 | buttonPressed = true; 92 | } 93 | 94 | // Tasks ----------------------------------------------------------------------- 95 | 96 | void initTask(void *parameter) 97 | { 98 | setupChirp(); 99 | 100 | uint32_t output_sample_rate = chirp_sdk_set_output_sample_rate(chirp, SAMPLE_RATE); 101 | setupAudioOutput(SAMPLE_RATE); 102 | 103 | Serial.printf("Heap size: %u\n", ESP.getFreeHeap()); 104 | startTasks = true; 105 | vTaskDelete(NULL); 106 | } 107 | 108 | void processOutputTask(void *parameter) 109 | { 110 | esp_err_t audioError; 111 | chirp_sdk_error_code_t chirpError; 112 | 113 | size_t bytesLength = 0; 114 | short buffer[BUFFER_SIZE] = {0}; 115 | int32_t ibuffer[BUFFER_SIZE] = {0}; 116 | 117 | while (currentState >= CHIRP_SDK_STATE_RUNNING) 118 | { 119 | chirpError = chirp_sdk_process_shorts_output(chirp, buffer, BUFFER_SIZE); 120 | chirpErrorHandler(chirpError); 121 | 122 | for (int i = 0; i < BUFFER_SIZE; i++) 123 | { 124 | ibuffer[i] = (int32_t) buffer[i]; 125 | } 126 | audioError = i2s_write(I2S_NUM_1, ibuffer, BUFFER_SIZE * 4, &bytesLength, portMAX_DELAY); 127 | } 128 | vTaskDelete(NULL); 129 | } 130 | 131 | // Chirp ----------------------------------------------------------------------- 132 | 133 | void onStateChangedCallback(void *chirp, chirp_sdk_state_t previous, chirp_sdk_state_t current) 134 | { 135 | currentState = current; 136 | Serial.printf("State changed from %d to %d\n", previous, current); 137 | } 138 | 139 | void onSendingCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) 140 | { 141 | Serial.println("Sending data..."); 142 | digitalWrite(LED_PIN, HIGH); 143 | } 144 | 145 | void onSentCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) 146 | { 147 | char *data = (char *)calloc(length + 1, sizeof(uint8_t)); 148 | memcpy(data, payload, length * sizeof(uint8_t)); 149 | Serial.printf("Send data: %s\n", data); 150 | free(data); 151 | digitalWrite(LED_PIN, LOW); 152 | } 153 | 154 | void setupChirp() 155 | { 156 | chirp = new_chirp_sdk(CHIRP_APP_KEY, CHIRP_APP_SECRET); 157 | if (chirp == NULL) 158 | { 159 | Serial.println("Chirp initialisation failed."); 160 | return; 161 | } 162 | 163 | chirp_sdk_error_code_t err = chirp_sdk_set_config(chirp, CHIRP_APP_CONFIG); 164 | chirpErrorHandler(err); 165 | 166 | chirp_sdk_callback_set_t callbacks = {0}; 167 | callbacks.on_sending = onSendingCallback; 168 | callbacks.on_sent = onSentCallback; 169 | callbacks.on_state_changed = onStateChangedCallback; 170 | 171 | err = chirp_sdk_set_callbacks(chirp, callbacks); 172 | chirpErrorHandler(err); 173 | 174 | err = chirp_sdk_set_callback_ptr(chirp, chirp); 175 | chirpErrorHandler(err); 176 | 177 | err = chirp_sdk_start(chirp); 178 | chirpErrorHandler(err); 179 | 180 | err = chirp_sdk_set_volume(chirp, VOLUME); 181 | chirpErrorHandler(err); 182 | 183 | Serial.println("Chirp SDK initialised."); 184 | } 185 | 186 | void chirpErrorHandler(chirp_sdk_error_code_t code) 187 | { 188 | if (code != CHIRP_SDK_OK) 189 | { 190 | const char *error_string = chirp_sdk_error_code_to_string(code); 191 | Serial.println(error_string); 192 | exit(42); 193 | } 194 | } 195 | 196 | // I2S Audio ------------------------------------------------------------------- 197 | 198 | void setupAudioOutput(int sample_rate) 199 | { 200 | /* 201 | Set up I2S audio for UDA1334 DAC output 202 | */ 203 | esp_err_t err; 204 | Serial.println("Initialising audio output driver.."); 205 | 206 | const i2s_config_t i2s_config = 207 | { 208 | .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX), 209 | .sample_rate = sample_rate, 210 | .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, 211 | .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, 212 | .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB), 213 | .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, 214 | .dma_buf_count = 8, 215 | .dma_buf_len = 64, 216 | .use_apll = true 217 | }; 218 | 219 | const i2s_pin_config_t pin_config = 220 | { 221 | .bck_io_num = I2SO_BCK, 222 | .ws_io_num = I2SO_WSEL, 223 | .data_out_num = I2SO_DATA, 224 | .data_in_num = I2S_PIN_NO_CHANGE 225 | }; 226 | 227 | err = i2s_driver_install(I2S_NUM_1, &i2s_config, 0, NULL); 228 | if (err != ESP_OK) 229 | { 230 | Serial.printf("Failed installing driver: %d\n", err); 231 | while (true); 232 | } 233 | 234 | err = i2s_set_pin(I2S_NUM_1, &pin_config); 235 | if (err != ESP_OK) 236 | { 237 | Serial.printf("Failed setting pin: %d\n", err); 238 | while (true); 239 | } 240 | 241 | err = i2s_set_sample_rates(I2S_NUM_1, sample_rate); 242 | if (err != ESP_OK) 243 | { 244 | Serial.printf("Failed to set sample rates: %d\n", err); 245 | while (true); 246 | } 247 | 248 | /* 249 | * Known Issue 250 | * The output sample rate is not correct if I2S0 is not configured 251 | * This can be removed if receiving is set up on I2S0. 252 | */ 253 | i2s_config_t i2s_config_stub = i2s_config; 254 | i2s_config_stub.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT; 255 | i2s_driver_install(I2S_NUM_0, &i2s_config_stub, 0, NULL); 256 | 257 | Serial.println("Audio output driver initalised."); 258 | } 259 | -------------------------------------------------------------------------------- /examples/ESP32Send/credentials.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------ 2 | * 3 | * Credentials.h 4 | * 5 | * For full information on usage and licensing, see https://chirp.io/ 6 | * 7 | * Copyright © 2011-2019, Asio Ltd. 8 | * All rights reserved. 9 | * 10 | *----------------------------------------------------------------------------*/ 11 | 12 | #ifndef Credentials_h 13 | #define Credentials_h 14 | 15 | #error("Add your credentials below (from https://developers.chirp.io) and delete this line.") 16 | 17 | #define CHIRP_APP_KEY "YOUR_APP_KEY" 18 | #define CHIRP_APP_SECRET "YOUR_APP_SECRET" 19 | #define CHIRP_APP_CONFIG "YOUR_APP_CONFIG" 20 | 21 | #endif /* Credentials_h */ 22 | -------------------------------------------------------------------------------- /examples/MKRZeroSend/MKRZeroSend.ino: -------------------------------------------------------------------------------- 1 | /**----------------------------------------------------------------------------- 2 | 3 | Example code using the Chirp SDK to transmit data over sound, using the 4 | MKRZero and UDA1334 audio output. 5 | 6 | @file MKRZeroSend.ino 7 | 8 | @brief Create a developer account at https://developers.chirp.io, 9 | and copy and paste your key, secret and config string for the 10 | "16khz-mono-embedded" protocol into the credentials.h file. 11 | 12 | This example will start sending a random chirp payload on start up. 13 | 14 | The example creates a double buffer for DMA tranfer, and populates 15 | the second buffer whilst the first is being transmitted and vice versa. 16 | These buffers are read directly by the I2S peripheral to output 17 | audio data. 18 | 19 | *Note*: This board is send-only as it does not have a floating-point unit 20 | which is required to receive data. 21 | 22 | *Important*: The example will not start until this Serial Monitor is opened. 23 | To disable this behaviour, comment out the while(!Serial) line. 24 | 25 | Circuit: 26 | - Arduino MKRZero 27 | - Adafruit UDA1334 28 | 29 | Alternative Boards: 30 | - Arduino Vidor 4000 31 | - Genuino Zero 32 | - Arduino MKR Fox 1200 33 | - Arduino MKR1000 WiFi 34 | 35 | Copyright © 2011-2019, Asio Ltd. 36 | All rights reserved. 37 | 38 | ----------------------------------------------------------------------------*/ 39 | #include 40 | #include 41 | 42 | #include "chirp_sdk.h" 43 | #include "credentials.h" 44 | 45 | #define VOLUME 0.1 // Between 0 and 1 46 | 47 | #define NUM_BUFFERS 2 48 | #define BUFFER_SIZE 1024 49 | #define SAMPLE_RATE 44100 50 | 51 | // Global variables ------------------------------------------------------------ 52 | 53 | int buffer[NUM_BUFFERS][BUFFER_SIZE]; 54 | short tmpBuffer[BUFFER_SIZE / 2]; 55 | uint8_t nextBufferIndex, currentBufferIndex; 56 | 57 | Adafruit_ZeroI2S i2s; 58 | Adafruit_ZeroDMA dma; 59 | DmacDescriptor *desc; 60 | 61 | static chirp_sdk_t *chirp = NULL; 62 | static volatile bool dma_complete = true; 63 | 64 | // Function definitions -------------------------------------------------------- 65 | 66 | void dmaCallback(Adafruit_ZeroDMA *dma); 67 | void dmaErrorCallback(Adafruit_ZeroDMA *dma); 68 | void setupDMA(void); 69 | void setupChirp(void); 70 | void sendChirp(void); 71 | 72 | // Function declarations ------------------------------------------------------- 73 | 74 | void setup() 75 | { 76 | currentBufferIndex = 0; 77 | 78 | Serial.begin(115200); 79 | while(!Serial); // Wait for Serial monitor before continuing 80 | 81 | setupChirp(); 82 | setupDMA(); 83 | 84 | i2s.begin(I2S_32_BIT, SAMPLE_RATE); 85 | i2s.enableMCLK(); 86 | i2s.enableTx(); 87 | 88 | sendChirp(); 89 | 90 | ZeroDMAstatus stat = dma.startJob(); 91 | if (stat != DMA_STATUS_OK) 92 | { 93 | dma.printStatus(stat); 94 | Serial.println("Failed to start DMA"); 95 | } 96 | } 97 | 98 | void loop() 99 | { 100 | if (dma_complete) 101 | { 102 | nextBufferIndex = (currentBufferIndex + 1) % NUM_BUFFERS; 103 | 104 | // Process data in to the next mono buffer 105 | chirp_sdk_error_code_t err = chirp_sdk_process_shorts_output(chirp, tmpBuffer, BUFFER_SIZE / 2); 106 | chirpErrorHandler(err); 107 | 108 | // Copy the data into a stereo buffer for audio output 109 | for (int i = 0; i < BUFFER_SIZE / 2; i++) 110 | { 111 | int value = tmpBuffer[i] * INT16_MAX; 112 | buffer[nextBufferIndex][i * 2] = value; 113 | buffer[nextBufferIndex][i * 2 + 1] = value; 114 | } 115 | 116 | dma_complete = false; 117 | } 118 | } 119 | 120 | // Chirp ----------------------------------------------------------------------- 121 | 122 | void chirpErrorHandler(chirp_sdk_error_code_t code) 123 | { 124 | if (code != CHIRP_SDK_OK) 125 | { 126 | const char *error_string = chirp_sdk_error_code_to_string(code); 127 | Serial.println(error_string); 128 | exit(42); 129 | } 130 | } 131 | 132 | void onSendingCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) 133 | { 134 | Serial.println("Sending data..."); 135 | } 136 | 137 | void onSentCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) 138 | { 139 | Serial.println("Sent data..."); 140 | } 141 | 142 | void sendChirp() 143 | { 144 | chirp_sdk_error_code_t err; 145 | 146 | char *payload = "hello"; 147 | err = chirp_sdk_send(chirp, (uint8_t *)payload, strlen(payload)); 148 | chirpErrorHandler(err); 149 | 150 | Serial.print("Sending data: "); 151 | Serial.println(payload); 152 | } 153 | 154 | void setupChirp() 155 | { 156 | chirp = new_chirp_sdk(CHIRP_APP_KEY, CHIRP_APP_SECRET); 157 | if (chirp == NULL) 158 | { 159 | Serial.println("Chirp initialisation failed."); 160 | return; 161 | } 162 | 163 | chirp_sdk_error_code_t err = chirp_sdk_set_config(chirp, CHIRP_APP_CONFIG); 164 | chirpErrorHandler(err); 165 | 166 | chirp_sdk_callback_set_t callback_set = { 167 | .on_state_changed = NULL, 168 | .on_sending = onSendingCallback, 169 | .on_sent = onSentCallback, 170 | .on_receiving = NULL, 171 | .on_received = NULL 172 | }; 173 | 174 | err = chirp_sdk_set_callbacks(chirp, callback_set); 175 | chirpErrorHandler(err); 176 | 177 | err = chirp_sdk_set_output_sample_rate(chirp, SAMPLE_RATE); 178 | chirpErrorHandler(err); 179 | 180 | err = chirp_sdk_set_volume(chirp, VOLUME); 181 | chirpErrorHandler(err); 182 | 183 | err = chirp_sdk_start(chirp); 184 | chirpErrorHandler(err); 185 | 186 | Serial.println("Chirp SDK initialised."); 187 | Serial.flush(); 188 | } 189 | 190 | // I2S DMA --------------------------------------------------------------------- 191 | 192 | void dmaCallback(Adafruit_ZeroDMA *dma) 193 | { 194 | currentBufferIndex++; 195 | if (currentBufferIndex >= NUM_BUFFERS) 196 | { 197 | currentBufferIndex -= NUM_BUFFERS; 198 | } 199 | dma->changeDescriptor(desc, buffer[currentBufferIndex]); 200 | ZeroDMAstatus stat = dma->startJob(); 201 | if (stat == DMA_STATUS_OK) 202 | { 203 | dma_complete = true; 204 | } 205 | else 206 | { 207 | Serial.println("ERROR"); 208 | } 209 | } 210 | 211 | void dmaErrorCallback(Adafruit_ZeroDMA *dma) 212 | { 213 | Serial.println("DMAERROR"); 214 | } 215 | 216 | void setupDMA(void) 217 | { 218 | Serial.println("Configuring DMA trigger"); 219 | dma.setTrigger(I2S_DMAC_ID_TX_0); 220 | dma.setAction(DMA_TRIGGER_ACTON_BEAT); 221 | 222 | Serial.println("Allocating DMA channel"); 223 | ZeroDMAstatus stat = dma.allocate(); 224 | dma.printStatus(stat); 225 | 226 | Serial.println("Setting up transfer"); 227 | desc = dma.addDescriptor( 228 | buffer[currentBufferIndex], 229 | (void *)(&I2S->DATA[0].reg), 230 | BUFFER_SIZE, 231 | DMA_BEAT_SIZE_WORD, 232 | true, 233 | false 234 | ); 235 | 236 | Serial.println("Adding DMA callbacks"); 237 | dma.setCallback(dmaCallback); 238 | dma.setCallback(dmaErrorCallback, DMA_CALLBACK_TRANSFER_ERROR); 239 | } 240 | -------------------------------------------------------------------------------- /examples/MKRZeroSend/credentials.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------ 2 | * 3 | * Credentials.h 4 | * 5 | * For full information on usage and licensing, see https://chirp.io/ 6 | * 7 | * Copyright © 2011-2019, Asio Ltd. 8 | * All rights reserved. 9 | * 10 | *----------------------------------------------------------------------------*/ 11 | 12 | #ifndef Credentials_h 13 | #define Credentials_h 14 | 15 | #error("Add your credentials below (from https://developers.chirp.io) and delete this line.") 16 | 17 | #define CHIRP_APP_KEY "YOUR_APP_KEY" 18 | #define CHIRP_APP_SECRET "YOUR_APP_SECRET" 19 | #define CHIRP_APP_CONFIG "YOUR_APP_CONFIG" 20 | 21 | #endif /* Credentials_h */ 22 | -------------------------------------------------------------------------------- /examples/MXChipSendReceive/MXChipSendReceive.ino: -------------------------------------------------------------------------------- 1 | /**------------------------------------------------------------------------------ 2 | * 3 | * Simple example using the Chirp SDK on the Microsoft MXChip IoT DevKit. 4 | * 5 | * @file MXChipSendReceive.ino 6 | * 7 | * @brief After creating a developer account on https://developers.chirp.io, get 8 | * your key, secret and config string from your account using the "16kHz-mono-embedded" 9 | * protocol, and set them in this file (in CHIRP_APP_KEY, CHIRP_APP_SECRET, CHIRP_APP_CONFIG). 10 | * 11 | * This example will start in listening mode. The listening and playing modes 12 | * can alternate by pressing the button A (on the left). 13 | * 14 | * Each time the SDK starts receiving some data, the LED will turn blue. 15 | * If the data has been successfully decoded then the LED will turn green and the 16 | * hexadecimal representation of the data as well as the length of the message, 17 | * in bytes, will be displayed. If the decode fails, the LED will turn red. 18 | * 19 | * In playing mode, each press on button B (on the right) will start sending a 20 | * random payload of random length, and turn the LED yellow. Once the payload 21 | * has been sent, the LED will turn cyan and the hexadecimal representation of the 22 | * data sent as well as the length of the payload, in bytes, will be displayed. 23 | * The audio data is sent via the 3.5mm jack output. 24 | * 25 | * See README.md for further information and known issues. 26 | * 27 | * Copyright © 2011-2018, Asio Ltd. 28 | * All rights reserved. 29 | * 30 | *----------------------------------------------------------------------------*/ 31 | 32 | /* 33 | * MXChip and Arduino native headers. 34 | */ 35 | #include "Arduino.h" 36 | #include "AudioClassV2.h" 37 | #include "OledDisplay.h" 38 | #include "RGB_LED.h" 39 | 40 | /* 41 | * Main Chirp SDK header. This header and the ones it depends on must be in 42 | * the same folder. 43 | */ 44 | #include "chirp_sdk.h" 45 | #include "credentials.h" 46 | 47 | /* 48 | * The audio sample rate used by the microphone. At present, only 16kHz is 49 | * supported by the SDK on the MXChip board. 50 | */ 51 | #define SAMPLE_RATE 16000 52 | #define AUDIO_SAMPLE_SIZE 16 53 | #define SHORT_BUFFER_SIZE (AUDIO_CHUNK_SIZE / 2) 54 | #define FLOAT_BUFFER_SIZE (SHORT_BUFFER_SIZE / 2) 55 | 56 | /* 57 | * To keep track of audio buffer states. 58 | */ 59 | typedef enum { 60 | BUFFER_STATE_NONE, 61 | BUFFER_STATE_EMPTY, 62 | BUFFER_STATE_FULL, 63 | } bufferState; 64 | 65 | /* 66 | * Class handling the audio on the board. The state is recording by default. 67 | */ 68 | static AudioClass& Audio = AudioClass::getInstance(); 69 | AUDIO_STATE_TypeDef audioState = AUDIO_STATE_RECORDING; 70 | 71 | /* 72 | * Buffers containnig the audio to play and record data. 73 | */ 74 | static int16_t shortRecordBuffer[SHORT_BUFFER_SIZE] = {0}; 75 | static float floatRecordBuffer[FLOAT_BUFFER_SIZE] = {0}; 76 | bufferState recordBufferState = BUFFER_STATE_EMPTY; 77 | 78 | static int16_t shortPlayBuffer[SHORT_BUFFER_SIZE] = {0}; 79 | bufferState playBufferState = BUFFER_STATE_EMPTY; 80 | 81 | int lastButtonAState; 82 | int buttonAState; 83 | 84 | int buttonBState; 85 | int lastButtonBState; 86 | 87 | RGB_LED rgbLed; 88 | 89 | /* 90 | * Convert a payload to an hexadecimal identifer terminating with '\0' 91 | */ 92 | void payload_to_hex(char *payload, int payload_length, char *hex_str) 93 | { 94 | for (int i = 0; i < payload_length; i++) 95 | { 96 | sprintf(hex_str + i * 2, "%02x", payload[i]); 97 | } 98 | hex_str[payload_length * 2] = '\0'; 99 | } 100 | 101 | /* 102 | * Global pointer to the SDK structure. This is global as this pointer is 103 | * needed when processing the audio in the loop() function. 104 | */ 105 | chirp_sdk_t *chirp = NULL; 106 | 107 | /* 108 | * Simple error handler which display an error message and loop indefinitely. 109 | */ 110 | void errorHandler(chirp_sdk_error_code_t errorCode) 111 | { 112 | if (errorCode != CHIRP_SDK_OK) 113 | { 114 | Serial.printf("Error handler : %s\n", chirp_sdk_error_code_to_string(errorCode)); 115 | while(true); 116 | } 117 | } 118 | 119 | /* 120 | * Audio recording callback called by the Audio Class instance when a new 121 | * buffer of samples is available with new recorded samples. 122 | */ 123 | void recordCallback(void) 124 | { 125 | Audio.readFromRecordBuffer((char *) shortRecordBuffer, SHORT_BUFFER_SIZE * 2); 126 | recordBufferState = BUFFER_STATE_FULL; 127 | } 128 | 129 | /* 130 | * Audio playing callback called by the Audio Class instance when a new 131 | * buffer of samples is available with new samples to be played. 132 | */ 133 | void playCallback(void) 134 | { 135 | if(playBufferState == BUFFER_STATE_FULL) 136 | { 137 | Audio.writeToPlayBuffer((char *) shortPlayBuffer, SHORT_BUFFER_SIZE * 2); 138 | playBufferState = BUFFER_STATE_EMPTY; 139 | } 140 | } 141 | 142 | /* 143 | * Callback reached when the SDK starts sending data. 144 | */ 145 | void on_sending_callback(void *data, uint8_t *payload, size_t length, uint8_t channel) 146 | { 147 | Screen.clean(); 148 | rgbLed.setColor(255, 255, 0); 149 | } 150 | 151 | /* 152 | * Callback reached when the SDK has sent the data. 153 | */ 154 | void on_sent_callback(void *data, uint8_t *payload, size_t length, uint8_t channel) 155 | { 156 | char identifier[length * 2 + 1]; 157 | payload_to_hex((char *) payload, length, identifier); 158 | char strLength[8] = {0}; 159 | itoa(length, strLength, 10); 160 | Screen.clean(); 161 | Screen.print(0, "Sent !"); 162 | Screen.print(1, (const char *) identifier, true); 163 | Screen.print(3, strLength); 164 | rgbLed.setColor(0, 255, 255); 165 | } 166 | 167 | /* 168 | * Callback reached when the SDK starts receiving some data. 169 | */ 170 | void on_receiving_callback(void *data, uint8_t *payload, size_t length, uint8_t channel) 171 | { 172 | rgbLed.setColor(0, 0, 255); 173 | } 174 | 175 | /* 176 | * Callback reached when the SDK has received some data. 177 | */ 178 | void on_received_callback(void *data, uint8_t *payload, size_t length, uint8_t channel) 179 | { 180 | // A pointer not null with a length different than 0 means the decode has succedeed. 181 | if (payload && length != 0) 182 | { 183 | char identifier[length * 2 + 1]; 184 | payload_to_hex((char *) payload, length, identifier); 185 | char strLength[8] = {0}; 186 | itoa(length, strLength, 10); 187 | Screen.clean(); 188 | Screen.print(0, "Received !"); 189 | Screen.print(1, (const char *) identifier, true); 190 | Screen.print(3, strLength); 191 | rgbLed.setColor(0, 255, 0); 192 | } 193 | // A null pointer with a length of 0 means the decode has failed. 194 | else 195 | { 196 | Screen.clean(); 197 | Screen.print(0, "Decode failed =("); 198 | rgbLed.setColor(255, 0, 0); 199 | } 200 | } 201 | 202 | /* 203 | * Setup function where the SDK is initialised. 204 | */ 205 | void setup() 206 | { 207 | Serial.begin(115200); 208 | delay(1000); 209 | 210 | pinMode(USER_BUTTON_A, INPUT); 211 | lastButtonAState = digitalRead(USER_BUTTON_A); 212 | 213 | chirp = new_chirp_sdk(CHIRP_APP_KEY, CHIRP_APP_SECRET); 214 | if (chirp) 215 | { 216 | printf("Initialisation is OK\n"); 217 | } 218 | else 219 | { 220 | printf("Initialisation failed\nAre your key and secret correct ?\n"); 221 | exit(1); 222 | } 223 | 224 | chirp_sdk_error_code_t errorCode = chirp_sdk_set_config(chirp, CHIRP_APP_CONFIG); 225 | errorHandler(errorCode); 226 | 227 | printf("Config set correctly\n"); 228 | 229 | char *info = chirp_sdk_get_info(chirp); 230 | printf("%s - V%s [%s]\n", info, chirp_sdk_get_version(), chirp_sdk_get_build_number()); 231 | chirp_sdk_free(info); 232 | 233 | errorCode = chirp_sdk_set_input_sample_rate(chirp, SAMPLE_RATE); 234 | errorHandler(errorCode); 235 | printf("Input sample rate is : %u\n", chirp_sdk_get_input_sample_rate(chirp)); 236 | 237 | errorCode = chirp_sdk_set_output_sample_rate(chirp, SAMPLE_RATE); 238 | errorHandler(errorCode); 239 | printf("Output sample rate is : %u\n", chirp_sdk_get_output_sample_rate(chirp)); 240 | 241 | // The static structure is set to 0. This is needed because we are not setting 242 | // the `on_state_changed` callback. 243 | chirp_sdk_callback_set_t callbacks = {0}; 244 | callbacks.on_sending = on_sending_callback; 245 | callbacks.on_sent = on_sent_callback; 246 | callbacks.on_received = on_received_callback; 247 | callbacks.on_receiving = on_receiving_callback; 248 | 249 | errorCode = chirp_sdk_set_callbacks(chirp, callbacks); 250 | errorHandler(errorCode); 251 | 252 | printf("Callbacks set\n"); 253 | 254 | // MXChip specific : A software adjustment of the sample rate is needed. 255 | errorCode = chirp_sdk_set_frequency_correction(chirp, 0.9950933459f); 256 | errorHandler(errorCode); 257 | 258 | errorCode = chirp_sdk_start(chirp); 259 | errorHandler(errorCode); 260 | 261 | printf("SDK started\n"); 262 | 263 | Screen.clean(); 264 | Screen.print(0, "Chirp Arduino"); 265 | Screen.print(1, "Listening ..."); 266 | 267 | // Setup the audio class and start recording. 268 | Audio.format(SAMPLE_RATE, AUDIO_SAMPLE_SIZE); 269 | int res = Audio.startRecord(recordCallback); 270 | if (res != 0) 271 | { 272 | Serial.printf("Error when starting audio\n"); 273 | while(true); 274 | } 275 | } 276 | 277 | void loop() 278 | { 279 | buttonAState = digitalRead(USER_BUTTON_A); 280 | buttonBState = digitalRead(USER_BUTTON_B); 281 | chirp_sdk_error_code_t errorCode; 282 | 283 | // If we've pressed the button A, alternate the audio state between Recording and Playing. 284 | if (buttonAState == LOW && lastButtonAState == HIGH) 285 | { 286 | if (audioState == AUDIO_STATE_RECORDING) 287 | { 288 | audioState = AUDIO_STATE_PLAYING; 289 | Audio.stop(); 290 | Audio.startPlay(playCallback); 291 | Screen.clean(); 292 | Screen.print(0, "Playing"); 293 | } 294 | else if (audioState == AUDIO_STATE_PLAYING) 295 | { 296 | audioState = AUDIO_STATE_RECORDING; 297 | Audio.stop(); 298 | Audio.startRecord(recordCallback); 299 | Screen.clean(); 300 | Screen.print(0, "Recording"); 301 | } 302 | 303 | rgbLed.turnOff(); 304 | } 305 | 306 | if (audioState == AUDIO_STATE_RECORDING) 307 | { 308 | // Once the recording buffer is full, we process it. 309 | if (recordBufferState == BUFFER_STATE_FULL) 310 | { 311 | // Convert the stereo audio samples into mono by taking every other sample and convert them 312 | // from int16_t to float. 313 | for (int i = 0; i < FLOAT_BUFFER_SIZE; i++) 314 | { 315 | floatRecordBuffer[i] = (float) shortRecordBuffer[i * 2] / 32767.0f; 316 | } 317 | errorCode = chirp_sdk_process_input(chirp, floatRecordBuffer, FLOAT_BUFFER_SIZE); 318 | errorHandler(errorCode); 319 | recordBufferState = BUFFER_STATE_EMPTY; 320 | } 321 | } 322 | else if (audioState == AUDIO_STATE_PLAYING) 323 | { 324 | // If the button B is pressed a chirp is sent. 325 | if (buttonBState == LOW && lastButtonBState == HIGH) 326 | { 327 | size_t randomPayloadLength = 0; 328 | uint8_t *randomPayload = chirp_sdk_random_payload(chirp, &randomPayloadLength); 329 | errorCode = chirp_sdk_send(chirp, randomPayload, randomPayloadLength); 330 | errorHandler(errorCode); 331 | chirp_sdk_free(randomPayload); 332 | } 333 | 334 | chirp_sdk_state_t state = chirp_sdk_get_state(chirp); 335 | if (state == CHIRP_SDK_STATE_SENDING && playBufferState == BUFFER_STATE_EMPTY) 336 | { 337 | float tmpBuffer[SHORT_BUFFER_SIZE / 2] = {0}; 338 | errorCode = chirp_sdk_process_output(chirp, tmpBuffer, SHORT_BUFFER_SIZE / 2); 339 | errorHandler(errorCode); 340 | // On the contrary of the recording part, we duplicate the data produced by the SDK 341 | // to create a stereo audio stream that is converted from float to int16_t samples. 342 | for (uint16_t i = 0; i < SHORT_BUFFER_SIZE / 2; i++) 343 | { 344 | shortPlayBuffer[i * 2] = tmpBuffer[i] * 32767.0f; 345 | shortPlayBuffer[i * 2 + 1] = tmpBuffer[i] * 32767.0f; 346 | } 347 | playBufferState = BUFFER_STATE_FULL; 348 | } 349 | } 350 | 351 | lastButtonAState = buttonAState; 352 | lastButtonBState = buttonBState; 353 | } 354 | -------------------------------------------------------------------------------- /examples/MXChipSendReceive/credentials.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------ 2 | * 3 | * Credentials.h 4 | * 5 | * For full information on usage and licensing, see https://chirp.io/ 6 | * 7 | * Copyright © 2011-2019, Asio Ltd. 8 | * All rights reserved. 9 | * 10 | *----------------------------------------------------------------------------*/ 11 | 12 | #ifndef Credentials_h 13 | #define Credentials_h 14 | 15 | #error("Add your credentials below (from https://developers.chirp.io) and delete this line.") 16 | 17 | #define CHIRP_APP_KEY "YOUR_APP_KEY" 18 | #define CHIRP_APP_SECRET "YOUR_APP_SECRET" 19 | #define CHIRP_APP_CONFIG "YOUR_APP_CONFIG" 20 | 21 | #endif /* Credentials_h */ 22 | -------------------------------------------------------------------------------- /examples/Nano33SenseReceive/Nano33SenseReceive.ino: -------------------------------------------------------------------------------- 1 | /**----------------------------------------------------------------------------- 2 | 3 | Example code using the Chirp SDK to receive data using the 4 | Arduino Nano 33 Sense board. 5 | 6 | @file Nano33SenseReceive.ino 7 | 8 | @brief Create a developer account at https://developers.chirp.io, 9 | and copy and paste your key, secret and config string for the 10 | "16khz-mono-embedded" protocol into the credentials.h file. 11 | 12 | This example will start listening for chirps and print to the terminal 13 | when anything is received. 14 | 15 | *Note*: this example can be used in conjunction with the send example, 16 | to send and receive data in the same application. 17 | 18 | *Important*: The example will not start until this Serial Monitor is opened. 19 | To disable this behaviour, comment out the while(!Serial) line. 20 | 21 | Circuit: 22 | - Arduino Nano 33 BLE board 23 | 24 | Copyright © 2011-2019, Asio Ltd. 25 | All rights reserved. 26 | 27 | ----------------------------------------------------------------------------*/ 28 | #include 29 | 30 | #include "chirp_sdk.h" 31 | #include "credentials.h" 32 | 33 | #define SAMPLE_RATE 16000 // Audio sample rate 34 | #define BUFFER_SIZE 256 // Audio buffer size 35 | 36 | // Global variables ------------------------------------------------------------ 37 | 38 | static chirp_sdk_t *chirp = NULL; 39 | short sampleBuffer[BUFFER_SIZE]; 40 | volatile int samplesRead; 41 | 42 | // Function definitions -------------------------------------------------------- 43 | 44 | void setupChirp(void); 45 | void chirpErrorHandler(chirp_sdk_error_code_t code); 46 | void onPDMdata(void); 47 | 48 | // Main ------------------------------------------------------------------------ 49 | 50 | void setup() 51 | { 52 | Serial.begin(115200); 53 | while (!Serial); 54 | 55 | // Enable high frequency oscillator 56 | NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; 57 | NRF_CLOCK->TASKS_HFCLKSTART = 1; 58 | while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); 59 | 60 | setupChirp(); 61 | 62 | PDM.onReceive(onPDMdata); 63 | PDM.setGain(30); 64 | 65 | if (!PDM.begin(1, SAMPLE_RATE)) 66 | { 67 | Serial.println("Failed to start PDM!"); 68 | while (1); 69 | } 70 | } 71 | 72 | void loop() 73 | { 74 | if (samplesRead) 75 | { 76 | chirp_sdk_error_code_t err = chirp_sdk_process_shorts_input(chirp, sampleBuffer, samplesRead); 77 | chirpErrorHandler(err); 78 | samplesRead = 0; 79 | } 80 | } 81 | 82 | void onPDMdata() 83 | { 84 | int bytesAvailable = PDM.available(); 85 | PDM.read(sampleBuffer, bytesAvailable); 86 | samplesRead = bytesAvailable / sizeof(short); 87 | } 88 | 89 | // Chirp ----------------------------------------------------------------------- 90 | 91 | void onReceivingCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) 92 | { 93 | Serial.println("Receiving data..."); 94 | } 95 | 96 | void onReceivedCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) 97 | { 98 | if (payload) 99 | { 100 | char *data = (char *)calloc(length + 1, sizeof(uint8_t)); 101 | memcpy(data, payload, length * sizeof(uint8_t)); 102 | Serial.print("Received data: "); 103 | Serial.println(data); 104 | free(data); 105 | } 106 | else 107 | { 108 | Serial.println("Decode failed."); 109 | } 110 | } 111 | 112 | void chirpErrorHandler(chirp_sdk_error_code_t code) 113 | { 114 | if (code != CHIRP_SDK_OK) 115 | { 116 | const char *errorString = chirp_sdk_error_code_to_string(code); 117 | Serial.println(errorString); 118 | exit(42); 119 | } 120 | } 121 | 122 | void setupChirp(void) 123 | { 124 | chirp = new_chirp_sdk(CHIRP_APP_KEY, CHIRP_APP_SECRET); 125 | if (chirp == NULL) 126 | { 127 | Serial.println("Chirp initialisation failed."); 128 | return; 129 | } 130 | 131 | chirp_sdk_error_code_t err = chirp_sdk_set_config(chirp, CHIRP_APP_CONFIG); 132 | chirpErrorHandler(err); 133 | 134 | chirp_sdk_callback_set_t callback_set = 135 | { 136 | .on_state_changed = NULL, 137 | .on_sending = NULL, 138 | .on_sent = NULL, 139 | .on_receiving = onReceivingCallback, 140 | .on_received = onReceivedCallback 141 | }; 142 | 143 | err = chirp_sdk_set_callbacks(chirp, callback_set); 144 | chirpErrorHandler(err); 145 | 146 | err = chirp_sdk_set_input_sample_rate(chirp, SAMPLE_RATE); 147 | chirpErrorHandler(err); 148 | 149 | // A fixed frequency correction coefficient is needed to correct a clock 150 | // mismatch between the 16000Hz requested sample rate and the Nano's actual 151 | // audio sample rate. 152 | err = chirp_sdk_set_frequency_correction(chirp, 1.00812); 153 | chirpErrorHandler(err); 154 | 155 | err = chirp_sdk_start(chirp); 156 | chirpErrorHandler(err); 157 | 158 | Serial.println("Chirp SDK initialised."); 159 | Serial.flush(); 160 | } 161 | -------------------------------------------------------------------------------- /examples/Nano33SenseReceive/credentials.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------ 2 | * 3 | * Credentials.h 4 | * 5 | * For full information on usage and licensing, see https://chirp.io/ 6 | * 7 | * Copyright © 2011-2019, Asio Ltd. 8 | * All rights reserved. 9 | * 10 | *----------------------------------------------------------------------------*/ 11 | 12 | #ifndef Credentials_h 13 | #define Credentials_h 14 | 15 | #error("Add your credentials below (from https://developers.chirp.io) and delete this line.") 16 | 17 | #define CHIRP_APP_KEY "YOUR_APP_KEY" 18 | #define CHIRP_APP_SECRET "YOUR_APP_SECRET" 19 | #define CHIRP_APP_CONFIG "YOUR_APP_CONFIG" 20 | 21 | #endif /* Credentials_h */ 22 | -------------------------------------------------------------------------------- /examples/Nano33SenseSend/Nano33SenseSend.ino: -------------------------------------------------------------------------------- 1 | /**----------------------------------------------------------------------------- 2 | 3 | Example code to send data using the Chirp SDK, on the Arduino Nano 33 Sense 4 | board with Adafruit MAX98357A and a mini oval speaker 5 | 6 | @file Nano33SenseSend.ino 7 | 8 | @brief Create a developer account at https://developers.chirp.io, 9 | and copy and paste your key, secret and config string for the 10 | "16khz-mono-embedded" protocol into the credentials.h file. 11 | 12 | This example will send a single Chirp signal on startup, containing random 13 | data. 14 | 15 | *Important*: The example will not start until this Serial Monitor is opened. 16 | To disable this behaviour, comment out the while(!Serial) line. 17 | 18 | Circuit: 19 | - Arduino Nano 33 BLE board 20 | - Adafruit MAX98357A amplifier 21 | - Adafruit Mini Oval speaker 22 | 23 | Copyright © 2011-2019, Asio Ltd. 24 | All rights reserved. 25 | 26 | ----------------------------------------------------------------------------*/ 27 | #include "chirp_sdk.h" 28 | #include "credentials.h" 29 | 30 | #define VOLUME 0.1 // Between 0 and 1 31 | #define BUFFER_SIZE 256 32 | #define OUTPUT_SAMPLE_RATE 16667 33 | 34 | #define I2S_DATA_PIN 23 // D7 35 | #define I2S_SCK_PIN 21 // D8 36 | #define I2S_LRCK_PIN 27 // D9 37 | 38 | // Global variables ------------------------------------------------------------ 39 | 40 | static chirp_sdk_t *chirp = NULL; 41 | short *currentBuffer; 42 | short buffer1[BUFFER_SIZE]; 43 | short buffer2[BUFFER_SIZE]; 44 | 45 | // Function definitions -------------------------------------------------------- 46 | 47 | void chirpErrorHandler(chirp_sdk_error_code_t code); 48 | void setupChirp(void); 49 | void sendChirp(void); 50 | void i2s_init(void); 51 | void i2s_start(void); 52 | 53 | // Main ------------------------------------------------------------------------ 54 | 55 | void setup() 56 | { 57 | Serial.begin(115200); 58 | while(!Serial); // Wait for Serial monitor before continuing 59 | 60 | // Enable high frequency oscillator 61 | NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; 62 | NRF_CLOCK->TASKS_HFCLKSTART = 1; 63 | while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); 64 | 65 | setupChirp(); 66 | sendChirp(); 67 | 68 | i2s_init(); 69 | i2s_start(); 70 | } 71 | 72 | void loop() 73 | { 74 | if (NRF_I2S->EVENTS_TXPTRUPD != 0) 75 | { 76 | currentBuffer = currentBuffer == buffer1 ? buffer2 : buffer1; 77 | chirp_sdk_error_code_t err = chirp_sdk_process_shorts_output(chirp, currentBuffer, BUFFER_SIZE); 78 | chirpErrorHandler(err); 79 | NRF_I2S->TXD.PTR = (uint32_t)(currentBuffer); 80 | NRF_I2S->EVENTS_TXPTRUPD = 0; 81 | } 82 | } 83 | 84 | // Chirp ----------------------------------------------------------------------- 85 | 86 | void onSendingCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) 87 | { 88 | Serial.println("Sending data..."); 89 | } 90 | 91 | void onSentCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) 92 | { 93 | char *data = (char *)calloc(length + 1, sizeof(uint8_t)); 94 | memcpy(data, payload, length); 95 | Serial.print("Sent data: "); 96 | Serial.println(data); 97 | free(data); 98 | } 99 | 100 | void chirpErrorHandler(chirp_sdk_error_code_t code) 101 | { 102 | if (code != CHIRP_SDK_OK) 103 | { 104 | const char *error_string = chirp_sdk_error_code_to_string(code); 105 | Serial.println(error_string); 106 | exit(42); 107 | } 108 | } 109 | 110 | void setupChirp(void) 111 | { 112 | chirp = new_chirp_sdk(CHIRP_APP_KEY, CHIRP_APP_SECRET); 113 | if (chirp == NULL) 114 | { 115 | Serial.println("Chirp initialisation failed."); 116 | return; 117 | } 118 | 119 | chirp_sdk_error_code_t err = chirp_sdk_set_config(chirp, CHIRP_APP_CONFIG); 120 | chirpErrorHandler(err); 121 | 122 | chirp_sdk_callback_set_t callback_set = { 123 | .on_state_changed = NULL, 124 | .on_sending = onSendingCallback, 125 | .on_sent = onSentCallback, 126 | .on_receiving = NULL, 127 | .on_received = NULL 128 | }; 129 | 130 | err = chirp_sdk_set_callbacks(chirp, callback_set); 131 | chirpErrorHandler(err); 132 | 133 | err = chirp_sdk_set_output_sample_rate(chirp, OUTPUT_SAMPLE_RATE); 134 | chirpErrorHandler(err); 135 | 136 | err = chirp_sdk_set_volume(chirp, VOLUME); 137 | chirpErrorHandler(err); 138 | 139 | err = chirp_sdk_start(chirp); 140 | chirpErrorHandler(err); 141 | 142 | Serial.println("Chirp SDK initialised."); 143 | Serial.flush(); 144 | } 145 | 146 | void sendChirp() 147 | { 148 | chirp_sdk_error_code_t err; 149 | 150 | char *payload = "hello"; 151 | err = chirp_sdk_send(chirp, (uint8_t *)payload, strlen(payload)); 152 | chirpErrorHandler(err); 153 | 154 | Serial.print("Sending data: "); 155 | Serial.println(payload); 156 | } 157 | 158 | // I2S Audio ------------------------------------------------------------------- 159 | 160 | void i2s_init() 161 | { 162 | // Enable clocks 163 | NRF_I2S->CONFIG.TXEN = I2S_CONFIG_TXEN_TXEN_Enabled << I2S_CONFIG_TXEN_TXEN_Pos; 164 | NRF_I2S->CONFIG.MCKEN = I2S_CONFIG_MCKEN_MCKEN_Enabled << I2S_CONFIG_MCKEN_MCKEN_Pos; 165 | 166 | // MCKFREQ = 6.4 MHz 167 | NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV5 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos; 168 | 169 | // Ratio = 384 170 | // LCRK = 16667 Hz 171 | NRF_I2S->CONFIG.RATIO = I2S_CONFIG_RATIO_RATIO_384X << I2S_CONFIG_RATIO_RATIO_Pos; 172 | 173 | // Master mode 174 | NRF_I2S->CONFIG.MODE = I2S_CONFIG_MODE_MODE_MASTER << I2S_CONFIG_MODE_MODE_Pos; 175 | 176 | // 16 bits 177 | NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16Bit << I2S_CONFIG_SWIDTH_SWIDTH_Pos; 178 | 179 | // Left alignment 180 | NRF_I2S->CONFIG.ALIGN = I2S_CONFIG_ALIGN_ALIGN_Left << I2S_CONFIG_ALIGN_ALIGN_Pos; 181 | 182 | // I2S format 183 | NRF_I2S->CONFIG.FORMAT = I2S_CONFIG_FORMAT_FORMAT_I2S << I2S_CONFIG_FORMAT_FORMAT_Pos; 184 | 185 | // Mono 186 | NRF_I2S->CONFIG.CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_Left << I2S_CONFIG_CHANNELS_CHANNELS_Pos; 187 | 188 | // Configure pins 189 | NRF_I2S->PSEL.SCK = I2S_SCK_PIN << I2S_PSEL_SCK_PIN_Pos; 190 | NRF_I2S->PSEL.LRCK = I2S_LRCK_PIN << I2S_PSEL_LRCK_PIN_Pos; 191 | NRF_I2S->PSEL.SDOUT = I2S_DATA_PIN << I2S_PSEL_SDOUT_PIN_Pos; 192 | } 193 | 194 | void i2s_start() 195 | { 196 | NRF_I2S->ENABLE = 1; 197 | 198 | // Configure DMA buffer 199 | NRF_I2S->TXD.PTR = (uint32_t)(buffer1); 200 | NRF_I2S->RXTXD.MAXCNT = BUFFER_SIZE / 2; 201 | 202 | NRF_I2S->TASKS_START = 1; 203 | } 204 | -------------------------------------------------------------------------------- /examples/Nano33SenseSend/credentials.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------ 2 | * 3 | * Credentials.h 4 | * 5 | * For full information on usage and licensing, see https://chirp.io/ 6 | * 7 | * Copyright © 2011-2019, Asio Ltd. 8 | * All rights reserved. 9 | * 10 | *----------------------------------------------------------------------------*/ 11 | 12 | #ifndef Credentials_h 13 | #define Credentials_h 14 | 15 | #error("Add your credentials below (from https://developers.chirp.io) and delete this line.") 16 | 17 | #define CHIRP_APP_KEY "YOUR_APP_KEY" 18 | #define CHIRP_APP_SECRET "YOUR_APP_SECRET" 19 | #define CHIRP_APP_CONFIG "YOUR_APP_CONFIG" 20 | 21 | #endif /* Credentials_h */ 22 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For ChirpSDK 3 | ####################################### 4 | 5 | ####################################### 6 | # Methods and Functions (KEYWORD2) 7 | ####################################### 8 | 9 | new_chirp_sdk KEYWORD2 10 | del_chirp_sdk KEYWORD2 11 | chirp_sdk_free KEYWORD2 12 | chirp_sdk_set_config KEYWORD2 13 | chirp_sdk_get_info KEYWORD2 14 | chirp_sdk_set_callbacks KEYWORD2 15 | chirp_sdk_start KEYWORD2 16 | chirp_sdk_stop KEYWORD2 17 | chirp_sdk_get_max_payload_length KEYWORD2 18 | chirp_sdk_get_duration_for_payload_length KEYWORD2 19 | chirp_sdk_is_valid KEYWORD2 20 | chirp_sdk_random_payload KEYWORD2 21 | chirp_sdk_send KEYWORD2 22 | chirp_sdk_process KEYWORD2 23 | chirp_sdk_process_input KEYWORD2 24 | chirp_sdk_process_output KEYWORD2 25 | chirp_sdk_process_shorts KEYWORD2 26 | chirp_sdk_process_shorts_input KEYWORD2 27 | chirp_sdk_process_shorts_output KEYWORD2 28 | chirp_sdk_get_state_for_channel KEYWORD2 29 | chirp_sdk_get_transmission_channel KEYWORD2 30 | chirp_sdk_set_transmission_channel KEYWORD2 31 | chirp_sdk_get_channel_count KEYWORD2 32 | chirp_sdk_get_state KEYWORD2 33 | chirp_sdk_get_volume KEYWORD2 34 | chirp_sdk_set_volume KEYWORD2 35 | chirp_sdk_get_input_sample_rate KEYWORD2 36 | chirp_sdk_get_output_sample_rate KEYWORD2 37 | chirp_sdk_set_input_sample_rate KEYWORD2 38 | chirp_sdk_set_output_sample_rate KEYWORD2 39 | chirp_sdk_get_listen_to_self KEYWORD2 40 | chirp_sdk_set_listen_to_self KEYWORD2 41 | chirp_sdk_set_callback_ptr KEYWORD2 42 | chirp_sdk_set_frequency_correction KEYWORD2 43 | chirp_sdk_get_version KEYWORD2 44 | 45 | 46 | ####################################### 47 | # Constants (LITERAL1) 48 | ####################################### 49 | 50 | chirp_sdk_error_code_t KEYWORD1 DATA_TYPE 51 | chirp_sdk_callback_t KEYWORD1 DATA_TYPE 52 | chirp_sdk_state_callback_t KEYWORD1 DATA_TYPE 53 | chirp_sdk_state_callback_t KEYWORD1 DATA_TYPE 54 | chirp_sdk_state_t KEYWORD1 DATA_TYPE 55 | 56 | CHIRP_SDK_STATE_NOT_CREATED LITERAL1 57 | CHIRP_SDK_STATE_STOPPED LITERAL1 58 | CHIRP_SDK_STATE_RUNNING LITERAL1 59 | CHIRP_SDK_STATE_SENDING LITERAL1 60 | CHIRP_SDK_STATE_RECEIVING LITERAL1 61 | 62 | CHIRP_SDK_OK LITERAL1 63 | CHIRP_SDK_OUT_OF_MEMORY LITERAL1 64 | CHIRP_SDK_NOT_INITIALISED LITERAL1 65 | CHIRP_SDK_INTERNAL_ERROR LITERAL1 66 | CHIRP_SDK_MEMORY_LEAK LITERAL1 67 | CHIRP_SDK_RECEIVING_NOT_AVAILABLE LITERAL1 68 | 69 | CHIRP_SDK_NOT_RUNNING LITERAL1 70 | CHIRP_SDK_ALREADY_RUNNING LITERAL1 71 | CHIRP_SDK_ALREADY_STOPPED LITERAL1 72 | CHIRP_SDK_ALREADY_SENDING LITERAL1 73 | 74 | CHIRP_SDK_INVALID_SAMPLE_RATE LITERAL1 75 | CHIRP_SDK_NULL_BUFFER LITERAL1 76 | CHIRP_SDK_NULL_POINTER LITERAL1 77 | CHIRP_SDK_CHANNEL_NOT_SUPPORTED LITERAL1 78 | CHIRP_SDK_INVALID_FREQUENCY_CORRECTION LITERAL1 79 | CHIRP_SDK_PROCESSING_ERROR LITERAL1 80 | 81 | CHIRP_SDK_INVALID_KEY LITERAL1 82 | CHIRP_SDK_INVALID_SECRET LITERAL1 83 | CHIRP_SDK_INVALID_CREDENTIALS LITERAL1 84 | CHIRP_SDK_MISSING_SIGNATURE LITERAL1 85 | CHIRP_SDK_INVALID_SIGNATURE LITERAL1 86 | CHIRP_SDK_MISSING_CONFIG LITERAL1 87 | CHIRP_SDK_INVALID_CONFIG LITERAL1 88 | CHIRP_SDK_EXPIRED_CONFIG LITERAL1 89 | CHIRP_SDK_INVALID_VERSION LITERAL1 90 | CHIRP_SDK_INVALID_PROJECT LITERAL1 91 | CHIRP_SDK_INVALID_CONFIG_CHARACTER LITERAL1 92 | 93 | CHIRP_SDK_PAYLOAD_EMPTY_MESSAGE LITERAL1 94 | CHIRP_SDK_PAYLOAD_INVALID_MESSAGE LITERAL1 95 | CHIRP_SDK_PAYLOAD_UNKNOWN_SYMBOLS LITERAL1 96 | CHIRP_SDK_PAYLOAD_DECODE_FAILED LITERAL1 97 | CHIRP_SDK_PAYLOAD_TOO_LONG LITERAL1 98 | CHIRP_SDK_PAYLOAD_TOO_SHORT LITERAL1 99 | 100 | CHIRP_SDK_INVALID_VOLUME LITERAL1 101 | CHIRP_SDK_UNKNOWN_ERROR LITERAL1 102 | 103 | CHIRP_SDK_NETWORK_ERROR LITERAL1 104 | CHIRP_SDK_NETWORK_NO_NETWORK LITERAL1 105 | CHIRP_SDK_NETWORK_PERMISSIONS_NOT_GRANTED LITERAL1 106 | CHIRP_SDK_ACCOUNT_DISABLED LITERAL1 107 | CHIRP_SDK_AUDIO_IO_ERROR LITERAL1 108 | CHIRP_SDK_SENDING_NOT_ENABLED LITERAL1 109 | CHIRP_SDK_RECEIVING_NOT_ENABLED LITERAL1 110 | CHIRP_SDK_DEVICE_IS_MUTED LITERAL1 -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=ChirpSDK 2 | version=3.4.1 3 | author=Asio Ltd 4 | maintainer=Joe Todd 5 | sentence=Chirp SDK 6 | paragraph=Send and receive data over sound 7 | category=Communication 8 | url=https://developers.chirp.io/docs/getting-started/arduino 9 | architectures=cortex-m4,esp32,cortex-m0plus,stm32f4,samd,mbed,avr,mk64fx512 10 | precompiled=true 11 | ldflags=-lChirpSDK 12 | -------------------------------------------------------------------------------- /src/chirp_sdk.h: -------------------------------------------------------------------------------- 1 | /**----------------------------------------------------------------------------- 2 | * 3 | * ASIO CONFIDENTIAL 4 | * 5 | * @file chirp_sdk.h 6 | * 7 | * @brief Chirp C SDK implementation header. 8 | * 9 | * All contents are strictly proprietary, and not for copying, resale, 10 | * or use outside of the agreed license. 11 | * 12 | * Copyright © 2011-2019, Asio Ltd. 13 | * All rights reserved. 14 | * 15 | *----------------------------------------------------------------------------*/ 16 | 17 | #ifndef CHIRP_SDK_H 18 | #define CHIRP_SDK_H 19 | 20 | #include 21 | #include 22 | 23 | /** 24 | * Mark the function as public. Any attempt to call a function without this 25 | * marker will fail. 26 | */ 27 | #if defined(__WIN32) || defined(_WIN32) || defined(WIN32) 28 | #define PUBLIC_SYM __declspec(dllexport) 29 | #else 30 | #define PUBLIC_SYM __attribute__ ((visibility ("default"))) 31 | #endif 32 | 33 | #include "chirp_sdk_errors.h" 34 | #include "chirp_sdk_events.h" 35 | #include "chirp_sdk_version.h" 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | /** 42 | * Typedef exposing the SDK structure to the API. 43 | */ 44 | typedef struct _chirp_sdk_t chirp_sdk_t; 45 | 46 | /** 47 | * Allocate the memory and create the SDK structure. This function should be the 48 | * first one to be called among all the API functions. 49 | * 50 | * During the program life time, this function should be called only one time. 51 | * 52 | * @param key The application key coming from your Chirp Account. 53 | * @param secret The application secret coming from your Chirp Account. 54 | * @return A pointer to the newly allocated SDK structure. 55 | */ 56 | PUBLIC_SYM chirp_sdk_t *new_chirp_sdk(const char *key, const char *secret); 57 | 58 | /** 59 | * Release the SDK. This function should be the last one to be called among all 60 | * the API functions. 61 | * 62 | * During the program life time, this function should be called only one time. 63 | * 64 | * @param sdk A pointer to the SDK structure that will be deleted. 65 | * @return An error code resulting from the call. CHIRP_SDK_OK will 66 | * be returned if everything went well. 67 | */ 68 | PUBLIC_SYM chirp_sdk_error_code_t del_chirp_sdk(chirp_sdk_t **sdk); 69 | 70 | /** 71 | * Free memory previously allocated and returned by the SDK. 72 | * 73 | * Note that this does not free the SDK itself. For this, use `del_chirp_sdk` 74 | * above. 75 | * 76 | * This function should be called to free the memory returned by the 77 | * following functions: 78 | * 79 | * `chirp_sdk_get_info` 80 | * `chirp_sdk_random_payload` 81 | * 82 | * As well as freeing the memory, this function tracks the ongoing heap 83 | * allocation which can be queried with `chirp_sdk_get_heap_usage`. 84 | * 85 | * @param ptr The pointer to the memory to be freed. 86 | */ 87 | PUBLIC_SYM void chirp_sdk_free(void *ptr); 88 | 89 | /** 90 | * Set the SDK config string coming from your Chirp account. Your Chirp config 91 | * string configures your application's transmission settings (audio frequency, 92 | * data rate, payload sizes). To get your Chirp config, sign in to the Chirp 93 | * Admin Centre at https://developers.chirp.io. 94 | * 95 | * @param sdk A pointer to the SDK structure which needs the config to be 96 | * set. 97 | * @param config The config string which will be set. 98 | * @return An error code resulting from the call. CHIRP_SDK_OK will 99 | * be returned if everything went well. 100 | */ 101 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_set_config(chirp_sdk_t *sdk, const char *config); 102 | 103 | /** 104 | * Return a short description string of the config being used. An example of the 105 | * type of string can be : "Chirp SDK with "standard-2018" config v1 106 | * [max 32 bytes in 4.52s]" 107 | * 108 | * @param sdk A pointer to the SDK structure. 109 | * @return The short config description string. The user has to free this 110 | * string with `chirp_sdk_free` once it is not needed anymore. 111 | */ 112 | PUBLIC_SYM char *chirp_sdk_get_info(chirp_sdk_t *sdk); 113 | 114 | /** 115 | * Set the callbacks to the SDK. Callbacks are functions which will be executed 116 | * once a key event happens. The list of the supported callbacks is explained in 117 | * the documentation of the `chirp_sdk_callback_set_t` structure in 118 | * `chirp_sdk_callbacks.h`. 119 | * 120 | * @param sdk A pointer to the SDK structure. 121 | * @param callback_set A set of callbacks which will be set to the SDK. 122 | * @return An error code resulting from the call. CHIRP_SDK_OK will 123 | * be returned if everything went well. 124 | */ 125 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_set_callbacks(chirp_sdk_t *sdk, chirp_sdk_callback_set_t callback_set); 126 | 127 | /** 128 | * Start the SDK and the audio processing. From this call, it is possible to 129 | * send and receive data. 130 | * 131 | * @param sdk A pointer to the SDK structure. 132 | * @return An error code resulting from the call. CHIRP_SDK_OK will 133 | * be returned if everything went well. 134 | */ 135 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_start(chirp_sdk_t *sdk); 136 | 137 | /** 138 | * Stop the SDK and the audio processing. Once this function is called, some 139 | * internal structures will be reset and any data being sent won't be 140 | * recoverable. 141 | * 142 | * @param sdk A pointer to the SDK structure. 143 | * @return An error code resulting from the call. CHIRP_SDK_OK will 144 | * be returned if everything went well. 145 | */ 146 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_stop(chirp_sdk_t *sdk); 147 | 148 | /** 149 | * Get the maximum payload length allowed by the current config set for the SDK. 150 | * 151 | * 152 | * @param sdk A pointer to the SDK structure. 153 | * @return The maximum payload length that can be sent. A length of 0 is 154 | * invalid. If the config hasn't been set yet when this function 155 | * is called 0 is returned. 156 | */ 157 | PUBLIC_SYM size_t chirp_sdk_get_max_payload_length(chirp_sdk_t *sdk); 158 | 159 | /** 160 | * Get the duration, in seconds, for a given payload length. 161 | * 162 | * @param sdk A pointer to the SDK structure. 163 | * @param payload_length The length, in bytes, of the payload we want to know the 164 | * duration. You can get the maximum allowed length with 165 | * `chirp_sdk_get_max_payload_length`. 166 | * @return The duration, in second, of the given length, -1 if the 167 | * payload is too short or -2 if the payload is too long. 168 | */ 169 | PUBLIC_SYM float chirp_sdk_get_duration_for_payload_length(chirp_sdk_t *sdk, size_t payload_length); 170 | 171 | /** 172 | * Validate a payload. If uncertain, the user can call this function to confirm 173 | * this payload can be sent without issues. 174 | * 175 | * @param sdk A pointer to the SDK structure. 176 | * @param bytes A pointer to the payload to be validated. 177 | * @param length The length, in bytes, of the payload. 178 | * @return An error code resulting from the call. CHIRP_SDK_OK will 179 | * be returned if everything went well. 180 | */ 181 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_is_valid(chirp_sdk_t *sdk, const uint8_t *bytes, size_t length); 182 | 183 | /** 184 | * Generate a random payload by allocating a payload and randomising its content. 185 | * 186 | * @param sdk A pointer to the SDK structure. 187 | * @param length A pointer containing the length, in bytes, of the payload to be 188 | * generated. If the length is 0, the SDK will randomise both the 189 | * length of the payload and its content. The length pointer will 190 | * then be updated with the random length. You can get the 191 | * maximum allowed length with `chirp_sdk_get_max_payload_length`. 192 | * @return A pointer to the newly created random data payload.The user 193 | * has to free this pointer once they doesn't need it anymore using 194 | * `chirp_sdk_free`. 195 | */ 196 | PUBLIC_SYM uint8_t *chirp_sdk_random_payload(chirp_sdk_t *sdk, size_t *length); 197 | 198 | /** 199 | * Send a payload. A valid length is between 1 and the value returned by 200 | * `chirp_sdk_get_max_payload_length`. 201 | * 202 | * @param sdk A pointer to the SDK structure. 203 | * @param bytes A pointer to the payload that will be sent. 204 | * @param length The length, in bytes, of the payload which will be sent. 205 | * @return An error code resulting from the call. CHIRP_SDK_OK will 206 | * be returned if everything went well. 207 | */ 208 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_send(chirp_sdk_t *sdk, uint8_t *bytes, size_t length); 209 | 210 | /** 211 | * Float audio processing function handling both the encoding (output) and the 212 | * decoding (input). 213 | * 214 | * @param sdk A pointer to the SDK structure. 215 | * @param in A pointer to the float mono input buffer. 216 | * @param out A pointer to the float mono output buffer. 217 | * @param length The length, in mono samples, of both the input and output buffers. 218 | * @return An error code resulting from the call. CHIRP_SDK_OK will 219 | * be returned if everything went well. 220 | */ 221 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_process(chirp_sdk_t *sdk, float *in, float *out, size_t length); 222 | 223 | /** 224 | * Float audio processing function for the decoding (input). 225 | * 226 | * @param sdk A pointer to the SDK structure. 227 | * @param buffer The input buffer containing mono samples which will be decoded. 228 | * @param length The length, in mono samples, of the input buffer. 229 | * @return An error code resulting from the call. CHIRP_SDK_OK will 230 | * be returned if everything went well. 231 | */ 232 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_process_input(chirp_sdk_t *sdk, float *buffer, size_t length); 233 | 234 | /** 235 | * Float audio processing function for the encoding (output). Fill a buffer with 236 | * as many bytes as needed once the sending of a payload has been triggered. 237 | * 238 | * @param sdk A pointer to the SDK structure. 239 | * @param buffer The output buffer which will be filled with new mono samples. 240 | * @param length The length, in mono samples, of the output buffer. 241 | * @return An error code resulting from the call. CHIRP_SDK_OK will 242 | * be returned if everything went well. 243 | */ 244 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_process_output(chirp_sdk_t *sdk, float *buffer, size_t length); 245 | 246 | /** 247 | * Short audio processing function handling both the encoding (output) and the 248 | * decoding (input). 249 | * 250 | * @param sdk A pointer to the SDK structure. 251 | * @param in A pointer to the short mono input buffer. 252 | * @param out A pointer to the short mono output buffer. 253 | * @param length The length, in mono samples, of both the input and output buffers. 254 | * @return An error code resulting from the call. CHIRP_SDK_OK will 255 | * be returned if everything went well. 256 | */ 257 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_process_shorts(chirp_sdk_t *sdk, short *in, short *out, size_t length); 258 | 259 | /** 260 | * Short audio processing function for the decoding (input). 261 | * 262 | * @param sdk A pointer to the SDK structure. 263 | * @param buffer The input buffer containing mono samples which will be decoded. 264 | * @param length The length, in mono samples, of the input buffer. 265 | * @return An error code resulting from the call. CHIRP_SDK_OK will 266 | * be returned if everything went well. 267 | */ 268 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_process_shorts_input(chirp_sdk_t *sdk, const short *buffer, size_t length); 269 | 270 | /** 271 | * Short audio processing function for the encoding (output). Fill a buffer, 272 | * as many times as needed, once the sending of a payload has been triggered. 273 | * 274 | * @param sdk A pointer to the SDK structure. 275 | * @param buffer The output buffer which will be filled with new mono samples. 276 | * @param length The length, in mono samples, of the output buffer. 277 | * @return An error code resulting from the call. CHIRP_SDK_OK will 278 | * be returned if everything went well. 279 | */ 280 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_process_shorts_output(chirp_sdk_t *sdk, short *buffer, size_t length); 281 | 282 | /** 283 | * Get the SDK state for the given channel. 284 | * 285 | * @param sdk A pointer to the SDK structure. 286 | * @param channel The channel we want to know the state of. 287 | * @return The channel state of the SDK. 288 | */ 289 | PUBLIC_SYM chirp_sdk_state_t chirp_sdk_get_state_for_channel(chirp_sdk_t *sdk, uint8_t channel); 290 | 291 | /** 292 | * Chirp listens for broadcasts on all channels simultaneously, but only 293 | * transmits on a single channel at a time. This function gets the channel on 294 | * which the data is sent. 295 | * 296 | * @param sdk A pointer to the SDK structure. 297 | * @return The channel on which the data is sent (including 0) or -1 if 298 | * the SDK hasn't been initialised. 299 | */ 300 | PUBLIC_SYM int8_t chirp_sdk_get_transmission_channel(chirp_sdk_t *sdk); 301 | 302 | /** 303 | * Set the channel on which the data will be sent. Allowed values are between 0 304 | * and chirp_sdk_get_channel_count() - 1. 305 | * 306 | * @param sdk A pointer to the SDK structure. 307 | * @param channel The channel number on which the data should be sent. 308 | * @return An error code resulting from the call. CHIRP_SDK_OK will 309 | * be returned if everything went well. 310 | */ 311 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_set_transmission_channel(chirp_sdk_t *sdk, uint8_t channel); 312 | 313 | /** 314 | * Get the number of channels supported by the protocol used. By default, most 315 | * protocols only support a single channel. To discuss support for multi-channel 316 | * transmission, please get in touch at developers@chirp.io. 317 | * 318 | * @param sdk A pointer to the SDK structure. 319 | * @return The number of available channels. 320 | */ 321 | PUBLIC_SYM uint8_t chirp_sdk_get_channel_count(chirp_sdk_t *sdk); 322 | 323 | /** 324 | * Get the state of the SDK. Possibles values are defined in chirp_sdk_states.h. 325 | * 326 | * @param sdk A pointer to the SDK structure. 327 | * @return The state of the SDK. 328 | */ 329 | PUBLIC_SYM chirp_sdk_state_t chirp_sdk_get_state(chirp_sdk_t *sdk); 330 | 331 | /** 332 | * Get the volume of the SDK, between 0 and 1. This volume only influences the 333 | * SDK's software output volume, and may be affected by the system's hardware 334 | * audio volume. 335 | * 336 | * @param sdk A pointer to the SDK structure. 337 | * @return The volume of the output of the SDK or -1 if an error happened. 338 | */ 339 | PUBLIC_SYM float chirp_sdk_get_volume(chirp_sdk_t *sdk); 340 | 341 | /** 342 | * Set the volume of the output of the SDK. 343 | * 344 | * @param sdk A pointer to the SDK structure. 345 | * @param volume The volume of the output wanted, between 0 and 1. 1 being 346 | * maximum volume and 0 being silent. 347 | * @return An error code resulting from the call. CHIRP_SDK_OK will 348 | * be returned if everything went well. 349 | */ 350 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_set_volume(chirp_sdk_t *sdk, float volume); 351 | 352 | /** 353 | * Get the sample rate at which the SDK is processing the input. 354 | * 355 | * @param sdk A pointer to the SDK structure. 356 | * @return The actual sample rate used by the SDK to process the input. 357 | */ 358 | PUBLIC_SYM uint32_t chirp_sdk_get_input_sample_rate(chirp_sdk_t *sdk); 359 | 360 | /** 361 | * Get the sample rate at which the SDK is processing the output. 362 | * 363 | * @param sdk A pointer to the SDK structure. 364 | * @return The actual sample rate used by the SDK to process the output. 365 | */ 366 | PUBLIC_SYM uint32_t chirp_sdk_get_output_sample_rate(chirp_sdk_t *sdk); 367 | 368 | /** 369 | * Set the input sample rate of the SDK. It must always be the same as the 370 | * system's audio I/O sample rate or the decoding will fail. 371 | * 372 | * @param sdk A pointer to the SDK structure. 373 | * @param sample_rate The sample rate wanted for the input. 374 | * @return An error code resulting from the call. CHIRP_SDK_OK will 375 | * be returned if everything went well. 376 | */ 377 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_set_input_sample_rate(chirp_sdk_t *sdk, uint32_t sample_rate); 378 | 379 | /** 380 | * Set the output sample rate of the SDK. It must always be the same as the 381 | * system's audio I/O sample rate or the encoding will be distorted. 382 | * 383 | * @param sdk A pointer to the SDK structure. 384 | * @param sample_rate The sample rate wanted for the output. 385 | * @return An error code resulting from the call. CHIRP_SDK_OK will 386 | * be returned if everything went well. 387 | */ 388 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_set_output_sample_rate(chirp_sdk_t *sdk, uint32_t sample_rate); 389 | 390 | /** 391 | * Get the SDK's listen to self state. This automatically mutes the decoder when 392 | * sending a chirp, to prevent the application from hearing its own chirps. 393 | * Defaults to false. 394 | * 395 | * Set to true if you want your application to be able to hear its own chirps. 396 | * This is typically only useful for testing and debugging - for example, when 397 | * passing the output of `process_output` directly into `process_input` 398 | * 399 | * @param sdk A pointer to the SDK structure. 400 | * @return True : The SDK will attempt to decode the payloads it sends. 401 | * False : The SDK will ignore the payloads it sends. 402 | */ 403 | PUBLIC_SYM bool chirp_sdk_get_listen_to_self(chirp_sdk_t *sdk); 404 | 405 | /** 406 | * Set the listen to self status of the SDK. 407 | * 408 | * @param sdk A pointer to the SDK structure. 409 | * @param listen_to_self True: The SDK will attempt to decode the payloads it sends. 410 | * False: The SDK will ignore the payloads it sends. 411 | * @return An error code resulting from the call. CHIRP_SDK_OK will 412 | * be returned if everything went well. 413 | */ 414 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_set_listen_to_self(chirp_sdk_t *sdk, bool listen_to_self); 415 | 416 | /** 417 | * Set the pointer which is accessible in the callbacks. This function doesn't 418 | * necessarily need to be to be called. In that case, the pointer passed the 419 | * callbacks will be NULL. 420 | * 421 | * @param sdk A pointer to the SDK structure. 422 | * @param ptr A pointer to any data you want to pass to the callbacks. 423 | * @return An error code resulting from the call. CHIRP_SDK_OK will 424 | * be returned if everything went well. 425 | */ 426 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_set_callback_ptr(chirp_sdk_t *sdk, void *ptr); 427 | 428 | /** 429 | * On some systems, the effective audio sample rate is not quite the same as the 430 | * expected sample rate - for example, if it is being driven by a clock whose 431 | * frequency is not an integer multiple of the required audio sample rate. This 432 | * setting rectifies the discrepancy between the two, by multiplying the detected 433 | * frequency by a fixed frequency correction coefficient. 434 | * 435 | * @param sdk A pointer to the SDK structure. 436 | * @param correction A correction value between 0.5 and 1.5. 437 | * @return An error code resulting from the call. CHIRP_SDK_OK will 438 | * be returned if everything went well. 439 | */ 440 | PUBLIC_SYM chirp_sdk_error_code_t chirp_sdk_set_frequency_correction(chirp_sdk_t *sdk, float correction); 441 | 442 | /** 443 | * Return the current heap usage of the SDK, in bytes. 444 | * 445 | * @param sdk A pointer to the SDK structure. 446 | * @return The heap usage in bytes of the SDK. 447 | */ 448 | PUBLIC_SYM int32_t chirp_sdk_get_heap_usage(chirp_sdk_t *sdk); 449 | 450 | #ifdef __cplusplus 451 | } 452 | #endif 453 | 454 | #endif /* !CHIRP_SDK_H */ 455 | -------------------------------------------------------------------------------- /src/chirp_sdk_errors.h: -------------------------------------------------------------------------------- 1 | /**----------------------------------------------------------------------------- 2 | * 3 | * ASIO CONFIDENTIAL 4 | * 5 | * @file chirp_sdk_errors.h 6 | * 7 | * @brief Error handling of the SDK. 8 | * 9 | * All contents are strictly proprietary, and not for copying, resale, 10 | * or use outside of the agreed license. 11 | * 12 | * Copyright © 2011-2019, Asio Ltd. 13 | * All rights reserved. 14 | * 15 | *----------------------------------------------------------------------------*/ 16 | 17 | #ifndef CHIRP_SDK_ERRORS_H 18 | #define CHIRP_SDK_ERRORS_H 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | /** 25 | * Various error codes the SDK can return. Note that some of the values don't 26 | * apply on this SDK. 27 | */ 28 | typedef enum { 29 | CHIRP_SDK_OK = 0, ///< No error. 30 | CHIRP_SDK_OUT_OF_MEMORY, ///< The SDK ran out of memory. 31 | CHIRP_SDK_NOT_INITIALISED, ///< The SDK hasn't been initialised, did you forget to set the config? 32 | CHIRP_SDK_INTERNAL_ERROR, ///< An internal error prevented the SDK from initialising correctly. 33 | CHIRP_SDK_MEMORY_LEAK, ///< Some memory hasn't been freed leading to some leaks. 34 | CHIRP_SDK_RECEIVING_NOT_AVAILABLE, ///< Receiving mode has been disabled and is not available. 35 | 36 | CHIRP_SDK_NOT_RUNNING, ///< The SDK is not running. 37 | CHIRP_SDK_ALREADY_RUNNING, ///< The SDK is already running. 38 | CHIRP_SDK_ALREADY_STOPPED, ///< The SDK has already stopped. 39 | CHIRP_SDK_ALREADY_SENDING, ///< The SDK is already sending. 40 | 41 | CHIRP_SDK_INVALID_SAMPLE_RATE = 20, ///< The sample rate is invalid (it must respect Nyquist law). 42 | CHIRP_SDK_NULL_BUFFER, ///< One of the parameters is a NULL buffer. 43 | CHIRP_SDK_NULL_POINTER, ///< One of the parameters is a NULL pointer. 44 | CHIRP_SDK_CHANNEL_NOT_SUPPORTED, ///< The channel asked is bigger than the maximum one authorised by the config being used. 45 | CHIRP_SDK_INVALID_FREQUENCY_CORRECTION, ///< Invalid frequency correction value. 46 | CHIRP_SDK_PROCESSING_ERROR, ///< An internal issue happened when processing. 47 | 48 | CHIRP_SDK_INVALID_KEY = 40, ///< Invalid application key. 49 | CHIRP_SDK_INVALID_SECRET, ///< Invalid application secret. 50 | CHIRP_SDK_INVALID_CREDENTIALS, ///< Invalid application credentials. 51 | CHIRP_SDK_MISSING_SIGNATURE, ///< Signature is missing from the config. 52 | CHIRP_SDK_INVALID_SIGNATURE, ///< Signature couldn't be verified. 53 | CHIRP_SDK_MISSING_CONFIG, ///< Config information is missing. 54 | CHIRP_SDK_INVALID_CONFIG, ///< Config information is invalid. 55 | CHIRP_SDK_EXPIRED_CONFIG, ///< This config has expired. 56 | CHIRP_SDK_INVALID_VERSION, ///< This config was generated for a different version. Please visit https://developers.chirp.io to upgrade your SDK. 57 | CHIRP_SDK_INVALID_PROJECT, ///< This config was generated for a different project. 58 | /*-------------------------------------------------------------------------- 59 | * CHIRP_SDK_INVALID_CONFIG_CHARACTER needs to be kept at the end of 60 | * the credentials error code list as it deals with base64 but it is 61 | * implemented in chirp-sdk. 62 | *------------------------------------------------------------------------*/ 63 | CHIRP_SDK_INVALID_CONFIG_CHARACTER, ///< Your config contains one or many unknown character(s). 64 | 65 | CHIRP_SDK_PAYLOAD_EMPTY_MESSAGE = 80, ///< The payload is empty. 66 | CHIRP_SDK_PAYLOAD_INVALID_MESSAGE, ///< The payload is invalid. 67 | CHIRP_SDK_PAYLOAD_UNKNOWN_SYMBOLS, ///< The payload contains unknown symbols. 68 | CHIRP_SDK_PAYLOAD_DECODE_FAILED, ///< Couldn't decode the payload. 69 | CHIRP_SDK_PAYLOAD_TOO_LONG, ///< The payload's length is longer than the maximum one authorised by the config being used. 70 | CHIRP_SDK_PAYLOAD_TOO_SHORT, ///< The payload's length is shorter than the minimum one authorised by the config being used.. 71 | 72 | CHIRP_SDK_INVALID_VOLUME = 99, ///< Volume value is incorrect. 73 | CHIRP_SDK_UNKNOWN_ERROR = 100, ///< The SDK has reported an unknown error. 74 | 75 | /*-------------------------------------------------------------------------- 76 | * Reserved for the high level SDKs. Don't update it but rather add an issue 77 | * in the C-SDK. 78 | *------------------------------------------------------------------------*/ 79 | CHIRP_SDK_NETWORK_ERROR = 200, ///< "Network error." 80 | CHIRP_SDK_NETWORK_NO_NETWORK, ///< "Couldn't reach the server, please check your network connection." 81 | CHIRP_SDK_NETWORK_PERMISSIONS_NOT_GRANTED, ///< "Network permissions were not granted by the application or user. Please add network permissions to your application, or contact sales@chirp.io to request completely offline operation." 82 | CHIRP_SDK_ACCOUNT_DISABLED, ///< "Your account has been disabled due to an unpaid license. Please contact sales@chirp.io." 83 | CHIRP_SDK_AUDIO_IO_ERROR, ///< "Audio IO error." 84 | CHIRP_SDK_SENDING_NOT_ENABLED, ///< "Send mode hasn't been enabled." 85 | CHIRP_SDK_RECEIVING_NOT_ENABLED, ///< "Receive mode hasn't been enabled." 86 | CHIRP_SDK_DEVICE_IS_MUTED, ///< "The device is muted. Cannot send data." 87 | } chirp_sdk_error_code_t; 88 | 89 | #include "chirp_sdk.h" 90 | 91 | /** 92 | * Convert a `chirp_sdk_error_code_t` code to a string describing the error. 93 | * 94 | * @param err The error code which needs to be detailed. 95 | * @return The string describing the error code. 96 | */ 97 | PUBLIC_SYM const char *chirp_sdk_error_code_to_string(chirp_sdk_error_code_t err); 98 | 99 | #ifdef __cplusplus 100 | } 101 | #endif 102 | 103 | #endif /* !CHIRP_SDK_ERRORS_H */ 104 | -------------------------------------------------------------------------------- /src/chirp_sdk_events.h: -------------------------------------------------------------------------------- 1 | /**----------------------------------------------------------------------------- 2 | * 3 | * ASIO CONFIDENTIAL 4 | * 5 | * @file chirp_sdk_events.h 6 | * 7 | * @brief Events implementations of the C SDK (callbacks and states). 8 | * 9 | * All contents are strictly proprietary, and not for copying, resale, 10 | * or use outside of the agreed license. 11 | * 12 | * Copyright © 2011-2019, Asio Ltd. 13 | * All rights reserved. 14 | * 15 | *----------------------------------------------------------------------------*/ 16 | 17 | #ifndef CHIRP_SDK_EVENTS_H 18 | #define CHIRP_SDK_EVENTS_H 19 | 20 | #include 21 | #include 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /** 28 | * Various states the SDK can return. 29 | */ 30 | typedef enum { 31 | CHIRP_SDK_STATE_NOT_CREATED, ///< The audio processing has not been initialised yet. 32 | CHIRP_SDK_STATE_STOPPED, ///< The SDK is not processing audio. 33 | CHIRP_SDK_STATE_RUNNING, ///< The audio processing is running. 34 | CHIRP_SDK_STATE_SENDING, ///< The SDK is sending data. 35 | CHIRP_SDK_STATE_RECEIVING, ///< The SDK is receiving data. 36 | } chirp_sdk_state_t; 37 | 38 | /** 39 | * On_sending, on_sent, on_receiving and on_received callback prototype 40 | * definitions. These callbacks are called if set and respectively if the SDK is 41 | * sending, sent, is receiving or received some data. 42 | * 43 | * @param ptr Pointer of data. It's either the pointer set when calling 44 | * `chirp_sdk_set_callback_ptr` or NULL. 45 | * @param bytes on_sending : The data being sent. 46 | * on_sent : The data sent. 47 | * on_receiving : NULL. 48 | * on_received : NULL if the decode failed or the data received. 49 | * @param length on_sending : The length, in bytes, of the data being sent. 50 | * on_sent : The length, in bytes, of the data sent. 51 | * on_receiving : 0. 52 | * on_received : 0 if the decode failed or the length, in bytes, 53 | * of the data received. 54 | * @param channel Channel on which the data has been received. 55 | */ 56 | typedef void (*chirp_sdk_callback_t)(void *ptr, uint8_t *bytes, size_t length, uint8_t channel); 57 | 58 | /** 59 | * On_state_changed callback prototype definition. This is called if the 60 | * callback has been set and when the SDK's state is changing. 61 | * The possibles values are the one of the `chirp_sdk_state_t` enum 62 | * located in `chirp_sdk_states.h`. 63 | * 64 | * @param ptr Pointer of data. It's either the pointer set when calling 65 | * `chirp_sdk_set_callback_ptr` or NULL. 66 | * @param old_state The old state of the SDK before reaching this callback. 67 | * @param new_state The new state of the SDK when leaving this callback. 68 | */ 69 | typedef void (*chirp_sdk_state_callback_t)(void *ptr, chirp_sdk_state_t old_state, chirp_sdk_state_t new_state); 70 | 71 | /** 72 | * Structure containing the callbacks pointers. It is not necessary to set all 73 | * the fields. Not setting a callback will only result in not being notified of 74 | * the event. 75 | */ 76 | typedef struct { 77 | chirp_sdk_state_callback_t on_state_changed; ///< Triggered when the SDK's state is changing. 78 | chirp_sdk_callback_t on_sending; ///< Triggered when the SDK starts sending some data. 79 | chirp_sdk_callback_t on_sent; ///< Triggered when the SDK has sent the data. 80 | chirp_sdk_callback_t on_receiving; ///< Triggered when the SDK starts receiving some data. 81 | chirp_sdk_callback_t on_received; ///< Triggered when the SDK has received the data. 82 | } chirp_sdk_callback_set_t; 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | 88 | #endif /* !CHIRP_SDK_EVENTS_H */ 89 | -------------------------------------------------------------------------------- /src/chirp_sdk_version.h: -------------------------------------------------------------------------------- 1 | /**----------------------------------------------------------------------------- 2 | * 3 | * @file chirp_sdk_version.h 4 | * 5 | * @brief Provides getter to the lib name, version and build number of the 6 | * library 7 | * 8 | * ASIO CONFIDENTIAL 9 | * 10 | * All contents are strictly proprietary, and not for copying, resale, 11 | * or use outside of the agreed license. 12 | * 13 | * Copyright © 2011-2019, Asio Ltd. 14 | * All rights reserved. 15 | * 16 | *----------------------------------------------------------------------------*/ 17 | 18 | #ifndef CHIRP_SDK_VERSION_H 19 | #define CHIRP_SDK_VERSION_H 20 | 21 | #include "chirp_sdk.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /** 28 | * Get the name of SDK : "chirp-sdk". This function doesn't rely at all on 29 | * the SDK creation and can be called at any time. 30 | * 31 | * @return The name of the library 32 | */ 33 | PUBLIC_SYM const char *chirp_sdk_get_library_name(void); 34 | 35 | /** 36 | * Get the version number of the SDK. This function doesn't rely at all on the 37 | * SDK creation and can be called at any time. 38 | * 39 | * @return The version number of the SDK in the MAJOR.MINOR.PATCH string 40 | * representation. 41 | */ 42 | PUBLIC_SYM const char *chirp_sdk_get_version(void); 43 | 44 | /** 45 | * Get the build number of the SDK. This function doesn't rely at all on the 46 | * SDK creation and can be called at any time. 47 | * 48 | * @return The build number of the SDK as a string. 49 | */ 50 | PUBLIC_SYM const char *chirp_sdk_get_build_number(void); 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif /* !CHIRP_SDK_VERSION_H */ 57 | -------------------------------------------------------------------------------- /src/cortex-m0plus/libChirpSDK.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chirp/chirp-arduino/6769d478a8ba8eb1079e7593abb5aaa3cdb3de1d/src/cortex-m0plus/libChirpSDK.a -------------------------------------------------------------------------------- /src/cortex-m4/libChirpSDK.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chirp/chirp-arduino/6769d478a8ba8eb1079e7593abb5aaa3cdb3de1d/src/cortex-m4/libChirpSDK.a -------------------------------------------------------------------------------- /src/esp32/libChirpSDK.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chirp/chirp-arduino/6769d478a8ba8eb1079e7593abb5aaa3cdb3de1d/src/esp32/libChirpSDK.a -------------------------------------------------------------------------------- /src/mk64fx512/libChirpSDK.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chirp/chirp-arduino/6769d478a8ba8eb1079e7593abb5aaa3cdb3de1d/src/mk64fx512/libChirpSDK.a --------------------------------------------------------------------------------