¿ªÔÆÌåÓý

Issue #4 Raspberry Pi 4 HDMI audio modules conflict with loopbacks


 

Referring to:?

Since my other comments on other issues have gone unanswered, I will try to discuss this here.

A screenshot of part of the issue:




I've talked about this a few times in this group:

/g/BITX20/message/108542? -- you don't have to rely on order of discovery if you use proper names

/g/BITX20/message/108485? -- stop using numbers, start using names

A fix is IMO pretty easy:
Create and use a new git branch so sending a PR is easier ('git checkout -b sbitx-alsa-names' will do this)
Go into sbitx.c and change?"plughw:0,0" to?"plughw:CARD=audioinjectorpi,DEV=0".
Go into sbitx_sound.c and change?"plughw:1,0" to?"plughw:CARD=Loopback,DEV=0".
Go into sbitx_sound.c and change?"plughw:2,1" to?"plughw:CARD=Loopback_1,DEV=1".

Rebuild the code and test that the sbitx app still works for rx and tx of voice modes.
Then test that the sbitx app still works with fldigi and/or wsjt-x external digital apps.

Then change /boot/config.txt to not disable HDMI audio (or standard broadcom headphone jack either).
Reboot and do the same tests.

Then plug in a USB headset or soundcard dongle, reboot, retest.

I'm pretty sure it will all just work based on the testing I did earlier.

It it works, send a PR to the ?repo and hopefully some day the fix will get merged.

I would do this, but my code base is now so different than the afarhan repo that it doesn't make sense for me to be the one to do it.


--
Regards,
Dave, N1AI


Paul
 

¿ªÔÆÌåÓý

Hi Dave
Might the update I did for the headset issue (/g/BITX20/message/108643) provide the solution for this too?
If you are able to identify the HDMI interface and set its priority as I did for the USB ports then at least you can prevent clashes with the loopback interfaces.
The one bit I probably haven¡¯t quite answered is the naming of the loopback interfaces, though I think looking at the alsa modules config might be the starting point.?
This bit of config would be the same regardless of the codebase as it is core sound config from a naming perspective, though that would have an impact on the code as references to the loopbacks would then have to be updated to reflect the new device names.
I am now at the point where I need to understand the code architecture at a higher level to see how the code modules (assuming its modular) interact with each other.?
While Ashar pointed me at the mixer section of the sbitx.sound.c code, it is called by something else that passes the device names, hence me needing to understand the code at an architectural/flow level before digging in. Maybe in doing so we can get to device naming at the same time.?
From what I can tell in the code Ashar refers to the aplay -l (or -L) command to get device names, what I don¡¯t see is how this is done and its not in the sbitx.sound.c code.
ALSA config will be the source of naming of devices but on reflection maybe the loopbacks could be individually named in the /etc/rc.local file instead of using the combined name of snd-aloop for all devices, try creating a line for each loopback e.g.

modprobe sbitx-digi-out enable=1 index=1
modprobe sbitx-digi-in enable=1 index=2

Instead of

modprobe snd-aloop enable=1,1,1,1 index=1,2,3,4

I suspect this is where /proc/asound/modules gets the loopback names from, do cat /proc/asound/modules to see what I mean.

I recall some references to snd-aloop in the code so it may need tweaking to reflect these changes.

Hope this helps in some way

Regards
Paul G0KAO


Paul
 

Actually had a bit of a google after I wrote the reply, this may be more help:?
snd-aloop is a module so the key is to change the id associated with it to? make it more identifiable, will still need a line for each loopback along the lines of :

Ok I did a test, I want to know the answer to this too, NOTE - I haven't run the sbitx app yet with these changes, it might not work from that point of view but answers the device naming question I think.
I tried two changes:
  • ?sudo nano /etc/modprobe.d/alsa-base.conf
  • options (efault) index=-2
    options snd-aloop index=1 id=sbitx-digi-out
    options snd_usb_audio index=5

