You are not logged in.

#1 2025-02-20 01:33:09

cubethethird
Member
Registered: 2016-01-25
Posts: 93
Website

Separate front and back audio ports for EasyEffects profile switching

I'm looking for help to split my front (headphones) and back (line out) audio ports. In EasyEffects, I have different presets for my headphones and my speakers. Ideally, I can associate these to different audio devices, which would then get switched automatically when changing profiles.

Currently, my only audio device choice is "Starship/Matisse HD Audio Controller Analog Stereo".

Here is my output for: pactl list cards

Card #50
	Name: alsa_card.pci-0000_0f_00.4
	Driver: alsa
	Owner Module: n/a
	Properties:
		api.acp.auto-port = "false"
		api.acp.auto-profile = "false"
		api.alsa.card = "1"
		api.alsa.card.longname = "HD-Audio Generic at 0xfc900000 irq 81"
		api.alsa.card.name = "HD-Audio Generic"
		api.alsa.path = "hw:1"
		api.alsa.split-enable = "true"
		api.alsa.use-acp = "true"
		api.dbus.ReserveDevice1 = "Audio1"
		api.dbus.ReserveDevice1.Priority = "-20"
		device.api = "alsa"
		device.bus = "pci"
		device.bus_path = "pci-0000:0f:00.4"
		device.description = "Starship/Matisse HD Audio Controller"
		device.enum.api = "udev"
		device.icon_name = "audio-card-analog-pci"
		device.name = "alsa_card.pci-0000_0f_00.4"
		device.nick = "HD-Audio Generic"
		device.plugged.usec = "8497133"
		device.product.id = "0x1487"
		device.product.name = "Starship/Matisse HD Audio Controller"
		device.subsystem = "sound"
		sysfs.path = "/devices/pci0000:00/0000:00:08.1/0000:0f:00.4/sound/card1"
		device.vendor.id = "0x1022"
		device.vendor.name = "Advanced Micro Devices, Inc. [AMD]"
		media.class = "Audio/Device"
		spa.object.id = "4"
		factory.id = "15"
		client.id = "48"
		object.id = "50"
		object.serial = "50"
		object.path = "alsa:acp:Generic"
		alsa.card = "1"
		alsa.card_name = "HD-Audio Generic"
		alsa.long_card_name = "HD-Audio Generic at 0xfc900000 irq 81"
		alsa.driver_name = "snd_hda_intel"
		alsa.mixer_name = "Realtek ALC897"
		alsa.components = "HDA:10ec0897,104387fb,00100500"
		alsa.id = "Generic"
		device.string = "1"
	Profiles:
		off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
		output:analog-stereo+input:analog-stereo: Analog Stereo Duplex (sinks: 1, sources: 1, priority: 6565, available: yes)
		output:analog-stereo: Analog Stereo Output (sinks: 1, sources: 0, priority: 6500, available: yes)
		output:iec958-stereo+input:analog-stereo: Digital Stereo (IEC958) Output + Analog Stereo Input (sinks: 1, sources: 1, priority: 5565, available: yes)
		output:iec958-stereo: Digital Stereo (IEC958) Output (sinks: 1, sources: 0, priority: 5500, available: yes)
		output:iec958-ac3-surround-51+input:analog-stereo: Digital Surround 5.1 (IEC958/AC3) Output + Analog Stereo Input (sinks: 1, sources: 1, priority: 365, available: yes)
		output:iec958-ac3-surround-51: Digital Surround 5.1 (IEC958/AC3) Output (sinks: 1, sources: 0, priority: 300, available: yes)
		input:analog-stereo: Analog Stereo Input (sinks: 0, sources: 1, priority: 65, available: yes)
		pro-audio: Pro Audio (sinks: 2, sources: 2, priority: 1, available: yes)
	Active Profile: output:analog-stereo+input:analog-stereo
	Ports:
		analog-input-front-mic: Front Microphone (type: Mic, priority: 8500, latency offset: 0 usec, availability group: Legacy 1, not available)
			Properties:
				port.type = "mic"
				port.availability-group = "Legacy 1"
				device.icon_name = "audio-input-microphone"
				card.profile.port = "0"
			Part of profile(s): input:analog-stereo, output:analog-stereo+input:analog-stereo, output:iec958-stereo+input:analog-stereo, output:iec958-ac3-surround-51+input:analog-stereo
		analog-input-rear-mic: Rear Microphone (type: Mic, priority: 8200, latency offset: 0 usec, availability group: Legacy 2, available)
			Properties:
				port.type = "mic"
				port.availability-group = "Legacy 2"
				device.icon_name = "audio-input-microphone"
				card.profile.port = "1"
			Part of profile(s): input:analog-stereo, output:analog-stereo+input:analog-stereo, output:iec958-stereo+input:analog-stereo, output:iec958-ac3-surround-51+input:analog-stereo
		analog-input-linein: Line In (type: Line, priority: 8100, latency offset: 0 usec, availability group: Legacy 3, not available)
			Properties:
				port.type = "line"
				port.availability-group = "Legacy 3"
				card.profile.port = "2"
			Part of profile(s): input:analog-stereo, output:analog-stereo+input:analog-stereo, output:iec958-stereo+input:analog-stereo, output:iec958-ac3-surround-51+input:analog-stereo
		analog-output-lineout: Line Out (type: Line, priority: 9000, latency offset: 0 usec, availability group: Legacy 4, available)
			Properties:
				port.type = "line"
				port.availability-group = "Legacy 4"
				card.profile.port = "3"
			Part of profile(s): output:analog-stereo, output:analog-stereo+input:analog-stereo
		analog-output-headphones: Headphones (type: Headphones, priority: 9900, latency offset: 0 usec, availability group: Legacy 5, not available)
			Properties:
				port.type = "headphones"
				port.availability-group = "Legacy 5"
				device.icon_name = "audio-headphones"
				card.profile.port = "4"
			Part of profile(s): output:analog-stereo, output:analog-stereo+input:analog-stereo
		iec958-stereo-output: Digital Output (S/PDIF) (type: SPDIF, priority: 0, latency offset: 0 usec, availability unknown)
			Properties:
				port.type = "spdif"
				card.profile.port = "5"
			Part of profile(s): output:iec958-stereo, output:iec958-stereo+input:analog-stereo

