├── A2DPspecv10.pdf ├── Bluetooth_A2DP_Source.ino ├── README.md ├── bt_app_core.c ├── bt_app_core.h ├── enigma.h ├── one_channel_moog_mod.h └── sdkconfig.defaults /A2DPspecv10.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgm3333/Arduino_A2DP_Source/c410fe916014d9140934d70c94619a409a43957c/A2DPspecv10.pdf -------------------------------------------------------------------------------- /Bluetooth_A2DP_Source.ino: -------------------------------------------------------------------------------- 1 | /* 2 | This example code is in the Public Domain (or CC0 licensed, at your option.) 3 | 4 | Unless required by applicable law or agreed to in writing, this 5 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 6 | CONDITIONS OF ANY KIND, either express or implied. 7 | */ 8 | /* 9 | * Arduino port of https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/a2dp_source 10 | * 11 | * After connection with A2DP sink is established, the example performs the following running loop 1-2-3-4-1: 12 | * 1. audio transmission starts and lasts for a while 13 | * 2. audio transmission stops 14 | * 3. disconnect with target device 15 | * 4. reconnect to target device 16 | * 17 | * The example implements an event loop triggered by a periodic "heart beat" timer and events from Bluetooth protocol stack callback functions. 18 | * 19 | * For current stage, the supported audio codec in ESP32 A2DP is SBC (SubBand Coding). 20 | * SBC specification is in Appendix B (page 50) of the document A2DP_Spec_V1_0 (can be found with search engine, although the original is behind the Bluetooth firewall) 21 | * 22 | * SBC audio stream is encoded from PCM data normally formatted as 44.1kHz sampling rate, two-channel 16-bit sample data. 23 | * Other SBC configurations can be supported but there is a need for additional modifications to the protocol stack. 24 | */ 25 | 26 | 27 | 28 | // Code tested and works on WEMOS Wifi and Bluetooth Battery (actually using HiGrow hardware) 29 | // The ESP32 is visible as ESP_A2DP_SRC - Would be nice if it was possible to send from ESP32 to android phone, but AFAICT the android stack doesn't implement the sink protocol 30 | // Change this to the name of your bluetooth speaker/headset 31 | #define BT_SINK "BNX-60" 32 | #define BT_DEVICE_NAME "ESP_A2DP_SRC" 33 | 34 | // samples from the mod archive: https://modarchive.org/index.php?request=view_by_moduleid&query=42146 35 | #include "enigma.h" 36 | #define CURMOD enigma_mod 37 | //#include "one_channel_moog_mod.h" 38 | //#define CURMOD one_channel_moog_mod //enigma_mod 39 | 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | extern "C" { 47 | #include "freertos/FreeRTOS.h" 48 | #include "freertos/task.h" 49 | #include "freertos/timers.h" 50 | #include "nvs.h" 51 | #include "nvs_flash.h" 52 | #include "esp_system.h" 53 | #include "ESP_LOG.h" 54 | 55 | #include "esp_bt.h" 56 | #include "esp_bt_main.h" 57 | #include "esp_bt_device.h" 58 | #include "esp_gap_bt_api.h" 59 | #include "esp_a2dp_api.h" 60 | #include "esp_avrc_api.h" 61 | 62 | #include "esp32-hal-bt.h" 63 | #include "esp32-hal-bt.c" 64 | }; 65 | #include "bt_app_core.h" 66 | #include "bt_app_core.c" 67 | 68 | 69 | #define BT_AV_TAG "BT_AV" 70 | 71 | /* event for handler "bt_av_hdl_stack_up */ 72 | enum { 73 | BT_APP_EVT_STACK_UP = 0, 74 | }; 75 | 76 | /* A2DP global state */ 77 | enum { 78 | APP_AV_STATE_IDLE, 79 | APP_AV_STATE_DISCOVERING, 80 | APP_AV_STATE_DISCOVERED, 81 | APP_AV_STATE_UNCONNECTED, 82 | APP_AV_STATE_CONNECTING, 83 | APP_AV_STATE_CONNECTED, 84 | APP_AV_STATE_DISCONNECTING, 85 | }; 86 | 87 | /* sub states of APP_AV_STATE_CONNECTED */ 88 | enum { 89 | APP_AV_MEDIA_STATE_IDLE, 90 | APP_AV_MEDIA_STATE_STARTING, 91 | APP_AV_MEDIA_STATE_STARTED, 92 | APP_AV_MEDIA_STATE_STOPPING, 93 | }; 94 | 95 | #define BT_APP_HEART_BEAT_EVT (0xff00) 96 | 97 | /// handler for bluetooth stack enabled events 98 | static void bt_av_hdl_stack_evt(uint16_t event, void *p_param); 99 | 100 | /// callback function for A2DP source 101 | static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); 102 | 103 | /// callback function for A2DP source audio data stream 104 | static int32_t bt_app_a2d_data_cb_static(uint8_t *data, int32_t len); 105 | static int32_t bt_app_a2d_data_cb_increase(uint8_t *data, int32_t len); 106 | static int32_t bt_app_a2d_data_cb_sine(uint8_t *data, int32_t len); 107 | static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len); 108 | 109 | static void a2d_app_heart_beat(void *arg); 110 | 111 | /// A2DP application state machine 112 | static void bt_app_av_sm_hdlr(uint16_t event, void *param); 113 | 114 | /* A2DP application state machine handler for each state */ 115 | static void bt_app_av_state_unconnected(uint16_t event, void *param); 116 | static void bt_app_av_state_connecting(uint16_t event, void *param); 117 | static void bt_app_av_state_connected(uint16_t event, void *param); 118 | static void bt_app_av_state_disconnecting(uint16_t event, void *param); 119 | 120 | static esp_bd_addr_t s_peer_bda = {0}; 121 | static uint8_t s_peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; 122 | static int s_a2d_state = APP_AV_STATE_IDLE; 123 | static int s_media_state = APP_AV_MEDIA_STATE_IDLE; 124 | static int s_intv_cnt = 0; 125 | static int s_connecting_intv = 0; 126 | static uint32_t s_pkt_cnt = 0; 127 | 128 | static TimerHandle_t s_tmr; 129 | 130 | 131 | static int sine_phase; 132 | 133 | static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) 134 | { 135 | if (bda == NULL || str == NULL || size < 18) { 136 | return NULL; 137 | } 138 | 139 | uint8_t *p = bda; 140 | sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", 141 | p[0], p[1], p[2], p[3], p[4], p[5]); 142 | return str; 143 | } 144 | 145 | void setup() 146 | { 147 | 148 | Serial.begin(115200); 149 | while(!Serial) { ; } // wait for serial port to connect. Needed for native USB port only 150 | Serial.flush(); 151 | Serial.println(); 152 | 153 | const char compile_data[] = __FILE__ " " __DATE__ " " __TIME__; 154 | Serial.println(compile_data); 155 | 156 | 157 | 158 | 159 | 160 | Serial.println("Initialize Non-Volatile Storage (NVS)"); 161 | esp_err_t ret = nvs_flash_init(); 162 | if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { 163 | ESP_ERROR_CHECK(nvs_flash_erase()); 164 | ret = nvs_flash_init(); 165 | } 166 | ESP_ERROR_CHECK( ret ); 167 | 168 | ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); 169 | 170 | esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); 171 | 172 | if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { 173 | Serial.printf("ESP_LOGE: BT_AV_TAG: In func: %s: initialize controller failed\n", __func__); 174 | return; 175 | } 176 | 177 | // Doesn't like BT Classic, but works with Dual Mode (ie don't use ESP_BT_MODE_CLASSIC_BT) 178 | if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) { 179 | Serial.printf("ESP_LOGE: BT_AV_TAG: In func: %s: enable controller failed\n", __func__); 180 | return; 181 | } 182 | 183 | if (esp_bluedroid_init() != ESP_OK) { 184 | Serial.printf("ESP_LOGE: BT_AV_TAG: In func: %s: initialize bluedroid failed\n", __func__); 185 | return; 186 | } 187 | 188 | if (esp_bluedroid_enable() != ESP_OK) { 189 | Serial.printf("ESP_LOGE: BT_AV_TAG: In func: %s: enable bluedroid failed\n", __func__); 190 | return; 191 | } 192 | 193 | /* create application task */ 194 | bt_app_task_start_up(); 195 | 196 | /* Bluetooth device name, connection mode and profile set up */ 197 | bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); 198 | 199 | #if (CONFIG_BT_SSP_ENABLED == true) 200 | /* Set default parameters for Secure Simple Pairing */ 201 | esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; 202 | esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; 203 | esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); 204 | #endif 205 | 206 | /* 207 | * Set default parameters for Legacy Pairing 208 | * Use variable pin, input pin code when pairing 209 | */ 210 | esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; 211 | esp_bt_pin_code_t pin_code; 212 | esp_bt_gap_set_pin(pin_type, 0, pin_code); 213 | } 214 | 215 | void loop() {} 216 | 217 | static bool get_name_from_eir(uint8_t *eir, uint8_t *bdname, uint8_t *bdname_len) 218 | { 219 | uint8_t *rmt_bdname = NULL; 220 | uint8_t rmt_bdname_len = 0; 221 | 222 | if (!eir) { 223 | return false; 224 | } 225 | 226 | rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len); 227 | if (!rmt_bdname) { 228 | rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len); 229 | } 230 | 231 | if (rmt_bdname) { 232 | if (rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN) { 233 | rmt_bdname_len = ESP_BT_GAP_MAX_BDNAME_LEN; 234 | } 235 | 236 | if (bdname) { 237 | memcpy(bdname, rmt_bdname, rmt_bdname_len); 238 | bdname[rmt_bdname_len] = '\0'; 239 | } 240 | if (bdname_len) { 241 | *bdname_len = rmt_bdname_len; 242 | } 243 | return true; 244 | } 245 | 246 | return false; 247 | } 248 | 249 | static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param) 250 | { 251 | char bda_str[18]; 252 | uint32_t cod = 0; 253 | int32_t rssi = -129; /* invalid value */ 254 | uint8_t *eir = NULL; 255 | esp_bt_gap_dev_prop_t *p; 256 | 257 | Serial.printf("ESP_LOGI: BT_AV_TAG: Scanned device: %s\n", bda2str(param->disc_res.bda, bda_str, 18)); 258 | for (int i = 0; i < param->disc_res.num_prop; i++) { 259 | p = param->disc_res.prop + i; 260 | switch (p->type) { 261 | case ESP_BT_GAP_DEV_PROP_COD: 262 | cod = *(uint32_t *)(p->val); 263 | Serial.printf("ESP_LOGI: BT_AV_TAG: --Class of Device: 0x%x\n", cod); 264 | // NB enumeration is listed in 265 | break; 266 | case ESP_BT_GAP_DEV_PROP_RSSI: 267 | rssi = *(int8_t *)(p->val); 268 | Serial.printf("ESP_LOGI: BT_AV_TAG: --RSSI (Received signal strength indication): %d\n", rssi); 269 | break; 270 | case ESP_BT_GAP_DEV_PROP_EIR: 271 | eir = (uint8_t *)(p->val); 272 | break; 273 | case ESP_BT_GAP_DEV_PROP_BDNAME: 274 | default: 275 | break; 276 | } 277 | } 278 | 279 | /* search for device with MAJOR service class as "rendering" in COD */ 280 | if (!esp_bt_gap_is_valid_cod(cod) || 281 | !(esp_bt_gap_get_cod_srvc(cod) & ESP_BT_COD_SRVC_RENDERING)) { 282 | return; 283 | } 284 | 285 | /* search for device named BT_SINK in its extended inqury response */ 286 | if (eir) { 287 | get_name_from_eir(eir, s_peer_bdname, NULL); 288 | if (strcmp((char *)s_peer_bdname, BT_SINK) != 0) { 289 | return; 290 | } 291 | 292 | Serial.printf("ESP_LOGI: BT_AV_TAG: Found a target device, address %s, name %s\n", bda_str, s_peer_bdname); 293 | s_a2d_state = APP_AV_STATE_DISCOVERED; 294 | memcpy(s_peer_bda, param->disc_res.bda, ESP_BD_ADDR_LEN); 295 | Serial.printf("ESP_LOGI: BT_AV_TAG: Cancel device discovery ...\n"); 296 | esp_bt_gap_cancel_discovery(); 297 | } 298 | } 299 | 300 | 301 | void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) 302 | { 303 | switch (event) { 304 | case ESP_BT_GAP_DISC_RES_EVT: { 305 | filter_inquiry_scan_result(param); 306 | break; 307 | } 308 | case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: { 309 | if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) { 310 | if (s_a2d_state == APP_AV_STATE_DISCOVERED) { 311 | s_a2d_state = APP_AV_STATE_CONNECTING; 312 | // Serial.printf("ESP_LOGI: BT_AV_TAG: Device discovery stopped.\n"); 313 | Serial.printf("ESP_LOGI: BT_AV_TAG: Device discovery stopped: a2dp connecting to peer: %s\n", s_peer_bdname); 314 | esp_a2d_source_connect(s_peer_bda); 315 | } else { 316 | // not discovered, continue to discover 317 | Serial.printf("ESP_LOGI: BT_AV_TAG: Device discovery failed, continue to discover...\n"); 318 | esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); 319 | } 320 | } else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) { 321 | Serial.printf("ESP_LOGI: BT_AV_TAG: Discovery started.\n"); 322 | } 323 | break; 324 | } 325 | case ESP_BT_GAP_RMT_SRVCS_EVT: 326 | case ESP_BT_GAP_RMT_SRVC_REC_EVT: 327 | break; 328 | case ESP_BT_GAP_AUTH_CMPL_EVT: { 329 | if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { 330 | Serial.printf("ESP_LOGI: BT_AV_TAG: authentication success: %s", param->auth_cmpl.device_name); 331 | // ESP_LOG_buffer_hex(" + BT_AV_TAG + ", param->auth_cmpl.bda, ESP_BD_ADDR_LEN); 332 | } else { 333 | Serial.printf("ESP_LOGE: BT_AV_TAG authentication failed, status:%d\n", param->auth_cmpl.stat); 334 | } 335 | break; 336 | } 337 | case ESP_BT_GAP_PIN_REQ_EVT: { 338 | Serial.printf("ESP_LOGI: BT_AV_TAG: ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d\n", param->pin_req.min_16_digit); 339 | if (param->pin_req.min_16_digit) { 340 | Serial.printf("ESP_LOGI: BT_AV_TAG: Input pin code: 0000 0000 0000 0000\n"); 341 | esp_bt_pin_code_t pin_code = {0}; 342 | esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code); 343 | } else { 344 | Serial.printf("ESP_LOGI: BT_AV_TAG: Input pin code: 1234\n"); 345 | esp_bt_pin_code_t pin_code; 346 | pin_code[0] = '1'; 347 | pin_code[1] = '2'; 348 | pin_code[2] = '3'; 349 | pin_code[3] = '4'; 350 | esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code); 351 | } 352 | break; 353 | } 354 | 355 | #if (CONFIG_BT_SSP_ENABLED == true) 356 | case ESP_BT_GAP_CFM_REQ_EVT: 357 | Serial.printf("ESP_LOGI: BT_AV_TAG: ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d\n", param->cfm_req.num_val); 358 | esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); 359 | break; 360 | case ESP_BT_GAP_KEY_NOTIF_EVT: 361 | Serial.printf("ESP_LOGI: BT_AV_TAG: ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d\n", param->key_notif.passkey); 362 | break; 363 | case ESP_BT_GAP_KEY_REQ_EVT: 364 | Serial.printf("ESP_LOGI: BT_AV_TAG: ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!\n"); 365 | break; 366 | #endif 367 | 368 | default: { 369 | Serial.printf("ESP_LOGI: BT_AV_TAG: event: %d", event); 370 | break; 371 | } 372 | } 373 | return; 374 | } 375 | 376 | static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) 377 | { 378 | Serial.printf("ESP_LOGD: BT_AV_TAG: %s evt %d\n", __func__, event); 379 | switch (event) { 380 | case BT_APP_EVT_STACK_UP: { 381 | /* set up device name */ 382 | char *dev_name = BT_DEVICE_NAME; 383 | esp_bt_dev_set_device_name(dev_name); 384 | 385 | /* register GAP callback function */ 386 | esp_bt_gap_register_callback(bt_app_gap_cb); 387 | 388 | /* initialize A2DP source */ 389 | esp_a2d_register_callback(&bt_app_a2d_cb); 390 | // esp_a2d_source_register_data_callback(bt_app_a2d_data_cb_static); // generates static/white noise 391 | // static int32_t bt_app_a2d_data_cb_increase(uint8_t *data, int32_t len); // generates linear increasing noise 392 | // static int32_t bt_app_a2d_data_cb_sine(uint8_t *data, int32_t len); // generates sine wave noise 393 | esp_a2d_source_register_data_callback(bt_app_a2d_data_cb); 394 | esp_a2d_source_init(); 395 | 396 | /* set discoverable and connectable mode */ 397 | esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); 398 | 399 | /* start device discovery */ 400 | Serial.printf("ESP_LOGI: BT_AV_TAG: Starting device discovery...\n"); 401 | s_a2d_state = APP_AV_STATE_DISCOVERING; 402 | esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); 403 | 404 | /* create and start heart beat timer */ 405 | do { 406 | int tmr_id = 0; 407 | s_tmr = xTimerCreate("connTmr", (10000 / portTICK_RATE_MS), 408 | pdTRUE, (void *)tmr_id, a2d_app_heart_beat); 409 | xTimerStart(s_tmr, portMAX_DELAY); 410 | } while (0); 411 | break; 412 | } 413 | default: 414 | Serial.printf("ESP_LOGE: BT_AV_TAG: In func: %s: unhandled evt %d", __func__, event); 415 | break; 416 | } 417 | } 418 | 419 | static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) 420 | { 421 | bt_app_work_dispatch(bt_app_av_sm_hdlr, event, param, sizeof(esp_a2d_cb_param_t), NULL); 422 | } 423 | 424 | static void a2d_app_heart_beat(void *arg) 425 | { 426 | bt_app_work_dispatch(bt_app_av_sm_hdlr, BT_APP_HEART_BEAT_EVT, NULL, 0, NULL); 427 | } 428 | 429 | static void bt_app_av_sm_hdlr(uint16_t event, void *param) 430 | { 431 | Serial.printf("ESP_LOGI: BT_AV_TAG: %s state %d, evt 0x%x: ", __func__, s_a2d_state, event); 432 | switch (s_a2d_state) { 433 | case APP_AV_STATE_DISCOVERING: 434 | Serial.println("APP_AV_STATE_DISCOVERING"); 435 | break; 436 | case APP_AV_STATE_DISCOVERED: 437 | Serial.println("APP_AV_STATE_DISCOVERED"); 438 | break; 439 | case APP_AV_STATE_UNCONNECTED: 440 | Serial.println("APP_AV_STATE_UNCONNECTED"); 441 | bt_app_av_state_unconnected(event, param); 442 | break; 443 | case APP_AV_STATE_CONNECTING: 444 | Serial.println("APP_AV_STATE_CONNECTING"); 445 | bt_app_av_state_connecting(event, param); 446 | break; 447 | case APP_AV_STATE_CONNECTED: 448 | Serial.println("APP_AV_STATE_CONNECTED"); 449 | bt_app_av_state_connected(event, param); 450 | break; 451 | case APP_AV_STATE_DISCONNECTING: 452 | Serial.println("APP_AV_STATE_DISCONNECTING"); 453 | bt_app_av_state_disconnecting(event, param); 454 | break; 455 | default: 456 | Serial.printf("\nESP_LOGE: BT_AV_TAG: In func: %s: invalid state %d\n", __func__, s_a2d_state); 457 | break; 458 | } 459 | } 460 | 461 | static void bt_app_av_state_unconnected(uint16_t event, void *param) 462 | { 463 | switch (event) { 464 | case ESP_A2D_CONNECTION_STATE_EVT: 465 | case ESP_A2D_AUDIO_STATE_EVT: 466 | case ESP_A2D_AUDIO_CFG_EVT: 467 | case ESP_A2D_MEDIA_CTRL_ACK_EVT: 468 | break; 469 | case BT_APP_HEART_BEAT_EVT: { 470 | uint8_t *p = s_peer_bda; 471 | Serial.printf("ESP_LOGI: BT_AV_TAG: Heartbeat Event: a2dp most recent peer connection: %s @ %02x:%02x:%02x:%02x:%02x:%02x\n", 472 | s_peer_bdname, p[0], p[1], p[2], p[3], p[4], p[5]); 473 | esp_a2d_source_connect(s_peer_bda); 474 | s_a2d_state = APP_AV_STATE_CONNECTING; 475 | s_connecting_intv = 0; 476 | break; 477 | } 478 | default: 479 | Serial.printf("ESP_LOGE: BT_AV_TAG: In func: %s: unhandled evt %d\n", __func__, event); 480 | break; 481 | } 482 | } 483 | 484 | static void bt_app_av_state_connecting(uint16_t event, void *param) 485 | { 486 | esp_a2d_cb_param_t *a2d = NULL; 487 | switch (event) { 488 | case ESP_A2D_CONNECTION_STATE_EVT: { 489 | a2d = (esp_a2d_cb_param_t *)(param); 490 | if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED) { 491 | Serial.printf("ESP_LOGI: BT_AV_TAG: a2dp connected\n"); 492 | s_a2d_state = APP_AV_STATE_CONNECTED; 493 | s_media_state = APP_AV_MEDIA_STATE_IDLE; 494 | esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_NONE); 495 | } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { 496 | s_a2d_state = APP_AV_STATE_UNCONNECTED; 497 | } 498 | break; 499 | } 500 | case ESP_A2D_AUDIO_STATE_EVT: 501 | case ESP_A2D_AUDIO_CFG_EVT: 502 | case ESP_A2D_MEDIA_CTRL_ACK_EVT: 503 | break; 504 | case BT_APP_HEART_BEAT_EVT: 505 | if (++s_connecting_intv >= 2) { 506 | s_a2d_state = APP_AV_STATE_UNCONNECTED; 507 | s_connecting_intv = 0; 508 | } 509 | break; 510 | default: 511 | Serial.printf("ESP_LOGE: BT_AV_TAG: In func: %s: unhandled evt %d\n", __func__, event); 512 | break; 513 | } 514 | } 515 | 516 | static void bt_app_av_media_proc(uint16_t event, void *param) 517 | { 518 | esp_a2d_cb_param_t *a2d = NULL; 519 | switch (s_media_state) { 520 | case APP_AV_MEDIA_STATE_IDLE: { 521 | if (event == BT_APP_HEART_BEAT_EVT) { 522 | Serial.printf("ESP_LOGI: BT_AV_TAG: a2dp media ready checking ...\n"); 523 | esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY); 524 | } else if (event == ESP_A2D_MEDIA_CTRL_ACK_EVT) { 525 | a2d = (esp_a2d_cb_param_t *)(param); 526 | if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY && 527 | a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS) { 528 | Serial.printf("ESP_LOGI: BT_AV_TAG: a2dp media ready, starting ...\n"); 529 | esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_START); 530 | s_media_state = APP_AV_MEDIA_STATE_STARTING; 531 | } 532 | } 533 | break; 534 | } 535 | case APP_AV_MEDIA_STATE_STARTING: { 536 | if (event == ESP_A2D_MEDIA_CTRL_ACK_EVT) { 537 | a2d = (esp_a2d_cb_param_t *)(param); 538 | if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_START && 539 | a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS) { 540 | Serial.printf("ESP_LOGI: BT_AV_TAG: a2dp media start successfully.\n"); 541 | s_intv_cnt = 0; 542 | s_media_state = APP_AV_MEDIA_STATE_STARTED; 543 | } else { 544 | // not started succesfully, transfer to idle state 545 | Serial.printf("ESP_LOGI: BT_AV_TAG: a2dp media start failed.\n"); 546 | s_media_state = APP_AV_MEDIA_STATE_IDLE; 547 | } 548 | } 549 | break; 550 | } 551 | case APP_AV_MEDIA_STATE_STARTED: { 552 | /* if (event == BT_APP_HEART_BEAT_EVT) { 553 | if (++s_intv_cnt >= 10) { 554 | Serial.printf("ESP_LOGI: BT_AV_TAG: a2dp media stopping...\n"); 555 | esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP); 556 | s_media_state = APP_AV_MEDIA_STATE_STOPPING; 557 | s_intv_cnt = 0; 558 | } 559 | } 560 | */ break; 561 | } 562 | case APP_AV_MEDIA_STATE_STOPPING: { 563 | if (event == ESP_A2D_MEDIA_CTRL_ACK_EVT) { 564 | a2d = (esp_a2d_cb_param_t *)(param); 565 | if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_STOP && 566 | a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS) { 567 | Serial.printf("ESP_LOGI: BT_AV_TAG: a2dp media stopped successfully, disconnecting...\n"); 568 | s_media_state = APP_AV_MEDIA_STATE_IDLE; 569 | esp_a2d_source_disconnect(s_peer_bda); 570 | s_a2d_state = APP_AV_STATE_DISCONNECTING; 571 | } else { 572 | Serial.printf("ESP_LOGI: BT_AV_TAG: a2dp media stopping...\n"); 573 | esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP); 574 | } 575 | } 576 | break; 577 | } 578 | } 579 | } 580 | 581 | static void bt_app_av_state_connected(uint16_t event, void *param) 582 | { 583 | esp_a2d_cb_param_t *a2d = NULL; 584 | switch (event) { 585 | case ESP_A2D_CONNECTION_STATE_EVT: { 586 | a2d = (esp_a2d_cb_param_t *)(param); 587 | if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { 588 | Serial.printf("ESP_LOGI: BT_AV_TAG: a2dp disconnected\n"); 589 | s_a2d_state = APP_AV_STATE_UNCONNECTED; 590 | esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); 591 | } 592 | break; 593 | } 594 | case ESP_A2D_AUDIO_STATE_EVT: { 595 | a2d = (esp_a2d_cb_param_t *)(param); 596 | if (ESP_A2D_AUDIO_STATE_STARTED == a2d->audio_stat.state) { 597 | s_pkt_cnt = 0; 598 | } 599 | break; 600 | } 601 | case ESP_A2D_AUDIO_CFG_EVT: 602 | // not suppposed to occur for A2DP source 603 | break; 604 | case ESP_A2D_MEDIA_CTRL_ACK_EVT: 605 | case BT_APP_HEART_BEAT_EVT: { 606 | bt_app_av_media_proc(event, param); 607 | break; 608 | } 609 | default: 610 | Serial.printf("ESP_LOGE: BT_AV_TAG: In func: %s: unhandled evt %d\n", __func__, event); 611 | break; 612 | } 613 | } 614 | 615 | static void bt_app_av_state_disconnecting(uint16_t event, void *param) 616 | { 617 | esp_a2d_cb_param_t *a2d = NULL; 618 | switch (event) { 619 | case ESP_A2D_CONNECTION_STATE_EVT: { 620 | a2d = (esp_a2d_cb_param_t *)(param); 621 | if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { 622 | Serial.printf("ESP_LOGI: BT_AV_TAG: a2dp disconnected\n"); 623 | s_a2d_state = APP_AV_STATE_UNCONNECTED; 624 | esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); 625 | } 626 | break; 627 | } 628 | case ESP_A2D_AUDIO_STATE_EVT: 629 | case ESP_A2D_AUDIO_CFG_EVT: 630 | case ESP_A2D_MEDIA_CTRL_ACK_EVT: 631 | case BT_APP_HEART_BEAT_EVT: 632 | break; 633 | default: 634 | Serial.printf("ESP_LOGE: BT_AV_TAG: In func: %s: unhandled evt %d\n", __func__, event); 635 | break; 636 | } 637 | } 638 | 639 | 640 | 641 | static int32_t bt_app_a2d_data_cb_static(uint8_t *data, int32_t len) 642 | { 643 | // Generates random numbers to provide static / white noise for forwarding to the output 644 | if (len < 0 || data == NULL) { 645 | Serial.printf("entered func: %s but no data to load\n", __func__); 646 | return 0; 647 | } 648 | 649 | // generate random sequence 650 | int val = rand() % (1 << 16); // restrict the number to a 16bit integer (ie max of 65536) 651 | for (int i = 0; i < (len >> 1); i++) { // len>>1==len/2 : data format is uint8_t, but SBC wants uint16_t, so you run the process once for every two bytes 652 | data[(i << 1)] = val & 0xff; // use bit mask to retain only the low byte // i<<1==i*2 : ie step 2 bytes for every value 653 | data[(i << 1) + 1] = (val >> 8) & 0xff; // bit shift to move the upper byte to the lower, then bit mask to retain only this part (ie mask out the old low byte) 654 | } 655 | 656 | return len; 657 | } 658 | 659 | 660 | uint16_t SBCVal=0; 661 | static int32_t bt_app_a2d_data_cb_increase(uint8_t *data, int32_t len) 662 | { 663 | // generates increasing value for forwarding to the output 664 | if (len < 0 || data == NULL) { 665 | Serial.printf("entered func: %s but no data to load\n", __func__); 666 | return 0; 667 | } 668 | 669 | for (int i = 0; i < (len >> 1); i++) { // len>>1==len/2 : data format is uint8_t, but SBC wants uint16_t, so you run the process once for every two bytes 670 | data[(i << 1)] = SBCVal & 0xff; // use bit mask to retain only the low byte // i<<1==i*2 : ie step 2 bytes for every value 671 | data[(i << 1) + 1] = (SBCVal >> 8) & 0xff; // bit shift to move the upper byte to the lower, then bit mask to retain only this part (ie mask out the old low byte) 672 | SBCVal = (SBCVal +1) % (1 << 16); // increment the value to continue the sequence (max val 65536) 673 | } 674 | 675 | return len; 676 | } 677 | 678 | 679 | static const int16_t sine_int16[] = { 680 | 32768, 34825, 36875, 38908, 40917, 42894, 44830, 46720, 48554, 50325, 681 | 52028, 53654, 55199, 56654, 58015, 59277, 60434, 61482, 62416, 63234, 682 | 63931, 64506, 64955, 65277, 65470, 65535, 65470, 65277, 64955, 64506, 683 | 63931, 63234, 62416, 61482, 60434, 59277, 58015, 56654, 55199, 53654, 684 | 52028, 50325, 48554, 46720, 44830, 42894, 40917, 38908, 36875, 34825, 685 | 32768, 30711, 28661, 26628, 24619, 22642, 20706, 18816, 16982, 15211, 686 | 13508, 11882, 10337, 8882, 7521, 6259, 5102, 4054, 3120, 2302, 687 | 1605, 1030, 581, 259, 66, 1, 66, 259, 581, 1030, 688 | 1605, 2302, 3120, 4054, 5102, 6259, 7521, 8882, 10337, 11882, 689 | 13508, 15211, 16982, 18816, 20706, 22642, 24619, 26628, 28661, 30711, 690 | }; 691 | int sineTableSize = sizeof(sine_int16); 692 | static int32_t bt_app_a2d_data_cb_sine(uint8_t *data, int32_t len) 693 | { 694 | // generates increasing value for forwarding to the output 695 | if (len < 0 || data == NULL) { 696 | Serial.printf("entered func: %s but no data to load\n", __func__); 697 | return 0; 698 | } 699 | 700 | // generate sine wave 701 | for (int i = 0; i < (len >> 1); i++) { 702 | data[(i << 1)] = sine_int16[sine_phase]; 703 | data[(i << 1) + 1] = sine_int16[sine_phase]; 704 | sine_phase = (sine_phase +1) % sineTableSize; 705 | } 706 | 707 | return len; 708 | } 709 | 710 | 711 | 712 | uint32_t modLoc=100; // Just a test, so guess a place to start which is hopefully past the header 713 | uint32_t modSize=sizeof(CURMOD); 714 | static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len) 715 | { 716 | // plays a mod from program memory 717 | if (len < 0 || data == NULL) { 718 | Serial.printf("entered func: %s but no data to load\n", __func__); 719 | return 0; 720 | } 721 | 722 | // use longer print statements only for testing: if you print too much it slows the Task and the watchdog may trigger 723 | Serial.printf("%d -> %d\n", modLoc, len); 724 | // Serial.printf("func: %s: Loaded data from %d to ", __func__, modLoc); 725 | 726 | int cycle=0; 727 | for (int i = 0; i < (len >> 1); i++) { 728 | data[(i << 1)] = CURMOD[modLoc]; 729 | data[(i << 1) + 1] = CURMOD[modLoc+1]; 730 | 731 | cycle++; 732 | if (cycle == 20) { 733 | modLoc = (modLoc + 2) % modSize; 734 | if (modLoc < 100) modLoc=100; 735 | cycle=0; 736 | } 737 | 738 | 739 | } 740 | // Serial.printf("to %d bytes of file (total size: %d)\n", modLoc, modSize); 741 | 742 | return len; 743 | } 744 | 745 | 746 | 747 | // data[(i << 1) + 1] = 0x00; // for 8bit data will have to be padded out 748 | // data[(i << 1)] = CURMOD[i] & 0xff; 749 | // data[(i << 1) + 1] = (CURMOD[i+1] >> 8) & 0xff; // bit shift to move the upper byte to the lower, then bit mask to retain only this part (ie mask out the old low byte) 750 | 751 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Port of the espresso ESP32 Bluetooth A2DP_Source to compile and log to Serial using Arduino 2 | https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/a2dp_source 3 |