This resulted in no change to the output from?cat /proc/asound/modules
pi@sbitx:~ $ cat /proc/asound/modules
?0 (efault)
?1 snd_aloop
?2 snd_aloop
?3 snd_aloop
?4 snd_aloop
?5 snd_usb_audio
pi@sbitx:~ $

the output from p
i@sbitx:~ $ cat /proc/asound/cards
?0 [audioinjectorpi]: audioinjector-p - audioinjector-pi-soundcard
? ? ? ? ? ? ? ? ? ? ? audioinjector-pi-soundcard
?1 [sbitxdigiout? ?]: Loopback - Loopback
? ? ? ? ? ? ? ? ? ? ? Loopback 1
?
I trimmed the rest as there was no change.
The next test was updating /etc/rc.local as I suggested as a possible option earlier:
pi@sbitx:~ $ sudo nano /etc/rc.local

? GNU nano 7.2? ? ? ? ? ? ? ? ? ? ? /etc/rc.local? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
modprobe snd-aloop enable=1,1,1,1 index=1,2,3,4 id=sbitxdigiout,sbitxdigiin,sbitxusbout,sbitxusbin

This after a reboot produces:
pi@sbitx:~ $ cat /proc/asound/cards
?0 [audioinjectorpi]: audioinjector-p - audioinjector-pi-soundcard
? ? ? ? ? ? ? ? ? ? ? audioinjector-pi-soundcard
?1 [sbitxdigiout? ?]: Loopback - Loopback
? ? ? ? ? ? ? ? ? ? ? Loopback 1
?2 [sbitxdigiin? ? ]: Loopback - Loopback
? ? ? ? ? ? ? ? ? ? ? Loopback 2
?3 [sbitxusbout? ? ]: Loopback - Loopback
? ? ? ? ? ? ? ? ? ? ? Loopback 3
?4 [sbitxusbin? ? ?]: Loopback - Loopback
? ? ? ? ? ? ? ? ? ? ? Loopback 4
?5 [II? ? ? ? ? ? ?]: USB-Audio - Jabra EVOLVE 30 II
? ? ? ? ? ? ? ? ? ? ? GN Audio A/S Jabra EVOLVE 30 II at usb-0000:01:00.0-1.4, full speed
pi@sbitx:~ $

no change to the output from?
pi@sbitx:~ $ cat /proc/asound/modules
?0 (efault)
?1 snd_aloop
?2 snd_aloop
?3 snd_aloop
?4 snd_aloop
?5 snd_usb_audio
pi@sbitx:~ $

as before. Just needs to test sbitx app now to see if it still runs with these changes :-)

Sbitx app started, I got sound, no antenna connected as I in the lounge working all this out while watching tv with the boss :-)
Built in FT8 appears to work into a dummy load anyway.
My JTDX needs work when I have a full size monitor available but this screenshot from settings shows the new device names are available now for digital software configuration:


initial signs look positive

Regards
Paul G0KAO

?
?


 

Paul,
Your perseverance on this topic is very sympathetic and I hope you can fulfill your original idea.
This is how you can get from "PlughW: 1.0" and "Plughw: 2.1" to [Sbitxdigiout] and [Sbitxdigiin].
The latter are more understandable to users.
This is where teamwork can be seen, where everyone adds their own knowledge to achieve a common goal.
--
Gyula HA3HZ


 

You can disable the HDMI audio in the config.text file in the boot folder. ?I am laid up and can not get to my computer to look up the specific line to add the ¡°,noaudio¡± to the end of the dev= line and do not remember the driver that the video is using.?


If you post the contents of config.txt I can tell you the link to modify. ? A search for noaudio in the group may also work


73
Evan
AC9TU


 

dtoverlay=vc4-kms-v3d,noaudio

On 2/4/24 11:14, Evan Hand wrote:

You can disable the HDMI audio in the config.text file in the boot folder. ?I am laid up and can not get to my computer to look up the specific line to add the ¡°,noaudio¡± to the end of the dev= line and do not remember the driver that the video is using.


If you post the contents of config.txt I can tell you the link to modify. ? A search for noaudio in the group may also work


73
Evan
AC9TU


 

Thanks Rafael, ?that is the line in config.txt.?


73
Evan
AC9TU


 

Is there a way we can provide a selection of where the audio routes from some kind of command??
I would love to ideally route the mic and speaker to a bluetooth headset or some rtp stream or the default speaker/mic.
- f

On Sun, Feb 4, 2024, 6:36 PM Evan Hand <elhandjr@...> wrote:

Thanks Rafael, ?that is the line in config.txt.?


73
Evan
AC9TU


 

On Sun, Feb 4, 2024 at 06:14 AM, Evan Hand wrote:
You can disable the HDMI audio in the config.text file in the boot folder. ?I am laid up and can not get to my computer to look up the specific line to add the ¡°,noaudio¡± to the end of the dev= line and do not remember the driver that the video is using.?
I hope no one thinks I'm picking on you.? I admire your many helpful posts here.? I hope you are feeling better soon.?

However, the point I am making is it should not be necessary to disable HDMI speakers, USB headsets, or the on-board headphone jack either, if just three lines of code in the sbitx application are changed.

IMO, we should be asking the question "how can I use other audio devices" instead of "how do we turn off other audio devices".

This is really relevant to those of us who have the board-only option and want to use the Pi in sbitx for many different things instead of it just being an embedded radio dsp/gui device.

And, for Paul, he wants to use his USB headset without having to take it out every time he reboots.

These are sensible goals, no?

I admire Paul's work.? He already has a deeper understanding of the situation than I do.

I don't really care which exact approach is taken.??

And in the case of Paul's work, maybe a better understanding of Linux's audio options will lead to everyone being able to use USB headsets and other USB-attached sound devices, perhaps Bluetooth as well.

Unfortunately for me it's bad timing for me to dig deeper into this space, all I can do is keep trying to get people to focus on what I think the goal should be.
?
--
Regards,
Dave, N1AI


 

On Sun, Feb 4, 2024 at 02:42 AM, Paul wrote:
If you are able to identify the HDMI interface and set its priority as I did for the USB ports then at least you can prevent clashes with the loopback interfaces.
I agree.

The one bit I probably haven¡¯t quite answered is the naming of the loopback interfaces, though I think looking at the alsa modules config might be the starting point.?
This bit of config would be the same regardless of the codebase as it is core sound config from a naming perspective, though that would have an impact on the code as references to the loopbacks would then have to be updated to reflect the new device names.
I am now at the point where I need to understand the code architecture at a higher level to see how the code modules (assuming its modular) interact with each other.?
While Ashar pointed me at the mixer section of the sbitx.sound.c code, it is called by something else that passes the device names, hence me needing to understand the code at an architectural/flow level before digging in. Maybe in doing so we can get to device naming at the same time.?

I am confident that I am showing the exact lines of code that set the device names in this post.

Look for the highlighted "plughw" strings in three places in that post.

These are the three device names being used by sbitx to access the codec and the two loopback devices.

They are being set by the functions that start the sound handling threads.

This is also why I say they are running even when no one is listening, the code for the devices are being started unconditionally.

And I am giving the names that I think should work and will not depend on boot order:
Go into sbitx.c and change?"plughw:0,0" to?"plughw:CARD=audioinjectorpi,DEV=0".
Go into sbitx_sound.c and change?"plughw:1,0" to?"plughw:CARD=Loopback,DEV=0".
Go into sbitx_sound.c and change?"plughw:2,1" to?"plughw:CARD=Loopback_1,DEV=1".

