PeppyMeter

PeppyMeter is a software VU Meter written in Python. It was originally developed as new 'VU Meter' screensaver for Peppy Player. With minor modifications it became a stand-alone application. PeppyMeter gets audio data from media players (e.g. mpd) via fifo and displays current volume level in a Graphical User Interface in a form of traditional VU Meter.

meters.jpg


Here are the key features of the program:

  • Written in Python.
  • Pygame library leveraged for UI purposes.
  • Fixed resolution 480x320 pixels.
  • Can work with any media player which is capable to output PCM signal to the fifo/named pipe.
  • Supplies 9 default meters out of the box.
  • Allows to add your own meters.
  • Open-source. All source files are available on Github.
  • Provides different algorithms for processing PCM data.
  • Several data sources are available for testing and tuning.
More details including all source files can be found on project's wiki:
https://github.com/project-owner/PeppyMeter.doc/wiki
 
  • Like
Reactions: 1 user
It looks great, but could not run it.

It looks like some issue with Python, which is the first time i use, btw...:confused:

Traceback (most recent call last):
File "peppymeter.py", line 22, in <module>
from util import Util
File "/home/pi/PeppyMeter/util.py", line 24, in <module>
from config import Config
File "/home/pi/PeppyMeter/config.py", line 22, in <module>
from configparser import ConfigParser
ImportError: No module named configparser
 
Fixed!:D

https://github.com/project-owner/Peppy.doc/wiki


Python comes with Raspbian distribution therefore there is no need to install it separately. The Peppy player was written using Python syntax of version 3. But the default Python version is 2.7. So if you just start Python from command line the version 2.7 will be in use. There is the symbolic link which points to version 2.7 - /usr/bin/python. That link should point to version 3 instead. To re-link run the following command:

sudo ln -s -f /usr/bin/python3.4 /usr/bin/python

I have seen from the previous project that your player is provided with a WEBui. Any chance to use your meter in a self made webui without too much work?
 
Thank you Odal3 and GDO!

GDO, yes in addition to the touchscreen connected to the Raspberry, Peppy Player also has a Web UI.But that Web UI doesn't support the screensavers running in the touchscreen. That's because devices where you are running Web UI usually have they own screensavers. Another reason - eliminate network traffic. Therefore when Web UI receives 'start screensaver' event it just greys out the current screen. When it receives 'stop screensaver' event it removes that grey mask.

Theoretically PeppyMeter can be implemented in web browser as well. But there are some things which should be changed in the current Peppy Player implementation and some stuff should be created from scratch. Overall this is not one weekend task ;) Maybe in version #2? But I don't guarantee that. I have some other plans for the next project.

If you feel yourself comfortable in Python and web technologies you can definitely try to do that yourself.
 
Ok... obviously i don't really feel comfortable between snakes and screensavers...:D

Anyway your meter will be usefull for monitoring recording sessions on a rpi that i am trying to control from webui. I can still control the sessions from webui while outputting your meter to another screen connected to the rpi hdmi output.
 
New version of PeppyMeter was released today.
New features:

  • Added new native resolution 320x240px
  • Redesigned volume data extraction from named pipe
  • Handling of data input from different audio players through ALSA file plugin
  • Implemented support for output to Serial Interface and I2C interface

Here is example implementation of I2C output:


i2c-1.png



i2c-4.jpg



Here is example implementation of Serial interface created by Tobias (Hamburg):


serial.jpg



More details can be found on wiki pages:
Home * project-owner/PeppyMeter.doc Wiki * GitHub
 
Last edited:
When I start peppymeter, the meter is showing frenetic activity before any sound program is running. Is that normal?

Your sample asoundrc is valid, but no sound comes from the speakers, and the short piece of music does not finish. Any thoughts?

Would be good if it can be made to work.

Regards,
Andy
 
Last edited:
When I start peppymeter, the meter is showing frenetic activity before any sound program is running. Is that normal?

Your sample asoundrc is valid, but no sound comes from the speakers, and the short piece of music does not finish. Any thoughts?

Would be good if it can be made to work.

Regards,
Andy


The default data source configured in /home/pi/PeppyMeter/config.txt is 'noise'. It's using random volume numbers. This is to make sure that everything required for UI was properly installed/configured. To see the real volume you need to define 'pipe' data source for property 'type' in section [data.source] of the config.txt. Also in the same section you need to define pipe name in property 'pipe.name' (e.g. /home/pi/myfifo).


Which audio player do you use? In most cases you need to start PeppyMeter before starting audio player.


I believe these changes should help if not feel free to ask for help.
 
Does the peppy script keep reading/flushing the named pipe? If the pipe buffer gets full, I would expect the playback to stop as the popen in file plugin starts waiting on the write operation to the pipe.


You are right, to prevent buffer overflow PeppyMeter should be started before audio player and it should be kept running when audio player is running. If you don't use PeppyMeter the pipe configuration should be excluded from the ALSA configuration.


I found that when you configure pipe output for MPD and don't use ALSA file plugin then MPD handles pipe much better than ALSA plugin. It is not sensitive to buffer underrun/overflow so you can start MPD and PeppyMeter in any order. Also it provides normal signal in both channels.
 
MPD opens the fifo in nonblocking mode MPD/FifoOutputPlugin.cxx at master * MusicPlayerDaemon/MPD * GitHub and keeps checking the write result - if the pipe is full, it drops the samples MPD/FifoOutputPlugin.cxx at master * MusicPlayerDaemon/MPD * GitHub

Whereas alsa file plugin does not specify the nonblocking flag - for both files git.alsa-project.org Git - alsa-lib.git/blob - src/pcm/pcm_file.c and pipes git.alsa-project.org Git - alsa-lib.git/blob - src/pcm/pcm_file.c . When the pipe is full, the writer gets blocked in the syscall.
 
