From 5db7eca37d5f5723efed5c25e60a12f96afc9915 Mon Sep 17 00:00:00 2001 From: tueddy Date: Sat, 16 Oct 2021 11:34:32 +0200 Subject: [PATCH] Bluetooth: - Support for AVRC Commands (play/pause, next, previous) - Logging for BT connected/disconnected - set_mono_downmix if PLAY_MONO_SPEAKER defined --- src/Bluetooth.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++++ src/Bluetooth.h | 13 +++++++- src/Cmd.cpp | 33 +++++++++++++++---- 3 files changed, 123 insertions(+), 7 deletions(-) diff --git a/src/Bluetooth.cpp b/src/Bluetooth.cpp index ab53e71..7654c88 100644 --- a/src/Bluetooth.cpp +++ b/src/Bluetooth.cpp @@ -1,6 +1,9 @@ #include +#include #include "settings.h" #include "Bluetooth.h" +#include "Log.h" +#include "RotaryEncoder.h" #include "System.h" #ifdef BLUETOOTH_ENABLE @@ -9,9 +12,42 @@ #endif #ifdef BLUETOOTH_ENABLE + #define BLUETOOTHPLAYER_VOLUME_MAX 21u + #define BLUETOOTHPLAYER_VOLUME_MIN 0u + BluetoothA2DPSink *a2dp_sink; #endif +void Bluetooth_Connected(void) { + #ifdef BLUETOOTH_ENABLE + Serial.println("Bluetooth: Connected"); + #endif +} + +void Bluetooth_Disconnected(void) { + #ifdef BLUETOOTH_ENABLE + Serial.println("Bluetooth: Disonnected"); + #endif +} +void Bluetooth_VolumeChanged(int _newVolume) { + #ifdef BLUETOOTH_ENABLE + snprintf(Log_Buffer, Log_BufferLength, "%s %d !", (char *) FPSTR("Bluetooth, volume changed: "), _newVolume); + Log_Println(Log_Buffer, LOGLEVEL_ERROR); + uint8_t _volume; + if (_newVolume < BLUETOOTHPLAYER_VOLUME_MIN) { + return; + } else if (_newVolume > BLUETOOTHPLAYER_VOLUME_MAX) { + return; + } else { + // map bluetooth volume (0..127) to ESPuino volume (0..21) to + _volume = map(_newVolume, 0, 0x7F, BLUETOOTHPLAYER_VOLUME_MIN, BLUETOOTHPLAYER_VOLUME_MAX); + AudioPlayer_SetCurrentVolume(_volume); + // update rotary encoder + RotaryEncoder_Readjust(); + } + #endif +} + void Bluetooth_Init(void) { #ifdef BLUETOOTH_ENABLE if (System_GetOperationMode() == OPMODE_BLUETOOTH) { @@ -23,6 +59,12 @@ void Bluetooth_Init(void) { .data_in_num = I2S_PIN_NO_CHANGE}; a2dp_sink->set_pin_config(pin_config); a2dp_sink->activate_pin_code(false); + #ifdef PLAY_MONO_SPEAKER + a2dp_sink->set_mono_downmix(true); + #endif + a2dp_sink->set_on_connected2BT(Bluetooth_Connected); + a2dp_sink->set_on_disconnected2BT(Bluetooth_Disconnected); + a2dp_sink->set_on_volumechange(Bluetooth_VolumeChanged); a2dp_sink->start((char *)FPSTR(nameBluetoothDevice)); } else { esp_bt_mem_release(ESP_BT_MODE_BTDM); @@ -39,3 +81,45 @@ void Bluetooth_Cyclic(void) { } #endif } + +void Bluetooth_PlayPauseTrack(void) { + #ifdef BLUETOOTH_ENABLE + esp_a2d_audio_state_t state = a2dp_sink->get_audio_state(); + if (state == ESP_A2D_AUDIO_STATE_STARTED) { + a2dp_sink->play(); + } else { + a2dp_sink->pause(); + } + #endif +} + +void Bluetooth_NextTrack(void) { + #ifdef BLUETOOTH_ENABLE + a2dp_sink->next(); + #endif +} + +void Bluetooth_PreviousTrack(void) { + #ifdef BLUETOOTH_ENABLE + a2dp_sink->previous(); + #endif +} + +// set volume from ESPuino to phone needs at least Arduino ESP version 2.0.0 +void Bluetooth_SetVolume(const int32_t _newVolume, bool reAdjustRotary) { + #ifdef BLUETOOTH_ENABLE + uint8_t _volume; + if (_newVolume < BLUETOOTHPLAYER_VOLUME_MIN) { + return; + } else if (_newVolume > BLUETOOTHPLAYER_VOLUME_MAX) { + return; + } else { + // map ESPuino min/max volume (0..21) to bluetooth volume (0..127) + _volume = map(_newVolume, BLUETOOTHPLAYER_VOLUME_MIN, BLUETOOTHPLAYER_VOLUME_MAX, 0, 0x7F); + a2dp_sink->set_volume(_volume); + if (reAdjustRotary) { + RotaryEncoder_Readjust(); + } + } + #endif +} diff --git a/src/Bluetooth.h b/src/Bluetooth.h index d1d20ed..d78f48c 100644 --- a/src/Bluetooth.h +++ b/src/Bluetooth.h @@ -1,4 +1,15 @@ #pragma once + void Bluetooth_Init(void); -void Bluetooth_Cyclic(void); \ No newline at end of file +void Bluetooth_Cyclic(void); + +// AVRC commands, see https://github.com/pschatzmann/ESP32-A2DP/wiki/Controlling-your-Phone-with-AVRC-Commands + +// Support for AVRC Commands starting from ESP32 Release 1.0.6 +void Bluetooth_PlayPauseTrack(void); +void Bluetooth_NextTrack(void); +void Bluetooth_PreviousTrack(void); + +// Support for AVRC Commands starting from ESP32 Release 2.0.0 +void Bluetooth_SetVolume(const int32_t _newVolume, bool reAdjustRotary); diff --git a/src/Cmd.cpp b/src/Cmd.cpp index 6844f3f..a063243 100644 --- a/src/Cmd.cpp +++ b/src/Cmd.cpp @@ -3,6 +3,7 @@ #include "Cmd.h" #include "AudioPlayer.h" #include "Battery.h" +#include "Bluetooth.h" #include "Ftp.h" #include "Led.h" #include "Log.h" @@ -259,17 +260,29 @@ void Cmd_Action(const uint16_t mod) { #endif case CMD_PLAYPAUSE: { - AudioPlayer_TrackControlToQueueSender(PAUSEPLAY); + if (OPMODE_NORMAL == System_GetOperationMode()) { + AudioPlayer_TrackControlToQueueSender(PAUSEPLAY); + } else { + Bluetooth_PlayPauseTrack(); + } break; } case CMD_PREVTRACK: { - AudioPlayer_TrackControlToQueueSender(PREVIOUSTRACK); + if (OPMODE_NORMAL == System_GetOperationMode()) { + AudioPlayer_TrackControlToQueueSender(PREVIOUSTRACK); + } else { + Bluetooth_PreviousTrack(); + } break; } case CMD_NEXTTRACK: { - AudioPlayer_TrackControlToQueueSender(NEXTTRACK); + if (OPMODE_NORMAL == System_GetOperationMode()) { + AudioPlayer_TrackControlToQueueSender(NEXTTRACK); + } else { + Bluetooth_NextTrack(); + } break; } @@ -289,13 +302,21 @@ void Cmd_Action(const uint16_t mod) { } case CMD_VOLUMEUP: { - AudioPlayer_VolumeToQueueSender(AudioPlayer_GetCurrentVolume() + 1, true); + if (OPMODE_NORMAL == System_GetOperationMode()) { + AudioPlayer_VolumeToQueueSender(AudioPlayer_GetCurrentVolume() + 1, true); + } else { + Bluetooth_SetVolume(AudioPlayer_GetCurrentVolume() + 1, true); + } break; } case CMD_VOLUMEDOWN:{ - AudioPlayer_VolumeToQueueSender(AudioPlayer_GetCurrentVolume() - 1, true); - break; + if (OPMODE_NORMAL == System_GetOperationMode()) { + AudioPlayer_VolumeToQueueSender(AudioPlayer_GetCurrentVolume() - 1, true); + } else { + Bluetooth_SetVolume(AudioPlayer_GetCurrentVolume() - 1, true); + } + break; } case CMD_MEASUREBATTERY: {