From 6f5680fce01e03739a5b61980fcb680c27a4f885 Mon Sep 17 00:00:00 2001 From: Neil McKechnie Date: Sat, 4 Feb 2023 20:59:19 +0000 Subject: [PATCH] DFPlayer: Avoid jumps in volume when switching song and reducing volume at the same time. --- IO_DFPlayer.h | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/IO_DFPlayer.h b/IO_DFPlayer.h index ad09ca5..4439fbc 100644 --- a/IO_DFPlayer.h +++ b/IO_DFPlayer.h @@ -70,10 +70,12 @@ class DFPlayer : public IODevice { private: + const uint8_t MAXVOLUME=30; HardwareSerial *_serial; bool _playing = false; uint8_t _inputIndex = 0; unsigned long _commandSendTime; // Allows timeout processing + uint8_t _lastVolumeLevel = MAXVOLUME; // When two commands are sent in quick succession, the device sometimes // fails to execute one. A delay is required between successive commands. @@ -179,41 +181,45 @@ protected: // Volume may be specified as second parameter to writeAnalogue. // If value is zero, the player stops playing. // WriteAnalogue on second pin sets the output volume. + // If starting a new file and setting volume, then avoid a short burst of loud noise by + // the following strategy: + // - If the volume is increasing, start playing the song before setting the volume, + // - If the volume is decreasing, decrease it and then start playing. + // void _writeAnalogue(VPIN vpin, int value, uint8_t volume=0, uint16_t=0) override { uint8_t pin = vpin - _firstVpin; + #ifdef DIAG_IO + DIAG(F("DFPlayer: VPIN:%d FileNo:%d Volume:%d"), vpin, value, volume); + #endif + // Validate parameter. - volume = min((uint8_t)30,volume); + if (volume > MAXVOLUME) volume = MAXVOLUME; if (pin == 0) { // Play track if (value > 0) { - #ifdef DIAG_IO - DIAG(F("DFPlayer: Play %d"), value); - #endif - sendPacket(0x03, value); // Play track - _playing = true; - if (volume > 0) { - #ifdef DIAG_IO - DIAG(F("DFPlayer: Volume %d"), volume); - #endif - sendPacket(0x06, volume); // Set volume + if (volume != 0) { + if (volume <= _lastVolumeLevel) + sendPacket(0x06, volume); // Set volume before starting + sendPacket(0x03, value); // Play track + _playing = true; + if (volume > _lastVolumeLevel) + sendPacket(0x06, volume); // Set volume after starting + _lastVolumeLevel = volume; + } else { + // Volume not changed, just play + sendPacket(0x03, value); + _playing = true; } } else { - #ifdef DIAG_IO - DIAG(F("DFPlayer: Stop")); - #endif sendPacket(0x16); // Stop play _playing = false; } } else if (pin == 1) { // Set volume (0-30) - if (value > 30) value = 30; - else if (value < 0) value = 0; - #ifdef DIAG_IO - DIAG(F("DFPlayer: Volume %d"), value); - #endif - sendPacket(0x06, value); + sendPacket(0x06, value); + _lastVolumeLevel = volume; } }