PeppyMeter

It looks like 'perf' utility is not completely installed on Raspberry OS. After installing missing parts I ran the following command for 'mpd' player with peppyalsa plugin and without:
perf record -F 99 -p 18104 sleep 30
I took the command from this page:
Linux perf Examples
18104 is 'mpd' PID. 30 is the seconds for the running interval.

Here is the result of that command when 'mpd' was running with 'peppyalsa' plugin:
Code:
Samples: 3K of event 'cycles:uppp', Event count (approx.): 42629778897
Overhead  Command          Shared Object                  Symbol
  53.10%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e884
  18.27%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e28c
   7.16%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e2a0
   6.03%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e888
   5.32%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e298
   5.18%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e290
   1.75%  rtio             caps.so                        [.] Eq10::cycle
   1.23%  decoder:mad      libmad.so.0.2.1                [.] 0x000083d8
   1.02%  rtio             libasound.so.2.0.0             [.] snd_pcm_area_copy
   0.23%  rtio             libasound.so.2.0.0             [.] snd_pcm_lfloat_convert_float_integer
   0.21%  rtio             libasound.so.2.0.0             [.] snd_pcm_lfloat_convert_integer_float
   0.09%  decoder:mad      libmad.so.0.2.1                [.] 0x00004180
   0.03%  rtio             libasound_module_pcm_equal.so  [.] 0x000010b0
   0.03%  rtio             libarmmem-v7l.so               [.] memmove
   0.03%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e23c
   0.03%  decoder:mad      libmad.so.0.2.1                [.] 0x00008554
   0.03%  output:My ALSA   mpd                            [.] 0x0008c8c0
   0.02%  rtio             libasound_module_pcm_equal.so  [.] 0x00001030
   0.02%  rtio             libasound.so.2.0.0             [.] 0x000447fc
   0.02%  rtio             libasound.so.2.0.0             [.] 0x00056404
   0.02%  rtio             libasound_module_pcm_equal.so  [.] 0x0000100c
   0.02%  rtio             libasound.so.2.0.0             [.] 0x0007af28
   0.02%  rtio             libasound_module_pcm_equal.so  [.] 0x00001320
   0.02%  rtio             libasound.so.2.0.0             [.] snd_pcm_areas_copy
   0.02%  rtio             libasound_module_pcm_equal.so  [.] 0x000010a8
   0.02%  rtio             libasound_module_pcm_equal.so  [.] 0x000010b8
   0.02%  rtio             libasound_module_pcm_equal.so  [.] 0x00001134
   0.02%  rtio             mpd                            [.] 0x000505cc
   0.02%  rtio             libasound.so.2.0.0             [.] snd_pcm_mmap_commit
   0.02%  rtio             libasound_module_pcm_equal.so  [.] 0x000011f8
   0.02%  rtio             libasound_module_pcm_equal.so  [.] 0x00000ff8
   0.00%  player           libpthread-2.28.so             [.] __pthread_mutex_lock
   0.00%  output:My ALSA   libarmmem-v7l.so               [.] memcpy
   0.00%  decoder:mad      libmad.so.0.2.1                [.] 0x0000709c
Here is the result when 'mpd' was running without plugin:
Code:
Samples: 475  of event 'cycles:uppp', Event count (approx.): 1832608515
Overhead  Command          Shared Object                  Symbol
  43.89%  rtio             caps.so                        [.] Eq10::cycle
  15.44%  rtio             libasound.so.2.0.0             [.] snd_pcm_area_copy
   5.82%  rtio             libasound.so.2.0.0             [.] snd_pcm_lfloat_convert_float_integer
   3.27%  decoder:mad      libmad.so.0.2.1                [.] III_imdct_l
   3.19%  rtio             libasound.so.2.0.0             [.] snd_pcm_lfloat_convert_integer_float
   2.85%  decoder:mad      libmad.so.0.2.1                [.] 0x00004248
   2.30%  decoder:mad      libmad.so.0.2.1                [.] 0x000041cc
   1.22%  decoder:mad      libmad.so.0.2.1                [.] 0x0000419c
   0.95%  decoder:mad      libmad.so.0.2.1                [.] 0x00006e08
   0.83%  decoder:mad      mpd                            [.] 0x000a6da0
   0.73%  decoder:mad      libmad.so.0.2.1                [.] 0x00006ec8
   0.69%  decoder:mad      libmad.so.0.2.1                [.] mad_bit_read
   0.65%  decoder:mad      libmad.so.0.2.1                [.] 0x000041d8
   0.64%  decoder:mad      libmad.so.0.2.1                [.] 0x000041e4
   0.64%  decoder:mad      libmad.so.0.2.1                [.] 0x00004214
   0.59%  decoder:mad      libmad.so.0.2.1                [.] 0x000041f0
   0.59%  rtio             libarmmem-v7l.so               [.] memcpy
   0.46%  rtio             libasound_module_pcm_equal.so  [.] 0x000011e0
   0.44%  decoder:mad      libmad.so.0.2.1                [.] 0x00007ed0
   0.43%  decoder:mad      libarmmem-v7l.so               [.] memset
   0.42%  decoder:mad      libmad.so.0.2.1                [.] 0x0000391c
   0.42%  decoder:mad      libmad.so.0.2.1                [.] 0x00007fe4
   0.39%  decoder:mad      libmad.so.0.2.1                [.] 0x000040f8
   0.38%  decoder:mad      libmad.so.0.2.1                [.] 0x00003620
   0.38%  decoder:mad      libmad.so.0.2.1                [.] 0x0000638c
   0.38%  decoder:mad      libmad.so.0.2.1                [.] 0x00006e98
   0.37%  decoder:mad      libmad.so.0.2.1                [.] 0x00007fec
   0.37%  decoder:mad      libmad.so.0.2.1                [.] 0x00006434
   0.37%  decoder:mad      libmad.so.0.2.1                [.] 0x00003c80
   0.37%  decoder:mad      libmad.so.0.2.1                [.] 0x00004084
   0.37%  decoder:mad      libmad.so.0.2.1                [.] 0x00002f8c
   0.36%  decoder:mad      libmad.so.0.2.1                [.] 0x00003174
   0.36%  decoder:mad      libmad.so.0.2.1                [.] 0x00007b0c
   0.35%  decoder:mad      libmad.so.0.2.1                [.] 0x00008564
 
Last edited:
The following data was collected when 'mpd' was using the 'peppyalsa' plugin but it was taking about 12% CPU. It's very similar to the no-plugin data. This the first time when there is the reference to the 'libpeppyalsa.so':
Code:
 51.42%  rtio             caps.so                        [.] Eq10::cycle
  22.20%  rtio             libasound.so.2.0.0             [.] snd_pcm_area_copy
   6.59%  rtio             libasound.so.2.0.0             [.] snd_pcm_lfloat_convert_float_integer
   3.28%  decoder:mad      libmad.so.0.2.1                [.] 0x000041f0
   3.00%  decoder:mad      libmad.so.0.2.1                [.] 0x000041e4
   2.91%  decoder:mad      libmad.so.0.2.1                [.] 0x00004238
   2.45%  rtio             libasound.so.2.0.0             [.] snd_pcm_lfloat_convert_integer_float
   1.91%  decoder:mad      libmad.so.0.2.1                [.] 0x000041c4
   1.85%  decoder:mad      libmad.so.0.2.1                [.] 0x00004188
   0.96%  output:My ALSA   libpeppyalsa.so.0.0.0          [.] get_channel_level.isra.0
   0.84%  decoder:mad      libmad.so.0.2.1                [.] 0x00003d8c
   0.83%  decoder:mad      libmad.so.0.2.1                [.] 0x00003614
   0.42%  rtio             libasound_module_pcm_equal.so  [.] 0x00001314
   0.42%  rtio             libasound.so.2.0.0             [.] 0x000b6a34
   0.20%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e290
   0.17%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e2a0
   0.13%  decoder:mad      mpd                            [.] 0x000a6dc0
   0.13%  decoder:mad      libmad.so.0.2.1                [.] 0x00003cb4
   0.13%  io               libpthread-2.28.so             [.] __aeabi_read_tp
   0.11%  player           mpd                            [.] 0x00083abc
   0.01%  output:My ALSA   mpd                            [.] 0x000867d8
   0.01%  output:My ALSA   libarmmem-v7l.so               [.] memcpy
   0.01%  decoder:mad      libmad.so.0.2.1                [.] III_imdct_l
   0.00%  decoder:mad      libmad.so.0.2.1                [.] mad_bit_read
   0.00%  io               libcurl-gnutls.so.4.5.0        [.] 0x0002ff18
   0.00%  player           mpd                            [.] 0x000234fc
   0.00%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e28c
   0.00%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e884
   0.00%  output:My ALSA   libasound.so.2.0.0             [.] 0x0005e888
   0.00%  io               libcurl-gnutls.so.4.5.0        [.] 0x00013a9c
   0.00%  output:My ALSA   mpd                            [.] 0x0008b2cc
   0.00%  decoder:mad      libmad.so.0.2.1                [.] 0x00004118
   0.00%  decoder:mad      libmad.so.0.2.1                [.] 0x00004250
   0.00%  io               libcurl-gnutls.so.4.5.0        [.] 0x00063354
 
