Disable/enable Speaker pHAT lights with vlc in python?

Following my previous issue with the Speaker pHAT and pygame (Speaker pHAT ‘ALSA write failed (unrecoverable): File descriptor in bad state’ error when running pygame) I’ve started using vlc.py as an audio player for my python script. I’m getting on well with vlc, but one issue that I’ve had is that I can’t seem to disable the Speaker pHAT VU meter anymore. With pygame I can call sn3218.disable() to disable the VU meter, but this function doesn’t seem to affect the VU meter’s response to the output from VLC.

Any thoughts about this? I really like the VU meter but I run the Pi headless and would like to be able to disable the lights through python.

The correct method to disable it would be to modify your /etc/asound.conf file to remove the VU meter plugin, so it wont even try to drive the LEDs in the first place.

You will see at the very top of this file a block that looks something like:

pcm.!default {
    type meter
    slave.pcm "softvol"
    scopes.0 pivumeter
}

Which, if I recall correctly, you can just change to:

pcm.!default {
    type plug
    slave.pcm "softvol"
}

Hi gadgetoid,

This disables the VU meter but only once the script has been reset, unlike the sn3218.disable() function which disables the VU meter whilst the script is running, but which doesn’t seem to work with the VLC audio output. Any ideas about how this might be done within a python script? I wondered if changing asound.conf and then restarting the VLC instance would work, but I’m not exactly sure how I would do this using the VLC API. Or might there be a way to configure VLC’s output to be compatible with sn3218.disable()?

Grateful for any advice!

Oh, you’re looking to disable/enable the VU meter on the fly?

Exactly! If it’s possible…

That’s something I’ve been addressing in the development branch of Pi VU Meter, with a move away from the plugging outputting VU info directly onto the device, to using a Python server to accomplish it.

See: https://github.com/pimoroni/pivumeter/tree/devel

If you install the development branch,

git clone https://github.com/pimoroni/pivumeter -b devel
cd pivumeter
./setup.sh

Change the asound.conf to use the socket plugin:

pcm_scope.pivumeter {
	type pivumeter
	decay_ms 500
	peak_ms 400
	brightness 128
	output_device socket
}

run the Speaker pHAT server: https://github.com/pimoroni/pivumeter/blob/devel/python_server/speakerphat.py

And modify that Python file to just ignore the incoming data when required, then you should be able to achieve the effect you want.

Your feedback on this work-in-progress would be handy, too ;)

Many thanks for your response. I’ve given this a go but haven’t yet been able to get it working, probably I’m punching above my weight a bit!

I’ve installed the development branch and edited asound.conf. I found speakerphat.py included with the development branch but am a bit unsure what to do next and how this script relates to the socket output. From what I can see the script only allows direct control of the speaker phat lights, but not an interface with the audio output. Apologies if I’ve missed something here.

I tried editing the above asound.conf section with “output_device speaker-phat” and I am able to get the effect I want with sn3218.disable()/enable(). However, after calling these functions very often the script just gives up and closes without explanation.

The speakerphat.py sets up a socket to which the ALSA plugin connects. If you set output as “socket”, run speakerphat.py and then play audio, you should see the LEDs light up.

I’ve just had a go, but no luck, are you sure that the speakerphat.py you linked to was the file you were thinking of? It doesn’t seem to start the socket server. I noticed that blinkt_server.py was more fleshed out and referred to both the socket_server and speakerphat, so I’ve had a tinker with it and seem to have it working.

I renamed blinkt_server.py to speakerphat_server and edited it to the following:

#!/usr/bin/env python3

import socket_server
import signal
import speakerphat

BRIGHTNESS = 255

class OutputSpeakerPhat(socket_server.OutputDevice):
    def setup(self):
        self.base_colours = [(0,0,0) for x in range(speakerphat.numpix)]
        self.generate_base_colours(BRIGHTNESS)

    def generate_base_colours(self, brightness = 255.0):
        for x in range(speakerphat.numpix):
            self.base_colours[x] = (float(brightness)/speakerphat.numpix-1) * x, float(brightness) - ((255/15) * x), 0

    def display_fft(self, bins):
        pass

    def display_vu(self, left, right):
        left /= 2000.0
        right /= 2000.0

        level = max(left, right)
        level = max(min(level, 8), 0)

        for x in range(speakerphat.numpix):
            val = 0

            if level > 1:
                val = 1
            elif level > 0:
                val = level

            r, g, b = [int(c * val) for c in self.base_colours[x]]

            speakerphat.set_led(x, int(val * 255.0))
            level -= 1 

        speakerphat.show()

    def cleanup(self):
        self.display_vu(0, 0)

socket_server.run(OutputSpeakerPhat)

I then created a variable called numpix in speakerphat.py and set it to 10,

I’m using python 3, so I also had to change

os.chmod(SOCKET_FILE,0777) in socket_server.py 

to

os.chmod(SOCKET_FILE,0o777)

Then in my script I start the server with:

import speakerphat
import speakerphat_server

VU = speakerphat_server.OutputSpeakerPhat()

VU.display_vu(0,0)

Now sn3218.disable/enable work fine with VLC output!

Actually, it seems that calling speakerphat_server.OutputSpeakerPhat() isn’t necessary to start the server, importing is enough.

Nice work! Also you’re absolutely right. I didn’t look carefully at speakerphat.py and, in retrospect, realise it’s nothing but a simple driver for Speaker pHAT that I was importing into an actual server file for testing.

I need to tidy all this stuff up and convert it into a library so users can just include it in their project and do whatever they please with the VU and FFT data.

Thanks for your feedback, it’ll be super useful!

Thanks for your work on this, would have had no clue without the scripts you provided :D Let me know when you’ve got the library uploaded : )

1 Like

I’ve merged some of your feedback in, plus fully refactored the code into a library and introduced a proper Speaker pHAT example which you can find here:

You’ll have to cd into the library directory and install it with sudo python ./setup.py install (or python3 if you’re using it) until we package up and release it properly.

Working good for me : )