Which audio player do you use? In most cases you need to start PeppyMeter before starting audio player.

I use audacious, configured to use ALSA output.

That output is modified by an extensive .asoundrc file (actually /etc/asound.conf) for crossover and equalisation. ALSA is quite picky about which pcm type can be slave to another pcm. I have been able to make a blue meter work by pretending it is mplayer and setting pipe.size to 8192.

Unfortunately hi-res files seem to defeat it, even with pipe.size set to 32k.

Regards,

Andy
 
MPD opens the fifo in nonblocking mode MPD/FifoOutputPlugin.cxx at master * MusicPlayerDaemon/MPD * GitHub and keeps checking the write result - if the pipe is full, it drops the samples MPD/FifoOutputPlugin.cxx at master * MusicPlayerDaemon/MPD * GitHub

Whereas alsa file plugin does not specify the nonblocking flag - for both files git.alsa-project.org Git - alsa-lib.git/blob - src/pcm/pcm_file.c and pipes git.alsa-project.org Git - alsa-lib.git/blob - src/pcm/pcm_file.c . When the pipe is full, the writer gets blocked in the syscall.


Thank you for the detailed info. I think the best way to avoid this kind of issues is to implement new ALSA plugin specific for PeppyMeter. This way it will be possible to have full control on pipe. Something similar to 'ameter' plugin:
ameter
Hopefully it's doable and could be good candidate for the next release.

I use audacious, configured to use ALSA output.

That output is modified by an extensive .asoundrc file (actually /etc/asound.conf) for crossover and equalisation. ALSA is quite picky about which pcm type can be slave to another pcm. I have been able to make a blue meter work by pretending it is mplayer and setting pipe.size to 8192.

Unfortunately hi-res files seem to defeat it, even with pipe.size set to 32k.

Regards,

Andy


Yeah more likely hi-res signal is too much for this Python app. I think only dedicated ALSA plugin could help here. In this case some PCM signal processing could be done in C/C++ in plugin itself and Python could be used just for UI purposes.

...
Unfortunately hi-res files seem to defeat it, even with pipe.size set to 32k.

Andy


You can also try to play with value for 'polling.interval' property. Usually
when you increase pipe size it's better to increase polling interval. For example
try to set it to 0.02. Though I've never used hi-res signal.
 
Honestly, I would not spend time developing a specific alsa-lib plugin, the API slowly drifts and if the code is not in upstream, you will end up with non-compilable code eventually.

You can use specialized buffer implementations instead of simple fifo, such as mbuffer.

IMO python should be able to handle processing high res samples, if it can afford processing data in larger chunks - e.g. mbuffer with larger size and reasonably set watermarks.
 
Alsa file plugin can pipe to mbuffer using the ! notation. It gives information on format parameters via replacement characters.

I still think a python script with dedicated reader thread should be able to handle high res via regular pipe from the file plugin. It would be started with format parameters to understand the incoming stream (the file plugin closes the pipe when the stream closes) and output the averaged numbers to some continuously running display daemon, also in python. If python did not start fast enough before the pipe fills in and stops the alsa chain, you can always throw mbuffer in between.

The C plugin would have to either compute fast, or use a separate reading thread anyway.

Just my 2 cents, I prefer python to C :)
 
OK, I'll check if I can leverage that ! notation in Python.

PeppyMeter is doing exactly what you described - it reads data from pipe in separate thread, processes that data and provides it to UI which is running in another thread.

Theoretically PeppyMeter should be able to support hi-res signal as well as it's using Python library 'audioop' which should support signal resolution up to 32 bit:
22.1. audioop — Manipulate raw audio data — Python 3.6.5 documentation

I just never tried that. I'm not sure if I have such files in my collection. Usually some trade-off should be found between pipe size and polling interval.

I also faced some issue with ALSA File plugin - it looks like the signal in right channel has much lower value than the signal in left channel. Maybe it's the question of data format which plugin provides. Probably that's not "pure" PCM signal and has some additional info.
 
OK, I'll check if I can leverage that ! notation in Python.

You can do it easily, it just runs a command and sends the samples to its stdin via popen ALSA project - the C library reference: PCM (digital audio) plugins The described parameters are replaced in the command name.


PeppyMeter is doing exactly what you described - it reads data from pipe in separate thread, processes that data and provides it to UI which is running in another thread.

I understand. But the file plugin starts the process when the alsa device is open and closes popen (which usually results in the process exit) when the device is closed. That would be affecting your GUI process too.

It is good to have the reader started with the new stream as it will always know the actual stream parameters, passed as command line options.



Theoretically PeppyMeter should be able to support hi-res signal as well as it's using Python library 'audioop' which should support signal resolution up to 32 bit:
22.1. audioop — Manipulate raw audio data — Python 3.6.5 documentation

Looks very good.

I just never tried that. I'm not sure if I have such files in my collection.

You can convert/generate arbitrary format with sox.

I also faced some issue with ALSA File plugin - it looks like the signal in right channel has much lower value than the signal in left channel. Maybe it's the question of data format which plugin provides. Probably that's not "pure" PCM signal and has some additional info.

The plugin outputs format which you specify - raw or wav (= raw + wav header). The actual stream format depends on the samples being played and is passed by the plugin to your program via those command-line parameters.

It did work OK when I was testing the addition of the pipe capability to the file plugin git.alsa-project.org Git - alsa-lib.git/commit

I really like your project. I have been watching it closely as this area does interest me ( I few years ago I toyed with Home * pavhofman/plabs-player Wiki * GitHub, some new features are currently WIP... )
 
Last edited: