All of lore.kernel.org
 help / color / mirror / Atom feed
* [virtio-dev] Request for a new device number for a virtio-audio device.
@ 2019-04-28 22:22 Marco Martinelli - 13Byte srl
  2019-04-29 13:47 ` Stefan Hajnoczi
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Martinelli - 13Byte srl @ 2019-04-28 22:22 UTC (permalink / raw)
  To: virtio-dev

[-- Attachment #1: Type: text/plain, Size: 2699 bytes --]

Hi everyone,

my name is Marco, from Italy. I'm a developer that recently got an 
interest in improving the current situation of audio in qemu/kvm.

I've been working successfully on multiple patches for Scream 
(https://github.com/duncanthrax/scream 
<https://github.com/duncanthrax/scream> ), a virtual sound card for 
Microsoft Windows, that allow to transfer audio from a Windows VM to a 
Linux host. The project initially supported only stereo sound over the 
network, but with my patches now it support up to 7.1 surround and it 
can transfer the audio samples using shared memory between the VM and 
the host (based on IVSHMEM), for lower latency.

Now that was a good project, but I want to do more. I dream of an 
virtio-audio device that can handle multichannel audio in and out of the 
VM, to be used with more guest OSs than just Windows.

I know I have a long way to go to reach this goal, but I'm motivated and 
willing to learn. I admit I don't have much experience with the qemu 
source code or the virtio source code, but I learn fast.

My work on Scream was to familiarize with Windows driver development, 
VM-to-host communication and low latency audio processing.
My idea is to start with small self-contained projects to familiarize 
with the source codes of the various projects and gain the experience I 
lack, then moving on the real virtio-audio project.
This way I can both obtain more knowledge on the subjects and help the 
open source community that over the years have done so much for many.

As we speak I'm reading the VirtIO documentation, where I've found out 
that I need to require a new device number for this project (Appendix 
B.3). So, here I am.

I'm not quite sure if this email is enough to obtain a new number or if 
I need to follow some process I'm not aware of. In the meantime I'm 
using the device number 65535 as documented in the specifications.

Looking around I've seen there is a recent issue on GitHub to reserve a 
virtio-audio device id, and a patch was submitter to assign id 25 to 
audio devices.

I'm not sure how this works, is that number already assigned and I 
should use that or should I get a new one?

For last, I have a question to clear the things up for me. It is my 
understanding that in this mailing list you discuss about the 
specifications, not the actual code. What's the usual process when 
writing a new virtio device?
Should I start with writing the code and then document how it works or 
is it the opposite? Should I document it and have it approved and then 
implement the specifications?

I know that this may sound like a stupid question, but please be patient 
with me, it's my first time.


Best Regards,

Marco

[-- Attachment #2: Type: text/html, Size: 3289 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-04-28 22:22 [virtio-dev] Request for a new device number for a virtio-audio device Marco Martinelli - 13Byte srl
@ 2019-04-29 13:47 ` Stefan Hajnoczi
  2019-04-29 17:39   ` Marco Martinelli - 13Byte srl
  0 siblings, 1 reply; 29+ messages in thread
From: Stefan Hajnoczi @ 2019-04-29 13:47 UTC (permalink / raw)
  To: Marco Martinelli - 13Byte srl; +Cc: virtio-dev

[-- Attachment #1: Type: text/plain, Size: 3510 bytes --]

On Mon, Apr 29, 2019 at 12:22:41AM +0200, Marco Martinelli - 13Byte srl wrote:
> Hi everyone,
> 
> my name is Marco, from Italy. I'm a developer that recently got an interest
> in improving the current situation of audio in qemu/kvm.
> 
> I've been working successfully on multiple patches for Scream
> (https://github.com/duncanthrax/scream
> <https://github.com/duncanthrax/scream> ), a virtual sound card for
> Microsoft Windows, that allow to transfer audio from a Windows VM to a Linux
> host. The project initially supported only stereo sound over the network,
> but with my patches now it support up to 7.1 surround and it can transfer
> the audio samples using shared memory between the VM and the host (based on
> IVSHMEM), for lower latency.
> 
> Now that was a good project, but I want to do more. I dream of an
> virtio-audio device that can handle multichannel audio in and out of the VM,
> to be used with more guest OSs than just Windows.
> 
> I know I have a long way to go to reach this goal, but I'm motivated and
> willing to learn. I admit I don't have much experience with the qemu source
> code or the virtio source code, but I learn fast.
> 
> My work on Scream was to familiarize with Windows driver development,
> VM-to-host communication and low latency audio processing.
> My idea is to start with small self-contained projects to familiarize with
> the source codes of the various projects and gain the experience I lack,
> then moving on the real virtio-audio project.
> This way I can both obtain more knowledge on the subjects and help the open
> source community that over the years have done so much for many.
> 
> As we speak I'm reading the VirtIO documentation, where I've found out that
> I need to require a new device number for this project (Appendix B.3). So,
> here I am.
> 
> I'm not quite sure if this email is enough to obtain a new number or if I
> need to follow some process I'm not aware of. In the meantime I'm using the
> device number 65535 as documented in the specifications.
> 
> Looking around I've seen there is a recent issue on GitHub to reserve a
> virtio-audio device id, and a patch was submitter to assign id 25 to audio
> devices.

Is this the same virtio-audio device type that you want to work on or is
this an independent effort from another author?  It seems important to
contact the author (if it's not you) to find out the status of their
device and see what work can be shared.

> I'm not sure how this works, is that number already assigned and I should
> use that or should I get a new one?
> 
> For last, I have a question to clear the things up for me. It is my
> understanding that in this mailing list you discuss about the
> specifications, not the actual code. What's the usual process when writing a
> new virtio device?
> Should I start with writing the code and then document how it works or is it
> the opposite? Should I document it and have it approved and then implement
> the specifications?
> 
> I know that this may sound like a stupid question, but please be patient
> with me, it's my first time.

I suggest posting a draft specification for the new device type before
investing too much time in the implementation.

Then work on the code while the spec discussion is ongoing.  This way
you won't have to wait too long before implementation but you also won't
find that reviewers are asking for large changes after you completed
your work.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-04-29 13:47 ` Stefan Hajnoczi
@ 2019-04-29 17:39   ` Marco Martinelli - 13Byte srl
  2019-04-30 12:55     ` Michael S. Tsirkin
  2019-05-01 17:05     ` Stefan Hajnoczi
  0 siblings, 2 replies; 29+ messages in thread
From: Marco Martinelli - 13Byte srl @ 2019-04-29 17:39 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: virtio-dev


Il 29/04/19 15:47, Stefan Hajnoczi ha scritto:
> On Mon, Apr 29, 2019 at 12:22:41AM +0200, Marco Martinelli - 13Byte srl wrote:
>> Hi everyone,
>>
>> my name is Marco, from Italy. I'm a developer that recently got an interest
>> in improving the current situation of audio in qemu/kvm.
>>
>> I've been working successfully on multiple patches for Scream
>> (https://github.com/duncanthrax/scream
>> <https://github.com/duncanthrax/scream> ), a virtual sound card for
>> Microsoft Windows, that allow to transfer audio from a Windows VM to a Linux
>> host. The project initially supported only stereo sound over the network,
>> but with my patches now it support up to 7.1 surround and it can transfer
>> the audio samples using shared memory between the VM and the host (based on
>> IVSHMEM), for lower latency.
>>
>> Now that was a good project, but I want to do more. I dream of an
>> virtio-audio device that can handle multichannel audio in and out of the VM,
>> to be used with more guest OSs than just Windows.
>>
>> I know I have a long way to go to reach this goal, but I'm motivated and
>> willing to learn. I admit I don't have much experience with the qemu source
>> code or the virtio source code, but I learn fast.
>>
>> My work on Scream was to familiarize with Windows driver development,
>> VM-to-host communication and low latency audio processing.
>> My idea is to start with small self-contained projects to familiarize with
>> the source codes of the various projects and gain the experience I lack,
>> then moving on the real virtio-audio project.
>> This way I can both obtain more knowledge on the subjects and help the open
>> source community that over the years have done so much for many.
>>
>> As we speak I'm reading the VirtIO documentation, where I've found out that
>> I need to require a new device number for this project (Appendix B.3). So,
>> here I am.
>>
>> I'm not quite sure if this email is enough to obtain a new number or if I
>> need to follow some process I'm not aware of. In the meantime I'm using the
>> device number 65535 as documented in the specifications.
>>
>> Looking around I've seen there is a recent issue on GitHub to reserve a
>> virtio-audio device id, and a patch was submitter to assign id 25 to audio
>> devices.
> Is this the same virtio-audio device type that you want to work on or is
> this an independent effort from another author?  It seems important to
> contact the author (if it's not you) to find out the status of their
> device and see what work can be shared.

It is not my device, but I don't think there is any work behind this either.

The number 25 I was referring to comes from this message 
https://lists.oasis-open.org/archives/virtio/201903/msg00074.html

It seems to me that this number was reserved for a virtio-audio device, 
but not a specific one. Maybe I'm misinterpreting that message.

>
>> I'm not sure how this works, is that number already assigned and I should
>> use that or should I get a new one?
>>
>> For last, I have a question to clear the things up for me. It is my
>> understanding that in this mailing list you discuss about the
>> specifications, not the actual code. What's the usual process when writing a
>> new virtio device?
>> Should I start with writing the code and then document how it works or is it
>> the opposite? Should I document it and have it approved and then implement
>> the specifications?
>>
>> I know that this may sound like a stupid question, but please be patient
>> with me, it's my first time.
> I suggest posting a draft specification for the new device type before
> investing too much time in the implementation.
>
> Then work on the code while the spec discussion is ongoing.  This way
> you won't have to wait too long before implementation but you also won't
> find that reviewers are asking for large changes after you completed
> your work.
I feared that would be the answer.
As I stated I'm not familiar with most of the technologies involved. I 
don't know if I have the capabilities to write a draft of the 
specifications without first working on some code to clear things up.
I'll try my best.
> Stefan


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-04-29 17:39   ` Marco Martinelli - 13Byte srl
@ 2019-04-30 12:55     ` Michael S. Tsirkin
  2019-04-30 13:56       ` Marco Martinelli - 13Byte srl
  2019-05-01 17:05     ` Stefan Hajnoczi
  1 sibling, 1 reply; 29+ messages in thread
From: Michael S. Tsirkin @ 2019-04-30 12:55 UTC (permalink / raw)
  To: Marco Martinelli - 13Byte srl; +Cc: Stefan Hajnoczi, virtio-dev

On Mon, Apr 29, 2019 at 07:39:17PM +0200, Marco Martinelli - 13Byte srl wrote:
> 
> Il 29/04/19 15:47, Stefan Hajnoczi ha scritto:
> > On Mon, Apr 29, 2019 at 12:22:41AM +0200, Marco Martinelli - 13Byte srl wrote:
> > > Hi everyone,
> > > 
> > > my name is Marco, from Italy. I'm a developer that recently got an interest
> > > in improving the current situation of audio in qemu/kvm.
> > > 
> > > I've been working successfully on multiple patches for Scream
> > > (https://github.com/duncanthrax/scream
> > > <https://github.com/duncanthrax/scream> ), a virtual sound card for
> > > Microsoft Windows, that allow to transfer audio from a Windows VM to a Linux
> > > host. The project initially supported only stereo sound over the network,
> > > but with my patches now it support up to 7.1 surround and it can transfer
> > > the audio samples using shared memory between the VM and the host (based on
> > > IVSHMEM), for lower latency.
> > > 
> > > Now that was a good project, but I want to do more. I dream of an
> > > virtio-audio device that can handle multichannel audio in and out of the VM,
> > > to be used with more guest OSs than just Windows.
> > > 
> > > I know I have a long way to go to reach this goal, but I'm motivated and
> > > willing to learn. I admit I don't have much experience with the qemu source
> > > code or the virtio source code, but I learn fast.
> > > 
> > > My work on Scream was to familiarize with Windows driver development,
> > > VM-to-host communication and low latency audio processing.
> > > My idea is to start with small self-contained projects to familiarize with
> > > the source codes of the various projects and gain the experience I lack,
> > > then moving on the real virtio-audio project.
> > > This way I can both obtain more knowledge on the subjects and help the open
> > > source community that over the years have done so much for many.
> > > 
> > > As we speak I'm reading the VirtIO documentation, where I've found out that
> > > I need to require a new device number for this project (Appendix B.3). So,
> > > here I am.
> > > 
> > > I'm not quite sure if this email is enough to obtain a new number or if I
> > > need to follow some process I'm not aware of. In the meantime I'm using the
> > > device number 65535 as documented in the specifications.
> > > 
> > > Looking around I've seen there is a recent issue on GitHub to reserve a
> > > virtio-audio device id, and a patch was submitter to assign id 25 to audio
> > > devices.
> > Is this the same virtio-audio device type that you want to work on or is
> > this an independent effort from another author?  It seems important to
> > contact the author (if it's not you) to find out the status of their
> > device and see what work can be shared.
> 
> It is not my device, but I don't think there is any work behind this either.
> 
> The number 25 I was referring to comes from this message
> https://lists.oasis-open.org/archives/virtio/201903/msg00074.html
> 
> It seems to me that this number was reserved for a virtio-audio device, but
> not a specific one. Maybe I'm misinterpreting that message.

I think it's this one:

https://projectacrn.org/

given this project started using an ID without talking to anyone (which
almost led to a conflict - it only didn't because Paolo was super
diligent), it's a good idea to ask them whether they will be willing to
be more careful and at least reserve feature bits through the TC before
using them.

If not then we should rename this one to audio device (legacy)
and reserve an ID for 

Could you reach out to them?


> > 
> > > I'm not sure how this works, is that number already assigned and I should
> > > use that or should I get a new one?
> > > 
> > > For last, I have a question to clear the things up for me. It is my
> > > understanding that in this mailing list you discuss about the
> > > specifications, not the actual code. What's the usual process when writing a
> > > new virtio device?
> > > Should I start with writing the code and then document how it works or is it
> > > the opposite? Should I document it and have it approved and then implement
> > > the specifications?
> > > 
> > > I know that this may sound like a stupid question, but please be patient
> > > with me, it's my first time.
> > I suggest posting a draft specification for the new device type before
> > investing too much time in the implementation.
> > 
> > Then work on the code while the spec discussion is ongoing.  This way
> > you won't have to wait too long before implementation but you also won't
> > find that reviewers are asking for large changes after you completed
> > your work.
> I feared that would be the answer.
> As I stated I'm not familiar with most of the technologies involved. I don't
> know if I have the capabilities to write a draft of the specifications
> without first working on some code to clear things up.
> I'll try my best.

There are two other options for contributing which might be
easier for people not comfortable with writing specs:

1. If project acrn guys are willing to work with us
   in the future (meaning not making future interface changes
   without reserving a feature bit through the TC):
   - figure out their virtio-audio device interface, write
     compatible qemu device and guest driver implementations

2. if they are not willing
   - send a small patch just like
	https://lists.oasis-open.org/archives/virtio/201903/msg00074.html
     reserving a new id (+ renaming old one to legacy)
     then start hacking on your own as per option 1




> > Stefan
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
> For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org

---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-04-30 12:55     ` Michael S. Tsirkin
@ 2019-04-30 13:56       ` Marco Martinelli - 13Byte srl
  2019-04-30 14:00         ` Michael S. Tsirkin
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Martinelli - 13Byte srl @ 2019-04-30 13:56 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: Stefan Hajnoczi, virtio-dev

Il 30/04/19 14:55, Michael S. Tsirkin ha scritto:

> On Mon, Apr 29, 2019 at 07:39:17PM +0200, Marco Martinelli - 13Byte srl wrote:
>> Il 29/04/19 15:47, Stefan Hajnoczi ha scritto:
>>> On Mon, Apr 29, 2019 at 12:22:41AM +0200, Marco Martinelli - 13Byte srl wrote:
>>>> Hi everyone,
>>>>
>>>> my name is Marco, from Italy. I'm a developer that recently got an interest
>>>> in improving the current situation of audio in qemu/kvm.
>>>>
>>>> I've been working successfully on multiple patches for Scream
>>>> (https://github.com/duncanthrax/scream
>>>> <https://github.com/duncanthrax/scream> ), a virtual sound card for
>>>> Microsoft Windows, that allow to transfer audio from a Windows VM to a Linux
>>>> host. The project initially supported only stereo sound over the network,
>>>> but with my patches now it support up to 7.1 surround and it can transfer
>>>> the audio samples using shared memory between the VM and the host (based on
>>>> IVSHMEM), for lower latency.
>>>>
>>>> Now that was a good project, but I want to do more. I dream of an
>>>> virtio-audio device that can handle multichannel audio in and out of the VM,
>>>> to be used with more guest OSs than just Windows.
>>>>
>>>> I know I have a long way to go to reach this goal, but I'm motivated and
>>>> willing to learn. I admit I don't have much experience with the qemu source
>>>> code or the virtio source code, but I learn fast.
>>>>
>>>> My work on Scream was to familiarize with Windows driver development,
>>>> VM-to-host communication and low latency audio processing.
>>>> My idea is to start with small self-contained projects to familiarize with
>>>> the source codes of the various projects and gain the experience I lack,
>>>> then moving on the real virtio-audio project.
>>>> This way I can both obtain more knowledge on the subjects and help the open
>>>> source community that over the years have done so much for many.
>>>>
>>>> As we speak I'm reading the VirtIO documentation, where I've found out that
>>>> I need to require a new device number for this project (Appendix B.3). So,
>>>> here I am.
>>>>
>>>> I'm not quite sure if this email is enough to obtain a new number or if I
>>>> need to follow some process I'm not aware of. In the meantime I'm using the
>>>> device number 65535 as documented in the specifications.
>>>>
>>>> Looking around I've seen there is a recent issue on GitHub to reserve a
>>>> virtio-audio device id, and a patch was submitter to assign id 25 to audio
>>>> devices.
>>> Is this the same virtio-audio device type that you want to work on or is
>>> this an independent effort from another author?  It seems important to
>>> contact the author (if it's not you) to find out the status of their
>>> device and see what work can be shared.
>> It is not my device, but I don't think there is any work behind this either.
>>
>> The number 25 I was referring to comes from this message
>> https://lists.oasis-open.org/archives/virtio/201903/msg00074.html
>>
>> It seems to me that this number was reserved for a virtio-audio device, but
>> not a specific one. Maybe I'm misinterpreting that message.
> I think it's this one:
>
> https://projectacrn.org/
>
> given this project started using an ID without talking to anyone (which
> almost led to a conflict - it only didn't because Paolo was super
> diligent), it's a good idea to ask them whether they will be willing to
> be more careful and at least reserve feature bits through the TC before
> using them.
>
> If not then we should rename this one to audio device (legacy)
> and reserve an ID for
>
> Could you reach out to them?
I'll contact them today, thank you.
>
>
>>>> I'm not sure how this works, is that number already assigned and I should
>>>> use that or should I get a new one?
>>>>
>>>> For last, I have a question to clear the things up for me. It is my
>>>> understanding that in this mailing list you discuss about the
>>>> specifications, not the actual code. What's the usual process when writing a
>>>> new virtio device?
>>>> Should I start with writing the code and then document how it works or is it
>>>> the opposite? Should I document it and have it approved and then implement
>>>> the specifications?
>>>>
>>>> I know that this may sound like a stupid question, but please be patient
>>>> with me, it's my first time.
>>> I suggest posting a draft specification for the new device type before
>>> investing too much time in the implementation.
>>>
>>> Then work on the code while the spec discussion is ongoing.  This way
>>> you won't have to wait too long before implementation but you also won't
>>> find that reviewers are asking for large changes after you completed
>>> your work.
>> I feared that would be the answer.
>> As I stated I'm not familiar with most of the technologies involved. I don't
>> know if I have the capabilities to write a draft of the specifications
>> without first working on some code to clear things up.
>> I'll try my best.
> There are two other options for contributing which might be
> easier for people not comfortable with writing specs:
>
> 1. If project acrn guys are willing to work with us
>     in the future (meaning not making future interface changes
>     without reserving a feature bit through the TC):
>     - figure out their virtio-audio device interface, write
>       compatible qemu device and guest driver implementations
>
> 2. if they are not willing
>     - send a small patch just like
> 	https://lists.oasis-open.org/archives/virtio/201903/msg00074.html
>       reserving a new id (+ renaming old one to legacy)
>       then start hacking on your own as per option 1
>
Ok, I'll see what their answer is and then decide what to do. Thank you.
>
>
>>> Stefan
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
>> For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org

-- 
Marco


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-04-30 13:56       ` Marco Martinelli - 13Byte srl
@ 2019-04-30 14:00         ` Michael S. Tsirkin
  0 siblings, 0 replies; 29+ messages in thread
From: Michael S. Tsirkin @ 2019-04-30 14:00 UTC (permalink / raw)
  To: Marco Martinelli - 13Byte srl; +Cc: Stefan Hajnoczi, virtio-dev

On Tue, Apr 30, 2019 at 03:56:19PM +0200, Marco Martinelli - 13Byte srl wrote:
> Il 30/04/19 14:55, Michael S. Tsirkin ha scritto:
> 
> > On Mon, Apr 29, 2019 at 07:39:17PM +0200, Marco Martinelli - 13Byte srl wrote:
> > > Il 29/04/19 15:47, Stefan Hajnoczi ha scritto:
> > > > On Mon, Apr 29, 2019 at 12:22:41AM +0200, Marco Martinelli - 13Byte srl wrote:
> > > > > Hi everyone,
> > > > > 
> > > > > my name is Marco, from Italy. I'm a developer that recently got an interest
> > > > > in improving the current situation of audio in qemu/kvm.
> > > > > 
> > > > > I've been working successfully on multiple patches for Scream
> > > > > (https://github.com/duncanthrax/scream
> > > > > <https://github.com/duncanthrax/scream> ), a virtual sound card for
> > > > > Microsoft Windows, that allow to transfer audio from a Windows VM to a Linux
> > > > > host. The project initially supported only stereo sound over the network,
> > > > > but with my patches now it support up to 7.1 surround and it can transfer
> > > > > the audio samples using shared memory between the VM and the host (based on
> > > > > IVSHMEM), for lower latency.
> > > > > 
> > > > > Now that was a good project, but I want to do more. I dream of an
> > > > > virtio-audio device that can handle multichannel audio in and out of the VM,
> > > > > to be used with more guest OSs than just Windows.
> > > > > 
> > > > > I know I have a long way to go to reach this goal, but I'm motivated and
> > > > > willing to learn. I admit I don't have much experience with the qemu source
> > > > > code or the virtio source code, but I learn fast.
> > > > > 
> > > > > My work on Scream was to familiarize with Windows driver development,
> > > > > VM-to-host communication and low latency audio processing.
> > > > > My idea is to start with small self-contained projects to familiarize with
> > > > > the source codes of the various projects and gain the experience I lack,
> > > > > then moving on the real virtio-audio project.
> > > > > This way I can both obtain more knowledge on the subjects and help the open
> > > > > source community that over the years have done so much for many.
> > > > > 
> > > > > As we speak I'm reading the VirtIO documentation, where I've found out that
> > > > > I need to require a new device number for this project (Appendix B.3). So,
> > > > > here I am.
> > > > > 
> > > > > I'm not quite sure if this email is enough to obtain a new number or if I
> > > > > need to follow some process I'm not aware of. In the meantime I'm using the
> > > > > device number 65535 as documented in the specifications.
> > > > > 
> > > > > Looking around I've seen there is a recent issue on GitHub to reserve a
> > > > > virtio-audio device id, and a patch was submitter to assign id 25 to audio
> > > > > devices.
> > > > Is this the same virtio-audio device type that you want to work on or is
> > > > this an independent effort from another author?  It seems important to
> > > > contact the author (if it's not you) to find out the status of their
> > > > device and see what work can be shared.
> > > It is not my device, but I don't think there is any work behind this either.
> > > 
> > > The number 25 I was referring to comes from this message
> > > https://lists.oasis-open.org/archives/virtio/201903/msg00074.html
> > > 
> > > It seems to me that this number was reserved for a virtio-audio device, but
> > > not a specific one. Maybe I'm misinterpreting that message.
> > I think it's this one:
> > 
> > https://projectacrn.org/
> > 
> > given this project started using an ID without talking to anyone (which
> > almost led to a conflict - it only didn't because Paolo was super
> > diligent), it's a good idea to ask them whether they will be willing to
> > be more careful and at least reserve feature bits through the TC before
> > using them.
> > 
> > If not then we should rename this one to audio device (legacy)
> > and reserve an ID for
> > 
> > Could you reach out to them?
> I'll contact them today, thank you.

Thanks!
Pls Cc me on that email.

> > 
> > 
> > > > > I'm not sure how this works, is that number already assigned and I should
> > > > > use that or should I get a new one?
> > > > > 
> > > > > For last, I have a question to clear the things up for me. It is my
> > > > > understanding that in this mailing list you discuss about the
> > > > > specifications, not the actual code. What's the usual process when writing a
> > > > > new virtio device?
> > > > > Should I start with writing the code and then document how it works or is it
> > > > > the opposite? Should I document it and have it approved and then implement
> > > > > the specifications?
> > > > > 
> > > > > I know that this may sound like a stupid question, but please be patient
> > > > > with me, it's my first time.
> > > > I suggest posting a draft specification for the new device type before
> > > > investing too much time in the implementation.
> > > > 
> > > > Then work on the code while the spec discussion is ongoing.  This way
> > > > you won't have to wait too long before implementation but you also won't
> > > > find that reviewers are asking for large changes after you completed
> > > > your work.
> > > I feared that would be the answer.
> > > As I stated I'm not familiar with most of the technologies involved. I don't
> > > know if I have the capabilities to write a draft of the specifications
> > > without first working on some code to clear things up.
> > > I'll try my best.
> > There are two other options for contributing which might be
> > easier for people not comfortable with writing specs:
> > 
> > 1. If project acrn guys are willing to work with us
> >     in the future (meaning not making future interface changes
> >     without reserving a feature bit through the TC):
> >     - figure out their virtio-audio device interface, write
> >       compatible qemu device and guest driver implementations
> > 
> > 2. if they are not willing
> >     - send a small patch just like
> > 	https://lists.oasis-open.org/archives/virtio/201903/msg00074.html
> >       reserving a new id (+ renaming old one to legacy)
> >       then start hacking on your own as per option 1
> > 
> Ok, I'll see what their answer is and then decide what to do. Thank you.
> > 
> > 
> > > > Stefan
> > > 
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
> > > For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org
> 
> -- 
> Marco

---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-04-29 17:39   ` Marco Martinelli - 13Byte srl
  2019-04-30 12:55     ` Michael S. Tsirkin
@ 2019-05-01 17:05     ` Stefan Hajnoczi
  2019-05-02 11:18       ` Marco Martinelli - 13Byte srl
  1 sibling, 1 reply; 29+ messages in thread
From: Stefan Hajnoczi @ 2019-05-01 17:05 UTC (permalink / raw)
  To: Marco Martinelli - 13Byte srl; +Cc: virtio-dev, kraxel

[-- Attachment #1: Type: text/plain, Size: 2253 bytes --]

On Mon, Apr 29, 2019 at 07:39:17PM +0200, Marco Martinelli - 13Byte srl wrote:
> Il 29/04/19 15:47, Stefan Hajnoczi ha scritto:
> > On Mon, Apr 29, 2019 at 12:22:41AM +0200, Marco Martinelli - 13Byte srl wrote:
> > > I'm not sure how this works, is that number already assigned and I should
> > > use that or should I get a new one?
> > > 
> > > For last, I have a question to clear the things up for me. It is my
> > > understanding that in this mailing list you discuss about the
> > > specifications, not the actual code. What's the usual process when writing a
> > > new virtio device?
> > > Should I start with writing the code and then document how it works or is it
> > > the opposite? Should I document it and have it approved and then implement
> > > the specifications?
> > > 
> > > I know that this may sound like a stupid question, but please be patient
> > > with me, it's my first time.
> > I suggest posting a draft specification for the new device type before
> > investing too much time in the implementation.
> > 
> > Then work on the code while the spec discussion is ongoing.  This way
> > you won't have to wait too long before implementation but you also won't
> > find that reviewers are asking for large changes after you completed
> > your work.
> I feared that would be the answer.
> As I stated I'm not familiar with most of the technologies involved. I don't
> know if I have the capabilities to write a draft of the specifications
> without first working on some code to clear things up.
> I'll try my best.

I'm happy to help you get started.

I have a basic understanding of sound cards (mostly from an audio API
and application perspective) and can explain the virtio device model.

Please post the requirements and scope of the device you'd like to
create.  Are you thinking of something general-purpose like the USB
Audio Device Class specification, which can handle many different types
of devices.  Or were you thinking of something more limited?

In terms of virtio concepts, audio streams would be transferred in
chunks over virtqueues.  A "control" virtqueue might be necessary to
configure the device.  It would process configuration request/response
packets.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-01 17:05     ` Stefan Hajnoczi
@ 2019-05-02 11:18       ` Marco Martinelli - 13Byte srl
  2019-05-03 16:45         ` Stefan Hajnoczi
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Martinelli - 13Byte srl @ 2019-05-02 11:18 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: virtio-dev, kraxel

Il 01/05/19 19:05, Stefan Hajnoczi ha scritto:

> On Mon, Apr 29, 2019 at 07:39:17PM +0200, Marco Martinelli - 13Byte srl wrote:
>> Il 29/04/19 15:47, Stefan Hajnoczi ha scritto:
>>> On Mon, Apr 29, 2019 at 12:22:41AM +0200, Marco Martinelli - 13Byte srl wrote:
>>>> I'm not sure how this works, is that number already assigned and I should
>>>> use that or should I get a new one?
>>>>
>>>> For last, I have a question to clear the things up for me. It is my
>>>> understanding that in this mailing list you discuss about the
>>>> specifications, not the actual code. What's the usual process when writing a
>>>> new virtio device?
>>>> Should I start with writing the code and then document how it works or is it
>>>> the opposite? Should I document it and have it approved and then implement
>>>> the specifications?
>>>>
>>>> I know that this may sound like a stupid question, but please be patient
>>>> with me, it's my first time.
>>> I suggest posting a draft specification for the new device type before
>>> investing too much time in the implementation.
>>>
>>> Then work on the code while the spec discussion is ongoing.  This way
>>> you won't have to wait too long before implementation but you also won't
>>> find that reviewers are asking for large changes after you completed
>>> your work.
>> I feared that would be the answer.
>> As I stated I'm not familiar with most of the technologies involved. I don't
>> know if I have the capabilities to write a draft of the specifications
>> without first working on some code to clear things up.
>> I'll try my best.
> I'm happy to help you get started.
>
> I have a basic understanding of sound cards (mostly from an audio API
> and application perspective) and can explain the virtio device model.
>
> Please post the requirements and scope of the device you'd like to
> create.  Are you thinking of something general-purpose like the USB
> Audio Device Class specification, which can handle many different types
> of devices.  Or were you thinking of something more limited?
>
> In terms of virtio concepts, audio streams would be transferred in
> chunks over virtqueues.  A "control" virtqueue might be necessary to
> configure the device.  It would process configuration request/response
> packets.
>
> Stefan

Hi Stefan,

thank you for your offer.

I'll explain what I have in mind.

The scope of my project is to transfer a multichannel PCM stream from 
the VM to the host and another the other way.

The VM will see this transport interface like a generic soundcard with 
configurable input / output.

Both windows and alsa work with PCM internally and it's not a problem to 
feed the stream of one to the other, keeping in mind that channel 
mapping may vary.
I'm not aware of systems where PCM isn't used, I don't expect problems 
with this.

In Scream ( https://github.com/duncanthrax/scream ) I've used IVSHMEM as 
a ring buffer. That worked very well, it reduced the latency and 
improved the performances quite a bit over the original network 
protocol, but it's one way only (windows VM to linux host) and not as 
fast as it can be with virtio I think.

My idea is to have a device configuration layout where both the host and 
the guest can expose their current audio configuration, more or less 
like this.

struct virtio_audio_config {
         le32 sample_rate;      //from 8000Hz up to 192000Hz
         le8  sample_size;      //8bit, 16bit, 32bit or floating point
         le8  channels;         //from 1 (mono) up to 8 (7.1 surround) 
or even more in theory (eg. Dolby Atmos, 64 channels, or MAudio 1010, 
20+ channels)
         le8  channel_map[...]; //it's a list of constants to identify 
the channel order in the PCM stream (eg. CH_LEFT, CH_RIGHT, CH_CENTER)
};

The struct will be double, one from audio out, one for audio in. When 
the host or the guest change it's configuration its struct should be 
updated and the other side notified.

If the other side can't handle the configuration I'd like to figure out 
a graceful fallback. I have a few ideas in mind but I want to do some 
tests first.

If the host or the guest don't support audio out they can write 0 as 
number of channel, or zero out the entire struct during device 
initialization.
If they don't support audio input

I imagine two separate virtqueues, one for the output stream, another 
for the input stream.

What I want to do in the end consist in a few modules:
- virtio-audio specifications
- a new QEMU device based on the specs
- Windows driver for guest, based on MSVAD sample driver or SYSVAD 
sample driver, both released under MS-PL (I'll have to figure out how to 
have them signed and distributed, is MS-PL a problem?)
- ALSA driver for linux guest

Maybe I'll focus more on audio output at first and audio input later, 
because that's the common use case.

This weekend I'll take the time to document this better.

If you have any question or I was not clear let me know.


Marco


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-02 11:18       ` Marco Martinelli - 13Byte srl
@ 2019-05-03 16:45         ` Stefan Hajnoczi
  2019-05-03 19:52           ` Marco Martinelli - 13Byte srl
  0 siblings, 1 reply; 29+ messages in thread
From: Stefan Hajnoczi @ 2019-05-03 16:45 UTC (permalink / raw)
  To: Marco Martinelli - 13Byte srl; +Cc: virtio-dev, kraxel

[-- Attachment #1: Type: text/plain, Size: 6277 bytes --]

On Thu, May 02, 2019 at 01:18:40PM +0200, Marco Martinelli - 13Byte srl wrote:
> Il 01/05/19 19:05, Stefan Hajnoczi ha scritto:
> 
> > On Mon, Apr 29, 2019 at 07:39:17PM +0200, Marco Martinelli - 13Byte srl wrote:
> > > Il 29/04/19 15:47, Stefan Hajnoczi ha scritto:
> > > > On Mon, Apr 29, 2019 at 12:22:41AM +0200, Marco Martinelli - 13Byte srl wrote:
> > > > > I'm not sure how this works, is that number already assigned and I should
> > > > > use that or should I get a new one?
> > > > > 
> > > > > For last, I have a question to clear the things up for me. It is my
> > > > > understanding that in this mailing list you discuss about the
> > > > > specifications, not the actual code. What's the usual process when writing a
> > > > > new virtio device?
> > > > > Should I start with writing the code and then document how it works or is it
> > > > > the opposite? Should I document it and have it approved and then implement
> > > > > the specifications?
> > > > > 
> > > > > I know that this may sound like a stupid question, but please be patient
> > > > > with me, it's my first time.
> > > > I suggest posting a draft specification for the new device type before
> > > > investing too much time in the implementation.
> > > > 
> > > > Then work on the code while the spec discussion is ongoing.  This way
> > > > you won't have to wait too long before implementation but you also won't
> > > > find that reviewers are asking for large changes after you completed
> > > > your work.
> > > I feared that would be the answer.
> > > As I stated I'm not familiar with most of the technologies involved. I don't
> > > know if I have the capabilities to write a draft of the specifications
> > > without first working on some code to clear things up.
> > > I'll try my best.
> > I'm happy to help you get started.
> > 
> > I have a basic understanding of sound cards (mostly from an audio API
> > and application perspective) and can explain the virtio device model.
> > 
> > Please post the requirements and scope of the device you'd like to
> > create.  Are you thinking of something general-purpose like the USB
> > Audio Device Class specification, which can handle many different types
> > of devices.  Or were you thinking of something more limited?
> > 
> > In terms of virtio concepts, audio streams would be transferred in
> > chunks over virtqueues.  A "control" virtqueue might be necessary to
> > configure the device.  It would process configuration request/response
> > packets.
> > 
> > Stefan
> 
> Hi Stefan,
> 
> thank you for your offer.
> 
> I'll explain what I have in mind.

Thanks.  Some random thoughts (not strong opinions) below:

> 
> The scope of my project is to transfer a multichannel PCM stream from the VM
> to the host and another the other way.
> 
> The VM will see this transport interface like a generic soundcard with
> configurable input / output.
> 
> Both windows and alsa work with PCM internally and it's not a problem to
> feed the stream of one to the other, keeping in mind that channel mapping
> may vary.
> I'm not aware of systems where PCM isn't used, I don't expect problems with
> this.
> 
> In Scream ( https://github.com/duncanthrax/scream ) I've used IVSHMEM as a
> ring buffer. That worked very well, it reduced the latency and improved the
> performances quite a bit over the original network protocol, but it's one
> way only (windows VM to linux host) and not as fast as it can be with virtio
> I think.
> 
> My idea is to have a device configuration layout where both the host and the
> guest can expose their current audio configuration, more or less like this.
> 
> struct virtio_audio_config {
>         le32 sample_rate;      //from 8000Hz up to 192000Hz
>         le8  sample_size;      //8bit, 16bit, 32bit or floating point
>         le8  channels;         //from 1 (mono) up to 8 (7.1 surround) or
> even more in theory (eg. Dolby Atmos, 64 channels, or MAudio 1010, 20+
> channels)
>         le8  channel_map[...]; //it's a list of constants to identify the
> channel order in the PCM stream (eg. CH_LEFT, CH_RIGHT, CH_CENTER)
> };
> 
> The struct will be double, one from audio out, one for audio in. When the
> host or the guest change it's configuration its struct should be updated and
> the other side notified.
> 
> If the other side can't handle the configuration I'd like to figure out a
> graceful fallback. I have a few ideas in mind but I want to do some tests
> first.

This does not offer a way to enumerate supported configurations.  The
other side blindly suggests a configuration which may or may not be
accepted.

Enumeration of sample rates, channel topologies, sample formats, etc
would allow for negotiation that works the first time and instead of
guessing a configuration that ends up being rejected by the other side.

> If the host or the guest don't support audio out they can write 0 as number
> of channel, or zero out the entire struct during device initialization.
> If they don't support audio input
> 
> I imagine two separate virtqueues, one for the output stream, another for
> the input stream.
> 
> What I want to do in the end consist in a few modules:
> - virtio-audio specifications
> - a new QEMU device based on the specs
> - Windows driver for guest, based on MSVAD sample driver or SYSVAD sample
> driver, both released under MS-PL (I'll have to figure out how to have them
> signed and distributed, is MS-PL a problem?)
> - ALSA driver for linux guest

This is also what I'd imagine.

> 
> Maybe I'll focus more on audio output at first and audio input later,
> because that's the common use case.
> 
> This weekend I'll take the time to document this better.
> 
> If you have any question or I was not clear let me know.

Okay, it sounds like an audio API-level interface, not lower-level like
what the USB Audio Device Class does.  I'm not sure if we lose any
important functionality by choosing a high level interface.

How would soundcards with multiple inputs work?  Is each input
represented as a separate virtio-audio device?  The alternative is to
use an arbitrary number of mono or stereo channel pairs...

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-03 16:45         ` Stefan Hajnoczi
@ 2019-05-03 19:52           ` Marco Martinelli - 13Byte srl
  2019-05-06  5:27             ` Gerd Hoffmann
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Martinelli - 13Byte srl @ 2019-05-03 19:52 UTC (permalink / raw)
  To: Stefan Hajnoczi, virtio-dev; +Cc: kraxel


Il 03/05/19 18:45, Stefan Hajnoczi ha scritto:
> On Thu, May 02, 2019 at 01:18:40PM +0200, Marco Martinelli - 13Byte srl wrote:
>> Il 01/05/19 19:05, Stefan Hajnoczi ha scritto:
>>
>>> On Mon, Apr 29, 2019 at 07:39:17PM +0200, Marco Martinelli - 13Byte srl wrote:
>>>> Il 29/04/19 15:47, Stefan Hajnoczi ha scritto:
>>>>> On Mon, Apr 29, 2019 at 12:22:41AM +0200, Marco Martinelli - 13Byte srl wrote:
>>>>>> I'm not sure how this works, is that number already assigned and I should
>>>>>> use that or should I get a new one?
>>>>>>
>>>>>> For last, I have a question to clear the things up for me. It is my
>>>>>> understanding that in this mailing list you discuss about the
>>>>>> specifications, not the actual code. What's the usual process when writing a
>>>>>> new virtio device?
>>>>>> Should I start with writing the code and then document how it works or is it
>>>>>> the opposite? Should I document it and have it approved and then implement
>>>>>> the specifications?
>>>>>>
>>>>>> I know that this may sound like a stupid question, but please be patient
>>>>>> with me, it's my first time.
>>>>> I suggest posting a draft specification for the new device type before
>>>>> investing too much time in the implementation.
>>>>>
>>>>> Then work on the code while the spec discussion is ongoing.  This way
>>>>> you won't have to wait too long before implementation but you also won't
>>>>> find that reviewers are asking for large changes after you completed
>>>>> your work.
>>>> I feared that would be the answer.
>>>> As I stated I'm not familiar with most of the technologies involved. I don't
>>>> know if I have the capabilities to write a draft of the specifications
>>>> without first working on some code to clear things up.
>>>> I'll try my best.
>>> I'm happy to help you get started.
>>>
>>> I have a basic understanding of sound cards (mostly from an audio API
>>> and application perspective) and can explain the virtio device model.
>>>
>>> Please post the requirements and scope of the device you'd like to
>>> create.  Are you thinking of something general-purpose like the USB
>>> Audio Device Class specification, which can handle many different types
>>> of devices.  Or were you thinking of something more limited?
>>>
>>> In terms of virtio concepts, audio streams would be transferred in
>>> chunks over virtqueues.  A "control" virtqueue might be necessary to
>>> configure the device.  It would process configuration request/response
>>> packets.
>>>
>>> Stefan
>> Hi Stefan,
>>
>> thank you for your offer.
>>
>> I'll explain what I have in mind.
> Thanks.  Some random thoughts (not strong opinions) below:
>
>> The scope of my project is to transfer a multichannel PCM stream from the VM
>> to the host and another the other way.
>>
>> The VM will see this transport interface like a generic soundcard with
>> configurable input / output.
>>
>> Both windows and alsa work with PCM internally and it's not a problem to
>> feed the stream of one to the other, keeping in mind that channel mapping
>> may vary.
>> I'm not aware of systems where PCM isn't used, I don't expect problems with
>> this.
>>
>> In Scream ( https://github.com/duncanthrax/scream ) I've used IVSHMEM as a
>> ring buffer. That worked very well, it reduced the latency and improved the
>> performances quite a bit over the original network protocol, but it's one
>> way only (windows VM to linux host) and not as fast as it can be with virtio
>> I think.
>>
>> My idea is to have a device configuration layout where both the host and the
>> guest can expose their current audio configuration, more or less like this.
>>
>> struct virtio_audio_config {
>>          le32 sample_rate;      //from 8000Hz up to 192000Hz
>>          le8  sample_size;      //8bit, 16bit, 32bit or floating point
>>          le8  channels;         //from 1 (mono) up to 8 (7.1 surround) or
>> even more in theory (eg. Dolby Atmos, 64 channels, or MAudio 1010, 20+
>> channels)
>>          le8  channel_map[...]; //it's a list of constants to identify the
>> channel order in the PCM stream (eg. CH_LEFT, CH_RIGHT, CH_CENTER)
>> };
>>
>> The struct will be double, one from audio out, one for audio in. When the
>> host or the guest change it's configuration its struct should be updated and
>> the other side notified.
>>
>> If the other side can't handle the configuration I'd like to figure out a
>> graceful fallback. I have a few ideas in mind but I want to do some tests
>> first.
> This does not offer a way to enumerate supported configurations.  The
> other side blindly suggests a configuration which may or may not be
> accepted.
>
> Enumeration of sample rates, channel topologies, sample formats, etc
> would allow for negotiation that works the first time and instead of
> guessing a configuration that ends up being rejected by the other side.

I agree with you on this. The reason I opted to keep it simple in my 
description is that I have yet to clear my ideas on how to implement 
this particular feature.

 From my previous experience with MSVAD driver I saw that the driver 
enumerate all the possible configurations when it's initialized.

I think ALSA works in the same way but I have yet to verify this.

It's possible to enquiry the virtio-audio device about the host 
capabilities at this time but I'm not sure how to implement this in 
every audio backend of qemu (alsa, pulse, oss, coreaudio, dsound, ...)

Another thing to consider is that the host may have multiple sound 
cards. For example I have three sound cards at the moment, an integrated 
one with stereo at max 96kHZ, a dedicated one with 7.1 surround up to 
192kHz and my video card has HDMI audio out (not sure of the specs).

What can be considered a valid configuration in this scenario?

Another possibility is that the user can configure the virtio-audio 
device with the capabilities that he want to expose to the guest, 
regardless if the host really support them or not. What do you think?

In this scenario the user can even setup two separate VM with one 
virtio-audio device each and route the audio from one to another with 
something like JACK even if the host don't support the VM configuration. 
Anything capable of piping the stream from one VM to the other will do 
just fine.

Another idea is that the user may want to record the stream to process 
it later. It doesn't matter if the host audio card is not capable of 
reproducing it. The host may not even have a sound card in this case.

Can you think of any other use case?

>
>> If the host or the guest don't support audio out they can write 0 as number
>> of channel, or zero out the entire struct during device initialization.
>> If they don't support audio input they can ignore it.
>>
>> I imagine two separate virtqueues, one for the output stream, another for
>> the input stream.
>>
>> What I want to do in the end consist in a few modules:
>> - virtio-audio specifications
>> - a new QEMU device based on the specs
>> - Windows driver for guest, based on MSVAD sample driver or SYSVAD sample
>> driver, both released under MS-PL (I'll have to figure out how to have them
>> signed and distributed, is MS-PL a problem?)
>> - ALSA driver for linux guest
> This is also what I'd imagine.
>
>> Maybe I'll focus more on audio output at first and audio input later,
>> because that's the common use case.
>>
>> This weekend I'll take the time to document this better.
>>
>> If you have any question or I was not clear let me know.
> Okay, it sounds like an audio API-level interface, not lower-level like
> what the USB Audio Device Class does.  I'm not sure if we lose any
> important functionality by choosing a high level interface.

Yes, it's not too low level, all I want is to push the PCM stream to the 
host (or pull one if it's an input).

No channel mixing, no signal processing, .. this will be the host job.
> How would soundcards with multiple inputs work?  Is each input
> represented as a separate virtio-audio device?  The alternative is to
> use an arbitrary number of mono or stereo channel pairs...

I admit I never considered this. I always pictured one input and one 
output with different number of channels.

I guess the simple answer is that users can attach as many virtio-audio 
devices as they want with different configurations but I'll look around 
to see if there is any benefit in having multiple input or output in the 
same device.

>
> Stefan


Marco


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-03 19:52           ` Marco Martinelli - 13Byte srl
@ 2019-05-06  5:27             ` Gerd Hoffmann
  2019-05-09 10:10               ` Marco Martinelli - 13Byte srl
  0 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2019-05-06  5:27 UTC (permalink / raw)
  To: Marco Martinelli - 13Byte srl
  Cc: Stefan Hajnoczi, virtio-dev, Kővágó Zoltán

  Hi,

> It's possible to enquiry the virtio-audio device about the host capabilities
> at this time but I'm not sure how to implement this in every audio backend
> of qemu (alsa, pulse, oss, coreaudio, dsound, ...)

It is probably a good idea to coordinate this with Kővágó Zoltán (Cc'ed)
who has a stack of patches to rework the qemu audio configuration.  The
first batch (adding -audiodev command line switch) has been merged in
4.1, the remaining bits will hopefully follow in 4.2.  The not-yet
merged patches include:

  (1) linking guest sound cards to host backends.
  (2) 5.1 support (IIRC: usb-audio and pa + alsa backends).

In general looking: following current qemu capabilities too closely when
designing a virtio spec is a bad idea, we don't want have qemu
implementation details baked in there ...

> Another thing to consider is that the host may have multiple sound cards.
> For example I have three sound cards at the moment, an integrated one with
> stereo at max 96kHZ, a dedicated one with 7.1 surround up to 192kHz and my
> video card has HDMI audio out (not sure of the specs).
> 
> What can be considered a valid configuration in this scenario?

If you want allow your guest use all three sound cards, then you
probably want create three sound cards in the guest too, each with
different capabilities and linked to one of the host devices.

> Another possibility is that the user can configure the virtio-audio device
> with the capabilities that he want to expose to the guest, regardless if the
> host really support them or not. What do you think?

Not a good idea.  We don't want qemu do audio processing.  It already
does to (it can resample audio data in case there is a sample rate
mismatch between guest and host), but we certainly don't want extend
that.

> Another idea is that the user may want to record the stream to process it
> later. It doesn't matter if the host audio card is not capable of
> reproducing it. The host may not even have a sound card in this case.

There already is a backend writing the guest audio stream to a wav file.

> I guess the simple answer is that users can attach as many virtio-audio
> devices as they want with different configurations but I'll look around to
> see if there is any benefit in having multiple input or output in the same
> device.

One advantage I see with multiple inputs/outputs on a single device is
that synchronization will probably easier that way.

On the other hand supporting multiple outputs doesn't seem to be a
feature people want use, I can't remember any requests for that.

cheers,
  Gerd


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-06  5:27             ` Gerd Hoffmann
@ 2019-05-09 10:10               ` Marco Martinelli - 13Byte srl
  2019-05-09 12:27                 ` Gerd Hoffmann
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Martinelli - 13Byte srl @ 2019-05-09 10:10 UTC (permalink / raw)
  To: Gerd Hoffmann, virtio-dev
  Cc: Stefan Hajnoczi, Kővágó Zoltán

Hi Gerd,

thank you for your feedback and sorry for the late reply.

>    Hi,
>
>> It's possible to enquiry the virtio-audio device about the host capabilities
>> at this time but I'm not sure how to implement this in every audio backend
>> of qemu (alsa, pulse, oss, coreaudio, dsound, ...)
> It is probably a good idea to coordinate this with Kővágó Zoltán (Cc'ed)
> who has a stack of patches to rework the qemu audio configuration.  The
> first batch (adding -audiodev command line switch) has been merged in
> 4.1, the remaining bits will hopefully follow in 4.2.  The not-yet
> merged patches include:
>
>    (1) linking guest sound cards to host backends.
>    (2) 5.1 support (IIRC: usb-audio and pa + alsa backends).
Interesting, I wasn't aware of that. I'll make sure to look at his work.
> In general looking: following current qemu capabilities too closely when
> designing a virtio spec is a bad idea, we don't want have qemu
> implementation details baked in there ...
I absolutely agree. While my desire is to work on qemu the 
specifications must be agnostic.
>> Another thing to consider is that the host may have multiple sound cards.
>> For example I have three sound cards at the moment, an integrated one with
>> stereo at max 96kHZ, a dedicated one with 7.1 surround up to 192kHz and my
>> video card has HDMI audio out (not sure of the specs).
>>
>> What can be considered a valid configuration in this scenario?
> If you want allow your guest use all three sound cards, then you
> probably want create three sound cards in the guest too, each with
> different capabilities and linked to one of the host devices.

I don't really agree here, I don't see why I have to tie a virtual 
soundcard 1-to-1 to a real soundcard.

While the guest will support multiple virtio-audio cards what I imagine 
as a common scenario is something like the following.

The guest see one virtio-audio card.

On the host I open pavucontrol  (just an example) and set the default 
output to my internal sound card, where I have my headset attached.

On the guest I open my browser and listen to some music in stereo.

After a while I want to see a movie, I launch my movie player and in 
pavucontrol I switch the output to my external 7.1 amplifier.

Then I have to call a friend on skype, again I switch to my headset and 
as an input I select an usb microphone I just connected to my linux box.

All of this without touching the VM configuration.

This exact scenario is possible. It is what I have already done in 
Scream and it's working very well.


Having a 1-to-1 map between host sound cards  and virtio-audio sound 
cards just seems inconvenient. You attached a plug and play soundcard? 
Too bad. Stop your VM, add a new device, restart.. No, I don't really 
want that.

>> Another possibility is that the user can configure the virtio-audio device
>> with the capabilities that he want to expose to the guest, regardless if the
>> host really support them or not. What do you think?
> Not a good idea.  We don't want qemu do audio processing.

I don't want qemu to do audio processing either. It's not its job.

Having virtio-audio support configuration that the host sound card 
doesn't support doesn't mean that qemu have to do the audio processing.

Imagine this scenario. In a windows VM I can run some professional 
digital audio workstation software that currently don't support linux.

I can set these software to work with whatever settings I want (say, 
192kHz, floating point, 8 channels).

Virtio-audio will be able to transport the resulting PCM stream from the 
VM to the host unaltered, where for example JACK will take it and route 
them to, say, Ardour.

I don't need the host sound card support here. I really don't care if it 
can't play this stream directly.

As another example, I can have a virtio-audio with 10 input channels, 
and with JACK I can map different sources from the host to different 
channels to work on my audio workstation in the windows VM.

This will open the door to professional uses that are currently not 
possible.

Yes, in the end something will have to do the resampling, but that can 
be my linux DAW (eg. Ardour), or JACK, or Pulseaudio or anything. It 
will be up to the user to route the stream where he wants.

>   It already
> does to (it can resample audio data in case there is a sample rate
> mismatch between guest and host), but we certainly don't want extend
> that.
Agree.
>> Another idea is that the user may want to record the stream to process it
>> later. It doesn't matter if the host audio card is not capable of
>> reproducing it. The host may not even have a sound card in this case.
> There already is a backend writing the guest audio stream to a wav file.
Yes, I didn't explain it very well, sorry. I wasn't really thinking of 
writing this to a wav file but routing to professional audio tools like 
in the example above.
>> I guess the simple answer is that users can attach as many virtio-audio
>> devices as they want with different configurations but I'll look around to
>> see if there is any benefit in having multiple input or output in the same
>> device.
> One advantage I see with multiple inputs/outputs on a single device is
> that synchronization will probably easier that way.
>
> On the other hand supporting multiple outputs doesn't seem to be a
> feature people want use, I can't remember any requests for that.
Yeah, I thought about it and I don't think it's a common use case. That 
said I can see a few uses for it.
For example, I can set a virtio-audio card with 2 outputs and 1 input 
and set in my VM, say, spotify to output 2 and skype on output 1 and 
input 1.
On the host I can set the output of spotify to one soundcard, say, a 
bluetooth speaker in the room next door while I can skype chat with a 
friend on the headset.

Nowdays most softwares can remember the assigned input/output devices, 
so I can set this once and forget about it.


As a general note, I see virtio-audio as a generic interface to transfer 
PCM streams in and out of the VM.
I don't want to limit it or tying it too much to a particular system or 
backend.
I want it to be simple and flexible.
I'm sure the end users will imagine use cases that I can't even think 
about now. Maybe they'll be bizarre configurations, who knows, but I 
certainly don't want to limit them.

I think we agree that the specification should be independent of the end 
system.

The qemu device that will implement this specification is a specific 
implementation but now we don't really have to care what it will do with 
the streams it will receive from the guest. It can send them to 
/dev/null for all I care.
For the sake of the specification I think we need to focus on is how to 
transport these streams and how to share a configuration for each one.

How the stream will be handled by the host it's a matter of 
implementation in the qemu device (or whatever other software will 
implement this spec) and that's out of the scope of the specification.

Or at least this is how I think a specification should work, but please 
correct me if I'm wrong, I'm new to all of this.


> cheers,
>    Gerd
>

Regards,
Marco


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-09 10:10               ` Marco Martinelli - 13Byte srl
@ 2019-05-09 12:27                 ` Gerd Hoffmann
  2019-05-10  9:45                   ` Mikhail Golubev
  2019-05-10 10:34                   ` Stefan Hajnoczi
  0 siblings, 2 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2019-05-09 12:27 UTC (permalink / raw)
  To: Marco Martinelli - 13Byte srl
  Cc: virtio-dev, Stefan Hajnoczi, Kővágó Zoltán

  Hi,

> > If you want allow your guest use all three sound cards, then you
> > probably want create three sound cards in the guest too, each with
> > different capabilities and linked to one of the host devices.
> 
> I don't really agree here, I don't see why I have to tie a virtual soundcard
> 1-to-1 to a real soundcard.

Yes, but you still have to manage output capabilities somehow.

> While the guest will support multiple virtio-audio cards what I imagine as a
> common scenario is something like the following.
> 
> The guest see one virtio-audio card.
> 
> On the host I open pavucontrol  (just an example) and set the default output
> to my internal sound card, where I have my headset attached.
> 
> On the guest I open my browser and listen to some music in stereo.
> 
> After a while I want to see a movie, I launch my movie player and in
> pavucontrol I switch the output to my external 7.1 amplifier.

Ok, so the question is how you present that to the guest.  The guests
sound device suddenly changing capabilities (when you re-route from host
stereo to host 7.1) isn't going to work.

You could present a single output which is able to support both stereo
and 7.1.  You need somehow handle the case that your guest sends 7.1
while the output is routed to stereo on the host (can pulseaudio
resample that for us?)

You could present two outputs to the guest (doesn't matter much whenever
one card with two outputs or two cards with one output each), where one
supports stereo and the other 7.1.  Then allow routing the guests 7.1
output only to 7.1-capable host outputs, likewise for stereo.

Not sure which of the two options will work better in practice.

> Virtio-audio will be able to transport the resulting PCM stream from the VM
> to the host unaltered, where for example JACK will take it and route them
> to, say, Ardour.
> 
> I don't need the host sound card support here. I really don't care if it
> can't play this stream directly.

Yes, sure.  It's not so much about host soundcards, but about host
audio backends.  In some cases the qemu audio backend is linked to a
specific sound card (alsa, oss), but on other cases it isn't (pulseaudio).

With qemu sending the pcm stream to a sound server like pulseaudio (or
jack when someone writes a backend) the sound server can of course
re-route and/or process the stream as it pleases.

> For the sake of the specification I think we need to focus on is how to
> transport these streams and how to share a configuration for each one.

I think we need at least three virt queues.  One control queue for
commands (query capabilities, set configuration, start/stop streams,
volume control, ...).  One queue for input streams.  One queue for
output streams.

If we want allow for multiple inputs/outputs we have basically two
options: (a) one queue per stream, or (b) use a small header for each
data packet, telling what stream it belongs to.

Maybe a small header is a good idea anyway, for timestamps.

> Or at least this is how I think a specification should work, but please
> correct me if I'm wrong, I'm new to all of this.

That is correct.

cheers,
  Gerd


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-09 12:27                 ` Gerd Hoffmann
@ 2019-05-10  9:45                   ` Mikhail Golubev
  2019-05-10 12:16                     ` Gerd Hoffmann
  2019-05-10 10:34                   ` Stefan Hajnoczi
  1 sibling, 1 reply; 29+ messages in thread
From: Mikhail Golubev @ 2019-05-10  9:45 UTC (permalink / raw)
  To: Gerd Hoffmann, Marco Martinelli - 13Byte srl
  Cc: virtio-dev, Stefan Hajnoczi, Kővágó Zoltán

[-- Attachment #1: Type: text/plain, Size: 1396 bytes --]

Hi all!

Sorry for breaking in the middle of the virtio audio driver and device
development discussion. But we are developing a virtio sound card prototype for
a while and we would like to share our specification draft and public header
file (attaching 'virtio_snd.h' and 'virtio-snd-spec-draft.md'). The PoC for
proposed approach was tested with virtio audio driver in Linux and in Windows 10
as well.

It would be really great if we can collaborate on this topic. I would be happy
to answer any questions.


--
Mikhail Golubev
Software Engineer

OpenSynergy GmbH
Rotherstr. 20, 10245 Berlin

Telefon: +49 (30) 60 98 54 0 - 903
Fax:     +49 (30) 60 98 54 0 - 99
EMail:   mikhail.golubev@opensynergy.com

www.opensynergy.com

Handelsregister/Commercial Registry: Amtsgericht Charlottenburg, HRB 108616B
Geschäftsführer/Managing Director: Stefaan Sonck Thiebaut

Please mind our privacy notice<https://www.opensynergy.com/datenschutzerklaerung/privacy-notice-for-business-partners-pursuant-to-article-13-of-the-general-data-protection-regulation-gdpr/> pursuant to Art. 13 GDPR. // Unsere Hinweise zum Datenschutz gem. Art. 13 DSGVO finden Sie hier.<https://www.opensynergy.com/de/datenschutzerklaerung/datenschutzhinweise-fuer-geschaeftspartner-gem-art-13-dsgvo/>
COQOS Hypervisor certified by TÜV SÜD
                [COQOS Hypervisor certified by TÜV SÜD]

[-- Attachment #2: virtio-snd-spec-draft.md --]
[-- Type: text/markdown, Size: 28268 bytes --]

# VirtIO sound card draft specification

The VirtIO sound card is an extendible virtual audio device. It provides its
functionality in a form of device functions that can be configured and managed
in an independent way.

## Device ID

TBD

## Virtqueues

0
> controlq

##  Feature Bits

None currently defined

## Device Configuration Layout

Configuration space provides a maximum amount of available virtual queues. The
nqueues value MUST be at least one.

```
struct virtio_snd_config
{
    le32 nqueues;
};
```

## Device Initialization

The driver SHOULD perform the following initialization sequence:

1. Initialize all available virtual queues.
2. Read a device configuration.
3. For every available function perform function-specific initialization.

## Device Operation

All control messages are placed into a single virtual queue with index zero.

A control message consumes two virtual queue descriptors: one containing a
read-only request and one containing a writable response.

Each request begins with a 2-byte field that identifies a recipient function
followed by a 2-byte field that identifies a function-specific request type.

Each response begins with a 4-byte field that contains a status code. The values
0-31 are reserved for common status codes, a function can define function-specific
status codes starting from 32.

```
struct virtio_snd_req
{
    le16 function;
    le16 request;
};

/* no errors */
#define VIRTIO_SND_E_SUCCESS        0
/* an undefined error */
#define VIRTIO_SND_E_GENERAL        1
/* not supported input parameter(s) */
#define VIRTIO_SND_E_NOTSUPPORTED   2
/* invalid input parameter(s) */
#define VIRTIO_SND_E_INVALID        3
/* I/O error */
#define VIRTIO_SND_E_IO             4

struct virtio_snd_rsp
{
    le32 status; /* VIRTIO_SND_E_XXX */
};
```

If a request consists only of a generic header, it's referred as a *generic request*.

If a response consists only of a generic header, it's referred as a *generic response*.

### Device Configuration

The device reports its configuration using descriptors. A descriptor is a data
structure with a defined format. Each descriptor begins with a byte-wide field
that contains the total number of bytes in the descriptor followed by a byte-wide
field that identifies the descriptor type.

```
struct virtio_snd_generic_desc
{
    u8 length;
    u8 type;
    u16 padding;
};
```

With the exception of the base function, all implemented functions MUST define
its own descriptor(s) format (either presented in this specification or
vendor-specific) and MUST includes these in configuration only if a particular
function (or part of its functionality) is enabled in the device.

## Device Operation: Base Function

A function identifier zero is reserved for base messages that can affect the entire
device. The device MUST support all base requests and responses defined in this
specification.

```
#define VIRTIO_SND_FN_BASE              0

/* --- BASE REQUEST TYPES --- */
#define VIRTIO_SND_BASE_R_GET_CFG       0
#define VIRTIO_SND_BASE_R_SUSPEND       1
#define VIRTIO_SND_BASE_R_RESUME        2
```

### Function Operation

#### Get Device Configuration

The driver sends the VIRTIO_SND_BASE_R_GET_CFG generic request, the device
answers with a response containing device configuration. The driver MUST examine
response content, initialize all presented and supported device functions and
ignore all unsupported ones.

```
#define VIRTIO_SND_BASE_CFG_MAX_SIZE    1024

/* a response containing device configuration */
struct virtio_snd_base_configuration
{
    struct virtio_snd_rsp hdr;
    /* size in bytes of configuration data */
    le32 length;
    /* configuration data */
    u8 data[VIRTIO_SND_BASE_CFG_MAX_SIZE];
};
```

#### Suspend

The driver sends the VIRTIO_SND_BASE_R_SUSPEND generic request, the device
answers with a generic response. For each initialized function, the device SHOULD
be able to preserve its runtime state and MUST put it into function-specific
suspended state.

#### Resume

The driver sends the VIRTIO_SND_BASE_R_RESUME generic request, the device
answers with a generic response. For each initialized function, the device SHOULD
be able to restore its runtime state and MUST put it into function-specific
non-suspended state.

## Device Operation: PCM Function

The PCM function provides up to one playback and up to one capture PCM streams.
If the device supports more than one PCM streams of the same type, it MUST provide
them as separate PCM functions. A PCM stream contains one or more PCM substreams
sharing the same capabilities reported in configuration, and all further function
manipulations are happened on per dedicated substream basis.

The function supports only the interleaved channels and MUST support at least one
of the following operational modes:

- *Manual mode*: the driver assigns a dedicated virtual queue for a PCM substream
and use it to transmit data buffers to the device. The device writes/reads PCM
frames only upon receiving a buffer from the driver.
- *Automatic mode*: the driver allocates and shares with the device a pseudophysically
continuous memory area containing runtime control registers and data buffer itself.
In case of the playback stream, the device reads constant amount of PCM frames
with constant time intervals without any requests from the driver. In case of
the capture stream, the device writes constant amount of PCM frames with constant
time intervals without any notifications to the driver.

Regardless of the mode of operation, the device MAY require to specify an
approximate data buffer update frequency. In such case, the driver MUST specify
an approximate update frequency (expressed in both microseconds and bytes units)
before starting a PCM substream.

The function also MAY provide an ability to get and set supported channel maps.

The device reports mentioned functional features using the features field in a
PCM stream configuration descriptor.

A PCM request consists of or is preceded by a header:

```
#define VIRTIO_SND_FN_PCM               1

/* --- PCM REQUEST TYPES --- */
#define VIRTIO_SND_PCM_R_GET_FEATURE    0
#define VIRTIO_SND_PCM_R_SET_FEATURE    1
#define VIRTIO_SND_PCM_R_SET_FORMAT     2
#define VIRTIO_SND_PCM_R_PREPARE        3
#define VIRTIO_SND_PCM_R_START          4
#define VIRTIO_SND_PCM_R_STOP           5
#define VIRTIO_SND_PCM_R_PAUSE          6
#define VIRTIO_SND_PCM_R_UNPAUSE        7
#define VIRTIO_SND_PCM_R_REWIND         8
#define VIRTIO_SND_PCM_R_FORWARD        9

/* a PCM substream request header */
struct virtio_snd_pcm_hdr
{
    /* VIRTIO_SND_FN_PCM */
    le16 function;
    /* a PCM request type (VIRTIO_SND_PCM_R_XXX) */
    le16 request;
    /* a PCM identifier (assigned in configuration) */
    u8 pcm_id;
    /* a PCM stream type (VIRTIO_SND_PCM_T_XXX) */
    u8 stream_type;
    /* a PCM substream identifier */
    u8 substream_id;
    u8 padding;
};
```

If a PCM request consists only of a generic PCM header, it's referred to as a
*generic PCM request*.

A PCM response consists of or is preceded by a generic response header. It
contains one of the generic or PCM-specific error codes:

```
/* --- PCM ERROR CODES --- */

/* a PCM substream is not ready */
#define VIRTIO_SND_PCM_E_NOT_READY      32
```

### Function Configuration

The function puts into device configuration a PCM function descriptor followed
by up to two PCM stream descriptors.

```
#define VIRTIO_SND_DESC_PCM             0
#define VIRTIO_SND_DESC_PCM_STREAM      1

/* a PCM function descriptor */
struct virtio_snd_pcm_desc
{
    /* sizeof(struct virtio_snd_pcm_desc) */
    u8 length;
    /* VIRTIO_SND_DESC_PCM */
    u8 type;
    /* a PCM function ID (assigned by the device) */
    u8 pcm_id;
    /* # of PCM stream descriptors in the configuration (one per supported PCM stream type) */
    u8 nstreams;
};

/* supported PCM stream types */
#define VIRTIO_SND_PCM_T_PLAYBACK       0
#define VIRTIO_SND_PCM_T_CAPTURE        1

/* supported PCM stream features */
#define VIRTIO_SND_PCM_FEAT_COMMAND_MODE 0
#define VIRTIO_SND_PCM_FEAT_POLLING_MODE 1
#define VIRTIO_SND_PCM_FEAT_UPDATE_FREQUENCY 2
#define VIRTIO_SND_PCM_FEAT_CHANNEL_MAP 3

#define VIRTIO_SND_PCM_FEATBIT(bit)     (1U << VIRTIO_SND_PCM_FEAT_ ## bit)

#define VIRTIO_SND_PCM_FEATBIT_COMMAND_MODE \
    VIRTIO_SND_PCM_FEATBIT(COMMAND_MODE)
#define VIRTIO_SND_PCM_FEATBIT_POLLING_MODE \
    VIRTIO_SND_PCM_FEATBIT(POLLING_MODE)
#define VIRTIO_SND_PCM_FEATBIT_UPDATE_FREQUENCY \
    VIRTIO_SND_PCM_FEATBIT(UPDATE_FREQUENCY)
#define VIRTIO_SND_PCM_FEATBIT_CHANNEL_MAP \
    VIRTIO_SND_PCM_FEATBIT(CHANNEL_MAP)

/* supported PCM sample formats */
#define VIRTIO_SND_PCM_FMT_MU_LAW       0
#define VIRTIO_SND_PCM_FMT_A_LAW        1
#define VIRTIO_SND_PCM_FMT_S8           2
#define VIRTIO_SND_PCM_FMT_U8           3
#define VIRTIO_SND_PCM_FMT_S16_LE       4
#define VIRTIO_SND_PCM_FMT_S16_BE       5
#define VIRTIO_SND_PCM_FMT_U16_LE       6
#define VIRTIO_SND_PCM_FMT_U16_BE       7
#define VIRTIO_SND_PCM_FMT_S24_LE       8
#define VIRTIO_SND_PCM_FMT_S24_BE       9
#define VIRTIO_SND_PCM_FMT_U24_LE       10
#define VIRTIO_SND_PCM_FMT_U24_BE       11
#define VIRTIO_SND_PCM_FMT_S32_LE       12
#define VIRTIO_SND_PCM_FMT_S32_BE       13
#define VIRTIO_SND_PCM_FMT_U32_LE       14
#define VIRTIO_SND_PCM_FMT_U32_BE       15
#define VIRTIO_SND_PCM_FMT_FLOAT_LE     16
#define VIRTIO_SND_PCM_FMT_FLOAT_BE     17
#define VIRTIO_SND_PCM_FMT_FLOAT64_LE   18
#define VIRTIO_SND_PCM_FMT_FLOAT64_BE   19
#define VIRTIO_SND_PCM_FMT_S20_LE       20
#define VIRTIO_SND_PCM_FMT_S20_BE       21
#define VIRTIO_SND_PCM_FMT_U20_LE       22
#define VIRTIO_SND_PCM_FMT_U20_BE       23
#define VIRTIO_SND_PCM_FMT_S24_3LE      24
#define VIRTIO_SND_PCM_FMT_S24_3BE      25
#define VIRTIO_SND_PCM_FMT_U24_3LE      26
#define VIRTIO_SND_PCM_FMT_U24_3BE      27
#define VIRTIO_SND_PCM_FMT_S20_3LE      28
#define VIRTIO_SND_PCM_FMT_S20_3BE      29
#define VIRTIO_SND_PCM_FMT_U20_3LE      30
#define VIRTIO_SND_PCM_FMT_U20_3BE      31
#define VIRTIO_SND_PCM_FMT_S18_3LE      32
#define VIRTIO_SND_PCM_FMT_U18_3LE      33
#define VIRTIO_SND_PCM_FMT_S18_3BE      34
#define VIRTIO_SND_PCM_FMT_U18_3BE      35

#define VIRTIO_SND_PCM_FMTBIT(bit)      (1ULL << VIRTIO_SND_PCM_FMT_ ## bit)

#define VIRTIO_SND_PCM_FMTBIT_MU_LAW    VIRTIO_SND_PCM_FMTBIT(MU_LAW)
#define VIRTIO_SND_PCM_FMTBIT_A_LAW     VIRTIO_SND_PCM_FMTBIT(A_LAW)
#define VIRTIO_SND_PCM_FMTBIT_S8        VIRTIO_SND_PCM_FMTBIT(S8)
#define VIRTIO_SND_PCM_FMTBIT_U8        VIRTIO_SND_PCM_FMTBIT(U8)
#define VIRTIO_SND_PCM_FMTBIT_S16_LE    VIRTIO_SND_PCM_FMTBIT(S16_LE)
#define VIRTIO_SND_PCM_FMTBIT_S16_BE    VIRTIO_SND_PCM_FMTBIT(S16_BE)
#define VIRTIO_SND_PCM_FMTBIT_U16_LE    VIRTIO_SND_PCM_FMTBIT(U16_LE)
#define VIRTIO_SND_PCM_FMTBIT_U16_BE    VIRTIO_SND_PCM_FMTBIT(U16_BE)
#define VIRTIO_SND_PCM_FMTBIT_S24_LE    VIRTIO_SND_PCM_FMTBIT(S24_LE)
#define VIRTIO_SND_PCM_FMTBIT_S24_BE    VIRTIO_SND_PCM_FMTBIT(S24_BE)
#define VIRTIO_SND_PCM_FMTBIT_U24_LE    VIRTIO_SND_PCM_FMTBIT(U24_LE)
#define VIRTIO_SND_PCM_FMTBIT_U24_BE    VIRTIO_SND_PCM_FMTBIT(U24_BE)
#define VIRTIO_SND_PCM_FMTBIT_S32_LE    VIRTIO_SND_PCM_FMTBIT(S32_LE)
#define VIRTIO_SND_PCM_FMTBIT_S32_BE    VIRTIO_SND_PCM_FMTBIT(S32_BE)
#define VIRTIO_SND_PCM_FMTBIT_U32_LE    VIRTIO_SND_PCM_FMTBIT(U32_LE)
#define VIRTIO_SND_PCM_FMTBIT_U32_BE    VIRTIO_SND_PCM_FMTBIT(U32_BE)
#define VIRTIO_SND_PCM_FMTBIT_FLOAT_LE  VIRTIO_SND_PCM_FMTBIT(FLOAT_LE)
#define VIRTIO_SND_PCM_FMTBIT_FLOAT_BE  VIRTIO_SND_PCM_FMTBIT(FLOAT_BE)
#define VIRTIO_SND_PCM_FMTBIT_FLOAT64_LE VIRTIO_SND_PCM_FMTBIT(FLOAT64_LE)
#define VIRTIO_SND_PCM_FMTBIT_FLOAT64_BE VIRTIO_SND_PCM_FMTBIT(FLOAT64_BE)
#define VIRTIO_SND_PCM_FMTBIT_S20_LE    VIRTIO_SND_PCM_FMTBIT(S20_LE)
#define VIRTIO_SND_PCM_FMTBIT_S20_BE    VIRTIO_SND_PCM_FMTBIT(S20_BE)
#define VIRTIO_SND_PCM_FMTBIT_U20_LE    VIRTIO_SND_PCM_FMTBIT(U20_LE)
#define VIRTIO_SND_PCM_FMTBIT_U20_BE    VIRTIO_SND_PCM_FMTBIT(U20_BE)
#define VIRTIO_SND_PCM_FMTBIT_S24_3LE   VIRTIO_SND_PCM_FMTBIT(S24_3LE)
#define VIRTIO_SND_PCM_FMTBIT_S24_3BE   VIRTIO_SND_PCM_FMTBIT(S24_3BE)
#define VIRTIO_SND_PCM_FMTBIT_U24_3LE   VIRTIO_SND_PCM_FMTBIT(U24_3LE)
#define VIRTIO_SND_PCM_FMTBIT_U24_3BE   VIRTIO_SND_PCM_FMTBIT(U24_3BE)
#define VIRTIO_SND_PCM_FMTBIT_S20_3LE   VIRTIO_SND_PCM_FMTBIT(S20_3LE)
#define VIRTIO_SND_PCM_FMTBIT_S20_3BE   VIRTIO_SND_PCM_FMTBIT(S20_3BE)
#define VIRTIO_SND_PCM_FMTBIT_U20_3LE   VIRTIO_SND_PCM_FMTBIT(U20_3LE)
#define VIRTIO_SND_PCM_FMTBIT_U20_3BE   VIRTIO_SND_PCM_FMTBIT(U20_3BE)
#define VIRTIO_SND_PCM_FMTBIT_S18_3LE   VIRTIO_SND_PCM_FMTBIT(S18_3LE)
#define VIRTIO_SND_PCM_FMTBIT_S18_3BE   VIRTIO_SND_PCM_FMTBIT(S18_3BE)
#define VIRTIO_SND_PCM_FMTBIT_U18_3LE   VIRTIO_SND_PCM_FMTBIT(U18_3LE)
#define VIRTIO_SND_PCM_FMTBIT_U18_3BE   VIRTIO_SND_PCM_FMTBIT(U18_3BE)

/* supported PCM frame rates */
#define VIRTIO_SND_PCM_RATE_5512        0
#define VIRTIO_SND_PCM_RATE_8000        1
#define VIRTIO_SND_PCM_RATE_11025       2
#define VIRTIO_SND_PCM_RATE_16000       3
#define VIRTIO_SND_PCM_RATE_22050       4
#define VIRTIO_SND_PCM_RATE_32000       5
#define VIRTIO_SND_PCM_RATE_44100       6
#define VIRTIO_SND_PCM_RATE_48000       7
#define VIRTIO_SND_PCM_RATE_64000       8
#define VIRTIO_SND_PCM_RATE_88200       9
#define VIRTIO_SND_PCM_RATE_96000       10
#define VIRTIO_SND_PCM_RATE_176400      11
#define VIRTIO_SND_PCM_RATE_192000      12

#define VIRTIO_SND_PCM_RATEBIT(bit)     (1U << VIRTIO_SND_PCM_RATE_ ## bit)

#define VIRTIO_SND_PCM_RATEBIT_5512     VIRTIO_SND_PCM_RATEBIT(5512)
#define VIRTIO_SND_PCM_RATEBIT_8000     VIRTIO_SND_PCM_RATEBIT(8000)
#define VIRTIO_SND_PCM_RATEBIT_11025    VIRTIO_SND_PCM_RATEBIT(11025)
#define VIRTIO_SND_PCM_RATEBIT_16000    VIRTIO_SND_PCM_RATEBIT(16000)
#define VIRTIO_SND_PCM_RATEBIT_22050    VIRTIO_SND_PCM_RATEBIT(22050)
#define VIRTIO_SND_PCM_RATEBIT_32000    VIRTIO_SND_PCM_RATEBIT(32000)
#define VIRTIO_SND_PCM_RATEBIT_44100    VIRTIO_SND_PCM_RATEBIT(44100)
#define VIRTIO_SND_PCM_RATEBIT_48000    VIRTIO_SND_PCM_RATEBIT(48000)
#define VIRTIO_SND_PCM_RATEBIT_64000    VIRTIO_SND_PCM_RATEBIT(64000)
#define VIRTIO_SND_PCM_RATEBIT_88200    VIRTIO_SND_PCM_RATEBIT(88200)
#define VIRTIO_SND_PCM_RATEBIT_96000    VIRTIO_SND_PCM_RATEBIT(96000)
#define VIRTIO_SND_PCM_RATEBIT_176400   VIRTIO_SND_PCM_RATEBIT(176400)
#define VIRTIO_SND_PCM_RATEBIT_192000   VIRTIO_SND_PCM_RATEBIT(192000)

/* a PCM stream descriptor */
struct virtio_snd_pcm_stream_desc
{
    /* sizeof(struct virtio_snd_pcm_stream_desc) */
    u8 length;
    /* VIRTIO_SND_DESC_PCM_STREAM */
    u8 type;
    /* a PCM stream type (VIRTIO_SND_PCM_T_XXX) */
    u8 stream_type;
    /* # of substreams for the specified stream type */
    u8 nsubstreams;
    /* minimum # of supported channels */
    le16 channels_min;
    /* maximum # of supported channels */
    le16 channels_max;
    /* supported sample formats (VIRTIO_SND_PCM_FMTBIT_XXX, can be ORed) */
    le64 formats;
    /* supported frame rates (VIRTIO_SND_PCM_RATEBIT_XXX, can be ORed) */
    le32 rates;
    /* supported PCM stream features (VIRTIO_SND_PCM_FEATBIT_XXX, can be ORed) */
    le16 features;
    /* # of supported channel maps */
    le16 nchmaps;
};
```

### Function Initialization

Upon function initialization, the driver MUST set selected operational mode per
each available substream for all available streams.

### Function Operation

#### Features

The driver sends the VIRTIO_SND_PCM_R_GET_FEATURE/VIRTIO_SND_PCM_R_SET_FEATURE to
get/set substream feature-specific value.

```
/* get/set a PCM substream feature */
struct virtio_snd_pcm_feature
{
    /* VIRTIO_SND_FN_PCM */
    le16 function;
    /* VIRTIO_SND_PCM_R_GET_FEATURE / VIRTIO_SND_PCM_R_SET_FEATURE */
    le16 request;
    /* a PCM identifier (assigned in configuration) */
    u8 pcm_id;
    /* a PCM stream type (VIRTIO_SND_PCM_T_XXX) */
    u8 stream_type;
    /* a PCM substream identifier [0 .. virtio_snd_pcm_stream_desc::nsubstreams - 1] */
    u8 substream_id;
    /* a selected PCM substream feature (VIRTIO_SND_PCM_FEAT_XXX) */
    u8 feature;
    /* a feature-specific optional request data */
    union
    {
        /* VIRTIO_SND_PCM_FEAT_UPDATE_FREQUENCY [SET-only] */
        struct
        {
            /* an approximate update frequency in microseconds */
            le32 microseconds;
            /* an approximate update frequency in bytes */
            le32 bytes;
        } update_frequency;
        /*
         * VIRTIO_SND_PCM_FEAT_MANUAL_MODE [SET-only]
         *   .data = a virtual queue index
         * VIRTIO_SND_PCM_FEAT_AUTO_MODE [SET-only]
         *   .data = a pseudophysical start address of the virtio_snd_pcm_shmem structure
         * VIRTIO_SND_PCM_FEAT_CHANNEL_MAP [GET/SET]
         *   GET:
         *     .data = a channel map index [0 .. virtio_snd_pcm_stream_desc::nchmaps - 1]
         *   SET:
         *     .data = a pseudophysical start address of the virtio_snd_pcm_chmap_data structure
         */
        le64 data;
    };
};
```

<u>Manual mode (VIRTIO_SND_PCM_FEAT_MANUAL_MODE)</u>

If the device supports the manual operating mode, it sets the VIRTIO_SND_PCM_FEATBIT_MANUAL_MODE
bit in the features field value in PCM stream configuration descriptor.

In manual mode, the driver assigns a dedicated virtual queue for a PCM substream
and uses it to transmit data buffers to the device. In the playback mode, upon
receiving a data buffer, the device reads next available PCM frames from it. In
the capture mode, upon receiving a data buffer, the device writes available PCM
frames into it and notifies the driver only when the buffer is full.

The driver can move its read/write pointer using the VIRTIO_SND_PCM_R_REWIND or
the VIRTIO_SND_PCM_R_FORWARD requests.

The driver enables manual mode by setting the VIRTIO_SND_PCM_FEAT_MANUAL_MODE
feature for a substream and specifying virtual queue index as a request argument.
The device answers with a generic response.

<u>Automatic mode (VIRTIO_SND_PCM_FEAT_AUTO_MODE)</u>

If the device supports the automatic operating mode, it sets the VIRTIO_SND_PCM_FEATBIT_AUTO_MODE
bit in the features field value in PCM stream configuration descriptor.

In automatic mode, the driver allocates a pseudophysically continuous memory area
consisted of:

1. *Hardware registers*: represents the device runtime state.
2. *Software registers*: represents the driver runtime state.
3. *DMA buffer*: PCM frames storage.

```
/* --- PCM HARDWARE STATE BITMAP --- */
#define VIRTIO_SND_PCM_HW_S_RUNNING     0x0001
#define VIRTIO_SND_PCM_HW_S_PAUSED      0x0002

struct virtio_snd_pcm_hw_regs
{
    /*
     *  Bits | Mnemonic  | Description
     * ------+-----------+------------------------------------------------------
     *     0 | RUNNING   | 0 = Substream is not running
     *       |           | 1 = Substream is running
     * ------+-----------+------------------------------------------------------
     *     1 | PAUSED    | 0 = Substream is not paused
     *       |           | 1 = Substream is paused
     * ------+-----------+------------------------------------------------------
     *  2:31 |           | Reserved, must be zero.
     */
    le32 state;
    /* additional hardware latency: unsigned value in bytes */
    le32 latency;
    /* current hardware position: unsigned value in bytes [0 .. dma_size - 1] */
    le32 dma_position;
};

struct virtio_snd_pcm_sw_regs
{
    /* current DMA buffer size in bytes */
    le32 dma_size;
};

/* a PCM substream shared memory structure */
struct virtio_snd_pcm_shmem
{
    /*
     * automatic mode hardware registers
     *   device: writable
     *   driver: read-only
     */
    struct virtio_snd_pcm_hw_regs hwrs;

    /*
     * automatic mode software registers
     *   device: read-only
     *   driver: writable
     */
    struct virtio_snd_pcm_sw_regs swrs;

    /*
     * followed by a variable sized DMA buffer
     *   in the playback mode:
     *     device: read-only
     *     driver: writable
     *   in the capture mode:
     *     device: writable
     *     driver: read-only
     */
};
```

The driver enables automatic mode by setting the VIRTIO_SND_PCM_FEAT_AUTO_MODE
feature for a substream and specifying a pseudophysical start address of the
virtio_snd_pcm_shmem structure as a request argument. The device answers with a
generic response.

The driver MUST allocates DMA buffer of maximum possible size and set the dma_size
field value to this size while sending the VIRTIO_SND_PCM_R_SET_FEATURE request.
Depending on selected PCM format, the actual buffer size can be less or equal to
maximum possible one.

In case of the playback stream, the device reads constant amount of PCM frames
with constant time intervals without any requests from the driver. In case of
the capture stream, the device writes constant amount of PCM frames with constant
time intervals without any notifications to the driver.

<u>Update frequency (VIRTIO_SND_PCM_FEAT_UPDATE_FREQUENCY)</u>

If the device requires specifying an approximate data buffer update frequency,
it sets the VIRTIO_SND_PCM_FEATBIT_UPDATE_FREQUENCY bit in the features field
value in PCM stream configuration descriptor.

In such case, the driver MUST set the VIRTIO_SND_PCM_FEAT_UPDATE_FREQUENCY feature
and specify an approximate update frequency (expressed in both microseconds and
bytes units) as a request argument before starting a PCM substream. The device
answers with a generic response.

<u>Channel map (VIRTIO_SND_PCM_FEAT_CHANNEL_MAP)</u>

If the device provides an ability to get supported channel maps, it sets
the VIRTIO_SND_PCM_FEATBIT_CHANNEL_MAP bit in the features field value and
specifies an amount of supported channel maps in the nchmaps field in PCM stream
configuration descriptor.

The driver gets the VIRTIO_SND_PCM_FEAT_CHANNEL_MAP feature value in order to obtain
a channel map with specified index, the device answers with the virtio_snd_pcm_chmap
PCM response.

If channel map type allows to swap channels, the driver can set the VIRTIO_SND_PCM_FEAT_CHANNEL_MAP
feature value specifying selected channel map data as a request argument. The
device answers with a generic response.

```
/* a PCM channel map definitions */

/* All channels have fixed channel positions */
#define VIRTIO_SND_PCM_CHMAP_FIXED      0
/* All channels are swappable (e.g. {FL/FR/RL/RR} -> {RR/RL/FR/FL}) */
#define VIRTIO_SND_PCM_CHMAP_VARIABLE   1
/* Only pair-wise channels are swappable (e.g. {FL/FR/RL/RR} -> {RL/RR/FL/FR}) */
#define VIRTIO_SND_PCM_CHMAP_PAIRED     2

/* Standard channel position definition */
#define VIRTIO_SND_PCM_CH_NONE          0   /* undefined */
#define VIRTIO_SND_PCM_CH_NA            1   /* silent */
#define VIRTIO_SND_PCM_CH_MONO          2   /* mono stream */
#define VIRTIO_SND_PCM_CH_FL            3   /* front left */
#define VIRTIO_SND_PCM_CH_FR            4   /* front right */
#define VIRTIO_SND_PCM_CH_RL            5   /* rear left */
#define VIRTIO_SND_PCM_CH_RR            6   /* rear right */
#define VIRTIO_SND_PCM_CH_FC            7   /* front center */
#define VIRTIO_SND_PCM_CH_LFE           8   /* low frequency (LFE) */
#define VIRTIO_SND_PCM_CH_SL            9   /* side left */
#define VIRTIO_SND_PCM_CH_SR            10  /* side right */
#define VIRTIO_SND_PCM_CH_RC            11  /* rear center */
#define VIRTIO_SND_PCM_CH_FLC           12  /* front left center */
#define VIRTIO_SND_PCM_CH_FRC           13  /* front right center */
#define VIRTIO_SND_PCM_CH_RLC           14  /* rear left center */
#define VIRTIO_SND_PCM_CH_RRC           15  /* rear right center */
#define VIRTIO_SND_PCM_CH_FLW           16  /* front left wide */
#define VIRTIO_SND_PCM_CH_FRW           17  /* front right wide */
#define VIRTIO_SND_PCM_CH_FLH           18  /* front left high */
#define VIRTIO_SND_PCM_CH_FCH           19  /* front center high */
#define VIRTIO_SND_PCM_CH_FRH           20  /* front right high */
#define VIRTIO_SND_PCM_CH_TC            21  /* top center */
#define VIRTIO_SND_PCM_CH_TFL           22  /* top front left */
#define VIRTIO_SND_PCM_CH_TFR           23  /* top front right */
#define VIRTIO_SND_PCM_CH_TFC           24  /* top front center */
#define VIRTIO_SND_PCM_CH_TRL           25  /* top rear left */
#define VIRTIO_SND_PCM_CH_TRR           26  /* top rear right */
#define VIRTIO_SND_PCM_CH_TRC           27  /* top rear center */
#define VIRTIO_SND_PCM_CH_TFLC          28  /* top front left center */
#define VIRTIO_SND_PCM_CH_TFRC          29  /* top front right center */
#define VIRTIO_SND_PCM_CH_TSL           30  /* top side left */
#define VIRTIO_SND_PCM_CH_TSR           31  /* top side right */
#define VIRTIO_SND_PCM_CH_LLFE          32  /* left LFE */
#define VIRTIO_SND_PCM_CH_RLFE          33  /* right LFE */
#define VIRTIO_SND_PCM_CH_BC            34  /* bottom center */
#define VIRTIO_SND_PCM_CH_BLC           35  /* bottom left center */
#define VIRTIO_SND_PCM_CH_BRC           36  /* bottom right center */

/*
 * The channel is phase inverted (thus summing left and right channels would
 * result in almost silence).
 */
#define VIRTIO_SND_PCM_CH_F_PHASE_INVERSE 0x01

#define VIRTIO_SND_PCM_CH_MAX           256

/* a PCM channel information */
struct virtio_snd_pcm_chinfo
{
    /* a PCM channel position (VIRTIO_SND_PCM_CH_XXX) */
    u8 position;
    /* a PCM channel flags (VIRTIO_SND_PCM_CH_F_XXX, can be ORed) */
    u8 flags;
};

/* a PCM channel map data */
struct virtio_snd_pcm_chmap_data
{
    /* # of valid entries in the PCM channel map */
    le32 nchannels;
    /* a PCM channel map */
    struct virtio_snd_pcm_chinfo channel_map[VIRTIO_SND_PCM_CH_MAX];
};

/* a response containing PCM channel map */
struct virtio_snd_pcm_chmap
{
    struct virtio_snd_rsp hdr;
    /* a channel map type (VIRTIO_SND_PCM_CHMAP_XXX) */
    u8 type;
    /* reserved, must be zero */
    u8 reserved[3];
    /* a channel map data */
    struct virtio_snd_pcm_chmap_data data;
};
```

#### Set Format

The driver MUST send the VIRTIO_SND_PCM_R_SET_FORMAT request containing selected
PCM stream parameters, the device answers with a generic response.

```
/* set a PCM substream format */
struct virtio_snd_pcm_set_format
{
    /* .request = VIRTIO_SND_PCM_R_SET_FORMAT */
    struct virtio_snd_pcm_hdr hdr;
    /* # of channels */
    le16 channels;
    /* a PCM sample format (VIRTIO_SND_PCM_FMT_XXX) */
    le16 format;
    /* a PCM frame rate (VIRTIO_SND_PCM_RATE_XXX) */
    le16 rate;
    u16 padding;
};
```

#### Prepare

The driver MUST send the VIRTIO_SND_PCM_R_PREPARE generic PCM request to prepare
a substream for running, the device answers with a generic response.

#### Start

The driver sends the VIRTIO_SND_PCM_R_START generic PCM request, the device
answers with a generic response.

In automatic mode:

- on success, the VIRTIO_SND_PCM_HW_S_RUNNING substream state bit MUST be set,
- the device MUST start to read/write PCM frames from/to shared DMA buffer.

#### Stop

The driver sends the VIRTIO_SND_PCM_R_STOP generic PCM request, the device answers
with a generic response.

In manual mode:

- the device MUST release all provided buffers by setting result length to zero
and notifying the driver.

In automatic mode:

- the VIRTIO_SND_PCM_HW_S_RUNNING substream state bit MUST be cleared,
- the device MUST stop to read/write PCM frames from/to shared DMA buffer.

#### Pause

The driver sends the VIRTIO_SND_PCM_R_PAUSE generic PCM request, the device
answers with a generic response.

In automatic mode:

- on success, the VIRTIO_SND_PCM_HW_S_PAUSED substream state bit MUST be set.

#### Unpause

The driver sends the VIRTIO_SND_PCM_R_UNPAUSE generic PCM request, the device
answers with a generic response.

In automatic mode:

- the VIRTIO_SND_PCM_HW_S_PAUSED substream state bit MUST be cleared.

#### Rewind/Forward

[Available only in manual mode]

The driver sends the VIRTIO_SND_PCM_R_REWIND or the VIRTIO_SND_PCM_R_FORWARD
request containing seek count, the device answers with a generic response.

```
/* seek (rewind/forward) a PCM substream read/write position */
struct virtio_snd_pcm_seek
{
    /* .request = VIRTIO_SND_PCM_R_REWIND / VIRTIO_SND_PCM_R_FORWARD */
    struct virtio_snd_pcm_hdr hdr;
    /* seek count: unsigned value in bytes */
    le32 count;
    u32 padding;
};
```

[-- Attachment #3: virtio_snd.h --]
[-- Type: text/x-chdr, Size: 20054 bytes --]

/*
 * Copyright (C) 2019  OpenSynergy GmbH
 *
 * This header is BSD licensed so anyone can use the definitions to
 * implement compatible drivers/servers.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of OpenSynergy GmbH nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE. */

#ifndef VIRTIO_SND_IF_H
#define VIRTIO_SND_IF_H

#include <linux/virtio_types.h>

/*******************************************************************************
 * COMMON DEFINITIONS
 */

/* a configuration space */
struct virtio_snd_config
{
    /* maximum # of available virtual queues */
    __virtio32 nqueues;
};

/* --- GENERIC ERROR CODES --- */
/* no errors */
#define VIRTIO_SND_E_SUCCESS            0
/* an undefined error */
#define VIRTIO_SND_E_GENERAL            1
/* not supported input parameter(s) */
#define VIRTIO_SND_E_NOTSUPPORTED       2
/* invalid input parameter(s) */
#define VIRTIO_SND_E_INVALID            3
/* I/O error */
#define VIRTIO_SND_E_IO                 4

/* a generic request header */
struct virtio_snd_req
{
    __virtio16 function;
    __virtio16 request;
};

/* a generic response header */
struct virtio_snd_rsp
{
    __virtio32 status; /* VIRTIO_SND_E_XXX */
};

/* supported function types */
#define VIRTIO_SND_FN_BASE              0
#define VIRTIO_SND_FN_PCM               1

/* supported descriptor types */
#define VIRTIO_SND_DESC_PCM             0
#define VIRTIO_SND_DESC_PCM_STREAM      1

/* a generic descriptor */
struct virtio_snd_generic_desc
{
    __u8 length;
    __u8 type;
    __u16 padding;
};

/*******************************************************************************
 * BASE FUNCTION DEFINITIONS
 */

/* --- BASE REQUEST TYPES --- */
#define VIRTIO_SND_BASE_R_GET_CFG       0
#define VIRTIO_SND_BASE_R_SUSPEND       1
#define VIRTIO_SND_BASE_R_RESUME        2

/* a maximum possible configuration data size (in bytes) */
#define VIRTIO_SND_BASE_CFG_MAX_SIZE    1024

/* a response containing device configuration */
struct virtio_snd_base_configuration
{
    struct virtio_snd_rsp hdr;
    /* size in bytes of configuration data */
    __virtio32 length;
    /* configuration data */
    __u8 data[VIRTIO_SND_BASE_CFG_MAX_SIZE];
};

/*******************************************************************************
 * PCM FUNCTION DEFINITIONS
 */

/* supported PCM stream types */
#define VIRTIO_SND_PCM_T_PLAYBACK       0
#define VIRTIO_SND_PCM_T_CAPTURE        1

/* supported PCM stream features */
#define VIRTIO_SND_PCM_FEAT_MANUAL_MODE 0
#define VIRTIO_SND_PCM_FEAT_AUTO_MODE   1
#define VIRTIO_SND_PCM_FEAT_UPDATE_FREQUENCY 2
#define VIRTIO_SND_PCM_FEAT_CHANNEL_MAP 3

#define VIRTIO_SND_PCM_FEATBIT(bit)     (1U << VIRTIO_SND_PCM_FEAT_ ## bit)

#define VIRTIO_SND_PCM_FEATBIT_MANUAL_MODE \
    VIRTIO_SND_PCM_FEATBIT(MANUAL_MODE)
#define VIRTIO_SND_PCM_FEATBIT_AUTO_MODE \
    VIRTIO_SND_PCM_FEATBIT(AUTO_MODE)
#define VIRTIO_SND_PCM_FEATBIT_UPDATE_FREQUENCY \
    VIRTIO_SND_PCM_FEATBIT(UPDATE_FREQUENCY)
#define VIRTIO_SND_PCM_FEATBIT_CHANNEL_MAP \
    VIRTIO_SND_PCM_FEATBIT(CHANNEL_MAP)

/* supported PCM sample formats */
#define VIRTIO_SND_PCM_FMT_MU_LAW       0
#define VIRTIO_SND_PCM_FMT_A_LAW        1
#define VIRTIO_SND_PCM_FMT_S8           2
#define VIRTIO_SND_PCM_FMT_U8           3
#define VIRTIO_SND_PCM_FMT_S16_LE       4
#define VIRTIO_SND_PCM_FMT_S16_BE       5
#define VIRTIO_SND_PCM_FMT_U16_LE       6
#define VIRTIO_SND_PCM_FMT_U16_BE       7
#define VIRTIO_SND_PCM_FMT_S24_LE       8
#define VIRTIO_SND_PCM_FMT_S24_BE       9
#define VIRTIO_SND_PCM_FMT_U24_LE       10
#define VIRTIO_SND_PCM_FMT_U24_BE       11
#define VIRTIO_SND_PCM_FMT_S32_LE       12
#define VIRTIO_SND_PCM_FMT_S32_BE       13
#define VIRTIO_SND_PCM_FMT_U32_LE       14
#define VIRTIO_SND_PCM_FMT_U32_BE       15
#define VIRTIO_SND_PCM_FMT_FLOAT_LE     16
#define VIRTIO_SND_PCM_FMT_FLOAT_BE     17
#define VIRTIO_SND_PCM_FMT_FLOAT64_LE   18
#define VIRTIO_SND_PCM_FMT_FLOAT64_BE   19
#define VIRTIO_SND_PCM_FMT_S20_LE       20
#define VIRTIO_SND_PCM_FMT_S20_BE       21
#define VIRTIO_SND_PCM_FMT_U20_LE       22
#define VIRTIO_SND_PCM_FMT_U20_BE       23
#define VIRTIO_SND_PCM_FMT_S24_3LE      24
#define VIRTIO_SND_PCM_FMT_S24_3BE      25
#define VIRTIO_SND_PCM_FMT_U24_3LE      26
#define VIRTIO_SND_PCM_FMT_U24_3BE      27
#define VIRTIO_SND_PCM_FMT_S20_3LE      28
#define VIRTIO_SND_PCM_FMT_S20_3BE      29
#define VIRTIO_SND_PCM_FMT_U20_3LE      30
#define VIRTIO_SND_PCM_FMT_U20_3BE      31
#define VIRTIO_SND_PCM_FMT_S18_3LE      32
#define VIRTIO_SND_PCM_FMT_U18_3LE      33
#define VIRTIO_SND_PCM_FMT_S18_3BE      34
#define VIRTIO_SND_PCM_FMT_U18_3BE      35

#define VIRTIO_SND_PCM_FMTBIT(bit)      (1ULL << VIRTIO_SND_PCM_FMT_ ## bit)

#define VIRTIO_SND_PCM_FMTBIT_MU_LAW    VIRTIO_SND_PCM_FMTBIT(MU_LAW)
#define VIRTIO_SND_PCM_FMTBIT_A_LAW     VIRTIO_SND_PCM_FMTBIT(A_LAW)
#define VIRTIO_SND_PCM_FMTBIT_S8        VIRTIO_SND_PCM_FMTBIT(S8)
#define VIRTIO_SND_PCM_FMTBIT_U8        VIRTIO_SND_PCM_FMTBIT(U8)
#define VIRTIO_SND_PCM_FMTBIT_S16_LE    VIRTIO_SND_PCM_FMTBIT(S16_LE)
#define VIRTIO_SND_PCM_FMTBIT_S16_BE    VIRTIO_SND_PCM_FMTBIT(S16_BE)
#define VIRTIO_SND_PCM_FMTBIT_U16_LE    VIRTIO_SND_PCM_FMTBIT(U16_LE)
#define VIRTIO_SND_PCM_FMTBIT_U16_BE    VIRTIO_SND_PCM_FMTBIT(U16_BE)
#define VIRTIO_SND_PCM_FMTBIT_S24_LE    VIRTIO_SND_PCM_FMTBIT(S24_LE)
#define VIRTIO_SND_PCM_FMTBIT_S24_BE    VIRTIO_SND_PCM_FMTBIT(S24_BE)
#define VIRTIO_SND_PCM_FMTBIT_U24_LE    VIRTIO_SND_PCM_FMTBIT(U24_LE)
#define VIRTIO_SND_PCM_FMTBIT_U24_BE    VIRTIO_SND_PCM_FMTBIT(U24_BE)
#define VIRTIO_SND_PCM_FMTBIT_S32_LE    VIRTIO_SND_PCM_FMTBIT(S32_LE)
#define VIRTIO_SND_PCM_FMTBIT_S32_BE    VIRTIO_SND_PCM_FMTBIT(S32_BE)
#define VIRTIO_SND_PCM_FMTBIT_U32_LE    VIRTIO_SND_PCM_FMTBIT(U32_LE)
#define VIRTIO_SND_PCM_FMTBIT_U32_BE    VIRTIO_SND_PCM_FMTBIT(U32_BE)
#define VIRTIO_SND_PCM_FMTBIT_FLOAT_LE  VIRTIO_SND_PCM_FMTBIT(FLOAT_LE)
#define VIRTIO_SND_PCM_FMTBIT_FLOAT_BE  VIRTIO_SND_PCM_FMTBIT(FLOAT_BE)
#define VIRTIO_SND_PCM_FMTBIT_FLOAT64_LE VIRTIO_SND_PCM_FMTBIT(FLOAT64_LE)
#define VIRTIO_SND_PCM_FMTBIT_FLOAT64_BE VIRTIO_SND_PCM_FMTBIT(FLOAT64_BE)
#define VIRTIO_SND_PCM_FMTBIT_S20_LE    VIRTIO_SND_PCM_FMTBIT(S20_LE)
#define VIRTIO_SND_PCM_FMTBIT_S20_BE    VIRTIO_SND_PCM_FMTBIT(S20_BE)
#define VIRTIO_SND_PCM_FMTBIT_U20_LE    VIRTIO_SND_PCM_FMTBIT(U20_LE)
#define VIRTIO_SND_PCM_FMTBIT_U20_BE    VIRTIO_SND_PCM_FMTBIT(U20_BE)
#define VIRTIO_SND_PCM_FMTBIT_S24_3LE   VIRTIO_SND_PCM_FMTBIT(S24_3LE)
#define VIRTIO_SND_PCM_FMTBIT_S24_3BE   VIRTIO_SND_PCM_FMTBIT(S24_3BE)
#define VIRTIO_SND_PCM_FMTBIT_U24_3LE   VIRTIO_SND_PCM_FMTBIT(U24_3LE)
#define VIRTIO_SND_PCM_FMTBIT_U24_3BE   VIRTIO_SND_PCM_FMTBIT(U24_3BE)
#define VIRTIO_SND_PCM_FMTBIT_S20_3LE   VIRTIO_SND_PCM_FMTBIT(S20_3LE)
#define VIRTIO_SND_PCM_FMTBIT_S20_3BE   VIRTIO_SND_PCM_FMTBIT(S20_3BE)
#define VIRTIO_SND_PCM_FMTBIT_U20_3LE   VIRTIO_SND_PCM_FMTBIT(U20_3LE)
#define VIRTIO_SND_PCM_FMTBIT_U20_3BE   VIRTIO_SND_PCM_FMTBIT(U20_3BE)
#define VIRTIO_SND_PCM_FMTBIT_S18_3LE   VIRTIO_SND_PCM_FMTBIT(S18_3LE)
#define VIRTIO_SND_PCM_FMTBIT_S18_3BE   VIRTIO_SND_PCM_FMTBIT(S18_3BE)
#define VIRTIO_SND_PCM_FMTBIT_U18_3LE   VIRTIO_SND_PCM_FMTBIT(U18_3LE)
#define VIRTIO_SND_PCM_FMTBIT_U18_3BE   VIRTIO_SND_PCM_FMTBIT(U18_3BE)

/* supported PCM frame rates */
#define VIRTIO_SND_PCM_RATE_5512        0
#define VIRTIO_SND_PCM_RATE_8000        1
#define VIRTIO_SND_PCM_RATE_11025       2
#define VIRTIO_SND_PCM_RATE_16000       3
#define VIRTIO_SND_PCM_RATE_22050       4
#define VIRTIO_SND_PCM_RATE_32000       5
#define VIRTIO_SND_PCM_RATE_44100       6
#define VIRTIO_SND_PCM_RATE_48000       7
#define VIRTIO_SND_PCM_RATE_64000       8
#define VIRTIO_SND_PCM_RATE_88200       9
#define VIRTIO_SND_PCM_RATE_96000       10
#define VIRTIO_SND_PCM_RATE_176400      11
#define VIRTIO_SND_PCM_RATE_192000      12

#define VIRTIO_SND_PCM_RATEBIT(bit)     (1U << VIRTIO_SND_PCM_RATE_ ## bit)

#define VIRTIO_SND_PCM_RATEBIT_5512     VIRTIO_SND_PCM_RATEBIT(5512)
#define VIRTIO_SND_PCM_RATEBIT_8000     VIRTIO_SND_PCM_RATEBIT(8000)
#define VIRTIO_SND_PCM_RATEBIT_11025    VIRTIO_SND_PCM_RATEBIT(11025)
#define VIRTIO_SND_PCM_RATEBIT_16000    VIRTIO_SND_PCM_RATEBIT(16000)
#define VIRTIO_SND_PCM_RATEBIT_22050    VIRTIO_SND_PCM_RATEBIT(22050)
#define VIRTIO_SND_PCM_RATEBIT_32000    VIRTIO_SND_PCM_RATEBIT(32000)
#define VIRTIO_SND_PCM_RATEBIT_44100    VIRTIO_SND_PCM_RATEBIT(44100)
#define VIRTIO_SND_PCM_RATEBIT_48000    VIRTIO_SND_PCM_RATEBIT(48000)
#define VIRTIO_SND_PCM_RATEBIT_64000    VIRTIO_SND_PCM_RATEBIT(64000)
#define VIRTIO_SND_PCM_RATEBIT_88200    VIRTIO_SND_PCM_RATEBIT(88200)
#define VIRTIO_SND_PCM_RATEBIT_96000    VIRTIO_SND_PCM_RATEBIT(96000)
#define VIRTIO_SND_PCM_RATEBIT_176400   VIRTIO_SND_PCM_RATEBIT(176400)
#define VIRTIO_SND_PCM_RATEBIT_192000   VIRTIO_SND_PCM_RATEBIT(192000)

/* a PCM channel map definitions */

/* All channels have fixed channel positions */
#define VIRTIO_SND_PCM_CHMAP_FIXED      0
/* All channels are swappable (e.g. {FL/FR/RL/RR} -> {RR/RL/FR/FL}) */
#define VIRTIO_SND_PCM_CHMAP_VARIABLE   1
/* Only pair-wise channels are swappable (e.g. {FL/FR/RL/RR} -> {RL/RR/FL/FR}) */
#define VIRTIO_SND_PCM_CHMAP_PAIRED     2

/* Standard channel position definition */
#define VIRTIO_SND_PCM_CH_NONE          0   /* undefined */
#define VIRTIO_SND_PCM_CH_NA            1   /* silent */
#define VIRTIO_SND_PCM_CH_MONO          2   /* mono stream */
#define VIRTIO_SND_PCM_CH_FL            3   /* front left */
#define VIRTIO_SND_PCM_CH_FR            4   /* front right */
#define VIRTIO_SND_PCM_CH_RL            5   /* rear left */
#define VIRTIO_SND_PCM_CH_RR            6   /* rear right */
#define VIRTIO_SND_PCM_CH_FC            7   /* front center */
#define VIRTIO_SND_PCM_CH_LFE           8   /* low frequency (LFE) */
#define VIRTIO_SND_PCM_CH_SL            9   /* side left */
#define VIRTIO_SND_PCM_CH_SR            10  /* side right */
#define VIRTIO_SND_PCM_CH_RC            11  /* rear center */
#define VIRTIO_SND_PCM_CH_FLC           12  /* front left center */
#define VIRTIO_SND_PCM_CH_FRC           13  /* front right center */
#define VIRTIO_SND_PCM_CH_RLC           14  /* rear left center */
#define VIRTIO_SND_PCM_CH_RRC           15  /* rear right center */
#define VIRTIO_SND_PCM_CH_FLW           16  /* front left wide */
#define VIRTIO_SND_PCM_CH_FRW           17  /* front right wide */
#define VIRTIO_SND_PCM_CH_FLH           18  /* front left high */
#define VIRTIO_SND_PCM_CH_FCH           19  /* front center high */
#define VIRTIO_SND_PCM_CH_FRH           20  /* front right high */
#define VIRTIO_SND_PCM_CH_TC            21  /* top center */
#define VIRTIO_SND_PCM_CH_TFL           22  /* top front left */
#define VIRTIO_SND_PCM_CH_TFR           23  /* top front right */
#define VIRTIO_SND_PCM_CH_TFC           24  /* top front center */
#define VIRTIO_SND_PCM_CH_TRL           25  /* top rear left */
#define VIRTIO_SND_PCM_CH_TRR           26  /* top rear right */
#define VIRTIO_SND_PCM_CH_TRC           27  /* top rear center */
#define VIRTIO_SND_PCM_CH_TFLC          28  /* top front left center */
#define VIRTIO_SND_PCM_CH_TFRC          29  /* top front right center */
#define VIRTIO_SND_PCM_CH_TSL           30  /* top side left */
#define VIRTIO_SND_PCM_CH_TSR           31  /* top side right */
#define VIRTIO_SND_PCM_CH_LLFE          32  /* left LFE */
#define VIRTIO_SND_PCM_CH_RLFE          33  /* right LFE */
#define VIRTIO_SND_PCM_CH_BC            34  /* bottom center */
#define VIRTIO_SND_PCM_CH_BLC           35  /* bottom left center */
#define VIRTIO_SND_PCM_CH_BRC           36  /* bottom right center */

/*
 * The channel is phase inverted (thus summing left and right channels would
 * result in almost silence).
 */
#define VIRTIO_SND_PCM_CH_F_PHASE_INVERSE 0x01

/* a PCM function descriptor */
struct virtio_snd_pcm_desc
{
    /* sizeof(struct virtio_snd_pcm_desc) */
    __u8 length;
    /* VIRTIO_SND_DESC_PCM */
    __u8 type;
    /* a PCM function ID (assigned by the device) */
    __u8 pcm_id;
    /* # of PCM stream descriptors in the configuration (one per supported PCM stream type) */
    __u8 nstreams;
};

/* a PCM stream descriptor */
struct virtio_snd_pcm_stream_desc
{
    /* sizeof(struct virtio_snd_pcm_stream_desc) */
    __u8 length;
    /* VIRTIO_SND_DESC_PCM_STREAM */
    __u8 type;
    /* a PCM stream type (VIRTIO_SND_PCM_T_XXX) */
    __u8 stream_type;
    /* # of substreams for the specified stream type */
    __u8 nsubstreams;
    /* minimum # of supported channels */
    __virtio16 channels_min;
    /* maximum # of supported channels */
    __virtio16 channels_max;
    /* supported sample formats (VIRTIO_SND_PCM_FMTBIT_XXX, can be ORed) */
    __virtio64 formats;
    /* supported frame rates (VIRTIO_SND_PCM_RATEBIT_XXX, can be ORed) */
    __virtio32 rates;
    /* supported PCM stream features (VIRTIO_SND_PCM_FEATBIT_XXX, can be ORed) */
    __virtio16 features;
    /* # of supported channel maps */
    __virtio16 nchmaps;
};

/* --- PCM HARDWARE STATE BITMAP --- */
#define VIRTIO_SND_PCM_HW_S_RUNNING     0x0001
#define VIRTIO_SND_PCM_HW_S_PAUSED      0x0002

struct virtio_snd_pcm_hw_regs
{
    /*
     *  Bits | Mnemonic  | Description
     * ------+-----------+------------------------------------------------------
     *     0 | RUNNING   | 0 = Substream is not running
     *       |           | 1 = Substream is running
     * ------+-----------+------------------------------------------------------
     *     1 | PAUSED    | 0 = Substream is not paused
     *       |           | 1 = Substream is paused
     * ------+-----------+------------------------------------------------------
     *  2:31 |           | Reserved, must be zero.
     */
    __virtio32 state;
    /* additional hardware latency: unsigned value in bytes */
    __virtio32 latency;
    /* current hardware position: unsigned value in bytes [0 .. dma_size - 1] */
    __virtio32 dma_position;
};

struct virtio_snd_pcm_sw_regs
{
    /* current DMA buffer size in bytes */
    __virtio32 dma_size;
};

/* a PCM substream shared memory structure */
struct virtio_snd_pcm_shmem
{
    /*
     * automatic mode hardware registers
     *   device: writable
     *   driver: read-only
     */
    struct virtio_snd_pcm_hw_regs hwrs;

    /*
     * automatic mode software registers
     *   device: read-only
     *   driver: writable
     */
    struct virtio_snd_pcm_sw_regs swrs;

    /*
     * followed by a variable sized DMA buffer
     *   in the playback mode:
     *     device: read-only
     *     driver: writable
     *   in the capture mode:
     *     device: writable
     *     driver: read-only
     */
};

/* --- PCM REQUEST TYPES --- */
#define VIRTIO_SND_PCM_R_GET_FEATURE    0
#define VIRTIO_SND_PCM_R_SET_FEATURE    1
#define VIRTIO_SND_PCM_R_SET_FORMAT     2
#define VIRTIO_SND_PCM_R_PREPARE        3
#define VIRTIO_SND_PCM_R_START          4
#define VIRTIO_SND_PCM_R_STOP           5
#define VIRTIO_SND_PCM_R_PAUSE          6
#define VIRTIO_SND_PCM_R_UNPAUSE        7
#define VIRTIO_SND_PCM_R_REWIND         8
#define VIRTIO_SND_PCM_R_FORWARD        9

/* --- PCM ERROR CODES --- */
#define VIRTIO_SND_PCM_E_NOT_READY      32

/* a PCM substream request header */
struct virtio_snd_pcm_hdr
{
    /* VIRTIO_SND_FN_PCM */
    __virtio16 function;
    /* a PCM request type (VIRTIO_SND_PCM_R_XXX) */
    __virtio16 request;
    /* a PCM identifier (assigned in configuration) */
    __u8 pcm_id;
    /* a PCM stream type (VIRTIO_SND_PCM_T_XXX) */
    __u8 stream_type;
    /* a PCM substream identifier [0 .. virtio_snd_pcm_stream_desc::nsubstreams - 1] */
    __u8 substream_id;
    __u8 padding;
};

/* get/set a PCM substream feature */
struct virtio_snd_pcm_feature
{
    /* VIRTIO_SND_FN_PCM */
    __virtio16 function;
    /* VIRTIO_SND_PCM_R_GET_FEATURE / VIRTIO_SND_PCM_R_SET_FEATURE */
    __virtio16 request;
    /* a PCM identifier (assigned in configuration) */
    __u8 pcm_id;
    /* a PCM stream type (VIRTIO_SND_PCM_T_XXX) */
    __u8 stream_type;
    /* a PCM substream identifier [0 .. virtio_snd_pcm_stream_desc::nsubstreams - 1] */
    __u8 substream_id;
    /* a selected PCM substream feature (VIRTIO_SND_PCM_FEAT_XXX) */
    __u8 feature;
    /* a feature-specific optional request data */
    union
    {
        /* VIRTIO_SND_PCM_FEAT_UPDATE_FREQUENCY [SET-only] */
        struct
        {
            /* an approximate update frequency in microseconds */
            __virtio32 microseconds;
            /* an approximate update frequency in bytes */
            __virtio32 bytes;
        } update_frequency;
        /*
         * VIRTIO_SND_PCM_FEAT_MANUAL_MODE [SET-only]
         *   .data = a virtual queue index
         * VIRTIO_SND_PCM_FEAT_AUTO_MODE [SET-only]
         *   .data = a pseudophysical start address of the virtio_snd_pcm_shmem structure
         * VIRTIO_SND_PCM_FEAT_CHANNEL_MAP [GET/SET]
         *   GET:
         *     .data = a channel map index [0 .. virtio_snd_pcm_stream_desc::nchmaps - 1]
         *   SET:
         *     .data = a pseudophysical start address of the virtio_snd_pcm_chmap_data structure
         */
        __virtio64 data;
    };
};

#define VIRTIO_SND_PCM_CH_MAX           256

/* a PCM channel information */
struct virtio_snd_pcm_chinfo
{
    /* a PCM channel position (VIRTIO_SND_PCM_CH_XXX) */
    __u8 position;
    /* a PCM channel flags (VIRTIO_SND_PCM_CH_F_XXX, can be ORed) */
    __u8 flags;
};

/* a PCM channel map data */
struct virtio_snd_pcm_chmap_data
{
    /* # of valid entries in the PCM channel map */
    __virtio32 nchannels;
    /* a PCM channel map */
    struct virtio_snd_pcm_chinfo channel_map[VIRTIO_SND_PCM_CH_MAX];
};

/* a response containing PCM channel map */
struct virtio_snd_pcm_chmap
{
    struct virtio_snd_rsp hdr;
    /* a channel map type (VIRTIO_SND_PCM_CHMAP_XXX) */
    __u8 type;
    /* reserved, must be zero */
    __u8 reserved[3];
    /* a channel map data */
    struct virtio_snd_pcm_chmap_data data;
};

/* set a PCM substream format */
struct virtio_snd_pcm_set_format
{
    /* .request = VIRTIO_SND_PCM_R_SET_FORMAT */
    struct virtio_snd_pcm_hdr hdr;
    /* # of channels */
    __virtio16 channels;
    /* a PCM sample format (VIRTIO_SND_PCM_FMT_XXX) */
    __virtio16 format;
    /* a PCM frame rate (VIRTIO_SND_PCM_RATE_XXX) */
    __virtio16 rate;
    __u16 padding;
};

/* seek (rewind/forward) a PCM substream read/write position */
struct virtio_snd_pcm_seek
{
    /* .request = VIRTIO_SND_PCM_R_REWIND / VIRTIO_SND_PCM_R_FORWARD */
    struct virtio_snd_pcm_hdr hdr;
    /* seek count: unsigned value in bytes */
    __virtio32 count;
    __u32 padding;
};

#endif /* VIRTIO_SND_IF_H */


[-- Attachment #4: Type: text/plain, Size: 208 bytes --]


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-09 12:27                 ` Gerd Hoffmann
  2019-05-10  9:45                   ` Mikhail Golubev
@ 2019-05-10 10:34                   ` Stefan Hajnoczi
  1 sibling, 0 replies; 29+ messages in thread
From: Stefan Hajnoczi @ 2019-05-10 10:34 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Marco Martinelli - 13Byte srl, virtio-dev,
	Kővágó Zoltán

[-- Attachment #1: Type: text/plain, Size: 1387 bytes --]

On Thu, May 09, 2019 at 02:27:10PM +0200, Gerd Hoffmann wrote:
> > For the sake of the specification I think we need to focus on is how to
> > transport these streams and how to share a configuration for each one.
> 
> I think we need at least three virt queues.  One control queue for
> commands (query capabilities, set configuration, start/stop streams,
> volume control, ...).  One queue for input streams.  One queue for
> output streams.
> 
> If we want allow for multiple inputs/outputs we have basically two
> options: (a) one queue per stream, or (b) use a small header for each
> data packet, telling what stream it belongs to.
> 
> Maybe a small header is a good idea anyway, for timestamps.

I agree with the 3 virtqueue layout.

Multiplexing streams over a single input/output virtqueue pair has pros
and cons.  Overall I think it's a good fit though:
+ Number of streams can change at runtime (virtqueues are static!)
+ Easy to handle multiple inputs/outputs
+ Ability to synchronize streams, including transferring buffers for
  multiple streams in a single message with a single timestamp
- Virtqueue must be sized to handle maximum simultaneous streams without
  running out of descriptors
- Extra latency (jitter) and locking requirements due to sharing
  virtqueues between streams even if they are processed on different
  vCPUs

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-10  9:45                   ` Mikhail Golubev
@ 2019-05-10 12:16                     ` Gerd Hoffmann
  2019-05-10 14:15                       ` Anton Yakovlev
  0 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2019-05-10 12:16 UTC (permalink / raw)
  To: Mikhail Golubev
  Cc: Marco Martinelli - 13Byte srl, virtio-dev, Stefan Hajnoczi,
	Kővágó Zoltán

On Fri, May 10, 2019 at 11:45:24AM +0200, Mikhail Golubev wrote:
> Hi all!
> 
> Sorry for breaking in the middle of the virtio audio driver and device
> development discussion. But we are developing a virtio sound card prototype for
> a while and we would like to share our specification draft and public header
> file (attaching 'virtio_snd.h' and 'virtio-snd-spec-draft.md'). The PoC for
> proposed approach was tested with virtio audio driver in Linux and in Windows 10
> as well.
> 
> It would be really great if we can collaborate on this topic. I would be happy
> to answer any questions.

Wow.  That looks pretty complete already ...

> Configuration space provides a maximum amount of available virtual queues. The
> nqueues value MUST be at least one.
> 
> ```
> struct virtio_snd_config
> {
>     le32 nqueues;
> };
> ```

Including or excluding the control queue?

> Each request begins with a 2-byte field that identifies a recipient function
> followed by a 2-byte field that identifies a function-specific request type.
> 
> Each response begins with a 4-byte field that contains a status code. The values
> 0-31 are reserved for common status codes, a function can define function-specific
> status codes starting from 32.

I'd suggest to use a common scheme with a single le32 field for both
requests and responses.

#define VIRTIO_SND_BASE_OFFSET 0x10000
#define VIRTIO_SND_PCM_OFFSET  0x20000

enum virtio_sound_request {
	VIRTIO_SND_BASE_REQ1 = VIRTIO_SND_BASE_OFFSET,
        VIRTIO_SND_BASE_REQ2,
	[ ... ]
	VIRTIO_SND_PCM_REQ1 = VIRTIO_SND_PCM_OFFSET,
	VIRTIO_SND_PCM_REQ2,
	[ ... ]
};

enum virtio_sound_response {
	VIRTIO_SND_E_SUCCESS,

	VIRTIO_SND_E_GENERAL = VIRTIO_SND_BASE_OFFSET,
	VIRTIO_SND_E_NOTSUPPORTED,
	[ ... ]
	VIRTIO_SND_PCM_E_NOT_READY = VIRTIO_SND_PCM_OFFSET,
	[ ... ]
};

> struct virtio_snd_req
> {
	enum virtio_sound_request;

> struct virtio_snd_rsp
> {
	enum virtio_sound_response;

(maybe just drop the single-element structs and use the enums directly).

> ### Device Configuration
> 
> The device reports its configuration using descriptors. A descriptor is a data
> structure with a defined format. Each descriptor begins with a byte-wide field
> that contains the total number of bytes in the descriptor followed by a byte-wide
> field that identifies the descriptor type.
> 
> ```
> struct virtio_snd_generic_desc
> {
>     u8 length;
>     u8 type;
>     u16 padding;

I'd make length and type u16 and drop the padding.

> With the exception of the base function, all implemented functions MUST define
> its own descriptor(s) format (either presented in this specification or
> vendor-specific) and MUST includes these in configuration only if a particular
> function (or part of its functionality) is enabled in the device.

I don't think it is a good idea to allow vendor-specific descriptors
here.  It should all be in the virtio spec.  We might want reserve a
sub-range of "type" for experimental/development purposes though.

> ### Function Operation
> 
> #### Get Device Configuration
> 
> The driver sends the VIRTIO_SND_BASE_R_GET_CFG generic request, the device
> answers with a response containing device configuration.

Which is a list of descriptors I assume?

> #### Suspend
> 
> The driver sends the VIRTIO_SND_BASE_R_SUSPEND generic request, the device
> answers with a generic response. For each initialized function, the device SHOULD
> be able to preserve its runtime state and MUST put it into function-specific
> suspended state.
> 
> #### Resume
> 
> The driver sends the VIRTIO_SND_BASE_R_RESUME generic request, the device
> answers with a generic response. For each initialized function, the device SHOULD
> be able to restore its runtime state and MUST put it into function-specific
> non-suspended state.

Why these two are needed?

Also restoring state as optional device feature doesn't look useful to
me.

> - *Manual mode*: the driver assigns a dedicated virtual queue for a PCM substream
> and use it to transmit data buffers to the device. The device writes/reads PCM
> frames only upon receiving a buffer from the driver.

That is how I expect a virtio-audio device work.

> - *Automatic mode*: the driver allocates and shares with the device a pseudophysically
> continuous memory area containing runtime control registers and data buffer itself.

What is "pseudophysically continuous memory"?
Why do you think this is needed?

> Regardless of the mode of operation, the device MAY require to specify an
> approximate data buffer update frequency. In such case, the driver MUST specify
> an approximate update frequency (expressed in both microseconds and bytes units)
> before starting a PCM substream.

Why both microseconds and bytes?  Isn't that redundant?

> /* a PCM function descriptor */
> struct virtio_snd_pcm_desc
> {
>     /* sizeof(struct virtio_snd_pcm_desc) */
>     u8 length;
>     /* VIRTIO_SND_DESC_PCM */
>     u8 type;
>     /* a PCM function ID (assigned by the device) */
>     u8 pcm_id;
>     /* # of PCM stream descriptors in the configuration (one per supported PCM stream type) */
>     u8 nstreams;
> };

> /* supported PCM sample formats */
> #define VIRTIO_SND_PCM_FMT_MU_LAW       0
> #define VIRTIO_SND_PCM_FMT_A_LAW        1
> #define VIRTIO_SND_PCM_FMT_S8           2
> #define VIRTIO_SND_PCM_FMT_U8           3
> #define VIRTIO_SND_PCM_FMT_S16_LE       4
> #define VIRTIO_SND_PCM_FMT_S16_BE       5
> #define VIRTIO_SND_PCM_FMT_U16_LE       6
> #define VIRTIO_SND_PCM_FMT_U16_BE       7
> #define VIRTIO_SND_PCM_FMT_S24_LE       8
> #define VIRTIO_SND_PCM_FMT_S24_BE       9
> #define VIRTIO_SND_PCM_FMT_U24_LE       10
> #define VIRTIO_SND_PCM_FMT_U24_BE       11
> #define VIRTIO_SND_PCM_FMT_S32_LE       12
> #define VIRTIO_SND_PCM_FMT_S32_BE       13
> #define VIRTIO_SND_PCM_FMT_U32_LE       14
> #define VIRTIO_SND_PCM_FMT_U32_BE       15
> #define VIRTIO_SND_PCM_FMT_FLOAT_LE     16
> #define VIRTIO_SND_PCM_FMT_FLOAT_BE     17
> #define VIRTIO_SND_PCM_FMT_FLOAT64_LE   18
> #define VIRTIO_SND_PCM_FMT_FLOAT64_BE   19
> #define VIRTIO_SND_PCM_FMT_S20_LE       20
> #define VIRTIO_SND_PCM_FMT_S20_BE       21
> #define VIRTIO_SND_PCM_FMT_U20_LE       22
> #define VIRTIO_SND_PCM_FMT_U20_BE       23
> #define VIRTIO_SND_PCM_FMT_S24_3LE      24
> #define VIRTIO_SND_PCM_FMT_S24_3BE      25
> #define VIRTIO_SND_PCM_FMT_U24_3LE      26
> #define VIRTIO_SND_PCM_FMT_U24_3BE      27
> #define VIRTIO_SND_PCM_FMT_S20_3LE      28
> #define VIRTIO_SND_PCM_FMT_S20_3BE      29
> #define VIRTIO_SND_PCM_FMT_U20_3LE      30
> #define VIRTIO_SND_PCM_FMT_U20_3BE      31
> #define VIRTIO_SND_PCM_FMT_S18_3LE      32
> #define VIRTIO_SND_PCM_FMT_U18_3LE      33
> #define VIRTIO_SND_PCM_FMT_S18_3BE      34
> #define VIRTIO_SND_PCM_FMT_U18_3BE      35

That looks a bit over-engineered to me.

First, virtio uses little endian.  How about dropping all bigendian
formats?

Are 8-bit formats are still used in practice?

What are VIRTIO_SND_PCM_FMT_{S,U}20_LE ?

What are VIRTIO_SND_PCM_FMT_*_3BE ?

Which of these formats are actually implemented in your prototype?

> /* supported PCM frame rates */
> #define VIRTIO_SND_PCM_RATE_5512        0
> #define VIRTIO_SND_PCM_RATE_8000        1
> #define VIRTIO_SND_PCM_RATE_11025       2
> #define VIRTIO_SND_PCM_RATE_16000       3
> #define VIRTIO_SND_PCM_RATE_22050       4
> #define VIRTIO_SND_PCM_RATE_32000       5
> #define VIRTIO_SND_PCM_RATE_44100       6
> #define VIRTIO_SND_PCM_RATE_48000       7
> #define VIRTIO_SND_PCM_RATE_64000       8
> #define VIRTIO_SND_PCM_RATE_88200       9
> #define VIRTIO_SND_PCM_RATE_96000       10
> #define VIRTIO_SND_PCM_RATE_176400      11
> #define VIRTIO_SND_PCM_RATE_192000      12

Same question: Do we actually need all those?  My impression is that
these days 48000 is pretty much standard.  96000 + 192000 for higher
quality.  44100 sometimes still because it happens to be the CD sample
rate.  Maybe 32000/16000/8000 for low bandwidth codecs.

But 5512, 11025 & friends?

> The driver gets the VIRTIO_SND_PCM_FEAT_CHANNEL_MAP feature value in order to obtain
> a channel map with specified index, the device answers with the virtio_snd_pcm_chmap
> PCM response.
> 
> If channel map type allows to swap channels, the driver can set the VIRTIO_SND_PCM_FEAT_CHANNEL_MAP
> feature value specifying selected channel map data as a request argument. The
> device answers with a generic response.
> 
> ```
> /* a PCM channel map definitions */
> 
> /* All channels have fixed channel positions */
> #define VIRTIO_SND_PCM_CHMAP_FIXED      0
> /* All channels are swappable (e.g. {FL/FR/RL/RR} -> {RR/RL/FR/FL}) */
> #define VIRTIO_SND_PCM_CHMAP_VARIABLE   1
> /* Only pair-wise channels are swappable (e.g. {FL/FR/RL/RR} -> {RL/RR/FL/FR}) */
> #define VIRTIO_SND_PCM_CHMAP_PAIRED     2

What this is good for?  How would a driver ask the device to actually
swap the channels?  And isn't it easier to have the device provide a
complete list of possible channel maps and let the driver simply pick
one?

> /* Standard channel position definition */
> #define VIRTIO_SND_PCM_CH_NONE          0   /* undefined */
> #define VIRTIO_SND_PCM_CH_NA            1   /* silent */
> #define VIRTIO_SND_PCM_CH_MONO          2   /* mono stream */
> #define VIRTIO_SND_PCM_CH_FL            3   /* front left */
> #define VIRTIO_SND_PCM_CH_FR            4   /* front right */
> #define VIRTIO_SND_PCM_CH_RL            5   /* rear left */
> #define VIRTIO_SND_PCM_CH_RR            6   /* rear right */
> #define VIRTIO_SND_PCM_CH_FC            7   /* front center */
> #define VIRTIO_SND_PCM_CH_LFE           8   /* low frequency (LFE) */
> #define VIRTIO_SND_PCM_CH_SL            9   /* side left */
> #define VIRTIO_SND_PCM_CH_SR            10  /* side right */
> #define VIRTIO_SND_PCM_CH_RC            11  /* rear center */
> #define VIRTIO_SND_PCM_CH_FLC           12  /* front left center */
> #define VIRTIO_SND_PCM_CH_FRC           13  /* front right center */
> #define VIRTIO_SND_PCM_CH_RLC           14  /* rear left center */
> #define VIRTIO_SND_PCM_CH_RRC           15  /* rear right center */
> #define VIRTIO_SND_PCM_CH_FLW           16  /* front left wide */
> #define VIRTIO_SND_PCM_CH_FRW           17  /* front right wide */
> #define VIRTIO_SND_PCM_CH_FLH           18  /* front left high */
> #define VIRTIO_SND_PCM_CH_FCH           19  /* front center high */
> #define VIRTIO_SND_PCM_CH_FRH           20  /* front right high */
> #define VIRTIO_SND_PCM_CH_TC            21  /* top center */
> #define VIRTIO_SND_PCM_CH_TFL           22  /* top front left */
> #define VIRTIO_SND_PCM_CH_TFR           23  /* top front right */
> #define VIRTIO_SND_PCM_CH_TFC           24  /* top front center */
> #define VIRTIO_SND_PCM_CH_TRL           25  /* top rear left */
> #define VIRTIO_SND_PCM_CH_TRR           26  /* top rear right */
> #define VIRTIO_SND_PCM_CH_TRC           27  /* top rear center */
> #define VIRTIO_SND_PCM_CH_TFLC          28  /* top front left center */
> #define VIRTIO_SND_PCM_CH_TFRC          29  /* top front right center */
> #define VIRTIO_SND_PCM_CH_TSL           30  /* top side left */
> #define VIRTIO_SND_PCM_CH_TSR           31  /* top side right */
> #define VIRTIO_SND_PCM_CH_LLFE          32  /* left LFE */
> #define VIRTIO_SND_PCM_CH_RLFE          33  /* right LFE */
> #define VIRTIO_SND_PCM_CH_BC            34  /* bottom center */
> #define VIRTIO_SND_PCM_CH_BLC           35  /* bottom left center */
> #define VIRTIO_SND_PCM_CH_BRC           36  /* bottom right center */

Wow.  What is the use case for all those channels?  cinema sound?

> #### Prepare
> 
> The driver MUST send the VIRTIO_SND_PCM_R_PREPARE generic PCM request to prepare
> a substream for running, the device answers with a generic response.
> 
> #### Start
> 
> The driver sends the VIRTIO_SND_PCM_R_START generic PCM request, the device
> answers with a generic response.

So I guess the way to start a stream is (a) prepare, (b) queue some
buffers, (c) start.  Correct?

cheers,
  Gerd


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-10 12:16                     ` Gerd Hoffmann
@ 2019-05-10 14:15                       ` Anton Yakovlev
  2019-05-10 15:48                         ` Stefan Hajnoczi
  2019-05-13  9:32                         ` Gerd Hoffmann
  0 siblings, 2 replies; 29+ messages in thread
From: Anton Yakovlev @ 2019-05-10 14:15 UTC (permalink / raw)
  To: Gerd Hoffmann, Mikhail Golubev
  Cc: Marco Martinelli - 13Byte srl, virtio-dev, Stefan Hajnoczi,
	Kővágó Zoltán

Hi Gerd! My name is Anton and I'm the original author of this draft. Thanks for comments!

>> Configuration space provides a maximum amount of available virtual queues. The
>> nqueues value MUST be at least one.
>>
>> ```
>> struct virtio_snd_config
>> {
>>     le32 nqueues;
>> };
>> ```

> Including or excluding the control queue?

Including the control queue.


>> Each request begins with a 2-byte field that identifies a recipient function
>> followed by a 2-byte field that identifies a function-specific request type.
>>
>> Each response begins with a 4-byte field that contains a status code. The values
>> 0-31 are reserved for common status codes, a function can define function-specific
>> status codes starting from 32.

> I'd suggest to use a common scheme with a single le32 field for both
> requests and responses.
> ...
> (maybe just drop the single-element structs and use the enums directly).

IMO, both options are quite fine. We decided to choose separate namespaces because it's more flexible approach.


>> ### Device Configuration
>> ...
>> struct virtio_snd_generic_desc
>> {
>>     u8 length;
>>     u8 type;
>>     u16 padding;
>
> I'd make length and type u16 and drop the padding.

Well, it's a possible option. We just didn't want to waste additional space here.


>> With the exception of the base function, all implemented functions MUST define
>> its own descriptor(s) format (either presented in this specification or
>> vendor-specific) and MUST includes these in configuration only if a particular
>> function (or part of its functionality) is enabled in the device.
>
> I don't think it is a good idea to allow vendor-specific descriptors
> here.  It should all be in the virtio spec.  We might want reserve a
> sub-range of "type" for experimental/development purposes though.

Yeah, an ability to define some experimental extensions was one of the targets here (like adding sound controls, non-PCM streams, MIDI and so on). Also, this spec targeted the widest possible range of cases. Like, some hardware has very tricky features which can not be (or just has no point to be) defined in common specification. One example is to allow switching between speaker and bluetooth output. Ususally you don't need it, but if you want to provide such feature to the guest, it's better to implement this as a custom extension.



>> ### Function Operation
>>
>> #### Get Device Configuration
>>
>> The driver sends the VIRTIO_SND_BASE_R_GET_CFG generic request, the device
>> answers with a response containing device configuration.
>
> Which is a list of descriptors I assume?

You are right.


>> #### Suspend
>>
>> ...
>>
>> #### Resume
>>
>> ...
>>
>
> Why these two are needed?

I would say, that some virtualization platforms either do not notify your backend about guest suspend/resume or it's very tricky to distinguish such conditions from other shutdown/initialization types. According to my practice, it's always better to notify device side in explicit way, because the driver always know what is going now.

> Also restoring state as optional device feature doesn't look useful to
> me.

Well, restoring active playback or capturing is not impossible thing at all. From other side, maybe some device implementors might not want/need such functionality. So I'm not sure, what is better here.


>> - *Manual mode*: the driver assigns a dedicated virtual queue for a PCM substream
>> and use it to transmit data buffers to the device. The device writes/reads PCM
>> frames only upon receiving a buffer from the driver.
>
> That is how I expect a virtio-audio device work.

Yeah, I understand. But it's the very beginning of the road (see below).


>> - *Automatic mode*: the driver allocates and shares with the device a pseudophysically
>> continuous memory area containing runtime control registers and data buffer itself.
>
> What is "pseudophysically continuous memory"?

This memory is physically continuous from the driver's point of view.

> Why do you think this is needed?

When you implement an audio device, you usually start with what we call "manual mode". It works, but only for simple use cases. There're two major challenges here.

1) An application can use audio device in many different ways. It may fill the entire buffer with frames and let it draining. It may provides data in form of relatively big chunks. But usually you will face with so called "low latency" applications. These try to reduce result latency by providing small chunks of data. In extreme cases, the driver may receive requests containing only 5-10 frames. It means an amount of both system calls and requests to the device will grow. At some point this rate may become quite noticable. But things may become even worse, if an application activates both streams (playback and capture) at the same time. For example, voice chat applications (trying to reduce latency as much as possible) may hang you VM because of huge amount of small requests on both PCM streams. Thus, no requests/traps/hypercalls to the device while a stream is running - no problems here.

2) Everybody wants to reduce a latency as much as possible. One of the most logical way is to allow to mmap data buffer into the user space memory. (Actually, in some cases you even have no choice here, like in case of the WaveRT interface in Windows.) But memory mapped buffer means, that you either have a very little or have not at all an idea what is going on with buffer content. Even if you have information about when and where an application writes to or reads from the buffer (ALSA enforces an application to maintain its appl_ptr value), you will have a lot of headache with tracking the rewind/forward cases. I can't say for everyone, but our experiments with using "manual mode" here all failed. From other side, the isochronous nature of PCM stream and the nature of sound card itself suggest you right solution. You don't need to care about what and how an application does with a buffer. Since it's expected from the device to read/write data with constant rate. Thus, you can do the same in your virtual audio device. And it works like a charm!

We wanted to be ready for every possible use case, that's why we combined solutions for described issues into what we call "automatic mode". The funniest thing is, according to our tests, in automatic mode you can have stable and clean playback/capturing even under the very high CPU pressure.


>> Regardless of the mode of operation, the device MAY require to specify an
>> approximate data buffer update frequency. In such case, the driver MUST specify
>> an approximate update frequency (expressed in both microseconds and bytes units)
>> before starting a PCM substream.
>
> Why both microseconds and bytes?  Isn't that redundant?

Just to be sure that both ends have exactly the same ideas.


> /* a PCM function descriptor */
> struct virtio_snd_pcm_desc
> {
>     /* sizeof(struct virtio_snd_pcm_desc) */
>     u8 length;
>     /* VIRTIO_SND_DESC_PCM */
>     u8 type;
>     /* a PCM function ID (assigned by the device) */
>     u8 pcm_id;
>     /* # of PCM stream descriptors in the configuration (one per supported PCM stream type) */
>     u8 nstreams;
> };

> /* supported PCM sample formats */
> ...
>
> That looks a bit over-engineered to me.
>
> First, virtio uses little endian.  How about dropping all bigendian
> formats?
>
> Are 8-bit formats are still used in practice?

Actually, yeah. I saw quite recent chipsets with the U8 format support. Anyway, is it a big issue? It costs zero to support additional formats, so why not?


> What are VIRTIO_SND_PCM_FMT_{S,U}20_LE ?
>
> What are VIRTIO_SND_PCM_FMT_*_3BE ?
>
> Which of these formats are actually implemented in your prototype?

Some format's physical width is not multiple of 8. Such samples are kept in "a storage" which width is multiple of 8 (like 20-bit samples are kept either in 24-bit or in 32-bit storage).

Both Linux (ALSA) and Windows (WaveXXX interfaces) just expect from you to report support of these formats. You don't need to do anything special in order to implemented them. So, yes, we can support them in the prototype.


>> /* supported PCM frame rates */
>> ...
>
> Same question: Do we actually need all those?  My impression is that
> these days 48000 is pretty much standard.  96000 + 192000 for higher
> quality.  44100 sometimes still because it happens to be the CD sample
> rate.  Maybe 32000/16000/8000 for low bandwidth codecs.
>
> But 5512, 11025 & friends?

Same answer: why not? :)


>> /* a PCM channel map definitions */
>>
>> /* All channels have fixed channel positions */
>> #define VIRTIO_SND_PCM_CHMAP_FIXED      0
>> /* All channels are swappable (e.g. {FL/FR/RL/RR} -> {RR/RL/FR/FL}) */
>> #define VIRTIO_SND_PCM_CHMAP_VARIABLE   1
>> /* Only pair-wise channels are swappable (e.g. {FL/FR/RL/RR} -> {RL/RR/FL/FR}) */
>> #define VIRTIO_SND_PCM_CHMAP_PAIRED     2
>
> What this is good for?  How would a driver ask the device to actually
> swap the channels?  And isn't it easier to have the device provide a
> complete list of possible channel maps and let the driver simply pick
> one?

Basically, we were inspired how ALSA handles these and reused the same approach here. How: a hardware can have internal router/mixer to allow flexible configuration, there's nothing special. About how to provide a list of channel maps - it's a matter of responsibilities. I would like to stick to hardware-like approach, when hardware just reports minimum amount of capabilities, and it's up to the driver what to do with it.


>> /* Standard channel position definition */
>> ...
>
> Wow.  What is the use case for all those channels?  cinema sound?

Virtual cinema sound!


>> #### Prepare
>> ...
>> #### Start
>> ...
>
> So I guess the way to start a stream is (a) prepare, (b) queue some
> buffers, (c) start.  Correct?

Yeap!



cheers,
  Gerd


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org

--
Anton Yakovlev
Senior Software Engineer

OpenSynergy GmbH
Rotherstr. 20, 10245 Berlin

www.opensynergy.com

Please mind our privacy notice<https://www.opensynergy.com/datenschutzerklaerung/privacy-notice-for-business-partners-pursuant-to-article-13-of-the-general-data-protection-regulation-gdpr/> pursuant to Art. 13 GDPR. // Unsere Hinweise zum Datenschutz gem. Art. 13 DSGVO finden Sie hier.<https://www.opensynergy.com/de/datenschutzerklaerung/datenschutzhinweise-fuer-geschaeftspartner-gem-art-13-dsgvo/>
COQOS Hypervisor certified by TÜV SÜD
                [COQOS Hypervisor certified by TÜV SÜD]

---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-10 14:15                       ` Anton Yakovlev
@ 2019-05-10 15:48                         ` Stefan Hajnoczi
  2019-05-10 17:13                           ` Anton Yakovlev
  2019-05-13  9:32                         ` Gerd Hoffmann
  1 sibling, 1 reply; 29+ messages in thread
From: Stefan Hajnoczi @ 2019-05-10 15:48 UTC (permalink / raw)
  To: Anton Yakovlev
  Cc: Gerd Hoffmann, Mikhail Golubev, Marco Martinelli - 13Byte srl,
	virtio-dev, Kővágó Zoltán

[-- Attachment #1: Type: text/plain, Size: 4621 bytes --]

On Fri, May 10, 2019 at 02:15:00PM +0000, Anton Yakovlev wrote:
> > Why do you think this is needed?
> 
> When you implement an audio device, you usually start with what we call "manual mode". It works, but only for simple use cases. There're two major challenges here.
> 
> 1) An application can use audio device in many different ways. It may fill the entire buffer with frames and let it draining. It may provides data in form of relatively big chunks. But usually you will face with so called "low latency" applications. These try to reduce result latency by providing small chunks of data. In extreme cases, the driver may receive requests containing only 5-10 frames. It means an amount of both system calls and requests to the device will grow. At some point this rate may become quite noticable. But things may become even worse, if an application activates both streams (playback and capture) at the same time. For example, voice chat applications (trying to reduce latency as much as possible) may hang you VM because of huge amount of small requests on both PCM streams. Thus, no requests/traps/hypercalls to the device while a stream is running - no problems here.
> 
> 2) Everybody wants to reduce a latency as much as possible. One of the most logical way is to allow to mmap data buffer into the user space memory. (Actually, in some cases you even have no choice here, like in case of the WaveRT interface in Windows.) But memory mapped buffer means, that you either have a very little or have not at all an idea what is going on with buffer content. Even if you have information about when and where an application writes to or reads from the buffer (ALSA enforces an application to maintain its appl_ptr value), you will have a lot of headache with tracking the rewind/forward cases. I can't say for everyone, but our experiments with using "manual mode" here all failed. From other side, the isochronous nature of PCM stream and the nature of sound card itself suggest you right solution. You don't need to care about what and how an application does with a buffer. Since it's expected from the device to read/write data with constant rate. Thus, you can do the same in your virtual audio device. And it works like a charm!
> 
> We wanted to be ready for every possible use case, that's why we combined solutions for described issues into what we call "automatic mode". The funniest thing is, according to our tests, in automatic mode you can have stable and clean playback/capturing even under the very high CPU pressure.

Thanks for contributing your virtio-snd spec to the discussion!

Shared memory isn't a native concept to VIRTIO.  The device and the
driver don't assume shared memory access in the general case (i.e.
virtqueue buffers could even be copied and virtio-blk, virtio-net, etc
would still work!).

There is currently a spec extension on the mailing list to add Shared
Memory Resources to VIRTIO and new device types will use it.  However, I
don't think this is necessary for this use case.

Two techniques can be used to minimize virtqueue notifications:

1. Polling has become a commonly used technique over the last several
   years.  Both the driver and the device may disable notifications and
   simply peek at the ring indices to detect new buffers from the other
   side.

2. For synchronization and to reduce notifications the device could
   support bundling playback and capture into a single buffer so that
   only 1 virtqueue is used:

   /* A packet of PCM data associated with a stream */
   struct virtio_audio_pcm_data {
       unsigned stream_id;
       uint8_t data[num_frames * num_channels * bytes_per_sample];
   };

   /* An exchange of playback and capture PCM data */
   struct virtio_audio_pcm {
       /* Write (Driver -> Device) */
       /* Note that all playback and capture streams must have the same
	* sample rate.
        */
       unsigned num_playback; /* 0 or more */
       unsigned num_capture; /* 0 or more */

       /* All playback and capture streams transfer this number of
	* frames of PCM data.
        */
       unsigned num_frames;

       struct virtio_audio_pcm_data playback[num_playback];

       /* Read (Device -> Driver) */
       struct virtio_audio_pcm_data capture[num_capture];
       /* TODO status and error codes */
   };

   In other words, a single struct virtio_audio_pcm delivers playback
   samples to the device and returns capture samples to the driver.

   I used arrays so that multiple streams with the same sample rate can
   be bundled together.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-10 15:48                         ` Stefan Hajnoczi
@ 2019-05-10 17:13                           ` Anton Yakovlev
  2019-05-11 20:49                             ` Marco Martinelli - 13Byte srl
  2019-05-14 13:44                             ` Stefan Hajnoczi
  0 siblings, 2 replies; 29+ messages in thread
From: Anton Yakovlev @ 2019-05-10 17:13 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Gerd Hoffmann, Mikhail Golubev, Marco Martinelli - 13Byte srl,
	virtio-dev, Kővágó Zoltán

> Shared memory isn't a native concept to VIRTIO.  The device and the
> driver don't assume shared memory access in the general case (i.e.
> virtqueue buffers could even be copied and virtio-blk, virtio-net, etc
> would still work!).
>
> There is currently a spec extension on the mailing list to add Shared
> Memory Resources to VIRTIO and new device types will use it.  However, I
> don't think this is necessary for this use case.

Yes, we are awared about VIRTIO and shared memory relationships. Our original propose was to support classic way of communications by default. And, thanks to your comments, it can be further improved.

But there's one issue. An audio device is a real-time device. It has explicit hard deadline. And there're many factors helping an audio device to fail to meet the deadline due to virtualization overhead. And in that sense a virtual audio device differs from each and every other virtual devices. If a block device becomes slower - not a big deal, if a network device becomes slower - not a big deal, if a GPU device starts to skip frames - not very nice, but also not a big deal. But if an audio device starts to skip frames - it's a big problem, and device is nonfunctional as a matter of fact. Good audio device implementation must met two criterias:

1. Low latency
2. No frame dropping at all

All I want to say is that any queue-based approach can not guaranty correct functionality to an audio device for all possible use cases. Because a queue has its natural limitations: either in terms of additional latency due to queue notifications, or due to queue limited size. And an audio device eventually will hit one of them for some application. It means, we can not support some cases, which works pretty fine in native operating systems. But such limitations are artificial ones due, again, using a queue for data transfers. In case of shared memory such limitations are just gone.

So, our proposal is to support classic way of communications by default and introduce shared memory based approach as either non-standard extension or part of future VIRTIO device types. And switch to this mode where it's possible or make sense. Like, all modern type-2 hypervisors usually have no problems with sharing memory between guest and host, so why not provide to user high quality virtual audio device?

--
Anton Yakovlev
Senior Software Engineer

OpenSynergy GmbH
Rotherstr. 20, 10245 Berlin

www.opensynergy.com

Please mind our privacy notice<https://www.opensynergy.com/datenschutzerklaerung/privacy-notice-for-business-partners-pursuant-to-article-13-of-the-general-data-protection-regulation-gdpr/> pursuant to Art. 13 GDPR. // Unsere Hinweise zum Datenschutz gem. Art. 13 DSGVO finden Sie hier.<https://www.opensynergy.com/de/datenschutzerklaerung/datenschutzhinweise-fuer-geschaeftspartner-gem-art-13-dsgvo/>
COQOS Hypervisor certified by TÜV SÜD
                [COQOS Hypervisor certified by TÜV SÜD]

---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-10 17:13                           ` Anton Yakovlev
@ 2019-05-11 20:49                             ` Marco Martinelli - 13Byte srl
  2019-05-12 20:01                               ` Matti Moell
  2019-05-14 13:44                             ` Stefan Hajnoczi
  1 sibling, 1 reply; 29+ messages in thread
From: Marco Martinelli - 13Byte srl @ 2019-05-11 20:49 UTC (permalink / raw)
  To: Anton Yakovlev, Stefan Hajnoczi, virtio-dev
  Cc: Gerd Hoffmann, Mikhail Golubev, Kővágó Zoltán

Wow, it seems like you guys from opensinergy beat me on time. Nice job, 
congratulations!

Your work is way ahead of mine, so much that I'm thinking of stepping 
aside and letting you do the specifications, while experimenting on my 
code privately just for the fun of it.
Just a couple of questions.
You mentioned that the PoC was tested on Linux and Windows 10. I presume 
these are the guest OSs.
On the host side are you working on qemu or another hypervisor?
Besides contributing to the specifications, will you open source the 
actual implementation?
 From your website I see you work in the automotive business. Will your 
implementation be automotive oriented or general purpose?
My idea was to support the general public and in particular the gamers 
and the musicians with my project. I want to be sure that these 
categories will be supported.
The reason I'm asking these questions is to see if it makes sense for me 
to keep working on this project, perhaps to implement the specifications 
proposed by you, or if you're already taking care of everything I was 
interested in implementing.


Best regards,
Marco


Il 10/05/19 19:13, Anton Yakovlev ha scritto:
>> Shared memory isn't a native concept to VIRTIO.  The device and the
>> driver don't assume shared memory access in the general case (i.e.
>> virtqueue buffers could even be copied and virtio-blk, virtio-net, etc
>> would still work!).
>>
>> There is currently a spec extension on the mailing list to add Shared
>> Memory Resources to VIRTIO and new device types will use it.  However, I
>> don't think this is necessary for this use case.
> Yes, we are awared about VIRTIO and shared memory relationships. Our original propose was to support classic way of communications by default. And, thanks to your comments, it can be further improved.
>
> But there's one issue. An audio device is a real-time device. It has explicit hard deadline. And there're many factors helping an audio device to fail to meet the deadline due to virtualization overhead. And in that sense a virtual audio device differs from each and every other virtual devices. If a block device becomes slower - not a big deal, if a network device becomes slower - not a big deal, if a GPU device starts to skip frames - not very nice, but also not a big deal. But if an audio device starts to skip frames - it's a big problem, and device is nonfunctional as a matter of fact. Good audio device implementation must met two criterias:
>
> 1. Low latency
> 2. No frame dropping at all
>
> All I want to say is that any queue-based approach can not guaranty correct functionality to an audio device for all possible use cases. Because a queue has its natural limitations: either in terms of additional latency due to queue notifications, or due to queue limited size. And an audio device eventually will hit one of them for some application. It means, we can not support some cases, which works pretty fine in native operating systems. But such limitations are artificial ones due, again, using a queue for data transfers. In case of shared memory such limitations are just gone.
>
> So, our proposal is to support classic way of communications by default and introduce shared memory based approach as either non-standard extension or part of future VIRTIO device types. And switch to this mode where it's possible or make sense. Like, all modern type-2 hypervisors usually have no problems with sharing memory between guest and host, so why not provide to user high quality virtual audio device?
>
> --
> Anton Yakovlev
> Senior Software Engineer
>
> OpenSynergy GmbH
> Rotherstr. 20, 10245 Berlin
>
> www.opensynergy.com
>
> Please mind our privacy notice<https://www.opensynergy.com/datenschutzerklaerung/privacy-notice-for-business-partners-pursuant-to-article-13-of-the-general-data-protection-regulation-gdpr/> pursuant to Art. 13 GDPR. // Unsere Hinweise zum Datenschutz gem. Art. 13 DSGVO finden Sie hier.<https://www.opensynergy.com/de/datenschutzerklaerung/datenschutzhinweise-fuer-geschaeftspartner-gem-art-13-dsgvo/>
> COQOS Hypervisor certified by TÜV SÜD
>                  [COQOS Hypervisor certified by TÜV SÜD]
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
> For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-11 20:49                             ` Marco Martinelli - 13Byte srl
@ 2019-05-12 20:01                               ` Matti Moell
  0 siblings, 0 replies; 29+ messages in thread
From: Matti Moell @ 2019-05-12 20:01 UTC (permalink / raw)
  To: Marco Martinelli - 13Byte srl, Anton Yakovlev, Stefan Hajnoczi,
	virtio-dev
  Cc: Gerd Hoffmann, Mikhail Golubev, Kővágó Zoltán

Hi Marco,

On 11.05.19 22:49, Marco Martinelli - 13Byte srl wrote:
> Wow, it seems like you guys from opensinergy beat me on time. Nice job,
> congratulations!
Thanks a lot, I think out main problem was that we kept it under the
covers for so long.
>
> Your work is way ahead of mine, so much that I'm thinking of stepping
> aside and letting you do the specifications, while experimenting on my
> code privately just for the fun of it.
> Just a couple of questions.
> You mentioned that the PoC was tested on Linux and Windows 10. I presume
> these are the guest OSs.
For us, Linux is the primary guest OS at the moment.
> On the host side are you working on qemu or another hypervisor?
> Besides contributing to the specifications, will you open source the
> actual implementation?
The host side is another hypervisor.
> From your website I see you work in the automotive business. Will your
> implementation be automotive oriented or general purpose?
> My idea was to support the general public and in particular the gamers
> and the musicians with my project. I want to be sure that these
> categories will be supported.
Well, virtio is general purpose and so should all devices, even if we
use it in automotive contexts. TBH, automotive requirements aren't that
different from gaming or music production. You will often have very
strict latency requirements and need support for multiple channels
(coherent and non-coherent). So I think the overlap is huge.

But, as a matter of fact, I don't think Anton and I know exactly what
the general public is interested in so, your help would be very
appreciated here.

> The reason I'm asking these questions is to see if it makes sense for me
> to keep working on this project, perhaps to implement the specifications
> proposed by you, or if you're already taking care of everything I was
> interested in implementing.

It definitely makes sense for you to keep working on this, I believe
that we might not have the time at the moment to work on a full qemu
implementation and having an independent implementation of the device
side would be pretty awesome.

We plan to send patches for the device driver in Linux in the near
future and we might even be able to share the windows one (Anton should
know).

Cheers,

                Matti

----

Please mind our privacy notice<https://www.opensynergy.com/datenschutzerklaerung/privacy-notice-for-business-partners-pursuant-to-article-13-of-the-general-data-protection-regulation-gdpr/> pursuant to Art. 13 GDPR. // Unsere Hinweise zum Datenschutz gem. Art. 13 DSGVO finden Sie hier.<https://www.opensynergy.com/de/datenschutzerklaerung/datenschutzhinweise-fuer-geschaeftspartner-gem-art-13-dsgvo/>

---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-10 14:15                       ` Anton Yakovlev
  2019-05-10 15:48                         ` Stefan Hajnoczi
@ 2019-05-13  9:32                         ` Gerd Hoffmann
  2019-05-14 19:14                           ` Anton Yakovlev
  1 sibling, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2019-05-13  9:32 UTC (permalink / raw)
  To: Anton Yakovlev
  Cc: Mikhail Golubev, Marco Martinelli - 13Byte srl, virtio-dev,
	Stefan Hajnoczi, Kővágó Zoltán

On Fri, May 10, 2019 at 02:15:00PM +0000, Anton Yakovlev wrote:
> Hi Gerd! My name is Anton and I'm the original author of this draft. Thanks for comments!
> 
> >> Configuration space provides a maximum amount of available virtual queues. The
> >> nqueues value MUST be at least one.
> >>
> >> ```
> >> struct virtio_snd_config
> >> {
> >>     le32 nqueues;
> >> };
> >> ```
> 
> > Including or excluding the control queue?
> 
> Including the control queue.

Ok.  Please say so explicitly in the specs.

> >> Each request begins with a 2-byte field that identifies a recipient function
> >> followed by a 2-byte field that identifies a function-specific request type.
> >>
> >> Each response begins with a 4-byte field that contains a status code. The values
> >> 0-31 are reserved for common status codes, a function can define function-specific
> >> status codes starting from 32.
> 
> > I'd suggest to use a common scheme with a single le32 field for both
> > requests and responses.
> > ...
> > (maybe just drop the single-element structs and use the enums directly).
> 
> IMO, both options are quite fine. We decided to choose separate
> namespaces because it's more flexible approach.

I fail to see why it is more flexible.  If you want go with the separate
function/request fields I'd suggest to do the same for responses.

> >> ### Device Configuration
> >> ...
> >> struct virtio_snd_generic_desc
> >> {
> >>     u8 length;
> >>     u8 type;
> >>     u16 padding;
> >
> > I'd make length and type u16 and drop the padding.
> 
> Well, it's a possible option. We just didn't want to waste additional space here.

Ok, saw later in the patch that other descriptors _replace_ padding
instead of _appending_ to the struct.  So padding isn't there to align
fields appended, but round up the descriptor size for descriptor
alignment, correct?

I think it's fine then.

> >> With the exception of the base function, all implemented functions MUST define
> >> its own descriptor(s) format (either presented in this specification or
> >> vendor-specific) and MUST includes these in configuration only if a particular
> >> function (or part of its functionality) is enabled in the device.
> >
> > I don't think it is a good idea to allow vendor-specific descriptors
> > here.  It should all be in the virtio spec.  We might want reserve a
> > sub-range of "type" for experimental/development purposes though.
> 
> Yeah, an ability to define some experimental extensions was one of the
> targets here (like adding sound controls, non-PCM streams, MIDI and so
> on). Also, this spec targeted the widest possible range of cases.
> Like, some hardware has very tricky features which can not be (or just
> has no point to be) defined in common specification. One example is to
> allow switching between speaker and bluetooth output. Ususally you
> don't need it, but if you want to provide such feature to the guest,
> it's better to implement this as a custom extension.

Why?  I think it makes perfect sense to have a standard function for
stream routing.

Even when allowing vendor specific descriptors/functions a sub-range of
"type" must be reserved for that and a way to identify the vendor is
needed.


> >> ### Function Operation
> >>
> >> #### Get Device Configuration
> >>
> >> The driver sends the VIRTIO_SND_BASE_R_GET_CFG generic request, the device
> >> answers with a response containing device configuration.
> >
> > Which is a list of descriptors I assume?
> 
> You are right.

Good.  Please clarify the specs.

> >> #### Suspend
> >> #### Resume
> >
> > Why these two are needed?
> 
> I would say, that some virtualization platforms either do not notify
> your backend about guest suspend/resume or it's very tricky to
> distinguish such conditions from other shutdown/initialization types.
> According to my practice, it's always better to notify device side in
> explicit way, because the driver always know what is going now.

So the idea is the driver doesn't stop streams on suspend, but sends a
suspend notification to the device and expects the device stop the
streams?

> > Also restoring state as optional device feature doesn't look useful to
> > me.
> 
> Well, restoring active playback or capturing is not impossible thing
> at all. From other side, maybe some device implementors might not
> want/need such functionality. So I'm not sure, what is better here.

I think we should have *one* way to handle suspend/resume.  So either
make suspend/resume commands mandatory, or expect the driver to
stop/restart streams on suspend/resume.

I think the latter is the better way.  If you want know on the device
side why a stream was stopped (why do you need to know btw?) you can add
a "reason" field to the stop command.

> >> - *Automatic mode*: the driver allocates and shares with the device a pseudophysically
> >> continuous memory area containing runtime control registers and data buffer itself.
> >
> > What is "pseudophysically continuous memory"?
> 
> This memory is physically continuous from the driver's point of view.

So continuous in guest physical memory.

> > Why do you think this is needed?
> 
> When you implement an audio device, you usually start with what we
> call "manual mode". It works, but only for simple use cases. There're
> two major challenges here.
> 
> Thus, no requests/traps/hypercalls to the device while a stream is
> running - no problems here.

As already mentioned by Stefan you can run the virtqueue in polling mode
to avoid trapping into the hypervisor.

> 2) Everybody wants to reduce a latency as much as possible. One of the
> most logical way is to allow to mmap data buffer into the user space
> memory.

mmap() doesn't conflict with virtqueues.  Userspace must notify the
kernel driver about buffer updates though.

> (Actually, in some cases you even have no choice here, like in
> case of the WaveRT interface in Windows.) But memory mapped buffer
> means, that you either have a very little or have not at all an idea
> what is going on with buffer content.

So how do you maintain virtio_snd_pcm_hw_regs.dma_position?  Do you
allow userspace mmap the whole virtio_snd_pcm_shmem struct and update
it directly, without calling into the kernel driver?

> > Why both microseconds and bytes?  Isn't that redundant?
> 
> Just to be sure that both ends have exactly the same ideas.

I don't think this is needed.  If one end gets the microseconds <=>
bytes transformation wrong you'll have bigger problems anyway ...

> > Are 8-bit formats are still used in practice?
> 
> Actually, yeah. I saw quite recent chipsets with the U8 format
> support. Anyway, is it a big issue? It costs zero to support
> additional formats, so why not?

Well, the cost is not zero.  Some more code (not that much indeed).
More testing (more significant cost).  So I would try to avoid carrying
forward old stuff which is not used in practice any more just because
you can.

> > What are VIRTIO_SND_PCM_FMT_{S,U}20_LE ?
> >
> > What are VIRTIO_SND_PCM_FMT_*_3BE ?
> >
> > Which of these formats are actually implemented in your prototype?
> 
> Some format's physical width is not multiple of 8. Such samples are
> kept in "a storage" which width is multiple of 8 (like 20-bit samples
> are kept either in 24-bit or in 32-bit storage).

So VIRTIO_SND_PCM_FMT_U20_LE == VIRTIO_SND_PCM_FMT_U32_LE, except that
with U20 the sound hardware doesn't use the 12 least significant bits?

> Both Linux (ALSA) and Windows (WaveXXX interfaces) just expect from
> you to report support of these formats. You don't need to do anything
> special in order to implemented them. So, yes, we can support them in
> the prototype.

I guess I would have used the storage format and the number of
significant bits instead, but if sound APIs use different format
constants for these being consistent makes sense to me.

> > Same question: Do we actually need all those?  My impression is that
> > these days 48000 is pretty much standard.  96000 + 192000 for higher
> > quality.  44100 sometimes still because it happens to be the CD sample
> > rate.  Maybe 32000/16000/8000 for low bandwidth codecs.
> >
> > But 5512, 11025 & friends?
> 
> Same answer: why not? :)

Same reply as above ;)

> >> /* a PCM channel map definitions */
> >>
> >> /* All channels have fixed channel positions */
> >> #define VIRTIO_SND_PCM_CHMAP_FIXED      0
> >> /* All channels are swappable (e.g. {FL/FR/RL/RR} -> {RR/RL/FR/FL}) */
> >> #define VIRTIO_SND_PCM_CHMAP_VARIABLE   1
> >> /* Only pair-wise channels are swappable (e.g. {FL/FR/RL/RR} -> {RL/RR/FL/FR}) */
> >> #define VIRTIO_SND_PCM_CHMAP_PAIRED     2
> >
> > What this is good for?  How would a driver ask the device to actually
> > swap the channels?  And isn't it easier to have the device provide a
> > complete list of possible channel maps and let the driver simply pick
> > one?
> 
> Basically, we were inspired how ALSA handles these and reused the same
> approach here. How: a hardware can have internal router/mixer to allow
> flexible configuration, there's nothing special.

I mean in the virtio api.  Devices can report the mapping capability but
the driver can't pick one.  Or did I miss something (if so then this is
an indication that the spec should be more clear on how channel mapping
is supposed to work ...) ?

> >> #### Prepare ...  #### Start ...
> >
> > So I guess the way to start a stream is (a) prepare, (b) queue some
> > buffers, (c) start.  Correct?
> 
> Yeap!

Doesn't hurt to explicitly say so in the specs ;)

cheers,
  Gerd


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-10 17:13                           ` Anton Yakovlev
  2019-05-11 20:49                             ` Marco Martinelli - 13Byte srl
@ 2019-05-14 13:44                             ` Stefan Hajnoczi
  2019-05-15  6:30                               ` Anton Yakovlev
  1 sibling, 1 reply; 29+ messages in thread
From: Stefan Hajnoczi @ 2019-05-14 13:44 UTC (permalink / raw)
  To: Anton Yakovlev
  Cc: Gerd Hoffmann, Mikhail Golubev, Marco Martinelli - 13Byte srl,
	virtio-dev, Kővágó Zoltán

[-- Attachment #1: Type: text/plain, Size: 3039 bytes --]

On Fri, May 10, 2019 at 05:13:26PM +0000, Anton Yakovlev wrote:
> > Shared memory isn't a native concept to VIRTIO.  The device and the
> > driver don't assume shared memory access in the general case (i.e.
> > virtqueue buffers could even be copied and virtio-blk, virtio-net, etc
> > would still work!).
> >
> > There is currently a spec extension on the mailing list to add Shared
> > Memory Resources to VIRTIO and new device types will use it.  However, I
> > don't think this is necessary for this use case.
> 
> Yes, we are awared about VIRTIO and shared memory relationships. Our original propose was to support classic way of communications by default. And, thanks to your comments, it can be further improved.
> 
> But there's one issue. An audio device is a real-time device. It has explicit hard deadline. And there're many factors helping an audio device to fail to meet the deadline due to virtualization overhead. And in that sense a virtual audio device differs from each and every other virtual devices. If a block device becomes slower - not a big deal, if a network device becomes slower - not a big deal, if a GPU device starts to skip frames - not very nice, but also not a big deal. But if an audio device starts to skip frames - it's a big problem, and device is nonfunctional as a matter of fact. Good audio device implementation must met two criterias:
> 
> 1. Low latency
> 2. No frame dropping at all
> 
> All I want to say is that any queue-based approach can not guaranty correct functionality to an audio device for all possible use cases. Because a queue has its natural limitations: either in terms of additional latency due to queue notifications, or due to queue limited size. And an audio device eventually will hit one of them for some application. It means, we can not support some cases, which works pretty fine in native operating systems. But such limitations are artificial ones due, again, using a queue for data transfers. In case of shared memory such limitations are just gone.
> 
> So, our proposal is to support classic way of communications by default and introduce shared memory based approach as either non-standard extension or part of future VIRTIO device types. And switch to this mode where it's possible or make sense. Like, all modern type-2 hypervisors usually have no problems with sharing memory between guest and host, so why not provide to user high quality virtual audio device?

virtqueues offer reliable delivery, so #2 isn't an issue.

Real-time is achievable and can be done with low latency.  Make the
receiver a real-time thread that polls the vring periodically (based on
the latency/buffer size requirement).  The vring supports lock-free
access so this is perfect for real-time.

When I say "receiver" I mean the driver's capture and device's playback
components.  Both of them have real-time requirements.

Does this approach meet your requirements?

If not, please explain the shared memory approach and how it is better.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-13  9:32                         ` Gerd Hoffmann
@ 2019-05-14 19:14                           ` Anton Yakovlev
  0 siblings, 0 replies; 29+ messages in thread
From: Anton Yakovlev @ 2019-05-14 19:14 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Mikhail Golubev, Marco Martinelli - 13Byte srl, virtio-dev,
	Stefan Hajnoczi, Kővágó Zoltán

>>>> Each request begins with a 2-byte field that identifies a recipient function
>>>> followed by a 2-byte field that identifies a function-specific request type.
>>>>
>>>> Each response begins with a 4-byte field that contains a status code. The values
>>>> 0-31 are reserved for common status codes, a function can define function-specific
>>>> status codes starting from 32.
>>
>>> I'd suggest to use a common scheme with a single le32 field for both
>>> requests and responses.
>>> ...
>>> (maybe just drop the single-element structs and use the enums directly).
>>
>> IMO, both options are quite fine. We decided to choose separate
>> namespaces because it's more flexible approach.
>
> I fail to see why it is more flexible.  If you want go with the separate
> function/request fields I'd suggest to do the same for responses.

It's not like we definitely want to, it just was a design choice at the moment. As I mentioned, the both options look fine. If it's more reasonable to have single enum, let it be.


>> >> ### Device Configuration
>> >> ...
>> >> struct virtio_snd_generic_desc
>> >> {
>> >>     u8 length;
>> >>     u8 type;
>> >>     u16 padding;
>> >
>> > I'd make length and type u16 and drop the padding.
>>
>> Well, it's a possible option. We just didn't want to waste additional space here.
>
> Ok, saw later in the patch that other descriptors _replace_ padding
> instead of _appending_ to the struct.  So padding isn't there to align
> fields appended, but round up the descriptor size for descriptor
> alignment, correct?

> I think it's fine then.

Yes, this definition was done just for convenience.


>> >> With the exception of the base function, all implemented functions MUST define
>> >> its own descriptor(s) format (either presented in this specification or
>> >> vendor-specific) and MUST includes these in configuration only if a particular
>> >> function (or part of its functionality) is enabled in the device.
>> >
>> > I don't think it is a good idea to allow vendor-specific descriptors
>> > here.  It should all be in the virtio spec.  We might want reserve a
>> > sub-range of "type" for experimental/development purposes though.
>>
>> Yeah, an ability to define some experimental extensions was one of the
>> targets here (like adding sound controls, non-PCM streams, MIDI and so
>> on). Also, this spec targeted the widest possible range of cases.
>> Like, some hardware has very tricky features which can not be (or just
>> has no point to be) defined in common specification. One example is to
>> allow switching between speaker and bluetooth output. Ususally you
>> don't need it, but if you want to provide such feature to the guest,
>> it's better to implement this as a custom extension.
>
> Why?  I think it makes perfect sense to have a standard function for
> stream routing.
>
> Even when allowing vendor specific descriptors/functions a sub-range of
> "type" must be reserved for that and a way to identify the vendor is
> needed.

Okey, what is your proposal? Should specification define driver behavior for configuration parsing?


>> >> #### Suspend
>> >> #### Resume
>> >
>> > Why these two are needed?
>>
>> I would say, that some virtualization platforms either do not notify
>> your backend about guest suspend/resume or it's very tricky to
>> distinguish such conditions from other shutdown/initialization types.
>> According to my practice, it's always better to notify device side in
>> explicit way, because the driver always know what is going now.
>
> So the idea is the driver doesn't stop streams on suspend, but sends a
> suspend notification to the device and expects the device stop the
> streams?

Yes, that was the original idea.


>> > Also restoring state as optional device feature doesn't look useful to
>> > me.
>>
>> Well, restoring active playback or capturing is not impossible thing
>> at all. From other side, maybe some device implementors might not
>> want/need such functionality. So I'm not sure, what is better here.
>
> I think we should have *one* way to handle suspend/resume.  So either
> make suspend/resume commands mandatory, or expect the driver to
> stop/restart streams on suspend/resume.
>
> I think the latter is the better way.  If you want know on the device
> side why a stream was stopped (why do you need to know btw?) you can add
> a "reason" field to the stop command.

We want to know the reason for supporting running stream suspend/resume. If the driver was shutdown, the device does not need to do anything special. If it was suspended while running stream, the device must be ready to restart stream on resume (since from the driver's point of view nothing happened in between suspend/resume).

But I rethought this part and realized that it would not help. There're two types of suspends: when a guest enters low power state (like s3/s4) and when, for example, QEmu was suspended. In second case the driver will send nothing. Thus, there's no point having these special request types in specification.


>> 2) Everybody wants to reduce a latency as much as possible. One of the
>> most logical way is to allow to mmap data buffer into the user space
>> memory.
>
> mmap() doesn't conflict with virtqueues.  Userspace must notify the
> kernel driver about buffer updates though.

Userspace must notify the kernel, not the kernel driver itself. There's a huge difference. On Linux, ALSA design allows device driver to have information about buffer updates. But it's just a special case. In general, this information is required only by upper layer, not by the driver. And, for example, recent Windows versions do not notify the driver at all.


>> (Actually, in some cases you even have no choice here, like in
>> case of the WaveRT interface in Windows.) But memory mapped buffer
>> means, that you either have a very little or have not at all an idea
>> what is going on with buffer content.
>
> So how do you maintain virtio_snd_pcm_hw_regs.dma_position?  Do you
> allow userspace mmap the whole virtio_snd_pcm_shmem struct and update
> it directly, without calling into the kernel driver?

It's supposed to mmap only buffer part (without control registers).


>> > Why both microseconds and bytes?  Isn't that redundant?
>>
>> Just to be sure that both ends have exactly the same ideas.
>
> I don't think this is needed.  If one end gets the microseconds <=>
> bytes transformation wrong you'll have bigger problems anyway ...

I think we could do without these at all. I want to discuss it in my reply to Stefan.


>> > Are 8-bit formats are still used in practice?
>>
>> Actually, yeah. I saw quite recent chipsets with the U8 format
>> support. Anyway, is it a big issue? It costs zero to support
>> additional formats, so why not?
>
> Well, the cost is not zero.  Some more code (not that much indeed).
> More testing (more significant cost).  So I would try to avoid carrying
> forward old stuff which is not used in practice any more just because
> you can.

It seems reasonable to remove A_LAW/MU_LAW formats and endianness.

But regarding other formats you are not quite right. They are still being used, even S8/U8. Let's take a broader look. There's the Android and it has hardware compatibility requirements. According to PCM playback/capture requirements, Android wants to have 8-bit and 16-bit sample formats. I saw recent boards support for both types, and these boards were supposed to run the Android. If your goal is to run virtualized Android there, you definetly want to provide the same audio capabilities to the guest.

The same regarding sample rates. Android requires sample rate from 8 kHz to 48 kHz, and Android-compatible hardware does provide it.

I want to say these formats and rates are still alive in modern hardware.


>> > What are VIRTIO_SND_PCM_FMT_{S,U}20_LE ?
>> >
>> > What are VIRTIO_SND_PCM_FMT_*_3BE ?
>> >
>> > Which of these formats are actually implemented in your prototype?
>>
>> Some format's physical width is not multiple of 8. Such samples are
>> kept in "a storage" which width is multiple of 8 (like 20-bit samples
>> are kept either in 24-bit or in 32-bit storage).
>
> So VIRTIO_SND_PCM_FMT_U20_LE == VIRTIO_SND_PCM_FMT_U32_LE, except that
> with U20 the sound hardware doesn't use the 12 least significant bits?

Yes, correct.


>> Both Linux (ALSA) and Windows (WaveXXX interfaces) just expect from
>> you to report support of these formats. You don't need to do anything
>> special in order to implemented them. So, yes, we can support them in
>> the prototype.
>
> I guess I would have used the storage format and the number of
> significant bits instead, but if sound APIs use different format
> constants for these being consistent makes sense to me.

Yes, it's much easier to derive such information from defined format types than vice versa. Also, when you have defined types for supported formats, you automatically cut out all unsupported/invalid [storage bits, significant bits] combinations.


>> >> /* a PCM channel map definitions */
>> >>
>> >> /* All channels have fixed channel positions */
>> >> #define VIRTIO_SND_PCM_CHMAP_FIXED      0
>> >> /* All channels are swappable (e.g. {FL/FR/RL/RR} -> {RR/RL/FR/FL}) */
>> >> #define VIRTIO_SND_PCM_CHMAP_VARIABLE   1
>> >> /* Only pair-wise channels are swappable (e.g. {FL/FR/RL/RR} -> {RL/RR/FL/FR}) */
>> >> #define VIRTIO_SND_PCM_CHMAP_PAIRED     2
>> >
>> > What this is good for?  How would a driver ask the device to actually
>> > swap the channels?  And isn't it easier to have the device provide a
>> > complete list of possible channel maps and let the driver simply pick
>> > one?
>>
>> Basically, we were inspired how ALSA handles these and reused the same
>> approach here. How: a hardware can have internal router/mixer to allow
>> flexible configuration, there's nothing special.
>
> I mean in the virtio api.  Devices can report the mapping capability but
> the driver can't pick one.  Or did I miss something (if so then this is
> an indication that the spec should be more clear on how channel mapping
> is supposed to work ...) ?

1. If the device can provide information about channel map(s), it sets the CHANNEL_MAP feature bit and # of supported channel maps in a PCM stream configuration descriptor.
2. The driver can enumerate channel maps using the GET_FEATURE(CHANNEL_MAP) request containing a channel map index (from 0 to desc::nchmaps - 1).
3. If a channel map type allows to swap channel positions, the driver can send the SET_FEATURE(CHANNEL_MAP) request containing updated channel positions.

That's the idea.


>> >> #### Prepare ...  #### Start ...
>> >
>> > So I guess the way to start a stream is (a) prepare, (b) queue some
>> > buffers, (c) start.  Correct?
>>
>> Yeap!
>
> Doesn't hurt to explicitly say so in the specs ;)

Will be done!


--
Anton Yakovlev
Senior Software Engineer

OpenSynergy GmbH
Rotherstr. 20, 10245 Berlin

www.opensynergy.com

---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org



Please mind our privacy notice<https://www.opensynergy.com/datenschutzerklaerung/privacy-notice-for-business-partners-pursuant-to-article-13-of-the-general-data-protection-regulation-gdpr/> pursuant to Art. 13 GDPR. // Unsere Hinweise zum Datenschutz gem. Art. 13 DSGVO finden Sie hier.<https://www.opensynergy.com/de/datenschutzerklaerung/datenschutzhinweise-fuer-geschaeftspartner-gem-art-13-dsgvo/>
COQOS Hypervisor certified by TÜV SÜD
                [COQOS Hypervisor certified by TÜV SÜD]

---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-14 13:44                             ` Stefan Hajnoczi
@ 2019-05-15  6:30                               ` Anton Yakovlev
  2019-05-15  8:31                                 ` Anton Yakovlev
  2019-05-15 16:03                                 ` Stefan Hajnoczi
  0 siblings, 2 replies; 29+ messages in thread
From: Anton Yakovlev @ 2019-05-15  6:30 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Gerd Hoffmann, Mikhail Golubev, Marco Martinelli - 13Byte srl,
	virtio-dev, Kővágó Zoltán

>> So, our proposal is to support classic way of communications by default and introduce shared memory based approach as either non-standard extension or part of future VIRTIO device types. And switch to this mode where it's possible or make sense. Like, all modern type-2 hypervisors usually have no problems with sharing memory between guest and host, so why not provide to user high quality virtual audio device?
>
> virtqueues offer reliable delivery, so #2 isn't an issue.
>
> Real-time is achievable and can be done with low latency.  Make the
> receiver a real-time thread that polls the vring periodically (based on
> the latency/buffer size requirement).  The vring supports lock-free
> access so this is perfect for real-time.
>
> When I say "receiver" I mean the driver's capture and device's playback
> components.  Both of them have real-time requirements.
>
> Does this approach meet your requirements?

After careful consideration, I think polling mode should make it possible. Like, using dedicated "data" queue per stream in polling mode (multiplexing is not an option, since it reduces queue throughput in proportion to the number of multiplexed streams). How to describe it in specification?


--
Anton Yakovlev
Senior Software Engineer

OpenSynergy GmbH
Rotherstr. 20, 10245 Berlin

www.opensynergy.com

Please mind our privacy notice<https://www.opensynergy.com/datenschutzerklaerung/privacy-notice-for-business-partners-pursuant-to-article-13-of-the-general-data-protection-regulation-gdpr/> pursuant to Art. 13 GDPR. // Unsere Hinweise zum Datenschutz gem. Art. 13 DSGVO finden Sie hier.<https://www.opensynergy.com/de/datenschutzerklaerung/datenschutzhinweise-fuer-geschaeftspartner-gem-art-13-dsgvo/>
COQOS Hypervisor certified by TÜV SÜD
                [COQOS Hypervisor certified by TÜV SÜD]

---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-15  6:30                               ` Anton Yakovlev
@ 2019-05-15  8:31                                 ` Anton Yakovlev
  2019-05-15 16:03                                 ` Stefan Hajnoczi
  1 sibling, 0 replies; 29+ messages in thread
From: Anton Yakovlev @ 2019-05-15  8:31 UTC (permalink / raw)
  To: Stefan Hajnoczi, Gerd Hoffmann, Mikhail Golubev,
	Marco Martinelli - 13Byte srl, virtio-dev,
	Kővágó Zoltán

[-- Attachment #1: Type: text/plain, Size: 999 bytes --]

Hi all,

I updated the header file according to the comments and overall flow of the discussion (see attachment). Also I replaced defines with enumerations and

1. Added new PCM request type for assigning particular virtual queue for particular substream.
2. Removed the rewind/forward request types, since these are actually not needed.

Looking forward for your comments.

Anton Yakovlev
Senior Software Engineer

OpenSynergy GmbH
Rotherstr. 20, 10245 Berlin

www.opensynergy.com

Please mind our privacy notice<https://www.opensynergy.com/datenschutzerklaerung/privacy-notice-for-business-partners-pursuant-to-article-13-of-the-general-data-protection-regulation-gdpr/> pursuant to Art. 13 GDPR. // Unsere Hinweise zum Datenschutz gem. Art. 13 DSGVO finden Sie hier.<https://www.opensynergy.com/de/datenschutzerklaerung/datenschutzhinweise-fuer-geschaeftspartner-gem-art-13-dsgvo/>
COQOS Hypervisor certified by TÜV SÜD
                [COQOS Hypervisor certified by TÜV SÜD]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: virtio_snd.h --]
[-- Type: text/x-chdr; name="virtio_snd.h", Size: 14175 bytes --]

/*
 * Copyright (C) 2019  OpenSynergy GmbH
 *
 * This header is BSD licensed so anyone can use the definitions to
 * implement compatible drivers/servers.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of OpenSynergy GmbH nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE. */

#ifndef VIRTIO_SND_IF_H
#define VIRTIO_SND_IF_H

#include <linux/virtio_types.h>

/*******************************************************************************
 * COMMON DEFINITIONS
 */

/* a configuration space */
struct virtio_snd_config
{
    /* maximum # of available virtual queues (including the control queue) */
    __virtio32 nqueues;
};

/* supported function types */
enum
{
    VIRTIO_SND_FN_BASE,
    VIRTIO_SND_FN_PCM
};

/* supported descriptor types */
enum
{
    VIRTIO_SND_DESC_PCM,
    VIRTIO_SND_DESC_PCM_STREAM
};

/* supported control request types */
enum
{
    /* --- base request types --- */
    VIRTIO_SND_BASE_R_GET_CFG,
    /* --- pcm request types --- */
    VIRTIO_SND_PCM_R_GET_FEATURE = 0x1000,
    VIRTIO_SND_PCM_R_SET_FEATURE,
    VIRTIO_SND_PCM_R_SET_QUEUE,
    VIRTIO_SND_PCM_R_SET_FORMAT,
    VIRTIO_SND_PCM_R_PREPARE,
    VIRTIO_SND_PCM_R_START,
    VIRTIO_SND_PCM_R_STOP,
    VIRTIO_SND_PCM_R_PAUSE,
    VIRTIO_SND_PCM_R_UNPAUSE
};

/* supported error codes */
enum
{
    /* --- generic error codes --- */
    /* no errors */
    VIRTIO_SND_E_SUCCESS,
    /* an undefined error */
    VIRTIO_SND_E_GENERAL,
    /* not supported input parameter(s) */
    VIRTIO_SND_E_NOTSUPPORTED,
    /* invalid input parameter(s) */
    VIRTIO_SND_E_INVALID,
    /* I/O error */
    VIRTIO_SND_E_IO,
    /* --- pcm error codes --- */
    VIRTIO_SND_PCM_E_NOT_READY = 0x1000
};

/* a generic request header */
struct virtio_snd_req
{
    __virtio16 function;
    __virtio16 request;
};

/* a generic response header */
struct virtio_snd_rsp
{
    __virtio32 status; /* VIRTIO_SND_E_XXX */
};

/* a generic descriptor */
struct virtio_snd_generic_desc
{
    __u8 length;
    __u8 type;
    __u16 padding;
};

/*******************************************************************************
 * BASE FUNCTION DEFINITIONS
 */

/* a maximum possible configuration data size (in bytes) */
#define VIRTIO_SND_BASE_CFG_MAX_SIZE    1024

/* a response containing device configuration */
struct virtio_snd_base_configuration
{
    struct virtio_snd_rsp hdr;
    /* size in bytes of configuration data */
    __virtio32 length;
    /* configuration data */
    __u8 data[VIRTIO_SND_BASE_CFG_MAX_SIZE];
};

/*******************************************************************************
 * PCM FUNCTION DEFINITIONS
 */

/* supported PCM stream types */
enum
{
    VIRTIO_SND_PCM_T_PLAYBACK,
    VIRTIO_SND_PCM_T_CAPTURE
};

/* supported PCM stream features */
enum
{
    VIRTIO_SND_PCM_FEAT_UPDATE_FREQUENCY,
    VIRTIO_SND_PCM_FEAT_CHANNEL_MAP
};

#define VIRTIO_SND_PCM_FEATBIT(bit)     (1U << VIRTIO_SND_PCM_FEAT_ ## bit)

enum
{
    VIRTIO_SND_PCM_FEATBIT_UPDATE_FREQUENCY =
        VIRTIO_SND_PCM_FEATBIT(UPDATE_FREQUENCY),
    VIRTIO_SND_PCM_FEATBIT_CHANNEL_MAP =
        VIRTIO_SND_PCM_FEATBIT(CHANNEL_MAP)
};

/* supported PCM sample formats */
enum
{
    VIRTIO_SND_PCM_FMT_S8,
    VIRTIO_SND_PCM_FMT_U8,
    VIRTIO_SND_PCM_FMT_S16,
    VIRTIO_SND_PCM_FMT_U16,
    VIRTIO_SND_PCM_FMT_S24,
    VIRTIO_SND_PCM_FMT_U24,
    VIRTIO_SND_PCM_FMT_S32,
    VIRTIO_SND_PCM_FMT_U32,
    VIRTIO_SND_PCM_FMT_FLOAT,
    VIRTIO_SND_PCM_FMT_FLOAT64,
    VIRTIO_SND_PCM_FMT_S20,
    VIRTIO_SND_PCM_FMT_U20,
    VIRTIO_SND_PCM_FMT_S24_3,
    VIRTIO_SND_PCM_FMT_U24_3,
    VIRTIO_SND_PCM_FMT_S20_3,
    VIRTIO_SND_PCM_FMT_U20_3,
    VIRTIO_SND_PCM_FMT_S18_3,
    VIRTIO_SND_PCM_FMT_U18_3
};

#define VIRTIO_SND_PCM_FMTBIT(bit)      (1ULL << VIRTIO_SND_PCM_FMT_ ## bit)

enum
{
    VIRTIO_SND_PCM_FMTBIT_S8 = VIRTIO_SND_PCM_FMTBIT(S8),
    VIRTIO_SND_PCM_FMTBIT_U8 = VIRTIO_SND_PCM_FMTBIT(U8),
    VIRTIO_SND_PCM_FMTBIT_S16 = VIRTIO_SND_PCM_FMTBIT(S16),
    VIRTIO_SND_PCM_FMTBIT_U16 = VIRTIO_SND_PCM_FMTBIT(U16),
    VIRTIO_SND_PCM_FMTBIT_S24 = VIRTIO_SND_PCM_FMTBIT(S24),
    VIRTIO_SND_PCM_FMTBIT_U24 = VIRTIO_SND_PCM_FMTBIT(U24),
    VIRTIO_SND_PCM_FMTBIT_S32 = VIRTIO_SND_PCM_FMTBIT(S32),
    VIRTIO_SND_PCM_FMTBIT_U32 = VIRTIO_SND_PCM_FMTBIT(U32),
    VIRTIO_SND_PCM_FMTBIT_FLOAT = VIRTIO_SND_PCM_FMTBIT(FLOAT),
    VIRTIO_SND_PCM_FMTBIT_FLOAT64 = VIRTIO_SND_PCM_FMTBIT(FLOAT64),
    VIRTIO_SND_PCM_FMTBIT_S20 = VIRTIO_SND_PCM_FMTBIT(S20),
    VIRTIO_SND_PCM_FMTBIT_U20 = VIRTIO_SND_PCM_FMTBIT(U20),
    VIRTIO_SND_PCM_FMTBIT_S24_3 = VIRTIO_SND_PCM_FMTBIT(S24_3),
    VIRTIO_SND_PCM_FMTBIT_U24_3 = VIRTIO_SND_PCM_FMTBIT(U24_3),
    VIRTIO_SND_PCM_FMTBIT_S20_3 = VIRTIO_SND_PCM_FMTBIT(S20_3),
    VIRTIO_SND_PCM_FMTBIT_U20_3 = VIRTIO_SND_PCM_FMTBIT(U20_3),
    VIRTIO_SND_PCM_FMTBIT_S18_3 = VIRTIO_SND_PCM_FMTBIT(S18_3),
    VIRTIO_SND_PCM_FMTBIT_U18_3 = VIRTIO_SND_PCM_FMTBIT(U18_3)
};

/* supported PCM frame rates */
enum
{
    VIRTIO_SND_PCM_RATE_8000,
    VIRTIO_SND_PCM_RATE_11025,
    VIRTIO_SND_PCM_RATE_16000,
    VIRTIO_SND_PCM_RATE_22050,
    VIRTIO_SND_PCM_RATE_32000,
    VIRTIO_SND_PCM_RATE_44100,
    VIRTIO_SND_PCM_RATE_48000,
    VIRTIO_SND_PCM_RATE_64000,
    VIRTIO_SND_PCM_RATE_88200,
    VIRTIO_SND_PCM_RATE_96000,
    VIRTIO_SND_PCM_RATE_176400,
    VIRTIO_SND_PCM_RATE_192000
};

#define VIRTIO_SND_PCM_RATEBIT(bit)     (1U << VIRTIO_SND_PCM_RATE_ ## bit)

enum
{
    VIRTIO_SND_PCM_RATEBIT_8000 = VIRTIO_SND_PCM_RATEBIT(8000),
    VIRTIO_SND_PCM_RATEBIT_11025 = VIRTIO_SND_PCM_RATEBIT(11025),
    VIRTIO_SND_PCM_RATEBIT_16000 = VIRTIO_SND_PCM_RATEBIT(16000),
    VIRTIO_SND_PCM_RATEBIT_22050 = VIRTIO_SND_PCM_RATEBIT(22050),
    VIRTIO_SND_PCM_RATEBIT_32000 = VIRTIO_SND_PCM_RATEBIT(32000),
    VIRTIO_SND_PCM_RATEBIT_44100 = VIRTIO_SND_PCM_RATEBIT(44100),
    VIRTIO_SND_PCM_RATEBIT_48000 = VIRTIO_SND_PCM_RATEBIT(48000),
    VIRTIO_SND_PCM_RATEBIT_64000 = VIRTIO_SND_PCM_RATEBIT(64000),
    VIRTIO_SND_PCM_RATEBIT_88200 = VIRTIO_SND_PCM_RATEBIT(88200),
    VIRTIO_SND_PCM_RATEBIT_96000 = VIRTIO_SND_PCM_RATEBIT(96000),
    VIRTIO_SND_PCM_RATEBIT_176400 = VIRTIO_SND_PCM_RATEBIT(176400),
    VIRTIO_SND_PCM_RATEBIT_192000 = VIRTIO_SND_PCM_RATEBIT(192000)
};

/* PCM channel map definitions */

enum
{
    /* All channels have fixed channel positions */
    VIRTIO_SND_PCM_CHMAP_FIXED,
    /* All channels are swappable (e.g. {FL/FR/RL/RR} -> {RR/RL/FR/FL}) */
    VIRTIO_SND_PCM_CHMAP_VARIABLE,
    /* Only pair-wise channels are swappable (e.g. {FL/FR/RL/RR} -> {RL/RR/FL/FR}) */
    VIRTIO_SND_PCM_CHMAP_PAIRED
};

/* Standard channel position definition */
enum
{
    VIRTIO_SND_PCM_CH_NONE,     /* undefined */
    VIRTIO_SND_PCM_CH_NA,       /* silent */
    VIRTIO_SND_PCM_CH_MONO,     /* mono stream */
    VIRTIO_SND_PCM_CH_FL,       /* front left */
    VIRTIO_SND_PCM_CH_FR,       /* front right */
    VIRTIO_SND_PCM_CH_RL,       /* rear left */
    VIRTIO_SND_PCM_CH_RR,       /* rear right */
    VIRTIO_SND_PCM_CH_FC,       /* front center */
    VIRTIO_SND_PCM_CH_LFE,      /* low frequency (LFE) */
    VIRTIO_SND_PCM_CH_SL,       /* side left */
    VIRTIO_SND_PCM_CH_SR,       /* side right */
    VIRTIO_SND_PCM_CH_RC,       /* rear center */
    VIRTIO_SND_PCM_CH_FLC,      /* front left center */
    VIRTIO_SND_PCM_CH_FRC,      /* front right center */
    VIRTIO_SND_PCM_CH_RLC,      /* rear left center */
    VIRTIO_SND_PCM_CH_RRC,      /* rear right center */
    VIRTIO_SND_PCM_CH_FLW,      /* front left wide */
    VIRTIO_SND_PCM_CH_FRW,      /* front right wide */
    VIRTIO_SND_PCM_CH_FLH,      /* front left high */
    VIRTIO_SND_PCM_CH_FCH,      /* front center high */
    VIRTIO_SND_PCM_CH_FRH,      /* front right high */
    VIRTIO_SND_PCM_CH_TC,       /* top center */
    VIRTIO_SND_PCM_CH_TFL,      /* top front left */
    VIRTIO_SND_PCM_CH_TFR,      /* top front right */
    VIRTIO_SND_PCM_CH_TFC,      /* top front center */
    VIRTIO_SND_PCM_CH_TRL,      /* top rear left */
    VIRTIO_SND_PCM_CH_TRR,      /* top rear right */
    VIRTIO_SND_PCM_CH_TRC,      /* top rear center */
    VIRTIO_SND_PCM_CH_TFLC,     /* top front left center */
    VIRTIO_SND_PCM_CH_TFRC,     /* top front right center */
    VIRTIO_SND_PCM_CH_TSL,      /* top side left */
    VIRTIO_SND_PCM_CH_TSR,      /* top side right */
    VIRTIO_SND_PCM_CH_LLFE,     /* left LFE */
    VIRTIO_SND_PCM_CH_RLFE,     /* right LFE */
    VIRTIO_SND_PCM_CH_BC,       /* bottom center */
    VIRTIO_SND_PCM_CH_BLC,      /* bottom left center */
    VIRTIO_SND_PCM_CH_BRC       /* bottom right center */
};

/*
 * The channel is phase inverted (thus summing left and right channels would
 * result in almost silence).
 */
enum
{
    VIRTIO_SND_PCM_CH_F_PHASE_INVERSE = 0x01
};

/* PCM function descriptor */
struct virtio_snd_pcm_desc
{
    /* sizeof(struct virtio_snd_pcm_desc) */
    __u8 length;
    /* VIRTIO_SND_DESC_PCM */
    __u8 type;
    /* a PCM function ID (assigned by the device) */
    __u8 pcm_id;
    /* # of PCM stream descriptors in the configuration (one per supported PCM stream type) */
    __u8 nstreams;
};

/* PCM stream descriptor */
struct virtio_snd_pcm_stream_desc
{
    /* sizeof(struct virtio_snd_pcm_stream_desc) */
    __u8 length;
    /* VIRTIO_SND_DESC_PCM_STREAM */
    __u8 type;
    /* a PCM stream type (VIRTIO_SND_PCM_T_XXX) */
    __u8 stream_type;
    /* # of substreams for the specified stream type */
    __u8 nsubstreams;
    /* minimum # of supported channels */
    __u8 channels_min;
    /* maximum # of supported channels */
    __u8 channels_max;
    /* supported PCM stream features (VIRTIO_SND_PCM_FEATBIT_XXX, can be ORed) */
    __u8 features;
    /* # of supported channel maps */
    __u8 nchmaps;
    /* supported sample formats (VIRTIO_SND_PCM_FMTBIT_XXX, can be ORed) */
    __virtio32 formats;
    /* supported frame rates (VIRTIO_SND_PCM_RATEBIT_XXX, can be ORed) */
    __virtio32 rates;
};

/* PCM substream request header */
struct virtio_snd_pcm_hdr
{
    /* VIRTIO_SND_FN_PCM */
    __virtio16 function;
    /* a PCM request type (VIRTIO_SND_PCM_R_XXX) */
    __virtio16 request;
    /* a PCM identifier (assigned in configuration) */
    __u8 pcm_id;
    /* a PCM stream type (VIRTIO_SND_PCM_T_XXX) */
    __u8 stream_type;
    /* a PCM substream identifier [0 .. virtio_snd_pcm_stream_desc::nsubstreams - 1] */
    __u8 substream_id;
    __u8 padding;
};

/* get/set PCM substream feature */
struct virtio_snd_pcm_feature
{
    /* VIRTIO_SND_FN_PCM */
    __virtio16 function;
    /* VIRTIO_SND_PCM_R_GET_FEATURE / VIRTIO_SND_PCM_R_SET_FEATURE */
    __virtio16 request;
    /* a PCM identifier (assigned in configuration) */
    __u8 pcm_id;
    /* a PCM stream type (VIRTIO_SND_PCM_T_XXX) */
    __u8 stream_type;
    /* a PCM substream identifier [0 .. virtio_snd_pcm_stream_desc::nsubstreams - 1] */
    __u8 substream_id;
    /* a selected PCM substream feature (VIRTIO_SND_PCM_FEAT_XXX) */
    __u8 feature;
    /* a feature-specific request data */
    /*
     * VIRTIO_SND_PCM_FEAT_UPDATE_FREQUENCY [SET-only]
     *   .data = an approximate update frequency in bytes
     * VIRTIO_SND_PCM_FEAT_CHANNEL_MAP [GET/SET]
     *   GET:
     *     .data = a channel map index [0 .. virtio_snd_pcm_stream_desc::nchmaps - 1]
     *   SET:
     *     .data = a pseudophysical start address of the virtio_snd_pcm_chmap_data structure
     */
    __virtio64 data;
};

#define VIRTIO_SND_PCM_CH_MAX           256

/* PCM channel information */
struct virtio_snd_pcm_chinfo
{
    /* a PCM channel position (VIRTIO_SND_PCM_CH_XXX) */
    __u8 position;
    /* a PCM channel flags (VIRTIO_SND_PCM_CH_F_XXX, can be ORed) */
    __u8 flags;
};

/* PCM channel map data */
struct virtio_snd_pcm_chmap_data
{
    /* # of valid entries in the PCM channel map */
    __virtio32 nchannels;
    /* a PCM channel map */
    struct virtio_snd_pcm_chinfo channel_map[VIRTIO_SND_PCM_CH_MAX];
};

/* a response containing PCM channel map */
struct virtio_snd_pcm_chmap
{
    struct virtio_snd_rsp hdr;
    /* a channel map type (VIRTIO_SND_PCM_CHMAP_XXX) */
    __u8 type;
    /* reserved, must be zero */
    __u8 reserved[3];
    /* a channel map data */
    struct virtio_snd_pcm_chmap_data data;
};

/* assign data queue for PCM substream */
struct virtio_snd_pcm_set_queue
{
    /* .request = VIRTIO_SND_PCM_R_SET_QUEUE */
    struct virtio_snd_pcm_hdr hdr;
    /* a virtual queue index */
    __virtio32 queue;
};

/* set PCM substream format */
struct virtio_snd_pcm_set_format
{
    /* .request = VIRTIO_SND_PCM_R_SET_FORMAT */
    struct virtio_snd_pcm_hdr hdr;
    /* # of channels */
    __virtio16 channels;
    /* a PCM sample format (VIRTIO_SND_PCM_FMT_XXX) */
    __virtio16 format;
    /* a PCM frame rate (VIRTIO_SND_PCM_RATE_XXX) */
    __virtio16 rate;
    __u16 padding;
};

#endif /* VIRTIO_SND_IF_H */

[-- Attachment #3: Type: text/plain, Size: 208 bytes --]


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-15  6:30                               ` Anton Yakovlev
  2019-05-15  8:31                                 ` Anton Yakovlev
@ 2019-05-15 16:03                                 ` Stefan Hajnoczi
  2019-05-15 16:33                                   ` Anton Yakovlev
  1 sibling, 1 reply; 29+ messages in thread
From: Stefan Hajnoczi @ 2019-05-15 16:03 UTC (permalink / raw)
  To: Anton Yakovlev
  Cc: Gerd Hoffmann, Mikhail Golubev, Marco Martinelli - 13Byte srl,
	virtio-dev, Kővágó Zoltán

[-- Attachment #1: Type: text/plain, Size: 1977 bytes --]

On Wed, May 15, 2019 at 06:30:45AM +0000, Anton Yakovlev wrote:
> >> So, our proposal is to support classic way of communications by default and introduce shared memory based approach as either non-standard extension or part of future VIRTIO device types. And switch to this mode where it's possible or make sense. Like, all modern type-2 hypervisors usually have no problems with sharing memory between guest and host, so why not provide to user high quality virtual audio device?
> >
> > virtqueues offer reliable delivery, so #2 isn't an issue.
> >
> > Real-time is achievable and can be done with low latency.  Make the
> > receiver a real-time thread that polls the vring periodically (based on
> > the latency/buffer size requirement).  The vring supports lock-free
> > access so this is perfect for real-time.
> >
> > When I say "receiver" I mean the driver's capture and device's playback
> > components.  Both of them have real-time requirements.
> >
> > Does this approach meet your requirements?
> 
> After careful consideration, I think polling mode should make it possible. Like, using dedicated "data" queue per stream in polling mode (multiplexing is not an option, since it reduces queue throughput in proportion to the number of multiplexed streams). How to describe it in specification?

Polling is an implementation detail for both drivers and devices.
Therefore it's not described explicitly in the specification.

By the way, virtqueue buffers can be completed out-of-order by the
device.  This means sharing a virtqueue between multiple streams does
not necessarily introduce any kind of waiting.

The only issue is the virtqueue size (e.g. 128 buffers) determines how
many buffers can be made available from the driver to the device at any
given time.  Some device implementations uses virtqueue sizes like 1024
so that this does not become a practical concern.  Does this change your
view on multiplexing streams?

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-15 16:03                                 ` Stefan Hajnoczi
@ 2019-05-15 16:33                                   ` Anton Yakovlev
  2019-05-16 10:24                                     ` Stefan Hajnoczi
  0 siblings, 1 reply; 29+ messages in thread
From: Anton Yakovlev @ 2019-05-15 16:33 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Gerd Hoffmann, Mikhail Golubev, Marco Martinelli - 13Byte srl,
	virtio-dev, Kővágó Zoltán


>> After careful consideration, I think polling mode should make it possible. Like, using dedicated "data" queue per stream in polling mode (multiplexing is not an option, since it reduces queue throughput in proportion to the number of multiplexed streams). How to describe it in specification?
>
> Polling is an implementation detail for both drivers and devices.
> Therefore it's not described explicitly in the specification.

And the only source of information in such case is to take a look into already existed implementations?


> By the way, virtqueue buffers can be completed out-of-order by the
> device.  This means sharing a virtqueue between multiple streams does
> not necessarily introduce any kind of waiting.
>
> The only issue is the virtqueue size (e.g. 128 buffers) determines how
> many buffers can be made available from the driver to the device at any
> given time.  Some device implementations uses virtqueue sizes like 1024
> so that this does not become a practical concern.  Does this change your
> view on multiplexing streams?

Personally, I'm not a big fan of, because:

1. It makes overall logic more complex: you need to serialize access to the queue on driver side and dispatch messages (find out recepient, serialize access etc) on device side. With separated queues you have only one producer and consumer, and they both knows ahead how to handle buffers.
2. It requires to define message header for buffer transfers. With separated queues you just put into descriptors a pointer to the buffer and its length.

The simpler the better. And with multiplexing basically you have no pros except having one queue. Why separated queues are undesirable?


--
Anton Yakovlev
Senior Software Engineer

OpenSynergy GmbH
Rotherstr. 20, 10245 Berlin

www.opensynergy.com

Please mind our privacy notice<https://www.opensynergy.com/datenschutzerklaerung/privacy-notice-for-business-partners-pursuant-to-article-13-of-the-general-data-protection-regulation-gdpr/> pursuant to Art. 13 GDPR. // Unsere Hinweise zum Datenschutz gem. Art. 13 DSGVO finden Sie hier.<https://www.opensynergy.com/de/datenschutzerklaerung/datenschutzhinweise-fuer-geschaeftspartner-gem-art-13-dsgvo/>
COQOS Hypervisor certified by TÜV SÜD
                [COQOS Hypervisor certified by TÜV SÜD]

---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [virtio-dev] Request for a new device number for a virtio-audio device.
  2019-05-15 16:33                                   ` Anton Yakovlev
@ 2019-05-16 10:24                                     ` Stefan Hajnoczi
  0 siblings, 0 replies; 29+ messages in thread
From: Stefan Hajnoczi @ 2019-05-16 10:24 UTC (permalink / raw)
  To: Anton Yakovlev
  Cc: Gerd Hoffmann, Mikhail Golubev, Marco Martinelli - 13Byte srl,
	virtio-dev, Kővágó Zoltán

[-- Attachment #1: Type: text/plain, Size: 3437 bytes --]

On Wed, May 15, 2019 at 04:33:23PM +0000, Anton Yakovlev wrote:
> 
> >> After careful consideration, I think polling mode should make it possible. Like, using dedicated "data" queue per stream in polling mode (multiplexing is not an option, since it reduces queue throughput in proportion to the number of multiplexed streams). How to describe it in specification?
> >
> > Polling is an implementation detail for both drivers and devices.
> > Therefore it's not described explicitly in the specification.
> 
> And the only source of information in such case is to take a look into already existed implementations?

Yes.  The spec focusses on the hardware interface and the semantics but
not on how to implement it.

> > By the way, virtqueue buffers can be completed out-of-order by the
> > device.  This means sharing a virtqueue between multiple streams does
> > not necessarily introduce any kind of waiting.
> >
> > The only issue is the virtqueue size (e.g. 128 buffers) determines how
> > many buffers can be made available from the driver to the device at any
> > given time.  Some device implementations uses virtqueue sizes like 1024
> > so that this does not become a practical concern.  Does this change your
> > view on multiplexing streams?
> 
> Personally, I'm not a big fan of, because:
> 
> 1. It makes overall logic more complex: you need to serialize access to the queue on driver side and dispatch messages (find out recepient, serialize access etc) on device side. With separated queues you have only one producer and consumer, and they both knows ahead how to handle buffers.
> 2. It requires to define message header for buffer transfers. With separated queues you just put into descriptors a pointer to the buffer and its length.
> 
> The simpler the better. And with multiplexing basically you have no pros except having one queue. Why separated queues are undesirable?

I'm not sure which approach is best either.  In the real-time audio
programming I've done there was a function like this:

  process(const float **in_frames, int in_channels,
          float **out_frames, int out_channels,
	  int nframes);

This function processes audio frames periodically and is a callback from
the real-time audio API.

If the device multiplexes streams on a single virtqueue and uses the
batched request layout that I previously described, then the driver
implementation is very simple.  There is no need to bring together audio
data supplied through multiple virtqueues because it all comes in a
single buffer on a single virtqueue.  You mentioned that separate queues
avoid synchronization but in this case it seems to actually introduce a
synchronization requirement.

Having a single virtqueue where all audio data flows between the
process() function and the device is simple and minimizes per-virtqueue
overhead.  In an interrupt-driven implementation there are per-virtqueue
virtio-pci Queue Notify register writes and per-virtqueue interrupt
handlers, so this can generate a lot of vmexits and interrupts compared
to the multiplexed batched approach.

If your application processes audio streams in different threads and
without inter-stream synchronization, then I agree that multiple
virtqueues is the way to go.

I don't have a strong opinion on the optimal approach, just wanted to
explain why I had this idea.  Please choose as you wish.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2019-05-16 10:24 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-28 22:22 [virtio-dev] Request for a new device number for a virtio-audio device Marco Martinelli - 13Byte srl
2019-04-29 13:47 ` Stefan Hajnoczi
2019-04-29 17:39   ` Marco Martinelli - 13Byte srl
2019-04-30 12:55     ` Michael S. Tsirkin
2019-04-30 13:56       ` Marco Martinelli - 13Byte srl
2019-04-30 14:00         ` Michael S. Tsirkin
2019-05-01 17:05     ` Stefan Hajnoczi
2019-05-02 11:18       ` Marco Martinelli - 13Byte srl
2019-05-03 16:45         ` Stefan Hajnoczi
2019-05-03 19:52           ` Marco Martinelli - 13Byte srl
2019-05-06  5:27             ` Gerd Hoffmann
2019-05-09 10:10               ` Marco Martinelli - 13Byte srl
2019-05-09 12:27                 ` Gerd Hoffmann
2019-05-10  9:45                   ` Mikhail Golubev
2019-05-10 12:16                     ` Gerd Hoffmann
2019-05-10 14:15                       ` Anton Yakovlev
2019-05-10 15:48                         ` Stefan Hajnoczi
2019-05-10 17:13                           ` Anton Yakovlev
2019-05-11 20:49                             ` Marco Martinelli - 13Byte srl
2019-05-12 20:01                               ` Matti Moell
2019-05-14 13:44                             ` Stefan Hajnoczi
2019-05-15  6:30                               ` Anton Yakovlev
2019-05-15  8:31                                 ` Anton Yakovlev
2019-05-15 16:03                                 ` Stefan Hajnoczi
2019-05-15 16:33                                   ` Anton Yakovlev
2019-05-16 10:24                                     ` Stefan Hajnoczi
2019-05-13  9:32                         ` Gerd Hoffmann
2019-05-14 19:14                           ` Anton Yakovlev
2019-05-10 10:34                   ` Stefan Hajnoczi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.