Linux / OBS: Routing MIDI QSynth audio to Google Meet via VirtualMic while monitoring in headphones

gotofourths

New Member
Hi everyone,


I’m an online piano teacher. My current setup works like this:


  • I use DroidCam to send my video and microphone to OBS,
  • OBS routes the audio via VirtualMic to Google Meet.
    Students can hear both my voice and piano, and I can hear the students through my headphones. This works fine.

However, for evening lessons I want to prevent the piano sound from reaching the room (to avoid disturbing neighbors).


My setup involves:


  • A MIDI piano connected to my laptop,
  • QSynth generates the piano sound.

My goals are:


  1. Send QSynth piano audio to Google Meet,
  2. Hear both the QSynth piano and students in my headphones at the same time,
  3. Mute the physical piano in the room,
  4. Keep my voice (DroidCam microphone) going to Meet.

I’ve tried VirtualMic setups but they didn’t work.


My question: How can I set up this kind of system reliably on Linux with OBS and PulseAudio?
Is it possible to monitor both MIDI piano and students simultaneously in headphones while sending the correct audio to Meet?


Any advice, example configurations, or guidance would be greatly appreciated.
 
SOLVED - Final Working Solution
OBS + QSynth audio to Google Meet on Ubuntu (WORKING SOLUTION)

Problem​

On Ubuntu, routing audio from QSynth / system audio / OBS into Google Meet is frustrating:

  • While teaching piano on Google Meet using OBS and DroidCam, I needed to:

    • Use headphones only (so neighbors do not hear the piano)
    • Send both my voice (via DroidCam / OBS)
      and
    • The piano sound generated by QSynth
    to Google Meet at the same time,
    without acoustic feedback or echo,
    and without playing QSynth through speakers.




    In other words, QSynth audio had to be routed only to headphones and to Meet,
    while my microphone audio was already reaching Meet via OBS / VirtualMic.





    The challenge was that VirtualMic was already receiving microphone audio from OBS,
    but QSynth audio needed to be merged into the same VirtualMic source,
    while still being audible locally through headphones.



    Additional complication



    During troubleshooting, Chrome caching audio devices caused confusion
    (VirtualMic sometimes not appearing until Chrome was restarted),
    but this was not the core problem.




    Goal:
    Route QSynth piano audio to headphones + Google Meet,
    merge it with microphone audio already coming from OBS,
    and keep the entire setup silent to the room.
    Most solutions online are incomplete or unstable.

The working approach​

Use PulseAudio VirtualMic + OBS, with a strict startup order.

This setup was built and tested step-by-step with ChatGPT.


Required components​

  • PulseAudio
  • OBS Studio
  • QSynth (or any system audio source routed through PulseAudio)
  • VirtualMic (null sink + remapped source)

Startup order (THIS IS CRITICAL)​

Always follow this order:

  1. Run the VirtualMic setup script
  2. Start QSynth
  3. Start OBS
  4. Open Chrome → Google Meet
⚠️ Chrome must be fully closed before step 1


Why set VirtualMic as default source?​

Technically, it can work without it if Chrome is restarted.

However, setting VirtualMic as the default source:

  • Prevents Chrome from selecting the wrong microphone
  • Makes the system stable after reboot
  • Avoids manual device selection in Meet
Recommended for reliability.


PulseAudio verification​

After running the script, you should see something like:

virtualmic_mic.monitor module-null-sink.c
virtualmic_speaker.monitor module-null-sink.c
virtualmic_mic module-remap-source.c
If these exist, PulseAudio is correctly configured.


OBS configuration​

  • Add Monitor of VirtualMic Speaker as an audio source
  • Enable monitoring if needed
  • OBS must be started after the VirtualMic script

Google Meet settings​

In Meet → Settings → Audio:

  • Microphone: VirtualMic
  • Speakers: whatever you prefer
If VirtualMic does not appear:
➡️ Chrome was not restarted.


Scripts​

The solution relies on simple PulseAudio scripts:

  • Creating null sinks
  • Creating remapped sources
  • Optionally setting default source
Scripts will be shared below.


Final note​

This is not a workaround — it is a deterministic setup.
Once the order is respected, it works every time.

Tested on Ubuntu with OBS + QSynth + Google Meet.


This solution was developed through hands-on testing and troubleshooting on my system, with iterative discussion and refinement using ChatGPT as a thinking partner.
 

Attachments

This setup relies on a helper script named virtualmic downloaded from GitHub.
The script is placed under /usr/local/bin to make it available system-wide.
 

Attachments

Back
Top