[PLUGIN] Audio Keepalive (Volumio 4) - Seven years, one toggle, zero lost seconds

Dear Volumionauts,

Some of you have been here long enough to remember GitHub issue #1668 - “First couple of seconds of each track is always cut off with some DACs.” Filed in December 2018 for Volumio 2 and still not resolved. Open ever since. Old enough to have started primary school, learned to read, written a letter asking when it will be fixed, and received no reply.

The problem is simple. When Volumio stops playback, MPD closes the ALSA device. Your receiver loses the audio stream. When you press Play again, the receiver has to renegotiate format - channels, sample rate, bit depth - before it will output anything. That negotiation window eats the first 1-2 seconds of your track. With CEC involved, it gets worse. Much worse.

This affects HDMI AVRs, HDMI soundbars, SPDIF DACs, and certain USB DACs. It is protocol-level, not device-specific. If your equipment performs format negotiation on signal acquisition, you have this problem whether you have noticed it or not.

Kodi solved this years ago. Their “Keep audio device alive” setting sends inaudible noise to prevent the receiver from dropping the connection. MPD has supported the same mechanism natively via always_on for just as long. Volumio simply never exposed it.

Now it is exposed.

Audio Keepalive is available in the plugin store as beta.

It provides four settings, all disabled by default:

Keep audio device active - the core feature. Injects always_on “yes” and close_on_pause “no” into the MPD ALSA output block. MPD keeps the device open at all times, sending silence frames when idle. Your receiver stays locked. No more missing beginnings. No more negotiation delays.

Output buffer time - configurable ALSA buffer (default / 500 ms / 1s / 2s / 4s). Increasing this absorbs sample rate transitions and can eliminate pops and clicks on format changes. Leave on default unless you experience artifacts on rate switches.

Output period time - configurable ALSA period (default / 125 ms / 250 ms / 500 ms). Smaller values reduce latency, larger values improve stability during transitions. Leave on default unless needed.

Silence before DSD stop - injects stop_dsd_silence “yes” to play brief silence before stopping DSD playback. Prevents the burst of noise some DACs emit when a DSD stream ends abruptly.

The plugin patches /etc/mpd.conf at runtime using sentinel comments, monitors Volumio’s ALSA configuration callbacks, and automatically re-applies its patch when you change Playback Options in Volumio’s settings. On disable or uninstall, the patch is cleanly removed and MPD restarts with original behaviour. It survives reboots and re-applies after configuration changes.

Things to be aware of:

  • With keepalive enabled, MPD holds the ALSA device open permanently. This may conflict with Spotify Connect, Bluetooth audio, or Snapcast since they need their own device access. If you use these, you may need to toggle keepalive when switching.

  • Some receivers may not enter standby if they detect a continuous audio stream. That is the feature working as intended, but be aware if your receiver normally auto-powers-off.

  • The keepalive is unnecessary for 3.5 mm headphone output, most I2S DAC HATs, or analog output. No format negotiation, no problem. The buffer, period, and DSD silence settings may still be useful on these outputs.

Compatibility: Volumio 4.x (Bookworm), any ALSA output (HDMI, SPDIF, USB, I2S), Raspberry Pi 4B, Pi 5, x86. Compatible with the MPD HTTP & Icecast Output plugin. Languages: English, German, French, Spanish, Dutch, Polish.

Testing is open. This is beta. I need reports from people with HDMI AVRs, SPDIF DACs, and USB DACs that exhibit the negotiation delay. Install the plugin, enable “Keep audio device active”, reboot, and tell me:

  1. Does the initial play delay disappear?
  2. Does stop-wait-play still have the delay?
  3. Does skip (Next/Previous) behave correctly?
  4. Does changing Playback Options in Volumio settings preserve the patch?
  5. Does disabling the plugin cleanly restore original behaviour?

Report your receiver/DAC model, output type, and results in this thread.

Credit where it is due: @PluggedIn identified the problem clearly, provided the Kodi reference, and has volunteered as primary test pilot with an Onkyo TX-RZ50 on HDMI. The rest of you are welcome to join.

Seven years. One toggle. Sometimes the fix really is that simple.

Kind Regards,

3 Likes

Reserved

Yes, this has reached the community multiple times in the last years. It solves issues where the DAC manufacturer has no solution for it. Nice add.

Alright, here we go.

You and @Wheaten already know which receiver I have, but just for the rest, it’s an Onkyo TX-RZ50. The mode I use for this input is All Channel Stereo, and perhaps at times Dolby Surround (it’s the fake Dolby Atmos that is upmixed from anything between 2.0 and 6.1 channels).

Also just in case it matters, this is the HDMI cable I’m currently using: Amazon.com: Highwings 4K Micro HDMI to HDMI Cable 3 FT, Micro Male to HDMI Male Nylon Braided Cord Adapter 2.0 4K@60HZ 2K@165HZ 18Gbps Compatible for Laptop Tablet Camera Connected to Monitor Projector 3FT : Electronics

My Volumio machine is this Raspberry Pi 4B: Amazon.com: CanaKit Raspberry Pi 4 8GB Starter Kit - 8GB RAM : Electronics

The microSD card that has the Volumio install is this: Amazon.com: Samsung P9 Express microSD Express Card, 256GB microSDXC Memory Card, Up to 800 MB/s, for Nintendo-Switch ™ 2, (MB MK256T/AM) : Electronics

I think that covers the whole equipment thing.

So let’s go into the findings:

I opened the plugin store, and Audio Keepalive was right there as the first one. I installed it, rebooted, tried it, and it didn’t make a difference. So I went into the plugin settings and realized that even if it’s enabled in the plugin list, it also needs to be enabled within the plugin itself. So I did that, rebooted again, and navigated to albums I have in the same microSD card, in the Internal Storage partition.

At first it worked as intended. I tried a few tracks of different albums, and they started playing from the very start. I don’t think they started playing as soon as I clicked on the play button, but I don’t care about that, I only care that it starts playing from the beginning of the track. And that it did… until it didn’t.

While my brain’s RAM is seriously glitchy, so it can’t always recall the most recent events, I believe it happened after I started playing with the other settings, just to test, and because I like living on the edge.

So after that, the keep alive thing completely went away, and what puzzles me is that I even uninstalled the plugin, rebooted Volumio, installed it again, rebooted again, and it’s still not working, even at the default settings, except for the one that enables it.

Now, I’m wondering, the setting in the dev page that enables test plugins, does it stay on, or does it go back to False every reboot? However, I enabled it again and it still doesn’t work. It seems to me that perhaps I have to clean some kind of cache?

Hey @PluggedIn,

Good report. Thorough, structured, equipment documented. You are learning the ways.

The fact that it worked initially and then stopped after changing other settings is significant - it tells me the patch was applied correctly at first, and something in the subsequent configuration cycle broke or displaced it. But what exactly happened is not something I can determine from description alone.

I need the log.

Go to http://volumio.local/dev and generate a log. Paste the URL it gives you here.

I also need to see what MPD is currently working with. SSH in and run:

cat /etc/mpd.conf

Paste the full output.

Those two things will tell me whether the patch is present, whether it is in the correct location within the audio_output block, and whether MPD is actually honouring it. Everything else is speculation, and we do not do that here.

Plugins Test Mode stays on until you turn it off - it survives reboots.

Kind Regards,

Thank you, Obi Wan. You’re my only hope. Of getting this to work, that is.

http://logs.volumio.org/volumio/fZfri60.html

# Volumio MPD Configuration File

# Files and directories #######################################################
music_directory         "/var/lib/mpd/music"
playlist_directory              "/var/lib/mpd/playlists"
db_file                 "/var/lib/mpd/tag_cache"
log_file                        "/var/log/mpd.log"
#pid_file                       "/var/run/mpd/pid"
#state_file                     "/var/lib/mpd/state"
#sticker_file                   "/var/lib/mpd/sticker.sql"
###############################################################################

# General music daemon options ################################################
user                            "mpd"
group                          "audio"
bind_to_address         "any"
#port                           "6600"
log_level                       "default"
#save_absolute_paths_in_playlists       "no"
#metadata_to_use        "artist,album,title,track,name,genre,date,composer,performer,disc"
auto_update    "no"
#auto_update_depth "3"
###############################################################################
# Symbolic link behavior ######################################################
follow_outside_symlinks "yes"
follow_inside_symlinks          "yes"
###############################################################################
# Input #######################################################################
#
input {
        plugin "curl"
#       proxy "proxy.isp.com:8080"
#       proxy_user "user"
#       proxy_password "password"
}
###############################################################################