4 | The following link is another modification of the espressif source (which I found after uploading this): 5 | https://github.com/markingle/a2dp_source 6 |

7 | 8 | Ideally this could be merged with a more complete library which includes decoding of other codecs, etc 9 |

10 | 11 | As it stands the code can often (see below) connect to my BNX-60 bluetooth headset and play white noise or one of a couple of other patterns as per the original example, but playing a proper audio file isn't yet implemented... 12 |

13 | 14 | Unfortunately I have found this can require multiple reboots of the ESP32 and/or BT headset before it will pair (although it seems stable once it does), so I may also try the Blue Kitchen btstack https://github.com/bluekitchen/btstack which has a port for ESP-32 and rumour has it might be better... 15 |

16 | 17 | BTW in case it's helpful the following script can be run in Microsoft Word to convert binary files (such as mods or wav files) into text format for use with progmem if using eg ESP8622Audio library 18 | https://github.com/earlephilhower/ESP8266Audio 19 | 20 | ``` 21 | Sub modsToText() 22 | curFilename = "C:\Users\dgm3333\Downloads\1_channel_moog.it" ' change this to your file name 23 | 24 | Dim intFileNum%, bytTemp As Byte, intCellRow% 25 | intFileNum = FreeFile 26 | intCellRow = 0 27 | Open curFilename For Binary Access Read As intFileNum 28 | linecount = 0 29 | Selection.TypeText ("const unsigned char converted_mod[] PROGMEM = {" & vbCrLf & " ") 30 | Do While Not EOF(intFileNum) 31 | Get intFileNum, , bytTemp 32 | 'Selection.End.Select 33 | a = Hex(bytTemp) 34 | If Len(a) = 1 Then a = "0" & a 35 | Selection.TypeText (" 0x" & a) 36 | If Not EOF(intFileNum) Then 37 | linecount = linecount + 1 38 | If linecount = 9 Then linecount = 0 39 | If linecount = 0 Then 40 | Selection.TypeText ("," & vbCrLf & " ") 41 | Else 42 | Selection.TypeText (",") 43 | End If 44 | End If 45 | Loop 46 | Selection.TypeText (vbCrLf & "};") 47 | 48 | Close intFileNum 49 | End Sub 50 | ``` 51 |