From what I can tell in the code Ashar refers to the aplay -l (or -L) command to get device names, what I don¡¯t see is how this is done and its not in the sbitx.sound.c code.
ALSA config will be the source of naming of devices but on reflection maybe the loopbacks could be individually named in the /etc/rc.local file instead of using the combined name of snd-aloop for all devices, try creating a line for each loopback e.g.
?
modprobe sbitx-digi-out enable=1 index=1
modprobe sbitx-digi-in enable=1 index=2
?
Instead of
?
modprobe snd-aloop enable=1,1,1,1 index=1,2,3,4
?
I suspect this is where /proc/asound/modules gets the loopback names from, do cat /proc/asound/modules to see what I mean.
I think that's not going to work.?

'modprobe' loads LKMs (loadable kernel modules) into the kernel.

So 'snd-aloop' is the name of a module ( snd-aloop.ko ) that provides support for the loopback devices.

I think changing the names this way will not work.
?
--
Regards,
Dave, N1AI


 

On Sun, Feb 4, 2024 at 03:32 AM, Paul wrote:
initial signs look positive
You are definitely getting to the heart of the issue.?

The issue now is that the sbitx application is still relying on the codec to be at index 0, loopback to be at 1, loopback_1 to be at 2.

That's because it opens the ALSA devices using names based on their index, i.e. "plughw:0,0", "plughw:1,0", "plughw:2,1".

It's better if the app uses names that are not based on index.

You are heading down the path of still making sure codec is 0, loopback is 1, loopback_1 is 2, etc.

You're changes are helping make that happen and at the same time giving them better names.

I'm not that confident that you can be sure to get the right index in every use case of things plugged into the Pi.

For instance HDMI audio is started very early in the boot process so if it is enabled then it probably gets index 0.

I think it's better to just not rely on the index and to have the sbitx app use the right name to find the right device regardless of index.

That's why I recommended:
Go into sbitx.c and change?"plughw:0,0" to?"plughw:CARD=audioinjectorpi,DEV=0".
Go into sbitx_sound.c and change?"plughw:1,0" to?"plughw:CARD=Loopback,DEV=0".
Go into sbitx_sound.c and change?"plughw:2,1" to?"plughw:CARD=Loopback_1,DEV=1".

These are the default names.

Your approach is an improvement because it assigns better names for the loopback devices.

In turn this will make the documentation easier to write and understand, IMO.

If we can assign a better name to the codec instead of "audioinjectorpi" then it too could be found by that name instead of "audioinjectorpi".

On the other hand, some may say that this adds more complexity to /boot/config.txt and /etc/rc.local and makes it harder for "tinkerers" to understand what is going on because we're not using the default (standard?) names.

Also it makes it more difficult for others to get the sbitx code by doing "./update", they also must change /etc/rc.local and /boot/config.txt to get the better names to be present.? We know many here aren't going to want to have to do that.?

So, I think you are definitely getting to the heart of the matter, but may just want to try changing the code the way I suggest and seeing if it works with the default/standard names so that complexity is avoided.? If it works, the code can be merged then ./update will still work.

Just use a simple editor (nano?) to change those three places to use the names I suggest, then do:

cd $HOME
./build sbitx

and see if it still works.

--
Regards,
Dave, N1AI


 

Hi Dave,

I agree that solving the root problem is a much better solution if it is incorporated into the main code. ?It becomes difficult if the modifications need to be done every time you want to update.?


I do not feel that you are picking on me. ?I am always open for new information and the opportunity to learn

Thank you for the feedback and the work you are doing on the sbitx.?

73
Evan
AC9TU


 

On Sun, Feb 4, 2024 at 08:46 AM, Ashhar Farhan wrote:
Is there a way we can provide a selection of where the audio routes from some kind of command??
Yes.? I will share one of your favorite diagrams:



It is the sbitx app that decides to read audio in from the 'right in' channel of the codec and write sound to the 'left out' of the codec.

These paths are hard-wired to the speaker and mic.??