# Decoder ################################################################

decoder {
        plugin "faad"
        enabled "no"
}





###############################################################################

# Audio Output ################################################################

resampler {
                plugin "soxr"
                quality "very high"
                threads "1"
}

audio_output {
                type            "alsa"
                name            "alsa"
                device          "volumio"
                dop                     "no"
                mixer_device    "SoftMaster"
                mixer_control   "SoftMaster"
                mixer_type      "hardware"

                format      "96000:24:2"


    # audio_keepalive_begin
    always_on       "yes"
    close_on_pause  "no"
    buffer_time     "500000"
    period_time     "125000"
    # audio_keepalive_end
}





audio_output {
    type            "fifo"
    enabled         "no"
    name            "multiroom"
    path            "/tmp/snapfifo"
    format          "44100:16:2"
}

#replaygain                     "album"
#replaygain_preamp              "0"
volume_normalization            "no"
###############################################################################

# MPD Internal Buffering ######################################################
audio_buffer_size               "12288"
###############################################################################


# Resource Limitations ########################################################
#connection_timeout             "60"
max_connections                 "20"
max_playlist_length             "81920"
max_command_list_size           "81920"
max_output_buffer_size          "81920"
###############################################################################

# Character Encoding ##########################################################
filesystem_charset              "UTF-8"
###############################################################################

Let me know if you need to run any specific tests.

Thanks!

Hey @PluggedIn,

Before I dig into the logs - which micro HDMI port on the Pi is the cable actually plugged into right now? The one closer to the power connector (port 0) or the one further away (port 1)?

I ask because your software is talking to port 0, and I want to make sure the cable got the memo.

Kind Regards,

It’s port 0.

Hey @PluggedIn,

Good - port 0 confirmed. Software and hardware agree.

Now, before we chase the keepalive issue further, we need a clean baseline. There are remnants from previous configurations that may be interfering, and the only way to rule them out is to strip it back and rebuild step by step.

Do the following in this exact order, testing after each stage:

Stage 1 - Strip the plugin back

Open Audio Keepalive settings. Set “Keep audio device active” to off. Leave all other settings at default. Save. Then go to the plugin list and disable the plugin entirely. Reboot.

Stage 2 - Reset audio output to analog

Go to Playback Options. Set output to “Audio Jack” (the 3.5mm headphone output). Set mixer to “Hardware”. Apply. Reboot. This is just a sanity check - we are proving that Volumio regenerates a clean mpd.conf without any keepalive patch residue.

Stage 3 - Switch back to HDMI 0

Go to Playback Options. Set output to HDMI 0. Set up the mixer as before. Apply. Reboot. Play a track. Confirm audio comes through your Onkyo - even if there is the usual delay. This proves the base audio path works without the plugin.

Stage 4 - Re-enable Audio Keepalive

Enable the plugin. Reboot. Open plugin settings. Enable only “Keep audio device active” - nothing else. Leave buffer time, period time, and DSD silence all at defaults. Save. Reboot. Test.

Do not touch the other settings until we confirm the basic keepalive toggle works on its own.

If the delay disappears at Stage 4, we have our baseline. If it does not, SSH in and run these three commands:

While a track is playing:

cat /proc/asound/card2/pcm0p/sub0/status

After stopping playback, wait 10 seconds:

cat /proc/asound/card2/pcm0p/sub0/status

Then:

mpc outputs

Paste all three outputs here.

Kind Regards,

OK I followed every single step, still doesn’t work unfortunately.

Here’s the output from those commands:

volumio@volumio:~$ cat /proc/asound/card2/pcm0p/sub0/status
state: RUNNING
owner_pid   : 2166
trigger_time: 311.470411538
tstamp      : 0.000000000
delay       : 20316
avail       : 1734
avail_max   : 4490
-----
hw_ptr      : 1307094
appl_ptr    : 1327410
volumio@volumio:~$ cat /proc/asound/card2/pcm0p/sub0/status
closed
volumio@volumio:~$ mpc outputs
Output 1 (alsa) is enabled
        allowed_formats=""
        dop="0"