I'm not certain whether this is something I can accomplish with Wireplumber, with pipewire, or if I need an ALSA config (or a combination of these).
I don't necessarily need to output audio to both devices at the same time. I mainly just need to have them listed as two devices that I can switch between via software, without ports being enabled/disabled when plugging in or removing the audio jack.

Any help is much appreciated.

Offline

#2 2025-02-20 17:51:02

V1del
Forum Moderator
Registered: 2012-10-16
Posts: 24,859

Re: Separate front and back audio ports for EasyEffects profile switching

If you don't actually need distinct playback devices, you could probably listen to the jack event/the port switch getting triggered and adjusting the profile when the port switches (see e.g. "pactl monitor" you could put in a script), can you elaborate on the second part of the equation - I'm not as familiar with easyeffects as I used to be - but how would "distinct" audio devices help with associating easyeffect profiles? Can you just set sinks a profile is attached to? If it's just about showing multiple sinks and you being fine switching playback via set-default-sink and friends, the simplest would probably be to just allocate a virtual sink that duplicates the main card and then you associate profile "Speaker" with the real card and profile "Headphone"  with the virtual dupe. To load that you can use

pactl load-module module-virtual-sink name="Headphone virtual sink" master=alsa_card.pci-0000_0f_00.4.analog-stereo

that should copy all of the same properties by default iirc. If that works you could put

pulse.cmd = [
    { cmd = "load-module" args = "module-always-sink" flags = [ ] }
    { cmd = "load-module" args = "module-device-manager" flags = [ ] }
    { cmd = "load-module" args = "module-device-restore" flags = [ ] }
    { cmd = "load-module" args = "module-stream-restore" flags = [ ] }
    { cmd = "load-module" args = "module-virtual-sink name='Headphone virtual sink' master=alsa_card.pci-0000_0f_00.4.analog-stereo" flags = [ nofail ] }
]

or so into /etc/pipewire/pipewire-pulse.d/10-loadVirtualSink.conf or so.

To do this "properly" with a distinct playback sink for headphone and speakers you'd reconfigure the hda codec on the kernel module to expose the headphones as a distinct playback device and then talk to that via the pipewire pro-audio profile, see e.g. the general process from this thread: https://bbs.archlinux.org/viewtopic.php … 2#p2063242

Last edited by V1del (2025-02-20 17:53:14)

Offline

#3 2025-02-20 19:43:22

cubethethird
Member
Registered: 2016-01-25
Posts: 93
Website

Re: Separate front and back audio ports for EasyEffects profile switching

I think I see what you're getting at, but this might be the inverse solution to what I'm looking for.

In EasyEffects, you can create separate presets, and associate them to a device. When it is running, audio will be piped through the EasyEffects sink, which then channels it through to said device. The feature I am looking to use is by having different presets I can switch between from EasyEffects itself. From my understanding, doing so would change the device the audio is being routed to.

In my ideal world, I would have both headphones and speakers plugged in at the same time, and simply toggle the preset in EasyEffects. This would change my EQ along with the device I'm using all at once.

I don't know if this fully clarifies things, but as an example of how it looks in pavucontrol, my hardware device is listed as Starship/Matisse HD Audio Controller Analog Stereo, which is what I see in EasyEffects. Pavucontrol does also list the port (i.e. Line Out, Headphones), but EasyEffects cannot see these. I'm assuming I need to spoof it to list two different hardware devices, each of which are pointing to a different port on the same device.

Based on your info, I'm getting the impression I'd need to try via the kernel module approach?

Offline

#4 2025-02-20 20:03:27

V1del
Forum Moderator
Registered: 2012-10-16
Posts: 24,859

Re: Separate front and back audio ports for EasyEffects profile switching

If easy effects doesn't have a hard requirement on it being a physical sink, then the virtual-sink is very quickly tested (you basically get two sinks, both representing your physical card but from the perspective of something like easyeffects you can treat one as the "speaker" and the other as the "headphone"). you can immediately unload it if it doesn't have the desired effect if you take note of the id pactl will return and use

pactl unload-module $id

Generally the port distinction is unlikely to help you, as the port distinction is there for the purpose that it doesn't matter to the application trying to play back which port is relevant (normally). But well the other option would be to simply listen to the port event with as mentioned pactl subscribe or so (though testing this pactl subscribe doesn't give all that much info, but you could check whether a change event happens on the sink-port corresponding to your card and then get the info on which is the current port, and on switch to headphone port do

easyeffects -l headphones

and when switching off of that the corresponding one for speakers.

I'd prefer one of these two, the indep_hp switch can potentially have some annoying side effects if you don't actually need the distinct playback property.

Offline

Board footer

Powered by FluxBB