1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-30 03:26:13 +01:00

DFPlayer: Avoid jumps in volume when switching song and reducing volume at the same time.

This commit is contained in:
Neil McKechnie 2023-02-04 20:59:19 +00:00
parent 2f46a8e083
commit 6f5680fce0

View File

@ -70,10 +70,12 @@
class DFPlayer : public IODevice { class DFPlayer : public IODevice {
private: private:
const uint8_t MAXVOLUME=30;
HardwareSerial *_serial; HardwareSerial *_serial;
bool _playing = false; bool _playing = false;
uint8_t _inputIndex = 0; uint8_t _inputIndex = 0;
unsigned long _commandSendTime; // Allows timeout processing unsigned long _commandSendTime; // Allows timeout processing
uint8_t _lastVolumeLevel = MAXVOLUME;
// When two commands are sent in quick succession, the device sometimes // When two commands are sent in quick succession, the device sometimes
// fails to execute one. A delay is required between successive commands. // 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. // Volume may be specified as second parameter to writeAnalogue.
// If value is zero, the player stops playing. // If value is zero, the player stops playing.
// WriteAnalogue on second pin sets the output volume. // 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 { void _writeAnalogue(VPIN vpin, int value, uint8_t volume=0, uint16_t=0) override {
uint8_t pin = vpin - _firstVpin; uint8_t pin = vpin - _firstVpin;
#ifdef DIAG_IO
DIAG(F("DFPlayer: VPIN:%d FileNo:%d Volume:%d"), vpin, value, volume);
#endif
// Validate parameter. // Validate parameter.
volume = min((uint8_t)30,volume); if (volume > MAXVOLUME) volume = MAXVOLUME;
if (pin == 0) { if (pin == 0) {
// Play track // Play track
if (value > 0) { if (value > 0) {
#ifdef DIAG_IO if (volume != 0) {
DIAG(F("DFPlayer: Play %d"), value); if (volume <= _lastVolumeLevel)
#endif sendPacket(0x06, volume); // Set volume before starting
sendPacket(0x03, value); // Play track sendPacket(0x03, value); // Play track
_playing = true; _playing = true;
if (volume > 0) { if (volume > _lastVolumeLevel)
#ifdef DIAG_IO sendPacket(0x06, volume); // Set volume after starting
DIAG(F("DFPlayer: Volume %d"), volume); _lastVolumeLevel = volume;
#endif } else {
sendPacket(0x06, volume); // Set volume // Volume not changed, just play
sendPacket(0x03, value);
_playing = true;
} }
} else { } else {
#ifdef DIAG_IO
DIAG(F("DFPlayer: Stop"));
#endif
sendPacket(0x16); // Stop play sendPacket(0x16); // Stop play
_playing = false; _playing = false;
} }
} else if (pin == 1) { } else if (pin == 1) {
// Set volume (0-30) // 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;
} }
} }