Output 2 (multiroom) is disabled

BTW, where’s that 'find: “mpd.conf” file you speak of? I ran

find / mpd.conf

and I got

find: 'mpd.conf': No such file or directory

Hey @PluggedIn,

The command you want is:

find / -name "mpd.conf"

What you ran told find to search two separate things: the directory “/” and a path called “mpd.conf” in the current directory. The -name flag is what tells find what to look for.


Meanwhile, I am deep in kernel source code tracing how always_on interacts with the ALSA output thread’s pause state machine, cross-referencing ActiveAE silence injection architecture against Volumio’s ALSA device chain, and I have a Pi 4 wired to an HDMI audio extractor feeding a DSO so I can watch the audio info frames flatline the moment playback stops. The oscilloscope is showing me things I did not want to see. The phase generator is confirming things I hoped were not true. My bulk order of caffeine this week just shipped.

Short version: I now know exactly why always_on does not work for HDMI. The fix requires a fundamentally different approach. Sit tight while I finish arguing with the laws of physics.

Kind Regards,

1 Like

Ah that’s what happens when you Google things and you play it by ear. I thought the -name was supposed to be replaced by the name of the file I was looking for.

I see you also speak Chinese. Good for you! :rofl:

What puzzles me is what made it work the first time, and then it stopped working?

Hey @PluggedIn,

Chinese - that is actually Japanese. The kanji in the MPD debug log were track metadata from a test file. But yes, I do speak the global supply components language fluently - PCB silkscreen, datasheets, and “please refer to schematic revision C” are my mother tongue. I think @Darmur not only speaks it, but dreams in it. Last one is Volumio related - you should see his creations. The veil of silk screen flowing with perfectly written markings. Resistors perpendicular with perfect spacing. ICs softly placed as close to their exits as the tracks allow. Even the round through-holes are perfectly round and evenly spaced. I never managed a Christmas tree this beautiful.

On the find command - you got it. The -name flag is the filter, and the first argument is where to start looking. Classic trap.

Now to your actual question, which is a good one.

“What made it work the first time, and then it stopped working?”

Short answer: I do not believe it ever worked. I believe the timing coincidentally hid the problem.

The reason I know this: I have traced the exact code path through source. When always_on is true and playback stops, MPD calls InternalPause(), which calls BeginPause(), which calls Cancel(), which calls snd_pcm_drop(). That function tells the kernel to stop the PCM stream immediately. No more audio frames. No more HDMI audio info frames. Your Onkyo sees the signal vanish and drops the link after its timeout.

The fix I am building takes a completely different approach. I have validated the full lifecycle on a Pi 4 with an HDMI audio extractor. The mechanism works. The engineering challenge now is the handoff timing between the silence feeder and MPD - making sure one releases the device before the other tries to grab it. That part is what I am still working on.

I will have something for you to test in a day or so. Your Onkyo is the real-world validation target.

Kind Regards,

1 Like

I think @Darmur has some tattooed on invisible placed :joy:

2 Likes

@Darmur - is this true?

Kind Regards,

I do have tattoos, but not in hidden places and not related to PCB

Back in time I wanted to make another one on my arm, something like this, but my laziness won at the end

2 Likes

Well looks very much like tracks…
And pretty sure if we apply some high voltage on the big black pads (in a kind gentle way off coarse), it will come alive, or at least moves a bit :slight_smile:

1 Like

:joy:

I think my back and forth with you is the most fun I’ve ever had in any forum since I started using the internet in 1997.

I must confess it’s entirely possible that I imagined the whole thing. But I’m still convinced that I installed the plugin the first time, browsed my library for something that I knew started with an audible note (I have a lot of classical music and film scores that start very low and take time to get to a normal volume), and I heard it play from the very first bit. But well, maybe I did imagine it.

Once it’s ready, I have other devices with HDMI inputs to test it in. A Yamaha receiver, an Oppo 4K Blu-ray player with HDMI input, and the Fire TV Cube also has an HDMI input. I also have a Pioneer VSX-935 receiver, although if it works in the Onkyo, obviously it’s going to work in the Pioneer.

An HDMI nerd gear collector walks among us, whispering “this cable is lying” under his breath. :astonished:

1 Like