52 | 53 | 54 | -------------------------------------------------------------------------------- /bt_app_core.c: -------------------------------------------------------------------------------- 1 | /* 2 | This example code is in the Public Domain (or CC0 licensed, at your option.) 3 | 4 | Unless required by applicable law or agreed to in writing, this 5 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 6 | CONDITIONS OF ANY KIND, either express or implied. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include "freertos/xtensa_api.h" 13 | #include "freertos/FreeRTOSConfig.h" 14 | #include "freertos/FreeRTOS.h" 15 | #include "freertos/queue.h" 16 | #include "freertos/task.h" 17 | #include "esp_log.h" 18 | #include "bt_app_core.h" 19 | 20 | static void bt_app_task_handler(void *arg); 21 | static bool bt_app_send_msg(bt_app_msg_t *msg); 22 | static void bt_app_work_dispatched(bt_app_msg_t *msg); 23 | 24 | static xQueueHandle s_bt_app_task_queue = NULL; 25 | static xTaskHandle s_bt_app_task_handle = NULL; 26 | 27 | bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback) 28 | { 29 | ESP_LOGD(BT_APP_CORE_TAG, "%s event 0x%x, param len %d", __func__, event, param_len); 30 | 31 | bt_app_msg_t msg; 32 | memset(&msg, 0, sizeof(bt_app_msg_t)); 33 | 34 | msg.sig = BT_APP_SIG_WORK_DISPATCH; 35 | msg.event = event; 36 | msg.cb = p_cback; 37 | 38 | if (param_len == 0) { 39 | return bt_app_send_msg(&msg); 40 | } else if (p_params && param_len > 0) { 41 | if ((msg.param = malloc(param_len)) != NULL) { 42 | memcpy(msg.param, p_params, param_len); 43 | /* check if caller has provided a copy callback to do the deep copy */ 44 | if (p_copy_cback) { 45 | p_copy_cback(&msg, msg.param, p_params); 46 | } 47 | return bt_app_send_msg(&msg); 48 | } 49 | } 50 | 51 | return false; 52 | } 53 | 54 | static bool bt_app_send_msg(bt_app_msg_t *msg) 55 | { 56 | if (msg == NULL) { 57 | return false; 58 | } 59 | 60 | if (xQueueSend(s_bt_app_task_queue, msg, 10 / portTICK_RATE_MS) != pdTRUE) { 61 | ESP_LOGE(BT_APP_CORE_TAG, "%s xQueue send failed", __func__); 62 | return false; 63 | } 64 | return true; 65 | } 66 | 67 | static void bt_app_work_dispatched(bt_app_msg_t *msg) 68 | { 69 | if (msg->cb) { 70 | msg->cb(msg->event, msg->param); 71 | } 72 | } 73 | 74 | static void bt_app_task_handler(void *arg) 75 | { 76 | bt_app_msg_t msg; 77 | for (;;) { 78 | if (pdTRUE == xQueueReceive(s_bt_app_task_queue, &msg, (portTickType)portMAX_DELAY)) { 79 | ESP_LOGD(BT_APP_CORE_TAG, "%s, sig 0x%x, 0x%x", __func__, msg.sig, msg.event); 80 | switch (msg.sig) { 81 | case BT_APP_SIG_WORK_DISPATCH: 82 | bt_app_work_dispatched(&msg); 83 | break; 84 | default: 85 | ESP_LOGW(BT_APP_CORE_TAG, "%s, unhandled sig: %d", __func__, msg.sig); 86 | break; 87 | } // switch (msg.sig) 88 | 89 | if (msg.param) { 90 | free(msg.param); 91 | } 92 | } 93 | } 94 | } 95 | 96 | void bt_app_task_start_up(void) 97 | { 98 | s_bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t)); 99 | xTaskCreate(bt_app_task_handler, "BtAppT", 2048, NULL, configMAX_PRIORITIES - 3, &s_bt_app_task_handle); 100 | return; 101 | } 102 | 103 | void bt_app_task_shut_down(void) 104 | { 105 | if (s_bt_app_task_handle) { 106 | vTaskDelete(s_bt_app_task_handle); 107 | s_bt_app_task_handle = NULL; 108 | } 109 | if (s_bt_app_task_queue) { 110 | vQueueDelete(s_bt_app_task_queue); 111 | s_bt_app_task_queue = NULL; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /bt_app_core.h: -------------------------------------------------------------------------------- 1 | /* 2 | This example code is in the Public Domain (or CC0 licensed, at your option.) 3 | 4 | Unless required by applicable law or agreed to in writing, this 5 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 6 | CONDITIONS OF ANY KIND, either express or implied. 7 | */ 8 | 9 | #ifndef __BT_APP_CORE_H__ 10 | #define __BT_APP_CORE_H__ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #define BT_APP_CORE_TAG "BT_APP_CORE" 17 | 18 | #define BT_APP_SIG_WORK_DISPATCH (0x01) 19 | 20 | /** 21 | * @brief handler for the dispatched work 22 | */ 23 | typedef void (* bt_app_cb_t) (uint16_t event, void *param); 24 | 25 | /* message to be sent */ 26 | typedef struct { 27 | uint16_t sig; /*!< signal to bt_app_task */ 28 | uint16_t event; /*!< message event id */ 29 | bt_app_cb_t cb; /*!< context switch callback */ 30 | void *param; /*!< parameter area needs to be last */ 31 | } bt_app_msg_t; 32 | 33 | /** 34 | * @brief parameter deep-copy function to be customized 35 | */ 36 | typedef void (* bt_app_copy_cb_t) (bt_app_msg_t *msg, void *p_dest, void *p_src); 37 | 38 | /** 39 | * @brief work dispatcher for the application task 40 | */ 41 | bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback); 42 | 43 | void bt_app_task_start_up(void); 44 | 45 | void bt_app_task_shut_down(void); 46 | 47 | #endif /* __BT_APP_CORE_H__ */ 48 | -------------------------------------------------------------------------------- /one_channel_moog_mod.h: -------------------------------------------------------------------------------- 1 | const unsigned char one_channel_moog_mod[] PROGMEM = { 2 | 0x49, 0x4D, 0x50, 0x4D, 0x31, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x6E, 0x65, 3 | 0x6C, 0x20, 0x21, 0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x03, 0x00, 0x06, 0x00, 5 | 0x05, 0x00, 0x02, 0x00, 0x17, 0x02, 0x16, 0x02, 0x4D, 0x00, 0x07, 0x00, 6 | 0x80, 0x30, 0x0C, 0xB0, 0x80, 0x0C, 0xD5, 0x00, 0x01, 0x01, 0x00, 0x00, 7 | 0x38, 0x01, 0x00, 0x00, 0x20, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 8 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 9 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 10 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 11 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 12 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0x40, 0x40, 0x40, 0x40, 13 | 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 14 | 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 15 | 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 16 | 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 17 | 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 18 | 0x00, 0x01, 0xFF, 0xD6, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2A, 19 | 0x06, 0x00, 0x00, 0x54, 0x08, 0x00, 0x00, 0x7E, 0x0A, 0x00, 0x00, 0xA8, 20 | 0x0C, 0x00, 0x00, 0xD2, 0x0E, 0x00, 0x00, 0x22, 0x0F, 0x00, 0x00, 0x72, 21 | 0x0F, 0x00, 0x00, 0xC2, 0x0F, 0x00, 0x00, 0x12, 0x10, 0x00, 0x00, 0x62, 22 | 0x10, 0x00, 0x00, 0x15, 0x12, 0x00, 0x00, 0x01, 0x00, 0x0E, 0x35, 0x17, 23 | 0x06, 0x63, 0x00, 0x00, 0x00, 0x28, 0x63, 0x29, 0x4D, 0x61, 0x6E, 0x77, 24 | 0x65, 0x2F, 0x53, 0x61, 0x6E, 0x64, 0x53, 0x27, 0x32, 0x30, 0x30, 0x36, 25 | 0x0D, 0x6D, 0x61, 0x6E, 0x77, 0x65, 0x40, 0x64, 0x65, 0x6D, 0x6F, 0x73, 26 | 0x63, 0x65, 0x6E, 0x65, 0x2E, 0x72, 0x75, 0x0D, 0x77, 0x77, 0x77, 0x2E, 27 | 0x74, 0x68, 0x65, 0x73, 0x61, 0x6E, 0x64, 0x73, 0x2E, 0x72, 0x75, 0x0D, 28 | 0x4F, 0x6E, 0x6C, 0x79, 0x20, 0x31, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x6E, 29 | 0x65, 0x6C, 0x20, 0x75, 0x73, 0x65, 0x64, 0x21, 0x0D, 0x54, 0x72, 0x61, 30 | 0x63, 0x6B, 0x65, 0x64, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x42, 0x69, 0x67, 31 | 0x20, 0x43, 0x68, 0x69, 0x70, 0x20, 0x43, 0x6F, 0x6D, 0x70, 0x6F, 0x20, 32 | 0x23, 0x37, 0x2C, 0x0D, 0x69, 0x6E, 0x20, 0x34, 0x20, 0x6B, 0x62, 0x20, 33 | 0x6E, 0x6F, 0x6D, 0x69, 0x6E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x28, 34 | 0x34, 0x30, 0x39, 0x36, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x29, 0x2E, 35 | 0x0D, 0x54, 0x6F, 0x6F, 0x6B, 0x20, 0x32, 0x6E, 0x64, 0x20, 0x70, 0x6C, 36 | 0x61, 0x63, 0x65, 0x2E, 0x0D, 0x48, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 37 | 0x20, 0x65, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x76, 0x65, 38 | 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x62, 0x61, 0x73, 0x73, 0x20, 39 | 0x61, 0x6E, 0x64, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x20, 0x70, 40 | 0x61, 0x74, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, 41 | 0x2E, 0x00, 0x49, 0x4D, 0x50, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0x90, 0x01, 0x58, 0xA8, 0x28, 0x63, 44 | 0x29, 0x20, 0x4D, 0x61, 0x6E, 0x77, 0x65, 0x2F, 0x53, 0x61, 0x6E, 0x64, 45 | 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 46 | 0xD7, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x31, 0x01, 0x32, 0x01, 47 | 0x33, 0x01, 0x34, 0x01, 0x35, 0x01, 0x36, 0x01, 0x37, 0x01, 0x38, 0x01, 48 | 0x39, 0x01, 0x3A, 0x01, 0x3B, 0x01, 0x3C, 0x01, 0x3D, 0x01, 0x3E, 0x01, 49 | 0x3F, 0x01, 0x40, 0x01, 0x41, 0x01, 0x42, 0x01, 0x43, 0x01, 0x44, 0x01, 50 | 0x45, 0x01, 0x46, 0x01, 0x47, 0x01, 0x48, 0x01, 0x49, 0x01, 0x4A, 0x01, 51 | 0x4B, 0x01, 0x4C, 0x01, 0x4D, 0x01, 0x4E, 0x01, 0x4F, 0x01, 0x50, 0x01, 52 | 0x51, 0x01, 0x52, 0x01, 0x53, 0x01, 0x30, 0x02, 0x31, 0x02, 0x32, 0x02, 53 | 0x33, 0x02, 0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 0x37, 0x02, 0x38, 0x02, 54 | 0x39, 0x02, 0x3A, 0x02, 0x3B, 0x02, 0x3C, 0x02, 0x3D, 0x02, 0x3E, 0x02, 55 | 0x3F, 0x02, 0x40, 0x02, 0x41, 0x02, 0x42, 0x02, 0x43, 0x02, 0x44, 0x02, 56 | 0x45, 0x02, 0x46, 0x02, 0x47, 0x02, 0x48, 0x02, 0x49, 0x02, 0x4A, 0x02, 57 | 0x4B, 0x02, 0x4C, 0x02, 0x4D, 0x02, 0x4E, 0x02, 0x4F, 0x02, 0x50, 0x02, 58 | 0x51, 0x02, 0x52, 0x02, 0x53, 0x02, 0x30, 0x03, 0x31, 0x03, 0x32, 0x03, 59 | 0x33, 0x03, 0x34, 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, 0x03, 0x38, 0x03, 60 | 0x39, 0x03, 0x3A, 0x03, 0x3B, 0x03, 0x3C, 0x03, 0x3D, 0x03, 0x3E, 0x03, 61 | 0x3F, 0x03, 0x40, 0x03, 0x41, 0x03, 0x42, 0x03, 0x43, 0x03, 0x44, 0x03, 62 | 0x45, 0x03, 0x46, 0x03, 0x47, 0x03, 0x48, 0x03, 0x49, 0x03, 0x4A, 0x03, 63 | 0x4B, 0x03, 0x4C, 0x03, 0x4D, 0x03, 0x4E, 0x03, 0x4F, 0x03, 0x50, 0x03, 64 | 0x51, 0x03, 0x52, 0x03, 0x53, 0x03, 0x6C, 0x03, 0x6D, 0x03, 0x6E, 0x03, 65 | 0x6F, 0x03, 0x70, 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, 0x03, 0x74, 0x03, 66 | 0x75, 0x03, 0x76, 0x03, 0x77, 0x03, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 67 | 0x28, 0x00, 0x00, 0x28, 0x03, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x11, 0x00, 68 | 0x18, 0x12, 0x00, 0x18, 0x13, 0x00, 0x00, 0x17, 0x00, 0x10, 0x18, 0x00, 69 | 0x10, 0x19, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x23, 0x00, 0x0C, 0x24, 0x00, 70 | 0x0C, 0x25, 0x00, 0x00, 0x27, 0x00, 0x00, 0x2F, 0x00, 0x06, 0x30, 0x00, 71 | 0x00, 0x32, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 74 | 0x00, 0xF7, 0x11, 0x00, 0x0E, 0x12, 0x00, 0x0E, 0x17, 0x00, 0xEC, 0x18, 75 | 0x00, 0xEC, 0x22, 0x00, 0x18, 0x23, 0x00, 0x18, 0x2E, 0x00, 0x00, 0x2F, 76 | 0x00, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 77 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 78 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 79 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 80 | 0x00, 0xD4, 0x8B, 0x03, 0x00, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x20, 81 | 0x8E, 0x00, 0x08, 0x28, 0x01, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 82 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 83 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 84 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 85 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 86 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 87 | 0x00, 0x00, 0x15, 0x16, 0x49, 0x4D, 0x50, 0x49, 0x00, 0x00, 0x00, 0x00, 88 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 89 | 0x00, 0x00, 0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0x90, 0x01, 0x58, 0xA8, 90 | 0x77, 0x77, 0x77, 0x2E, 0x74, 0x68, 0x65, 0x73, 0x61, 0x6E, 0x64, 0x73, 91 | 0x2E, 0x72, 0x75, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 92 | 0x20, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x04, 93 | 0x02, 0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, 94 | 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, 0x0C, 0x04, 0x0D, 0x04, 95 | 0x0E, 0x04, 0x0F, 0x04, 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, 96 | 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, 0x18, 0x04, 0x19, 0x04, 97 | 0x1A, 0x04, 0x1B, 0x04, 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04, 98 | 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, 0x24, 0x04, 0x25, 0x04, 99 | 0x26, 0x04, 0x27, 0x04, 0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, 100 | 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04, 0x30, 0x04, 0x31, 0x04, 101 | 0x32, 0x04, 0x33, 0x04, 0x34, 0x04, 0x35, 0x04, 0x36, 0x04, 0x37, 0x04, 102 | 0x38, 0x04, 0x39, 0x04, 0x3A, 0x04, 0x3B, 0x04, 0x3C, 0x04, 0x3D, 0x04, 103 | 0x3E, 0x04, 0x3F, 0x04, 0x40, 0x04, 0x41, 0x04, 0x42, 0x04, 0x43, 0x04, 104 | 0x44, 0x04, 0x45, 0x04, 0x46, 0x04, 0x47, 0x04, 0x48, 0x04, 0x49, 0x04, 105 | 0x4A, 0x04, 0x4B, 0x04, 0x4C, 0x04, 0x4D, 0x04, 0x4E, 0x04, 0x4F, 0x04, 106 | 0x50, 0x04, 0x51, 0x04, 0x52, 0x04, 0x53, 0x04, 0x54, 0x04, 0x55, 0x04, 107 | 0x56, 0x04, 0x57, 0x04, 0x58, 0x04, 0x59, 0x04, 0x5A, 0x04, 0x5B, 0x04, 108 | 0x5C, 0x04, 0x5D, 0x04, 0x5E, 0x04, 0x5F, 0x04, 0x60, 0x04, 0x61, 0x04, 109 | 0x62, 0x04, 0x63, 0x04, 0x64, 0x04, 0x65, 0x04, 0x66, 0x04, 0x67, 0x04, 110 | 0x68, 0x04, 0x69, 0x04, 0x6A, 0x04, 0x6B, 0x04, 0x6C, 0x04, 0x6D, 0x04, 111 | 0x6E, 0x04, 0x6F, 0x04, 0x70, 0x04, 0x71, 0x04, 0x72, 0x04, 0x73, 0x04, 112 | 0x74, 0x04, 0x75, 0x04, 0x76, 0x04, 0x77, 0x04, 0x01, 0x05, 0x00, 0x00, 113 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x03, 0x00, 0x40, 114 | 0x6C, 0x01, 0x00, 0x7D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 115 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 118 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 120 | 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 121 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 122 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 123 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 124 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 125 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 126 | 0xE0, 0x00, 0x00, 0xD4, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 | 0x00, 0x00, 0x02, 0x00, 0x06, 0x03, 0x00, 0x06, 0x0E, 0x00, 0x0A, 0x0F, 128 | 0x00, 0x0A, 0x1A, 0x00, 0x0E, 0x1B, 0x00, 0x0E, 0x62, 0x00, 0x18, 0x63, 129 | 0x00, 0x18, 0x7B, 0x00, 0x0E, 0x7C, 0x00, 0x0E, 0xC3, 0x00, 0x06, 0xC4, 130 | 0x00, 0x06, 0xCF, 0x00, 0x0A, 0xD0, 0x00, 0x0A, 0xDB, 0x00, 0x14, 0xDC, 131 | 0x00, 0x14, 0x0B, 0x01, 0x12, 0x0C, 0x01, 0x12, 0x3B, 0x01, 0x0A, 0x3C, 132 | 0x01, 0x0A, 0x53, 0x01, 0x0E, 0x54, 0x01, 0xE0, 0x00, 0x00, 0xE0, 0x00, 133 | 0x00, 0x00, 0x00, 0x00, 0x15, 0x16, 0x49, 0x4D, 0x50, 0x49, 0x00, 0x00, 134 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 135 | 0x00, 0x00, 0x00, 0x00, 0x10, 0x58, 0x80, 0xA0, 0x00, 0x0C, 0x90, 0x01, 136 | 0x58, 0xA8, 0x4F, 0x6E, 0x6C, 0x79, 0x20, 0x6F, 0x6E, 0x65, 0x20, 0x63, 137 | 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x20, 0x75, 0x73, 0x65, 0x64, 0x2C, 138 | 0x20, 0x20, 0x20, 0x00, 0xC5, 0xF8, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x02, 139 | 0x01, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, 0x02, 0x05, 0x02, 0x06, 0x02, 140 | 0x07, 0x02, 0x08, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x0B, 0x02, 0x0C, 0x02, 141 | 0x0D, 0x02, 0x0E, 0x02, 0x0F, 0x02, 0x10, 0x02, 0x11, 0x02, 0x12, 0x02, 142 | 0x13, 0x02, 0x14, 0x02, 0x15, 0x02, 0x16, 0x02, 0x17, 0x02, 0x18, 0x02, 143 | 0x19, 0x02, 0x1A, 0x02, 0x1B, 0x02, 0x1C, 0x02, 0x1D, 0x02, 0x1E, 0x02, 144 | 0x1F, 0x02, 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x23, 0x02, 0x24, 0x02, 145 | 0x25, 0x02, 0x26, 0x02, 0x27, 0x02, 0x28, 0x02, 0x29, 0x02, 0x2A, 0x02, 146 | 0x2B, 0x02, 0x2C, 0x02, 0x2D, 0x02, 0x2E, 0x02, 0x2F, 0x02, 0x30, 0x02, 147 | 0x31, 0x02, 0x32, 0x02, 0x33, 0x02, 0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 148 | 0x37, 0x02, 0x38, 0x02, 0x39, 0x02, 0x3A, 0x02, 0x3B, 0x02, 0x3C, 0x02, 149 | 0x3D, 0x02, 0x3E, 0x02, 0x3F, 0x02, 0x40, 0x02, 0x41, 0x02, 0x42, 0x02, 150 | 0x43, 0x02, 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x47, 0x02, 0x48, 0x02, 151 | 0x49, 0x02, 0x4A, 0x02, 0x4B, 0x02, 0x4C, 0x02, 0x4D, 0x02, 0x4E, 0x02, 152 | 0x4F, 0x02, 0x50, 0x02, 0x51, 0x02, 0x52, 0x02, 0x53, 0x02, 0x54, 0x02, 153 | 0x55, 0x02, 0x56, 0x02, 0x57, 0x02, 0x58, 0x02, 0x59, 0x02, 0x5A, 0x02, 154 | 0x5B, 0x02, 0x5C, 0x02, 0x5D, 0x02, 0x5E, 0x02, 0x5F, 0x02, 0x60, 0x02, 155 | 0x61, 0x02, 0x62, 0x02, 0x63, 0x02, 0x64, 0x02, 0x65, 0x02, 0x66, 0x02, 156 | 0x67, 0x02, 0x68, 0x02, 0x69, 0x02, 0x6A, 0x02, 0x6B, 0x02, 0x6C, 0x02, 157 | 0x6D, 0x02, 0x6E, 0x02, 0x6F, 0x02, 0x70, 0x02, 0x71, 0x02, 0x72, 0x02, 158 | 0x73, 0x02, 0x74, 0x02, 0x75, 0x02, 0x76, 0x02, 0x77, 0x02, 0x01, 0x06, 159 | 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x25, 0x00, 0x0F, 0x70, 160 | 0x01, 0x0F, 0x1A, 0x04, 0x0C, 0x77, 0x04, 0x00, 0xB0, 0x04, 0x00, 0x00, 161 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 162 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 163 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 165 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0xE0, 0x00, 0x00, 0xE0, 167 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 168 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 169 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 170 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 171 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 172 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xD4, 0x83, 0x04, 0x00, 0x03, 0x00, 0x00, 173 | 0x00, 0x00, 0x00, 0xEE, 0x15, 0x00, 0x11, 0x3F, 0x00, 0x00, 0x64, 0x00, 174 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 175 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 176 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 177 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 178 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 179 | 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x16, 0x49, 0x4D, 0x50, 0x49, 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 181 | 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 182 | 0x90, 0x01, 0x58, 0xA8, 0x6C, 0x6F, 0x6F, 0x6B, 0x20, 0x69, 0x6E, 0x73, 183 | 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6D, 0x6F, 0x64, 0x75, 184 | 0x6C, 0x65, 0x2E, 0x20, 0x20, 0x00, 0xDD, 0x96, 0x00, 0x00, 0x00, 0x00, 185 | 0x00, 0x05, 0x01, 0x05, 0x02, 0x05, 0x03, 0x05, 0x04, 0x05, 0x05, 0x05, 186 | 0x06, 0x05, 0x07, 0x05, 0x08, 0x05, 0x09, 0x05, 0x0A, 0x05, 0x0B, 0x05, 187 | 0x0C, 0x05, 0x0D, 0x05, 0x0E, 0x05, 0x0F, 0x05, 0x10, 0x05, 0x11, 0x05, 188 | 0x12, 0x05, 0x13, 0x05, 0x14, 0x05, 0x15, 0x05, 0x16, 0x05, 0x17, 0x05, 189 | 0x18, 0x05, 0x19, 0x05, 0x1A, 0x05, 0x1B, 0x05, 0x1C, 0x05, 0x1D, 0x05, 190 | 0x1E, 0x05, 0x1F, 0x05, 0x20, 0x05, 0x21, 0x05, 0x22, 0x05, 0x23, 0x05, 191 | 0x24, 0x05, 0x25, 0x05, 0x26, 0x05, 0x27, 0x05, 0x28, 0x05, 0x29, 0x05, 192 | 0x2A, 0x05, 0x2B, 0x05, 0x2C, 0x05, 0x2D, 0x05, 0x2E, 0x05, 0x2F, 0x05, 193 | 0x30, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, 0x34, 0x05, 0x35, 0x05, 194 | 0x36, 0x05, 0x37, 0x05, 0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, 195 | 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05, 0x40, 0x05, 0x41, 0x05, 196 | 0x42, 0x05, 0x43, 0x05, 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, 197 | 0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, 0x4C, 0x05, 0x4D, 0x05, 198 | 0x4E, 0x05, 0x4F, 0x05, 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, 199 | 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0x57, 0x05, 0x58, 0x05, 0x59, 0x05, 200 | 0x5A, 0x05, 0x5B, 0x05, 0x5C, 0x05, 0x5D, 0x05, 0x5E, 0x05, 0x5F, 0x05, 201 | 0x60, 0x05, 0x61, 0x05, 0x62, 0x05, 0x63, 0x05, 0x64, 0x05, 0x65, 0x05, 202 | 0x66, 0x05, 0x67, 0x05, 0x68, 0x05, 0x69, 0x05, 0x6A, 0x05, 0x6B, 0x05, 203 | 0x6C, 0x05, 0x6D, 0x05, 0x6E, 0x05, 0x6F, 0x05, 0x70, 0x05, 0x71, 0x05, 204 | 0x72, 0x05, 0x73, 0x05, 0x74, 0x05, 0x75, 0x05, 0x76, 0x05, 0x77, 0x05, 205 | 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 206 | 0x40, 0x02, 0x00, 0x36, 0x05, 0x00, 0x11, 0x07, 0x00, 0x00, 0x09, 0x00, 207 | 0x00, 0x19, 0x00, 0x40, 0x14, 0x00, 0x02, 0x15, 0x00, 0x00, 0x00, 0x00, 208 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 209 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 210 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 211 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 212 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0xE0, 0x00, 213 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 214 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 215 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 216 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 217 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 218 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xD4, 0x00, 0x02, 0x01, 0x02, 219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x31, 0x00, 0x18, 220 | 0x32, 0x00, 0x18, 0x45, 0x00, 0xE8, 0x46, 0x00, 0xE8, 0x62, 0x00, 0xFA, 221 | 0x62, 0x00, 0xFA, 0x62, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 222 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 223 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 224 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 225 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x16, 0x49, 0x4D, 226 | 0x50, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 227 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xA0, 228 | 0x00, 0x00, 0x90, 0x01, 0x58, 0xA8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 229 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 230 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 231 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 232 | 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 233 | 0x0B, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, 0x00, 0x10, 0x00, 234 | 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 235 | 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1A, 0x00, 0x1B, 0x00, 0x1C, 0x00, 236 | 0x1D, 0x00, 0x1E, 0x00, 0x1F, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 237 | 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 238 | 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 239 | 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 240 | 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 241 | 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 242 | 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 243 | 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 244 | 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 245 | 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 246 | 0x59, 0x00, 0x5A, 0x00, 0x5B, 0x00, 0x5C, 0x00, 0x5D, 0x00, 0x5E, 0x00, 247 | 0x5F, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 248 | 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 249 | 0x6B, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6E, 0x00, 0x6F, 0x00, 0x70, 0x00, 250 | 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 251 | 0x77, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 252 | 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 253 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 254 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 255 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 256 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 257 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 258 | 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 259 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 260 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 261 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 262 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 263 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 264 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xD4, 0x00, 0x02, 265 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0xE0, 0x00, 266 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 267 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 268 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 269 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 270 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 271 | 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x16, 272 | 0x49, 0x4D, 0x50, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 273 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 274 | 0x00, 0x80, 0x00, 0x00, 0x90, 0x01, 0x58, 0xA8, 0x20, 0x20, 0x20, 0x20, 275 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 276 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 277 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 278 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 279 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 280 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 281 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 282 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 283 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 284 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 285 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 286 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 287 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 288 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 289 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 290 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 291 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 292 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 293 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 294 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 295 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 296 | 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 297 | 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 298 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 299 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 300 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 301 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 302 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 303 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 304 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 305 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 306 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 307 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 308 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 309 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 310 | 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xD4, 311 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 312 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 313 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 314 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 315 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 316 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 317 | 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 318 | 0x15, 0x16, 0x49, 0x4D, 0x50, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 319 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x19, 0x20, 0x28, 0x63, 320 | 0x29, 0x20, 0x4D, 0x61, 0x6E, 0x77, 0x65, 0x2F, 0x53, 0x61, 0x6E, 0x64, 321 | 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 322 | 0x05, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 323 | 0x00, 0x00, 0x76, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 324 | 0x00, 0x00, 0xC6, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4D, 325 | 0x50, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 326 | 0x00, 0x00, 0x00, 0x30, 0x19, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x74, 0x68, 327 | 0x65, 0x73, 0x61, 0x6E, 0x64, 0x73, 0x2E, 0x72, 0x75, 0x20, 0x20, 0x20, 328 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x05, 0x00, 0x60, 0x00, 329 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x76, 0x18, 330 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x15, 331 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4D, 0x50, 0x53, 0x00, 0x00, 332 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 333 | 0x19, 0x20, 0x4F, 0x6E, 0x6C, 0x79, 0x20, 0x6F, 0x6E, 0x65, 0x20, 0x63, 334 | 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x20, 0x75, 0x73, 0x65, 0x64, 0x2C, 335 | 0x20, 0x20, 0x20, 0x00, 0x05, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 336 | 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x76, 0x18, 0x00, 0x00, 0x00, 0x00, 337 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x15, 0x00, 0x00, 0x00, 0x00, 338 | 0x00, 0x00, 0x49, 0x4D, 0x50, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 339 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x19, 0x40, 0x6C, 0x6F, 340 | 0x6F, 0x6B, 0x20, 0x69, 0x6E, 0x73, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, 341 | 0x65, 0x20, 0x6D, 0x6F, 0x64, 0x75, 0x6C, 0x65, 0x2E, 0x20, 0x20, 0x00, 342 | 0x05, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 343 | 0x00, 0x00, 0xD8, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 344 | 0x00, 0x00, 0xA4, 0x15, 0x00, 0x00, 0x15, 0x16, 0x50, 0x00, 0x49, 0x4D, 345 | 0x50, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 346 | 0x00, 0x00, 0x00, 0x30, 0x19, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 347 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 348 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x05, 0x00, 0xA9, 0x00, 349 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x00, 0x00, 0x00, 0x44, 0xAC, 350 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x15, 351 | 0x00, 0x00, 0x15, 0x16, 0x50, 0x00, 0xAB, 0x01, 0x60, 0x00, 0x00, 0x00, 352 | 0x00, 0x00, 0x81, 0x03, 0x54, 0x03, 0x00, 0x81, 0x21, 0x57, 0x00, 0x01, 353 | 0x5B, 0x00, 0x01, 0x5E, 0x00, 0x81, 0x0B, 0x54, 0x01, 0x01, 0x0C, 0x00, 354 | 0x81, 0x21, 0x60, 0x00, 0x81, 0x29, 0x0C, 0x13, 0xB0, 0x00, 0x81, 0x21, 355 | 0x30, 0x00, 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x01, 0x60, 0x00, 0x81, 356 | 0x29, 0x0F, 0x01, 0x06, 0x00, 0x81, 0x25, 0x2E, 0x20, 0x00, 0x81, 0x29, 357 | 0x54, 0x01, 0x0C, 0x00, 0x01, 0x60, 0x13, 0xB2, 0x00, 0x81, 0x21, 0x0C, 358 | 0x00, 0x01, 0x30, 0x00, 0x01, 0x18, 0x00, 0x81, 0x29, 0x00, 0x01, 0x09, 359 | 0x00, 0x81, 0x0F, 0x48, 0x02, 0x10, 0x01, 0x03, 0x00, 0x81, 0x0B, 0x60, 360 | 0x01, 0x01, 0x0C, 0x00, 0x81, 0x29, 0x0F, 0x01, 0x06, 0x00, 0x81, 0x2D, 361 | 0x2E, 0x20, 0x01, 0x03, 0x00, 0x81, 0x0F, 0x48, 0x02, 0x05, 0x13, 0xD1, 362 | 0x00, 0x81, 0x0B, 0x54, 0x01, 0x01, 0x0C, 0x00, 0x81, 0x21, 0x60, 0x00, 363 | 0x81, 0x29, 0x0C, 0x13, 0xB0, 0x00, 0x81, 0x21, 0x30, 0x00, 0x01, 0x18, 364 | 0x00, 0x01, 0x00, 0x00, 0x01, 0x60, 0x00, 0x81, 0x29, 0x0F, 0x01, 0x06, 365 | 0x00, 0x81, 0x25, 0x2E, 0x20, 0x00, 0x81, 0x29, 0x54, 0x01, 0x0C, 0x00, 366 | 0x01, 0x60, 0x13, 0xB2, 0x00, 0x81, 0x21, 0x0C, 0x00, 0x01, 0x30, 0x00, 367 | 0x01, 0x18, 0x00, 0x01, 0x60, 0x00, 0x01, 0x00, 0x00, 0x81, 0x29, 0x0F, 368 | 0x01, 0x06, 0x00, 0x81, 0x69, 0x2E, 0x13, 0xB0, 0x00, 0x81, 0x29, 0x54, 369 | 0x01, 0x0C, 0x00, 0x81, 0x21, 0x60, 0x00, 0x01, 0x0C, 0x00, 0x01, 0x30, 370 | 0x00, 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x81, 0x29, 0x60, 0x01, 0x06, 371 | 0x00, 0x00, 0x01, 0x0F, 0x13, 0xB2, 0x00, 0x81, 0x61, 0x2E, 0x00, 0x81, 372 | 0x29, 0x54, 0x01, 0x0C, 0x00, 0x81, 0x21, 0x60, 0x00, 0x01, 0x0C, 0x00, 373 | 0x01, 0x30, 0x00, 0x01, 0x18, 0x00, 0x81, 0x29, 0x00, 0x01, 0x09, 0x00, 374 | 0x81, 0x0F, 0x3F, 0x02, 0x14, 0x01, 0x03, 0x00, 0x81, 0x03, 0x63, 0x01, 375 | 0x00, 0x01, 0x57, 0x03, 0x00, 0x81, 0x21, 0x5A, 0x00, 0x01, 0x5E, 0x00, 376 | 0x81, 0x03, 0x12, 0x01, 0x00, 0x01, 0x61, 0x03, 0x00, 0x81, 0x07, 0x31, 377 | 0x01, 0x20, 0x00, 0x81, 0x87, 0x3F, 0x02, 0x07, 0x00, 0x81, 0x0B, 0x57, 378 | 0x01, 0x01, 0x0C, 0x00, 0x81, 0x21, 0x63, 0x00, 0x81, 0x29, 0x0F, 0x13, 379 | 0xB0, 0x00, 0x81, 0x21, 0x33, 0x00, 0x01, 0x1B, 0x00, 0x01, 0x03, 0x00, 380 | 0x01, 0x63, 0x00, 0x81, 0x29, 0x12, 0x01, 0x06, 0x00, 0x81, 0x25, 0x31, 381 | 0x20, 0x00, 0x81, 0x29, 0x57, 0x01, 0x0C, 0x00, 0x01, 0x63, 0x13, 0xB2, 382 | 0x00, 0x81, 0x21, 0x0F, 0x00, 0x01, 0x33, 0x00, 0x01, 0x1B, 0x00, 0x01, 383 | 0x63, 0x00, 0x01, 0x03, 0x00, 0x81, 0x29, 0x12, 0x01, 0x06, 0x00, 0x81, 384 | 0x69, 0x31, 0x13, 0xB0, 0x00, 0x81, 0x29, 0x57, 0x01, 0x0C, 0x00, 0x81, 385 | 0x21, 0x63, 0x00, 0x01, 0x0F, 0x00, 0x01, 0x33, 0x00, 0x01, 0x1B, 0x00, 386 | 0x01, 0x03, 0x00, 0x81, 0x29, 0x63, 0x01, 0x06, 0x00, 0x00, 0x01, 0x12, 387 | 0x13, 0xB7, 0x00, 0x81, 0x08, 0x01, 0x01, 0x00, 0x00, 0xA9, 0x02, 0x80, 388 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x03, 0x54, 0x03, 0x00, 0x81, 0x21, 389 | 0x57, 0x00, 0x01, 0x5B, 0x00, 0x01, 0x5E, 0x00, 0x81, 0x0B, 0x54, 0x01, 390 | 0x01, 0x0C, 0x00, 0x81, 0x21, 0x60, 0x00, 0x81, 0x29, 0x0C, 0x13, 0xB0, 391 | 0x00, 0x81, 0x21, 0x30, 0x00, 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x01, 392 | 0x60, 0x00, 0x81, 0x29, 0x0F, 0x01, 0x06, 0x00, 0x81, 0x25, 0x2E, 0x20, 393 | 0x00, 0x81, 0x29, 0x54, 0x01, 0x0C, 0x00, 0x01, 0x60, 0x13, 0xB2, 0x00, 394 | 0x81, 0x21, 0x0C, 0x00, 0x01, 0x30, 0x00, 0x01, 0x18, 0x00, 0x81, 0x29, 395 | 0x00, 0x01, 0x09, 0x00, 0x81, 0x0F, 0x48, 0x02, 0x10, 0x01, 0x03, 0x00, 396 | 0x81, 0x0B, 0x60, 0x01, 0x01, 0x0C, 0x00, 0x81, 0x29, 0x0F, 0x01, 0x06, 397 | 0x00, 0x81, 0x2D, 0x2E, 0x20, 0x01, 0x03, 0x00, 0x81, 0x0F, 0x48, 0x02, 398 | 0x05, 0x13, 0xD1, 0x00, 0x81, 0x0B, 0x54, 0x01, 0x01, 0x0C, 0x00, 0x81, 399 | 0x21, 0x60, 0x00, 0x81, 0x29, 0x0C, 0x13, 0xB0, 0x00, 0x81, 0x21, 0x30, 400 | 0x00, 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x01, 0x60, 0x00, 0x81, 0x29, 401 | 0x0F, 0x01, 0x06, 0x00, 0x81, 0x25, 0x2E, 0x20, 0x00, 0x81, 0x29, 0x54, 402 | 0x01, 0x0C, 0x00, 0x01, 0x60, 0x13, 0xB2, 0x00, 0x81, 0x21, 0x0C, 0x00, 403 | 0x01, 0x30, 0x00, 0x01, 0x18, 0x00, 0x01, 0x60, 0x00, 0x81, 0x29, 0x00, 404 | 0x01, 0x09, 0x00, 0x81, 0x0B, 0x27, 0x04, 0x01, 0x03, 0x00, 0x01, 0x0F, 405 | 0x01, 0x01, 0x06, 0x00, 0x81, 0x69, 0x2E, 0x01, 0x03, 0x00, 0x81, 0x0B, 406 | 0x24, 0x04, 0x13, 0xB0, 0x00, 0x01, 0x54, 0x01, 0x01, 0x0C, 0x00, 0x81, 407 | 0x29, 0x60, 0x01, 0x09, 0x00, 0x81, 0x0B, 0x24, 0x04, 0x01, 0x03, 0x00, 408 | 0x01, 0x0C, 0x01, 0x01, 0x0C, 0x00, 0x81, 0x29, 0x30, 0x01, 0x09, 0x00, 409 | 0x81, 0x1A, 0x04, 0x01, 0x03, 0x00, 0x81, 0x0B, 0x18, 0x01, 0x01, 0x0C, 410 | 0x00, 0x81, 0x21, 0x00, 0x00, 0x81, 0x29, 0x60, 0x01, 0x09, 0x00, 0x81, 411 | 0x0B, 0x22, 0x04, 0x01, 0x03, 0x00, 0x81, 0x03, 0x0F, 0x01, 0x00, 0x00, 412 | 0x81, 0x69, 0x2E, 0x13, 0xB2, 0x00, 0x81, 0x03, 0x24, 0x04, 0x00, 0x81, 413 | 0x0B, 0x54, 0x01, 0x01, 0x0C, 0x00, 0x81, 0x29, 0x60, 0x01, 0x09, 0x00, 414 | 0x81, 0x0B, 0x24, 0x04, 0x01, 0x03, 0x00, 0x01, 0x0C, 0x01, 0x01, 0x0C, 415 | 0x00, 0x81, 0x21, 0x30, 0x00, 0x01, 0x18, 0x00, 0x81, 0x29, 0x00, 0x01, 416 | 0x09, 0x00, 0x81, 0x0F, 0x3F, 0x02, 0x14, 0x01, 0x03, 0x00, 0x81, 0x03, 417 | 0x63, 0x01, 0x00, 0x01, 0x57, 0x03, 0x00, 0x81, 0x21, 0x5A, 0x00, 0x01, 418 | 0x5E, 0x00, 0x81, 0x03, 0x12, 0x01, 0x00, 0x01, 0x61, 0x03, 0x00, 0x81, 419 | 0x07, 0x31, 0x01, 0x20, 0x00, 0x81, 0x0B, 0x27, 0x04, 0x01, 0x01, 0x00, 420 | 0x81, 0x0F, 0x3F, 0x02, 0x07, 0x01, 0x02, 0x00, 0x81, 0x0B, 0x57, 0x01, 421 | 0x01, 0x0C, 0x00, 0x81, 0x29, 0x63, 0x01, 0x09, 0x00, 0x81, 0x0B, 0x27, 422 | 0x04, 0x01, 0x03, 0x00, 0x01, 0x0F, 0x01, 0x13, 0xB0, 0x00, 0x81, 0x08, 423 | 0x01, 0x09, 0x00, 0x81, 0x21, 0x33, 0x00, 0x81, 0x1A, 0x04, 0x01, 0x03, 424 | 0x00, 0x81, 0x0B, 0x1B, 0x01, 0x01, 0x0C, 0x00, 0x81, 0x29, 0x03, 0x01, 425 | 0x09, 0x00, 0x81, 0x0B, 0x2C, 0x04, 0x01, 0x03, 0x00, 0x01, 0x63, 0x01, 426 | 0x01, 0x0C, 0x00, 0x81, 0x29, 0x12, 0x01, 0x06, 0x00, 0x81, 0x25, 0x31, 427 | 0x20, 0x00, 0x81, 0x29, 0x57, 0x01, 0x0C, 0x00, 0x01, 0x63, 0x01, 0x06, 428 | 0x00, 0x81, 0x08, 0x01, 0x03, 0x00, 0x81, 0x0B, 0x27, 0x04, 0x13, 0xB2, 429 | 0x00, 0x01, 0x0F, 0x01, 0x01, 0x0C, 0x00, 0x81, 0x29, 0x33, 0x01, 0x09, 430 | 0x00, 0x81, 0x1A, 0x04, 0x01, 0x03, 0x00, 0x81, 0x0B, 0x1B, 0x01, 0x01, 431 | 0x0C, 0x00, 0x81, 0x21, 0x63, 0x00, 0x81, 0x29, 0x03, 0x01, 0x09, 0x00, 432 | 0x81, 0x0B, 0x2A, 0x04, 0x01, 0x03, 0x00, 0x01, 0x12, 0x01, 0x01, 0x06, 433 | 0x00, 0x81, 0x69, 0x31, 0x01, 0x03, 0x00, 0x81, 0x0B, 0x27, 0x04, 0x13, 434 | 0xB0, 0x00, 0x01, 0x57, 0x01, 0x01, 0x0C, 0x00, 0x81, 0x29, 0x63, 0x01, 435 | 0x09, 0x00, 0x81, 0x0B, 0x27, 0x04, 0x01, 0x03, 0x00, 0x01, 0x0F, 0x01, 436 | 0x01, 0x0C, 0x00, 0x81, 0x29, 0x33, 0x01, 0x09, 0x00, 0x81, 0x1A, 0x04, 437 | 0x01, 0x03, 0x00, 0x81, 0x0B, 0x1B, 0x01, 0x01, 0x0C, 0x00, 0x81, 0x21, 438 | 0x03, 0x00, 0x81, 0x29, 0x63, 0x01, 0x09, 0x00, 0x81, 0x0B, 0x25, 0x04, 439 | 0x01, 0x03, 0x00, 0x81, 0x03, 0x12, 0x01, 0x00, 0x00, 0x81, 0x69, 0x31, 440 | 0x13, 0xB3, 0x00, 0x81, 0x03, 0x27, 0x04, 0x00, 0x81, 0x0B, 0x57, 0x01, 441 | 0x01, 0x0C, 0x00, 0x81, 0x29, 0x63, 0x13, 0xB0, 0x00, 0x81, 0x21, 0x0F, 442 | 0x00, 0x01, 0x33, 0x00, 0x01, 0x1B, 0x00, 0x01, 0x03, 0x00, 0x01, 0x63, 443 | 0x00, 0x01, 0x12, 0x00, 0x81, 0x29, 0x57, 0x13, 0xB2, 0x00, 0x81, 0x25, 444 | 0x63, 0x1C, 0x00, 0x01, 0x4B, 0x18, 0x00, 0x81, 0x2D, 0x0F, 0x14, 0x02, 445 | 0x00, 0x00, 0x49, 0x00, 0x05, 0x03, 0xC8, 0x98, 0xE1, 0x40, 0x02, 0x49, 446 | 0xEE, 0xE4, 0x00, 0x18, 0x27, 0x2C, 0xD5, 0x81, 0x14, 0x12, 0x0E, 0x24, 447 | 0x04, 0xB8, 0x2E, 0xC8, 0x5C, 0x92, 0x19, 0x40, 0x6B, 0xC1, 0xE0, 0x20, 448 | 0x93, 0x25, 0x62, 0xE6, 0x90, 0x91, 0xD0, 0xBA, 0x20, 0xF5, 0x48, 0x86, 449 | 0x04, 0xBE, 0x03, 0x03, 0x39, 0x77, 0xF5, 0x00, 0xAD, 0x08, 0x52, 0x22, 450 | 0x64, 0x18, 0xE4, 0x16, 0x44, 0x14, 0x00, 0x8E, 0x13, 0x12, 0xF2, 0xD5, 451 | 0x05, 0xA4, 0x10, 0x40, 0x00, 0x48, 0x00, 0xF8, 0x02, 0x46, 0x58, 0x46, 452 | 0xE5, 0xFB, 0x27, 0x97, 0x12, 0xEF, 0xC2, 0x0A, 0x0E, 0xFE, 0x8B, 0xD2, 453 | 0x74, 0x89, 0xA4, 0x0F, 0xEE, 0x0D, 0x1D, 0x58, 0xFE, 0x7F, 0xD1, 0x17, 454 | 0x25, 0x4B, 0xED, 0x5E, 0xC7, 0xB2, 0x79, 0x4C, 0x50, 0x07, 0xAE, 0x03, 455 | 0x6C, 0xD9, 0x15, 0xA4, 0xF5, 0x46, 0xA3, 0x49, 0xA1, 0x4B, 0x71, 0x60, 456 | 0x81, 0x48, 0x50, 0x79, 0x62, 0x3D, 0xEC, 0x63, 0x10, 0xE7, 0x8B, 0xAA, 457 | 0x94, 0x7A, 0x8F, 0x26, 0x19, 0x81, 0x1A, 0x47, 0x00, 0x13, 0xE6, 0x0D, 458 | 0xD4, 0xDD, 0x28, 0x13, 0xD8, 0x7D, 0xA8, 0x91, 0x4F, 0x5C, 0xE5, 0xE4, 459 | 0xB1, 0x32, 0x3A, 0xA5, 0xFC, 0x41, 0x4E, 0x0C, 0x8E, 0x9E, 0x36, 0x62, 460 | 0x51, 0x07, 0xDE, 0xAA, 0xB1, 0x61, 0x71, 0x4D, 0xBF, 0xA2, 0x77, 0x11, 461 | 0x51, 0x48, 0x1E, 0xC7, 0xBA, 0x51, 0x55, 0x86, 0x7C, 0xAE, 0x7C, 0x63, 462 | 0x49, 0x44, 0x4F, 0xBB, 0x74, 0x52, 0x59, 0x44, 0x5B, 0xAA, 0xFB, 0x64, 463 | 0x49, 0x43, 0xAC, 0xCE, 0xBF, 0x13, 0x81, 0x64, 0x22, 0x00, 0xFD, 0x18, 464 | 0x04, 0x1C, 0x7A, 0x7A, 0x32, 0xC6, 0x63, 0x06, 0x9E, 0x19, 0x8C, 0x81, 465 | 0xC3, 0x81, 0x99, 0xE6, 0x86, 0xE3, 0xB8, 0x0E, 0x88, 0x68, 0x23, 0x86, 466 | 0x88, 0x88, 0x82, 0x82, 0x3A, 0x08, 0x32, 0x16, 0x2E, 0x00, 0xFD, 0x10, 467 | 0x04, 0x84, 0xE3, 0xB8, 0xA1, 0x39, 0x6E, 0x80, 0x1B, 0xB8, 0xE1, 0x06, 468 | 0xB8, 0xE1, 0x06, 0x6E, 0x80, 0xBB, 0x81, 0xE3, 0xA6, 0x69, 0xA0, 0x69, 469 | 0xBA, 0x03, 0x00, 0x3A, 0xA0, 0x3B, 0xBA, 0xA3, 0x03, 0xE8, 0xA0, 0x03, 470 | 0x3A, 0x00, 0xE2, 0x00, 0xBA, 0x3B, 0x4E, 0x00, 0x00 471 | }; 472 | 473 | -------------------------------------------------------------------------------- /sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Override some defaults so BT stack is enabled and 2 | # Classic BT is enabled 3 | CONFIG_BT_ENABLED=y 4 | CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY= 5 | CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y 6 | CONFIG_BTDM_CONTROLLER_MODE_BTDM= 7 | CONFIG_BLUEDROID_ENABLED=y 8 | CONFIG_CLASSIC_BT_ENABLED=y 9 | CONFIG_A2DP_ENABLE=y 10 | CONFIG_BT_SPP_ENABLED=n 11 | CONFIG_GATTS_ENABLE=n 12 | CONFIG_GATTC_ENABLE=n 13 | CONFIG_BLE_SMP_ENABLE=n 14 | --------------------------------------------------------------------------------