From 82b97da56e39192027a948ac0f0ba1c6cb205052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Thu, 4 Apr 2019 05:25:59 +0200 Subject: [PATCH 1/3] Document internals of audio virtualization --- doc.md | 1 + system/audio.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 system/audio.md diff --git a/doc.md b/doc.md index e6312a44..e3bc777b 100644 --- a/doc.md +++ b/doc.md @@ -249,6 +249,7 @@ redirect_from: * [Networking in Qubes](/doc/networking/) * [Implementation of template sharing and updating](/doc/template-implementation/) * [Storage Pools](/doc/storage-pools/) + * [Audio virtualization](/doc/audio-virtualization/) ### Services diff --git a/system/audio.md b/system/audio.md new file mode 100644 index 00000000..a78fda7b --- /dev/null +++ b/system/audio.md @@ -0,0 +1,58 @@ +--- +layout: doc +title: Audio virtualization +permalink: /doc/audio-virtualization/ +--- + +Qubes audio virtualization - internals +====================================== + +VMs on Qubes OS have access to virtualized audio through Pulseaudio module. +It consists of two parts: + + - `pacat-simple-vchan` running in a dom0/Audio VM (standalone application, one per VM, connected to PulseAudio daemon) + - `module-vchan-sink` running in a VM (loaded into PulseAudio process) + +Protocol +-------- + +The protocol between those two is designed to be as simple as possible. +Specifically, there is no audio format negotiation, no compression etc. All the audio data is transferred as raw 44.1kHz samples in S16LE format, 2 channels. + +Those two parts are connected with two vchan links: + +1. Connection on vchan port 4713 used to transfer audio from VM to Dom0/Audio VM. There is no negotiation, headers etc - raw samples are sent over this channel. +2. Connection on vchan port 4714 used to transfer audio from Dom0/Audio VM to VM. Similar to previous one, audio data is sent as raw samples. + +Additionally, the second vchan connection (on port 4714) is used in the opposite direction (VM->dom0) to send simple notifications/commands about audio state. Each such notification is a 4-bytes number in little-endian format. + +List of defined codes: + + - `0x00010001` - VM want to receive audio input (some process is listening); prior to this message, `pacat-simple-vchan` will not send any audio samples to the VM + - `0x00010000` - VM do not want to receive audio input (no process is listening anymore); after this message, `pacat-simple-vchan` will not send any audio samples to the VM + - `0x00020000` - VM do not want to send audio output; informational for dom0, to avoid buffer under runs (may affect pulseaudio calculated delays) + - `0x00020001` - VM do want to send audio output + +pacat-simple-vchan +------------------ + +Dom0 (or Audio VM) part of the audio virtualization. It is responsible for transferring audio samples between pulseaudio daemon in Dom0/Audio VM (having access to actual audio hardware) and a VM playing/recording. +For each VM, matching `pacat-simple-vchan` process is running. Each of them open a separate input and output streams to local pulseaudio, which allows to control volume of each VM separately (using `pavucontrol` tool for example). + +Audio input to the VM is not sent by default. It needs to be both requested by the VM part and explicitly enabled in `pacat-simple-vchan`. Mechanism to do that differs between Qubes versions. +In Qubes before R4.1, `pacat-simple-vchan` is controlled over system D-Bus: + + - destination: `org.qubesos.Audio.VMNAME` (with `VMNAME` replaces with actual VM name) + - object path: `/org/qubesos/audio` + - interface: `org.qubesos.Audio` + - property: `RecAllowed` (settable using `org.freedesktop.DBus.Properties` interface) + +In Qubes R4.1 or later, `pacat-simple-vchan` is controlled over a UNIX socket at `/var/run/qubes/audio-control.VMNAME` (with `VMNAME` replaces with actual VM name). Supported commands: + + - `audio-input 1\n` - enable audio input + - `audio-input 0\n` - disable audio input + +Those commands can be send using `qubes.AudioInputEnable+VMNAME` and `qubes.AudioInputDisable+VMNAME` qrexec services respectively. +The current status is written into QubesDB at `/audio-input/VMNAME` (with `VMNAME` replaces with actual VM name) with values either `1` or `0`. Lack of the key means the `pacat-simple-vchan` for given VM is not running. + +In either version, it is exposed to the user as device of class `mic`, which can be attached to a VM (for example using `qvm-device mic` command). From ffd027f300518026dcb09778c79c9a7741aed040 Mon Sep 17 00:00:00 2001 From: Andrew David Wong Date: Mon, 8 Apr 2019 18:37:55 -0500 Subject: [PATCH 2/3] Clean up text --- system/audio.md | 62 +++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/system/audio.md b/system/audio.md index a78fda7b..e3b3de45 100644 --- a/system/audio.md +++ b/system/audio.md @@ -1,58 +1,70 @@ --- layout: doc -title: Audio virtualization +title: Audio Virtualization permalink: /doc/audio-virtualization/ --- -Qubes audio virtualization - internals -====================================== +Audio Virtualization +==================== -VMs on Qubes OS have access to virtualized audio through Pulseaudio module. +VMs on Qubes OS have access to virtualized audio through the PulseAudio module. It consists of two parts: - - `pacat-simple-vchan` running in a dom0/Audio VM (standalone application, one per VM, connected to PulseAudio daemon) - - `module-vchan-sink` running in a VM (loaded into PulseAudio process) + - `pacat-simple-vchan` running in a dom0/Audio VM (standalone application, one per VM, connected to the PulseAudio daemon) + - `module-vchan-sink` running in a VM (loaded into the PulseAudio process) Protocol -------- -The protocol between those two is designed to be as simple as possible. -Specifically, there is no audio format negotiation, no compression etc. All the audio data is transferred as raw 44.1kHz samples in S16LE format, 2 channels. +The protocol between these two parts is designed to be as simple as possible. +Specifically, there is no audio format negotiation, no compression, etc. +All the audio data is transferred as raw 44.1kHz samples in S16LE format, 2 channels. -Those two parts are connected with two vchan links: +These two parts are connected with two vchan links: -1. Connection on vchan port 4713 used to transfer audio from VM to Dom0/Audio VM. There is no negotiation, headers etc - raw samples are sent over this channel. -2. Connection on vchan port 4714 used to transfer audio from Dom0/Audio VM to VM. Similar to previous one, audio data is sent as raw samples. +1. Connection on vchan port 4713 used to transfer audio from VM to dom0/Audio VM. + There is no negotiation, no headers, etc. + Only raw samples are sent over this channel. +2. Connection on vchan port 4714 used to transfer audio from dom0/Audio VM to VM. + Like the previous one, audio data is sent as raw samples. -Additionally, the second vchan connection (on port 4714) is used in the opposite direction (VM->dom0) to send simple notifications/commands about audio state. Each such notification is a 4-bytes number in little-endian format. +Additionally, the second vchan connection (on port 4714) is used in the opposite direction (VM to dom0) to send simple notifications/commands about the audio state. +Each such notification is a 4-byte number in little-endian format. List of defined codes: - - `0x00010001` - VM want to receive audio input (some process is listening); prior to this message, `pacat-simple-vchan` will not send any audio samples to the VM - - `0x00010000` - VM do not want to receive audio input (no process is listening anymore); after this message, `pacat-simple-vchan` will not send any audio samples to the VM - - `0x00020000` - VM do not want to send audio output; informational for dom0, to avoid buffer under runs (may affect pulseaudio calculated delays) - - `0x00020001` - VM do want to send audio output + - `0x00010001` -- VM wants to receive audio input (some process is listening); prior to this message, `pacat-simple-vchan` will not send any audio samples to the VM. + - `0x00010000` -- VM does not want to receive audio input (no process is listening anymore); after this message, `pacat-simple-vchan` will not send any audio samples to the VM. + - `0x00020000` -- VM does not want to send audio output; informational for dom0, to avoid buffer under runs (may affect PulseAudio calculated delays). + - `0x00020001` -- VM does want to send audio output. pacat-simple-vchan ------------------ -Dom0 (or Audio VM) part of the audio virtualization. It is responsible for transferring audio samples between pulseaudio daemon in Dom0/Audio VM (having access to actual audio hardware) and a VM playing/recording. -For each VM, matching `pacat-simple-vchan` process is running. Each of them open a separate input and output streams to local pulseaudio, which allows to control volume of each VM separately (using `pavucontrol` tool for example). +This is the dom0 (or Audio VM) part of the audio virtualization. +It is responsible for transferring audio samples between the PulseAudio daemon in dom0/Audio VM (which has access to the actual audio hardware) and a VM playing/recording sounds. +In each VM, a corresponding `pacat-simple-vchan` process is running. +Each of them opens separate input and output streams to their local PulseAudio, which allows for controlling the volume of each VM separately (using the `pavucontrol` tool, for example). -Audio input to the VM is not sent by default. It needs to be both requested by the VM part and explicitly enabled in `pacat-simple-vchan`. Mechanism to do that differs between Qubes versions. +Audio input to the VM is not sent by default. +It needs to be both requested by the VM part and explicitly enabled in `pacat-simple-vchan`. +The mechanism to do this differs between Qubes versions. In Qubes before R4.1, `pacat-simple-vchan` is controlled over system D-Bus: - - destination: `org.qubesos.Audio.VMNAME` (with `VMNAME` replaces with actual VM name) + - destination: `org.qubesos.Audio.VMNAME` (where `VMNAME` is the VM's name) - object path: `/org/qubesos/audio` - interface: `org.qubesos.Audio` - - property: `RecAllowed` (settable using `org.freedesktop.DBus.Properties` interface) + - property: `RecAllowed` (which can be set using the `org.freedesktop.DBus.Properties` interface) -In Qubes R4.1 or later, `pacat-simple-vchan` is controlled over a UNIX socket at `/var/run/qubes/audio-control.VMNAME` (with `VMNAME` replaces with actual VM name). Supported commands: +In Qubes R4.1 and later, `pacat-simple-vchan` is controlled over a UNIX socket at `/var/run/qubes/audio-control.VMNAME` (where `VMNAME` is the VM's name). +Supported commands: - `audio-input 1\n` - enable audio input - `audio-input 0\n` - disable audio input -Those commands can be send using `qubes.AudioInputEnable+VMNAME` and `qubes.AudioInputDisable+VMNAME` qrexec services respectively. -The current status is written into QubesDB at `/audio-input/VMNAME` (with `VMNAME` replaces with actual VM name) with values either `1` or `0`. Lack of the key means the `pacat-simple-vchan` for given VM is not running. +These commands can be sent using the `qubes.AudioInputEnable+VMNAME` and `qubes.AudioInputDisable+VMNAME` qrexec services, respectively. +The current status is written into QubesDB at `/audio-input/VMNAME` (where `VMNAME` is the VM's name) with either `1` or `0` values. +The lack of a key means that the `pacat-simple-vchan` for a given VM is not running. + +In either version, it is exposed to the user as device of class `mic`, which can be attached to a VM (for example, using the `qvm-device mic` command). -In either version, it is exposed to the user as device of class `mic`, which can be attached to a VM (for example using `qvm-device mic` command). From 4b253153dd95815c2c9d0ac9e047bbc28d70c517 Mon Sep 17 00:00:00 2001 From: Andrew David Wong Date: Mon, 8 Apr 2019 19:43:52 -0500 Subject: [PATCH 3/3] Fix remark about pacat-simple-vchan process location --- system/audio.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/audio.md b/system/audio.md index e3b3de45..71d37ddf 100644 --- a/system/audio.md +++ b/system/audio.md @@ -43,7 +43,7 @@ pacat-simple-vchan This is the dom0 (or Audio VM) part of the audio virtualization. It is responsible for transferring audio samples between the PulseAudio daemon in dom0/Audio VM (which has access to the actual audio hardware) and a VM playing/recording sounds. -In each VM, a corresponding `pacat-simple-vchan` process is running. +A separate `pacat-simple-vchan` process runs in dom0 for each VM with audio. Each of them opens separate input and output streams to their local PulseAudio, which allows for controlling the volume of each VM separately (using the `pavucontrol` tool, for example). Audio input to the VM is not sent by default.