From f6318a3162132c488210ec7cf6f1d8739e7f664a Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Wed, 29 Jun 2022 03:41:01 +0200 Subject: [PATCH] Adjusted volume curve, only change volume if enabled and added option to cancel volume sync --- software/main/include/volume.h | 1 + software/main/src/twai.cpp | 92 ++++++++++++---------------------- software/main/src/volume.cpp | 26 ++++++++-- 3 files changed, 57 insertions(+), 62 deletions(-) diff --git a/software/main/include/volume.h b/software/main/include/volume.h index 1771843..ef25094 100644 --- a/software/main/include/volume.h +++ b/software/main/include/volume.h @@ -7,6 +7,7 @@ namespace volume_controller { void init(); void set_from_radio(int volume); void set_from_remote(int volume); + void cancel_sync(); uint8_t current(); } diff --git a/software/main/src/twai.cpp b/software/main/src/twai.cpp index aa8fe0f..31ae5b6 100644 --- a/software/main/src/twai.cpp +++ b/software/main/src/twai.cpp @@ -15,24 +15,32 @@ #define TWAI_TAG "APP_TWAI" -// @TODO Use this proof of concept to sync volume from phone to radio -static void send_test() { - ESP_LOGI(TWAI_TAG, "Send test!"); +static bool enabled = false; - can::Buttons buttons; - memset(&buttons, 0, sizeof(buttons)); +// @TODO Make sure that the other buttons are set to match the current state +// That way way the scroll wheel and long pressing will not have unintented effects +void twai::change_volume(bool up) { + // Make sure we only change the volume if we are enabled + if (enabled) { + can::Buttons buttons; + memset(&buttons, 0, sizeof(buttons)); - for (int i = 0; i < 6; i++) { - buttons.volume_up = !(i % 2); + if (up) { + buttons.volume_up = true; + } else { + buttons.volume_down = true; + } twai_message_t message; memset(&message, 0, sizeof(message)); + message.identifier = BUTTONS_ID; message.data_length_code = 3; message.data[0] = ((uint8_t*)&buttons)[0]; message.data[1] = ((uint8_t*)&buttons)[1]; message.data[2] = ((uint8_t*)&buttons)[2]; + for (int i = 0; i < message.data_length_code; i++) { ESP_LOGI(TWAI_TAG, "%i: 0x%X", i, message.data[i]); } @@ -43,57 +51,21 @@ static void send_test() { ESP_LOGI(TWAI_TAG, "Failed tp queue message for transmission"); } - // This is a good delay for this vTaskDelay(pdMS_TO_TICKS(50)); - } -} -// @TODO Make sure that the other buttons are set to match the current state -// That way way the scroll wheel and long pressing will not have unintented effects -void twai::change_volume(bool up) { - can::Buttons buttons; - memset(&buttons, 0, sizeof(buttons)); + buttons.volume_up = false; + buttons.volume_down = false; + message.data[0] = ((uint8_t*)&buttons)[0]; - if (up) { - buttons.volume_up = true; - } else { - buttons.volume_down = true; - } + for (int i = 0; i < message.data_length_code; i++) { + ESP_LOGI(TWAI_TAG, "%i: 0x%X", i, message.data[i]); + } - twai_message_t message; - memset(&message, 0, sizeof(message)); - - message.identifier = BUTTONS_ID; - message.data_length_code = 3; - message.data[0] = ((uint8_t*)&buttons)[0]; - message.data[1] = ((uint8_t*)&buttons)[1]; - message.data[2] = ((uint8_t*)&buttons)[2]; - - - for (int i = 0; i < message.data_length_code; i++) { - ESP_LOGI(TWAI_TAG, "%i: 0x%X", i, message.data[i]); - } - - if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) { - ESP_LOGI(TWAI_TAG, "Message queued for transmission"); - } else { - ESP_LOGI(TWAI_TAG, "Failed tp queue message for transmission"); - } - - vTaskDelay(pdMS_TO_TICKS(30)); - - buttons.volume_up = false; - buttons.volume_down = false; - message.data[0] = ((uint8_t*)&buttons)[0]; - - for (int i = 0; i < message.data_length_code; i++) { - ESP_LOGI(TWAI_TAG, "%i: 0x%X", i, message.data[i]); - } - - if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) { - ESP_LOGI(TWAI_TAG, "Message queued for transmission"); - } else { - ESP_LOGI(TWAI_TAG, "Failed tp queue message for transmission"); + if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) { + ESP_LOGI(TWAI_TAG, "Message queued for transmission"); + } else { + ESP_LOGI(TWAI_TAG, "Failed tp queue message for transmission"); + } } } @@ -109,7 +81,6 @@ static void listen(void*) { ESP_LOGI(TWAI_TAG, "Message is in Extended Format"); } - static bool enabled = false; switch (message.identifier) { case BUTTONS_ID: if (enabled) { @@ -118,7 +89,7 @@ static void listen(void*) { static MultiPurposeButton button_forward(avrcp::play_pause, avrcp::forward); button_forward.update(buttons.forward); - static MultiPurposeButton button_backward(send_test, avrcp::backward); + static MultiPurposeButton button_backward(nullptr, avrcp::backward); button_backward.update(buttons.backward); // @TODO Figure out what we want to do with the scroll button @@ -130,6 +101,11 @@ static void listen(void*) { scroll = buttons.scroll; ESP_LOGI(TWAI_TAG, "Scroll changed: 0x%X", buttons.scroll); } + + // If the volume is syncing make sure we can cancel it if we press the volume buttons in the car + if (buttons.volume_up || buttons.volume_down) { + volume_controller::cancel_sync(); + } } break; @@ -137,9 +113,7 @@ static void listen(void*) { if (enabled) { can::Volume volume = can::convert(message.data, message.data_length_code); // Only update the volume if the volume has actually changed - if (!volume._1) { - volume_controller::set_from_radio(volume.volume); - } + volume_controller::set_from_radio(volume.volume); } break; diff --git a/software/main/src/volume.cpp b/software/main/src/volume.cpp index c21a6a1..800aa27 100644 --- a/software/main/src/volume.cpp +++ b/software/main/src/volume.cpp @@ -20,6 +20,22 @@ static uint8_t radio_volume; static bool synced = true; static _lock_t lock; +// Helper functions for converting between internal volume level and radio volume level +// Since most of the time we are going to be around a radio volume of 15 the scaling is non-linear +static uint8_t to_radio_volume(uint8_t volume) { + /* return floor(volume / 4.2f); */ + return ceil((30.f / pow(127.f, 2)) * pow(volume, 2)); +} + +static uint8_t from_radio_volume(uint8_t volume) { + /* return ceil(volume * 4.2f); */ + return floor((127.f / sqrt(30.f)) * sqrt(volume)); +} + +void volume_controller::cancel_sync() { + synced = true; +} + void volume_controller::set_from_radio(int v) { ESP_LOGI(VOLUME_TAG, "Volume on radio updated: %i (0-30)", v); // Update the radio volume @@ -35,7 +51,11 @@ void volume_controller::set_from_radio(int v) { } // Convert the 0 - 30 range of the radio to 0 - 127 - uint8_t full_range = ceil(v * 4.2f); + uint8_t full_range = from_radio_volume(v); + if (full_range == volume) { + return; + } + ESP_LOGI(VOLUME_TAG, "Updating internal and remote to: %i (0-127)", full_range); // Update the remote volume @@ -66,7 +86,7 @@ uint8_t volume_controller::current() { static void correct_volume(void*) { for (;;) { if (!synced) { - uint8_t target = floor(volume / 4.2f); + uint8_t target = to_radio_volume(volume); if (radio_volume == target) { ESP_LOGI(VOLUME_TAG, "SYNCED!"); @@ -79,7 +99,7 @@ static void correct_volume(void*) { } } - vTaskDelay(pdMS_TO_TICKS(30)); + vTaskDelay(pdMS_TO_TICKS(50)); } }