Last edited:
Do you have the debug symbols for libasound2 in your distribution? In x86 debian/ubuntu the package is called libasound2-dbg. That would show the method name instead of offset.

EDIT: My wrong, some of your libasound2 methods are already listed, you already have that. I have to look at perf details what that output:: MY ALSA means.
 
Last edited:
Maybe I could narrow the scope.
In my case with FFT switched off (commented out) as
pcm_scope.!peppyalsa {
type peppyalsa
decay_ms 50
meter "/home/pi/mpd.fifo"
meter_max 100
meter_show 0
#spectrum "/home/pi/myfifosa"
#spectrum_max 100
#spectrum_size 30
}


there are no such huge spikes, I see 14-15% for about 2 secs.
So FFT is the reason?



I could just suggest my (favorite) “stone-age” technology – fprintf-ing timestamps + some data (as data amount) to a file. You should see everything you need immediately.


If I could be of any help, please let me know
 
There is audio_output section in mpd.conf called 'My ALSA Device':
Peppy.doc/mpd.conf at 0153b818b861facbf43bfefd5e42db64d5cb9558 * project-owner/Peppy.doc * GitHub
I think output: My ALSA is related to that.

I'm also testing without 'spectrum' data.
Serge, could you try to use the same audio_output in mpd.conf mentioned above?
Probably the issue is related to ALSA configuration (?). Here is the .asoundrc file which I'm using (with deleted 'spectrum' lines):
Peppy.doc/.asoundrc-equal-peppyalsa at master * project-owner/Peppy.doc * GitHub
To disable peppyalsa plugin I just comment out this line in .asoundrc:
#scopes.0 peppyalsa

Serge, there are just two main files in the plugin. Where do you suggest to place fprintf?

peppyalsa/meter.c at master * project-owner/peppyalsa * GitHub
peppyalsa/peppyalsa.c at master * project-owner/peppyalsa * GitHub
 
Here is the .asoundrc file which I'm using:
Code:
pcm.!default {
  type plug
  slave.pcm myequal;
}
ctl.!default {
  type hw
  card 0
}
pcm.myequal {
  type equal;
  slave.pcm reformat;
}
pcm.reformat {
  type lfloat
  slave {
    pcm "mypeppy"
    format S16_LE
  }
}
pcm.mypeppy {
  type meter
  slave.pcm "plughw:0,0"
  scopes.0 peppyalsa
}
ctl.equal {
  type equal;
}
pcm_scope.peppyalsa {
  type peppyalsa
  decay_ms 400
  meter "/home/pi/myfifo"
  meter_max 100
  meter_show 0
}
pcm_scope_type.peppyalsa {
  lib /usr/local/lib/libpeppyalsa.so
}
 
Here are more findings: the issue with high CPU usage occurs only when I switch online radio station streams. It doesn't happen with audio files. That probably means that players (mpd, mpv and vlc) buffer stream data but how it is related to the peppyalsa plugin?
 
How about something like this:

When a radio stream is switched, the input cache takes a while to fill up, before the player starts processing the stream (the incoming data come at playback speed, the cache cannot be filled very fast as in case of local/network file). What happens to alsa chain during the fill-up time? Is the alsa device closed, does the player play zeros, does it simply open the device and send no samples? The last case could lead to e.g. some loop spinning on zero data received etc...

Can you try if changing the input cache size (each player has a config for that) changes the high-CPU time? E.g. mplayer shows when the cache is being filled - is the high-CPU related to that period of the idle playback chain?
 
>Serge, could you try to use the same


Tried your mpd.conf and asound.conf (*).
Revealed a set of strangenesses(**), but no CPU spikes. Even installed the original PeppyMeter.
Could not reproduce the problem anyway.


(*) I have no idea for how you could use alsaplugin configured in .asoundrc (in home folder). Mpd starts in the name of the mpd user, so mpd will just ignore .asoundrc in home/pi.


(**) equalizer perfectly works with aplay, but take no effect with mpd. Maybe it’s because homeless mpd user the mpd starts in the name of. However the configuration is in etc/asound.conf, so for all users.
Also have stupid misunderstanding in connection with reflecting of etc/asound.conf changes.
Sometimes alsa reflects the changes on its own, sometimes reboot is required, alsactl doesn’t help
Your explanation/advice (if any) would be helpful.




>Where do you suggest to place fprintf?


No strict idea at the moment.
Lets follow the logic
So commenting “'scopes.0 peppyalsa» disables peppyalsa and solves the problem. Right?
Thus there are 2 possibilities
- peppyalsa itself creates the problem
- it’s not a peppyalsa direct problem, peppyalsa just affects something else to be CPU consumptive.


Lets start from the first and try to localize
Could you make some steps (one by one) and recompile/try-again libpeppyalsa.so
- comment the FFT part. I’m just not sure that commenting FFT in asound,conf switches the FFT off completely
- comment the pipe writing
- comment the pipe opening additionally

- something else I could invent on results of the above. Please send me the commented code.
- commenting all the payload in peppyalsa, leaving just the plugin skeleton.
(the latter should not cause any problems I believe, otherwise ….. it’s rather the alsa trick on specific hardware, btw did you try to just reboot)


I’m nearly sure you will be able to find something strict to catch at promptly.
 
It looks like the issue is really related to the caching/buffering network stream by the audio players. The issue goes away if I disable a network caching in vlc player (--network-caching=0). Though I don't think that changing caching settings in each player makes sense. It would be much better to handle it in the plugin somehow.

Serge, when I prepare the disk images for the Peppy player I configure the 'mpd' for the 'pi' user. Also I place mpd.conf in /home/pi/.config/mpd/mpd.conf

Regarding .asoundrc, it took me some time to realize that ALSA daemon is checking the correctness of the .asoundrc file. If you create invalid file it will replace it by the default file. That happened for example when I missed this section:
Code:
ctl.!default { 
   type hw card 0
}
 
The perf report showed the load was at the MPD output thread, in alsa-lib. IMO exploring what happens with alsa calls when the caching is underway and no samples are available yet would help to solve the issue.

As of the .asoundrc - there is no alsa daemon, all the reading configs is done by alsalib at the moment the soundcard is opened (snd_pcm_open). IME an incorrect .asoundrc results in an error message. The ctl.XXX section is not required.
 
>/var/lib/mpd


You are right, but how you could explain that alsa equalizer works perfectly for
“aplay wav-file” and “sudo aplay wav-file”, and doesn’t work for mpd?
The only alsa config is etc/asound.conf (so for all users). Mpd’s config is
audio_output {
type "alsa"
name "My ALSA Device"
device "default" # optional
mixer_type "software" # optional
}
so the default device as well.

How mpd could bypass the equalizer and reach the pipe for PeppyMeter?
Following the config above they are in the same processing chain and PeppyMeter at the bottom.
There are no .asoundrc-s in /home/pi, /root and var/lib/mpd
 
>issue is really related to the caching/buffering network stream by the audio players.


Could you use a worker (separate new thread) to serve peppymeter in peppyalsa?
At least there would be no dependencies between the peppy’s pipe/processing and the radio stream




>As of the .asoundrc - there is no alsa daemon, all the reading configs is done by alsalib at the moment the soundcard is opened (snd_pcm_open).


When and what could check and read/use etc/asound.conf correctness/etc. What do you think? By alsalib at the same moment as well?

How could I force it? Via alsactl init? By restarting the player/mpd? I’m really perplexed with the need to re-read/recheck etc/asound.conf after it’s changed manually
 
>I have lost track of how your asound.conf looks.

As Rpi posted yesterday. I was trying to reproduce his problem
pcm.!default {
type plug
slave.pcm myequal;
}
ctl.!default {
type hw
card 0
}
pcm.myequal {
type equal;
slave.pcm reformat;
}
pcm.reformat {
type lfloat
slave {
pcm "mypeppy"
format S16_LE
}
}
pcm.mypeppy {
type meter
slave.pcm "plughw:0,0"
scopes.0 peppyalsa
}
ctl.equal {
type equal;
}
pcm_scope.peppyalsa {
type peppyalsa
decay_ms 400
meter "/home/pi/myfifo"
meter_max 100
meter_show 0
}
pcm_scope_type.peppyalsa {
lib /usr/local/lib/libpeppyalsa.so
}


>Perhaps permissions?
-rw-r--r-- 1 pi pi 973 Jul 13 16:36 /etc/asound.conf
I could hardly imagine that taking into account the signal reached peppyalsa, pcm.myequal could be skipped.
MPD restart was made many times. It's a puzzle
 
As far as I understand the caching works this way: audio player opens network stream and starts caching/buffering incoming data. When a cached data will reach some threshold (e.g. 10% of the cache size) the sound goes to ALSA/speakers. The CPU issue which I observe lasts for the duration of the whole caching not only the initial 10%.