It is a "simple matter of software" for the code to chose devices, perhaps with some conversion of data formats, but not difficult to accomplish.

A bit of device discovery/configuration/naming code is needed to make this relatively easy for the user to chose their favorite sources/sinks.

I would love to ideally route the mic and speaker to a bluetooth headset or some rtp stream or the default speaker/mic.
ALSA supports Bluetooth directly via plug-in modules.

The easiest way (IMO) to do RTP streaming is to use PulseAudio in Debian 10/11 and PipeWire in Debian 12.

I have done manual setups for using RTP streams using Pulse in Debian 11 with the "quisk" app driving the Hermes-Lite 2 SDR.

It more or less happens automatically if you use ssh with x-windows tunneling enabled, but you may need to set some environment variables to get things to work the way you want.

There are other/better approaches to streaming audio over a wide area network, but this approach works well on a local area network.

As Paul is finding, there is a bunch of digging one needs to do, but pretty much everything is there, it's just a matter of figuring out the best way to access it.
?
--
Regards,
Dave, N1AI


 

On Sun, Feb 4, 2024 at 10:07 AM, Dave, N1AI wrote:
cd $HOME
./build sbitx
Brain fart.

This should be:

cd $HOME/sbitx
./build sbitx
?
--
Regards,
Dave, N1AI


Paul
 

Just need the software equivalent of this diagram to understand the code modules and how they fit together, and what parameters are passed between each code module


 

On Sun, Feb 4, 2024 at 11:59 AM, Dave, N1AI wrote:
I have done manual setups for using RTP streams using Pulse in Debian 11 with the "quisk" app driving the Hermes-Lite 2 SDR.

It more or less happens automatically if you use ssh with x-windows tunneling enabled, but you may need to set some environment variables to get things to work the way you want.

To try to add more detail, if you do 'man ssh' on a linux box you should see the '-X' option described as:


?
I guess it's proper name is "X11 forwarding" but most of us call it "tunneling".

On my Linux laptop I enable this by default by having the following in .bashrc:



When I use ssh from my laptop to the sbitx pi then start the 'vlc' program, its video is sent in the ssh tunnel using X forwarding to my laptop.

If I then use vlc's 'Media -> Open File' menu to open an audio file and hit the || button to play, I hear the audio.

The tunnel contains both xlib primatives for graphics as well as RTP/RTSP streams for audio.

This works because vlc is sending audio to the default PulseAudio device on the sbitx which is sending the audio via RTP that is then tunneled by ssh session to the Linux laptop which then sends it to the local PulseAudio to play on the laptop's default device.

If you run the PulseAudio 'pavucontrol' app on the laptop you can see that it is getting audio from VLC which is NOT running on the laptop!



If I start the sbitx application I do see its video, but do not hear any audio, it is playing to the sbitx speaker still.?

This is because the sbitx application hard codes use of the ALSA 'audioinjectorpi' device which writes the audio samples to the sbitx speaker.??

If you have a good 'ssh' client for Windows I believe all the same things will still happen when you use the equivalent of the '-X' flag to start it.

My favorite is MobaXterm ( ,? ).??

My head exploded when I first encountered it in the late 2010s.? It has an entire X server, plus ssh client, plus bash, plus all the rest of the Cygwin linux command set for DOS, plus lots of other stuff, all in a single Windows application?? I had worked with X on early RISC processors of the 1980s and 1990s, as well as early Linux x86 boxes from '386 onward.? All that stuff in a single Windows program?? I just could not believe it!!!

Having said that, these days I don't use Windows much so I have never tried it for this exact purpose, but I am pretty confident that it will work.

--
Regards,
Dave, N1AI


 

On Sun, Feb 4, 2024 at 01:57 PM, Paul wrote:
Just need the software equivalent of this diagram to understand the code modules and how they fit together, and what parameters are passed between each code module
May I suggest you use the FAFO (f--- around, find out) method first, then try to work out the architecture?

