I’ve got this idea in my head that I want a tofi based sound board that I can summon on a button press (and maybe fuzzy find through)

Should be fairly simple to do with the way tofi works to make the interface, but as far as I can find there’s not a quick and easy way to mix sounds in with mic input using pactl

Is there any single line solution for playing a sound over mic (like a soundboard would) anyone can think of or do I need to mess around with virtual audio devices to achieve this

  • teawrecks@sopuli.xyz
    link
    fedilink
    arrow-up
    4
    ·
    7 months ago

    I do exactly this using rofi to select a clip, pipe it to play (part of SoX), have a qpwGraph profile route the output to a null pw node (along with my mic input), then route that to discord or whatever.

    • flashgnash@lemm.eeOP
      link
      fedilink
      arrow-up
      3
      arrow-down
      1
      ·
      7 months ago

      Understood most of the words in that comment individually

      What does PW stand for?

      • teawrecks@sopuli.xyz
        link
        fedilink
        arrow-up
        5
        ·
        edit-2
        7 months ago

        Hah, pipewire, sorry.

        I was describing my setup from memory, here’s what I actually have:

        play "`find <path-to-clips> -type f -name "*.wav" | rofi -dmenu -i -fuzzy`"
        

        I then have this bound to a key combo in my qtile config which will pop up a menu so I can fuzzy search for a clip to play. However, this alone will just play the clip. To get it to go through discord, I also have a file ~/.config/pipewire/pipewire.conf.d/50-null-sinks.conf with this in it:

        context.objects = [
            {   
        	factory = adapter
                args = {
                    factory.name     = support.null-audio-sink
                    node.name        = "mic-loopback"
                    node.description = "Mic Loopback"
                    media.class      = Audio/Sink
                    audio.position   = [ FL FR ]
                    adapter.auto-port-config = {
                        mode = dsp
                        monitor = true
                        position = preserve
                    }
                }
            },
            {   
        	factory = adapter
                args = {
                    factory.name     = support.null-audio-sink
                    node.name        = "input-mix"
                    node.description = "Input Mix"
                    media.class      = Audio/Sink
                    audio.position   = [ FL FR ]
                    adapter.auto-port-config = {
                        mode = dsp
                        monitor = true
                        position = preserve
                    }
                }
            }
        ]
        

        This creates two new nodes that I can use to combine audio into a single source. I then use a combination of the pavucontrol and qpwgraph GUIs to control what audio streams go where. I wire my actual microphone along with the output ports of “Mic Loopback” to the input ports of “Input Mix”. Then whatever app I want to play back through my mic, I wire up to the input ports of “Mic Loopback”. To wire SoX up to Mic Loopback, I play a clip that’s long enough for me to make the switch, and then it tends to remember that for the next time SoX launches. Finally, I wire Input Mix up to discord or whatever program I’m using.

        The rofi/play combo is rock solid, I really like that. The pipewire/qpwgraph/pavucontrol part could probably be improved. It can feel a little non-deterministic, but really I think I don’t fully understand what each app involved is doing to manipulate the pipewire graph, or how to configure them so they don’t try to override each other when a pw node is added/removed.

        Edit: quick note. You might be wondering, what’s the point of having both Mic Loopback and Input Mix? Couldn’t I just have applications go directly to Input Mix? Yes, but generally you want to also hear the sound yourself, without hearing your own mic, and you want to be able to pick a single output device from within the app (most apps don’t let you choose more than one). Having two separate nodes lets you split off the output of Mic Loopback to both Input Mix and the output associated with your headphones/speakers, that way you don’t hear yourself too.

        • flashgnash@lemm.eeOP
          link
          fedilink
          arrow-up
          2
          ·
          7 months ago

          Ah fantastic, will have a look at this properly tomorrow

          Turns out I am using pipewire with the pulse module so this should work

    • flashgnash@lemm.eeOP
      link
      fedilink
      arrow-up
      5
      ·
      7 months ago

      I tried soundux, within 5 minutes of running it it was eating cpu and froze my pc up

      Tofi can do the sound searching stuff based on MP3 files in a directory, just need a way to play a sound on top of an input device from the cli