diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..28629df --- /dev/null +++ b/platformio.ini @@ -0,0 +1,27 @@ +; PlatformIO project configuration for BikeAudio +; Converted from Arduino IDE sketch (BikeAudio.ino). +; +; Board: ESP32 Dev Module (DevKitC v4) -> esp32dev +; ESP32 Arduino core: 2.0.17 (provided by platform espressif32 @ ~6.6.0) +; Do NOT move to core 3.x — BT stack regression. +; Partition scheme: Huge APP (3MB No OTA / 1MB SPIFFS) -> huge_app.csv +; Serial monitor: 115200 baud + +[env:esp32dev] +platform = espressif32 @ ~6.6.0 +board = esp32dev +framework = arduino + +; Huge APP partition table — required for the Bluetooth stack size. +board_build.partitions = huge_app.csv + +monitor_speed = 115200 + +; Phil Schatzmann's libraries (referenced by git URL, as in the .ino header — +; not published in the PlatformIO registry under these names). +; ESP32-A2DP depends on arduino-audio-tools. Pinned to exact commits for +; reproducible builds (ESP32-A2DP 1.8.11, audio-tools 1.2.4); src/main.cpp +; was adapted to match this API surface. +lib_deps = + https://github.com/pschatzmann/ESP32-A2DP#42601717cd70d5300c9b519f3c2bf1d64d77ea2b + https://github.com/pschatzmann/arduino-audio-tools#64b64dcb9bde18a0a17766eeb6529c3a53d920a8 diff --git a/BikeAudio.ino b/src/main.cpp similarity index 91% rename from BikeAudio.ino rename to src/main.cpp index 84b66c5..4cf94aa 100644 --- a/BikeAudio.ino +++ b/src/main.cpp @@ -27,11 +27,18 @@ * - Done — play audio, both speakers output simultaneously */ +#include + #include "AudioTools.h" #include "BluetoothA2DPSink.h" #include "BluetoothA2DPSource.h" #include "BluetoothA2DPCommon.h" +// Forward declaration — defined below. Required in .cpp builds: the Arduino IDE +// auto-generates prototypes for .ino files, but PlatformIO compiles .cpp directly +// and print_status() is called in setup()/loop() before its definition. +void print_status(); + // ─── CONFIGURATION ──────────────────────────────────────────────────────────── // Name this device shows to iPhone @@ -104,8 +111,9 @@ void audio_received_mirror_cb(const uint8_t *data, uint32_t len) { int32_t get_audio_for_jbl(uint8_t *data, int32_t len) { int32_t bytes_read = 0; - while (bytes_read < len && !ring_buf.isEmpty()) { - data[bytes_read++] = ring_buf.read(); + uint8_t b; + while (bytes_read < len && ring_buf.read(b)) { + data[bytes_read++] = b; } // Pad with silence if buffer underrun if (bytes_read < len) { @@ -116,8 +124,9 @@ int32_t get_audio_for_jbl(uint8_t *data, int32_t len) { int32_t get_audio_for_cardo(uint8_t *data, int32_t len) { int32_t bytes_read = 0; - while (bytes_read < len && !ring_buf_cardo.isEmpty()) { - data[bytes_read++] = ring_buf_cardo.read(); + uint8_t b; + while (bytes_read < len && ring_buf_cardo.read(b)) { + data[bytes_read++] = b; } if (bytes_read < len) { memset(data + bytes_read, 0, len - bytes_read); @@ -127,7 +136,7 @@ int32_t get_audio_for_cardo(uint8_t *data, int32_t len) { // ─── CONNECTION CALLBACKS ───────────────────────────────────────────────────── -void sink_connected_cb(esp_bd_addr_t addr, esp_a2d_connection_state_t state, void *obj) { +void sink_connected_cb(esp_a2d_connection_state_t state, void *obj) { if (state == ESP_A2D_CONNECTION_STATE_CONNECTED) { Serial.println("[SINK] iPhone connected"); iphone_connected = true; @@ -137,7 +146,7 @@ void sink_connected_cb(esp_bd_addr_t addr, esp_a2d_connection_state_t state, voi } } -void jbl_connected_cb(esp_bd_addr_t addr, esp_a2d_connection_state_t state, void *obj) { +void jbl_connected_cb(esp_a2d_connection_state_t state, void *obj) { if (state == ESP_A2D_CONNECTION_STATE_CONNECTED) { Serial.println("[JBL] Connected"); jbl_connected = true; @@ -148,7 +157,7 @@ void jbl_connected_cb(esp_bd_addr_t addr, esp_a2d_connection_state_t state, void } } -void cardo_connected_cb(esp_bd_addr_t addr, esp_a2d_connection_state_t state, void *obj) { +void cardo_connected_cb(esp_a2d_connection_state_t state, void *obj) { if (state == ESP_A2D_CONNECTION_STATE_CONNECTED) { Serial.println("[CARDO] Connected"); cardo_connected = true; @@ -171,7 +180,7 @@ void setup() { src_jbl.set_data_callback(get_audio_for_jbl); src_jbl.set_on_connection_state_changed(jbl_connected_cb); src_jbl.set_auto_reconnect(true); - src_jbl.start(JBL_NAME, true); // true = reconnect if known device + src_jbl.start(JBL_NAME); // auto-reconnect handled by set_auto_reconnect() above // Give it time to connect before starting second source // (Bluedroid needs sequential connection setup) @@ -190,7 +199,7 @@ void setup() { src_cardo.set_data_callback(get_audio_for_cardo); src_cardo.set_on_connection_state_changed(cardo_connected_cb); src_cardo.set_auto_reconnect(true); - src_cardo.start(CARDO_NAME, true); + src_cardo.start(CARDO_NAME); t = millis(); while (!cardo_connected && millis() - t < 10000) { @@ -219,14 +228,14 @@ void loop() { // Auto-reconnect JBL if lost if (!jbl_connected && millis() - last_reconnect_jbl > RECONNECT_MS) { Serial.println("[JBL] Retrying connection..."); - src_jbl.start(JBL_NAME, true); + src_jbl.start(JBL_NAME); last_reconnect_jbl = millis(); } // Auto-reconnect Cardo if lost if (!cardo_connected && millis() - last_reconnect_cardo > RECONNECT_MS) { Serial.println("[CARDO] Retrying connection..."); - src_cardo.start(CARDO_NAME, true); + src_cardo.start(CARDO_NAME); last_reconnect_cardo = millis(); }