Sorry, but if you are waiting for such a diagram, you will be waiting for a very long time, IMO.

I don't know of any good tool to automatically draw such a block diagram.

If someone knows of such a tool. please speak up.

I don't know of any manually-drawn diagrams for this code base.

The best method I know of is the UTSL method (Use the Source, Luke).

You gotta read the code.
?
--
Regards,
Dave, N1AI


Paul
 

Thanks Dave
That was going to be my approach anyway but was hoping, perhaps forlornly that it might have been done already :-)
I have been around IT for a long time(about 40 years ish) and know this is one of those areas that always gets overlooked. I was taught never to go near a computer keyboard until I understood what I wanted to achieve on paper first in a logical way at least :-)
I am not a programmer but know enough to be dangerous, and been around developers for a while at work before I finally gave up and retired :-)
I will dig in, might take me a while but once I have it drawn I will publish for others to correct :-)

Regards
Paul G0KAO


 

On Sun, Feb 4, 2024 at 02:30 PM, Paul wrote:
Thanks Dave
That was going to be my approach anyway but was hoping, perhaps forlornly that it might have been done already :-)
I have been around IT for a long time(about 40 years ish) and know this is one of those areas that always gets overlooked. I was taught never to go near a computer keyboard until I understood what I wanted to achieve on paper first in a logical way at least :-)
I am not a programmer but know enough to be dangerous, and been around developers for a while at work before I finally gave up and retired :-)
I will dig in, might take me a while but once I have it drawn I will publish for others to correct :-)
Please do work at whatever pace you are comfortable.

This is supposed to be fun!?

This too is a 'retirement project' for me and I have to keep telling myself to make sure I'm having fun.

I think you are already "drinking from a fire hose" just by looking into how Linux audio works.

I don't want to overload you, but feel I should point things out then you can use them if/when you can/want to.

Having said this, one thought your post triggered is that if you use the 'perf' tools in Linux you should be able to get a nice call-graph of what calls what.

Because it's performance-based it will give you a good idea of what the important run-time flows are.

I remember being able to get nice graphs such as:



?has all the steps to making such a graph.? As usual, some googling may be needed to work through any issues encountered, etc.

This graph isn't the best example because the functions all have strange names, but the best I could do on short notice.

There's a lot more detail in such graphs than you need.

I remember learning a bit about the tools being used, then learning how to filter out the uninteresting stuff so the interesting stuff became more clear.

It is actually (IMO) fairly easy to hand-edit the 'dot' file once you understand its format, just save a back up each step of the way in case you prune too heavily.

If you want an absolute 'fire hose' page please look at??...

The Visualizations section with Flame Graphs and Heat Maps are very cool.

The side bar on the left top points you to even more of Brandon's work, which is amazing.

I think 'Linux events' will be even more useful for this project, since so much of what we do is sensitive to latency, more so than throughput.

With the events subsystem, you can get a time stamp every time a bunch of samples leave the codec, enter the sbitx app, pass through our dsp, etc.

So many things to look at, so little time.
?
--
Regards,
Dave, N1AI


 

Folks;

I have a hack available that may help with sbitx audio output device experiments at

This code will accept an optional command line parameter to select a specific audio device.

To test it, I plugged in a dirt-cheap USB audio "thumb-size" sound card. lsusb shows it as:? Bus 001 Device 004: ID 0d8c:0014 C-Media Electronics, Inc. Audio Adapter (Unitek Y-247A)

Looking at the /var/log/syslog indicated that a new device hw:4,0 was created.

I then started the sbitx program with $ ./sbitx plughw:4,0

After a bit of settling, the receiver was heard on the left channel of my headphones that were plugged into the USB sound card.

This code is really meant to be used as a tool to experiment with using other sound devices for audio output. It may be possible to get a bluetooth device to work, but it seems that bluetooth in general is kinda fussy on a raspberry pi.

73; Steve, N3SB