How to adjust volume on RasPi

(Sort of from the other thread but new question)

I have since discovered that a lot of the problem was the BLUE TOOTH part of the speaker.
Got a 3.5mm cable and it works now a lot better than if using BT.

The speaker (built in amp too) is now plugged into the audio-out jack.
Is there a way (given the message has the required value set) to control the RasPi's volume?

(Torn between asking here or on the RasPi forum. But as I am using Node-red, it kinda falls in the grey area.)

:wink:

Thanks in advance.

If, as you say, related to other thread you do actually have the solution very close in front of you. Another option for ffplay, Just add -volume 50 (or another integer value 0-100)

Like...

ffplay -autoexit -nodisp -volume 30 /home/pi/beep-03.mp3

I admit I have the TTS working.

But as is, I can't adjust the volume on a message by message basis.

I set the volume and and can play simple messages at the set volume.

This is the command (exec node) settings


(Better layout of what I am doing.)
Note the TTS node on the left of the screen.
That is where all text goes in.
The other stuff you can see is testing.
(Yes, I'm messy) :wink:

So I think the command is:
ffmpeg -i {msg.payload} -f wav - | DISPLAY=:0 aplay
Yes?

One way I understand how to do the volume is the include that as a message part and then using the template node put the volume parameter in the command.

I can't translate what you posted as the command to what I have.
(Yes, I'm not smart)

I may need another nudge to explain what I am missing.

I cannot understand why you use ffmpeg, my example demonstrates how to use ffplay (that is part of the ffmpeg install)

You could prepare the payload that is sent to the exec node with the volume you wish, per message, what I think, just add -volume XX in front of the path to the file that shall be played. You understand what I mean?

Maybe you have to let the specific message set a flow variable with the wanted volume level and then you use that in the function node to prepare the payload that is being sent to the exec node

I'm using ffmpeg because that is what was used to get the TTS working.

Sorry. I can't build on things I don't know.
As ffmpeg was used originally, that is what I am still using.

Your example - as much as it works - I can't translate it to accept TTS messages.

I fear you are over estimating my ability to do that.
(Again: I'm being honest. This is new to me and I have NO IDEA on the wrokings of these programs.)

I used aplay because when testing output to my bluetooth speakers using a RPi Zero W, I found that saving the mp3 to a buffer and using ffplay introduced a longer delay than converting the mp3 to a wav with ffmpeg and piping the wav to aplay. Since you are able to hard wire your speakers to your RPi it is obviously not a Zero W and is therefore likely to be faster processor, so any delay may be more inconsequential. So use ffplay as suggested without using ffmpeg and all should be well.

I insist showing my example using ffplay. You may like it or not. It works well from my perspective, no reason for me to try something else

[{"id":"3e0d9b5c.fe01b4","type":"inject","z":"2a2ce5f5.67757a","name":"This works perfect for me","props":[{"p":"payload"},{"p":"volume","v":"30","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"This works perfect for me","payloadType":"str","x":270,"y":150,"wires":[["3d9635bc.53c14a"]]},{"id":"3d9635bc.53c14a","type":"ttsultimate","z":"2a2ce5f5.67757a","name":"","voice":"en-AU","ssml":false,"sonosipaddress":"192.168.1.109","sonosvolume":"30","sonoshailing":"0","config":"557d8082.eb5a8","property":"payload","propertyType":{},"rules":[],"playertype":"noplayer","speakingrate":"","speakingpitch":"","unmuteIfMuted":false,"elevenlabsStability":"","elevenlabsSimilarity_boost":"","x":540,"y":200,"wires":[["17d1372ec4e2fa56"],[]]},{"id":"17d1372ec4e2fa56","type":"switch","z":"2a2ce5f5.67757a","name":"","property":"filesArray","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","repair":false,"outputs":1,"x":720,"y":200,"wires":[["b6292f5b6fb85a0f"]]},{"id":"b6292f5b6fb85a0f","type":"function","z":"2a2ce5f5.67757a","name":"function 6","func":"let af = msg.filesArray[0].file;\nlet vol = parseInt(msg.passThroughMessage.volume, 10);\nmsg.payload = '-volume '+vol+' '+af;\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":880,"y":200,"wires":[["9b644a0b5cb0fbc9","cb2760a7571bf9b1"]]},{"id":"9b644a0b5cb0fbc9","type":"exec","z":"2a2ce5f5.67757a","command":"ffplay -nodisp -autoexit","addpay":"payload","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":1110,"y":200,"wires":[[],[],[]]},{"id":"172b415bc9693c77","type":"mqtt in","z":"2a2ce5f5.67757a","name":"","topic":"TTS","qos":"2","datatype":"auto-detect","broker":"4606489c.2375c8","nl":false,"rap":true,"rh":0,"inputs":0,"x":330,"y":90,"wires":[["3d9635bc.53c14a"]]},{"id":"5e7ad828a226b98f","type":"inject","z":"2a2ce5f5.67757a","name":"Shouting out loud","props":[{"p":"payload"},{"p":"volume","v":"100","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Shouting out loud","payloadType":"str","x":250,"y":200,"wires":[["3d9635bc.53c14a"]]},{"id":"2b5336427268b9e9","type":"inject","z":"2a2ce5f5.67757a","name":"Whispering something","props":[{"p":"payload"},{"p":"volume","v":"5","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Whispering something","payloadType":"str","x":260,"y":250,"wires":[["3d9635bc.53c14a"]]},{"id":"cb2760a7571bf9b1","type":"debug","z":"2a2ce5f5.67757a","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":880,"y":270,"wires":[]},{"id":"557d8082.eb5a8","type":"ttsultimate-config","name":"googletranslate","noderedipaddress":"127.0.0.1","noderedport":"1980","purgediratrestart":"leave","ttsservice":"googletranslate","TTSRootFolderPath":""},{"id":"4606489c.2375c8","type":"mqtt-broker","name":"","broker":"192.168.0.233","port":"1883","clientid":"","usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":""}]

Fair enough, I understand, but my willingness to provide example is just what I have shown, can't elaborate on all possible ways to reach the same goal

Sorry, we seem to have got on different thought tracks.

I'll check your flow again and let you know.

It isn't I was ignoring what you said. It just got lost in all the things I was doing.

BTW

(all)
I have MOVED ON from the bluetooth speakers!
It was PAINFUL (to say the least).
Messages getting lost, or not completely heard.

Got a 3.5mm cable and it is now wired.
Messages now 99.99% received and played.
Where as with the BT, it was 40% at best.

Sorry to report that there is NOTHING heard when I run that script.

Maybe because I have (since) wired the speaker rather than having it via BT.

Well, if you have a working solution, better keep that

EDIT: I think ffplay will use the default sound system, have you checked that the correct sound system is selected?

Anyway, for what it is worth, here is a simple diagnostic I tried

My example used .mp3 files and was working fine on 3 different computers so I thought it could be that you are using .wav that caused it not to work for you

  • download a .wav file and put it into /home/pi
  • run the following command in a terminal on my pi
 ffplay -autoexit -nodisp -hide_banner -volume 25 /home/pi/StarWars3.wav

The result (EDIT: using a JBL BT speaker connected to the RPi)

EDIT2: But...when I run the same command from the NR flow I hear nothing...the same as you. It works perfect on a Windows box as well as a Laptop running Debian. Must be some access rights missing for the standard pi user for BT speakers/devices. Works from terminal with pi user but not from Node-RED exec node

ALSA lib dlmisc.c:287:(snd1_dlobj_cache_get) Cannot open shared library /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_pcm_bluealsa.so ((null): /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_pcm_bluealsa.so: cannot open shared object file: No such file or directory)

Since I use RPi Zero's I use bluetooth, but as of Bullseye I had to make Pulse Audio either open system wide or specifically to Node Red. Not sure whether FFplay is dependent on PulseAudio but for what it is worth:

Making PulseAudio specifically available to Node Red

Create a PulseAudio Configuration File by entering into the Raspberry Pi Terminal:

sudo nano /home/<RPI-username>/.config/pulse/client.conf
Replace with the actual username for the RPI device.

In the configuration file in nano add the following lines

autospawn = no
daemon-binary = <default location>

where the <default location> is determined from that viewable in /etc/pulse/client.conf` file.

Exit and save the file. This configuration prevents PulseAudio from starting automatically and ensures it runs with minimal resources.

It is necessary to run PulseAudio for the Node-RED user using the pulseaudio command:

sudo -u <RPI-username> pulseaudio --start

Replace <RPI-username> with the actual username.

Another Possible issue
If you have updated to the latest Bookworm release of RPi OS, then PulseAudio has been replaced by PipeWire. Could that be an issue for Node Red?

Thanks for your advice, unfortunately it did not help. I wonder if it could be a problem related to the location of libasound_module_pcm_bluealsa.so
I have seen some other related discussions similar to the same kind of issue

Got it working now, from Node-RED using the JBL BT speaker

What I did:

  • re-installed sudo apt install bluealsa and after that the libasound_module_pcm_bluealsa.so was found

Still no sound from the speaker even if the debug showed that sound was correctly streamed out

  • turned off normal audio by commenting out the line dtparam=audio=on in config.txt
  • rebooted the RPi

Now it worked playing sound from Node-RED :+1:

But it stopped working from the Terminal...it streams ok but no sound...but hey...we wanted it to be working from Node-RED

https://forums.raspberrypi.com/viewtopic.php?t=170160

Just updating the flow so it handles messages via MQTT correctly, including setting the desired volume level. If you send a message via MQTT, send a payload with the following format: "The message to be spoken"|15 where 15 is the volume level

[
    {
        "id": "e43cfa8e3a673ea2",
        "type": "inject",
        "z": "bf1b20db733dbc1c",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "Water leakage dishwashing machine|3",
        "payloadType": "str",
        "x": 120,
        "y": 140,
        "wires": [
            [
                "0e9b67e3c9651ffa"
            ]
        ]
    },
    {
        "id": "0e9b67e3c9651ffa",
        "type": "mqtt out",
        "z": "bf1b20db733dbc1c",
        "name": "",
        "topic": "TTS",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "d25677b9.097f68",
        "x": 250,
        "y": 140,
        "wires": []
    },
    {
        "id": "3e0d9b5c.fe01b4",
        "type": "inject",
        "z": "bf1b20db733dbc1c",
        "name": "This works perfect for me",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "volume",
                "v": "20",
                "vt": "num"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "This works perfect for me",
        "payloadType": "str",
        "x": 180,
        "y": 270,
        "wires": [
            [
                "3d9635bc.53c14a"
            ]
        ]
    },
    {
        "id": "17d1372ec4e2fa56",
        "type": "switch",
        "z": "bf1b20db733dbc1c",
        "name": "",
        "property": "filesArray",
        "propertyType": "msg",
        "rules": [
            {
                "t": "nnull"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 630,
        "y": 320,
        "wires": [
            [
                "b6292f5b6fb85a0f"
            ]
        ]
    },
    {
        "id": "b6292f5b6fb85a0f",
        "type": "function",
        "z": "bf1b20db733dbc1c",
        "name": "function 6",
        "func": "let af = msg.filesArray[0].file;\nlet vol = parseInt(msg.passThroughMessage.volume, 10);\nmsg.payload = '-volume '+vol+' '+af;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 790,
        "y": 320,
        "wires": [
            [
                "9b644a0b5cb0fbc9"
            ]
        ]
    },
    {
        "id": "9b644a0b5cb0fbc9",
        "type": "exec",
        "z": "bf1b20db733dbc1c",
        "command": "ffplay -nodisp -autoexit",
        "addpay": "payload",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 1020,
        "y": 320,
        "wires": [
            [],
            [],
            []
        ]
    },
    {
        "id": "172b415bc9693c77",
        "type": "mqtt in",
        "z": "bf1b20db733dbc1c",
        "name": "",
        "topic": "TTS",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "d25677b9.097f68",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 250,
        "y": 210,
        "wires": [
            [
                "6163d16aeae6a338"
            ]
        ]
    },
    {
        "id": "5e7ad828a226b98f",
        "type": "inject",
        "z": "bf1b20db733dbc1c",
        "name": "Shouting out loud",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "volume",
                "v": "100",
                "vt": "num"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "Shouting out loud",
        "payloadType": "str",
        "x": 160,
        "y": 320,
        "wires": [
            [
                "3d9635bc.53c14a"
            ]
        ]
    },
    {
        "id": "2b5336427268b9e9",
        "type": "inject",
        "z": "bf1b20db733dbc1c",
        "name": "Whispering something",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "volume",
                "v": "5",
                "vt": "num"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "Whispering something",
        "payloadType": "str",
        "x": 170,
        "y": 370,
        "wires": [
            [
                "3d9635bc.53c14a"
            ]
        ]
    },
    {
        "id": "3d9635bc.53c14a",
        "type": "ttsultimate",
        "z": "bf1b20db733dbc1c",
        "name": "",
        "voice": "en-AU",
        "ssml": false,
        "sonosipaddress": "192.168.1.109",
        "sonosvolume": "30",
        "sonoshailing": "0",
        "config": "557d8082.eb5a8",
        "property": "payload",
        "propertyType": {},
        "rules": [],
        "playertype": "noplayer",
        "speakingrate": "",
        "speakingpitch": "",
        "unmuteIfMuted": false,
        "elevenlabsStability": "",
        "elevenlabsSimilarity_boost": "",
        "x": 450,
        "y": 320,
        "wires": [
            [
                "17d1372ec4e2fa56"
            ],
            []
        ]
    },
    {
        "id": "6163d16aeae6a338",
        "type": "change",
        "z": "bf1b20db733dbc1c",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "volume",
                "pt": "msg",
                "to": "$split(payload, '|')[1]\t",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$split(payload, '|')[0]",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 210,
        "wires": [
            [
                "3d9635bc.53c14a"
            ]
        ]
    },
    {
        "id": "d25677b9.097f68",
        "type": "mqtt-broker",
        "name": "",
        "broker": "127.0.0.1",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "sessionExpiry": ""
    },
    {
        "id": "557d8082.eb5a8",
        "type": "ttsultimate-config",
        "name": "googletranslate",
        "noderedipaddress": "127.0.0.1",
        "noderedport": "1980",
        "purgediratrestart": "leave",
        "ttsservice": "googletranslate",
        "TTSRootFolderPath": ""
    }
]
2 Likes

Um,

Reading the last 5 replies:
You seem to be stuck on me using Bluetooth speakers.

As I said in post 8:
I have moved on from them as they are NOT reliable.

Using WIRED speakers I get 99.99% of messages.
With the BT ones, it was about 40% at best.

This code works.

If I use this code:
(See on the right of the previous shot)

SILENCE.

No blame assigned.

But as I've said a few time already:
I do NOT understand the commands. ffplay and ffmpeg

So I can't just change using one with the other.

It would be nice to get a volume adjustment ability in the code.
That way normal messages can be played and heard where as IMPORTANT messages will be louder and therefore WILL be heard and actions taken.

Don't misunderstand, I have full respect for your solution that works for you, that's great, don't change then. My last postings where just about how to make it work with a BT speaker, I was puzzled & challenged why it did not work at first so I took it on and fixed it in my setup on the RPi. That's all I wanted to share, including how to change the volume on demand per message importance

(I believe there could/should be an option/parameter also for ffmpeg to set volume level per message. But that means searching for it, ffmpeg do have tons of options for all kind of things)

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.