Hey everyone!
I wrote code for PCM streams, which I'd like to discuss here. But since it
isn't
really complete yet, I thought I'd ask if I can copy paste the functions
that I want to ask
about and clear things that way.

For now I will just write my queries here and try to explain them as best
as I can.

Starting off with the get config function for pcm streams. Initially I
thought I
was supposed to store those configs in the VirtIOSound struct but then I
realized
these configurations should be queried from the backend and then be
presented to the driver/guest.

Now, the virtio sound card supports multiple formats and bit rates. If we
have fixed settings
turned on in the audiodev, the virtio sound card should support only a
single freq and frame rate
depending upon what was passed to the command line which we can get from
audio_get_pdo_out.
Is this correct?

Secondly if fixed settings was not set, what should the get config query
return with for supported
formats and bitrates? For now I am returning the formats defined in the
enum for the qemu
audio subsystem. I read in the man pages that if the mixing engine is off,
qemu assumes that
the backend supports the the multiple streams and channels that are
supported by the
virtual card. So should I return everything that the virito sound card can
support?

Thirdly, for the set params function, how do I change the params for an
SWVoiceOut stream? I could
not find a function for changing the audsettings for a stream. Should I
close the stream and
reopen it? Should I directly change the values in the pcm info struct
inside the stream?

I learned that the callback passed in AUD_open_out, (lets call it the write
audio callback,)  is supposed to mix and write the
buffers to HWVoiceOut. I have written that, the basic algorithm being:

1. Pop element from tx virtqueue.
2. Get the xfer header from the elem->out_sg (iov_to_buf(elem->out_sg, 1,
0, &hdr, sizeof(hdr)))
3. Get the buffer from elem->out_sg (iov_to_buf(elem->out_sg, 1,
sizeof(hdr), &mixbuf, period_bytes))
4. AUD_write the buffer
5. Initialize an VIRTIO_SND_S_OK response.
6. Write the response to elem->in_sg (iov_from_buf(elem->in_sg,
elem->in_num, 0, &resp, sizeof(resp)))
7. If tx queue is not empty go back to step 1.

I think I can send a period elapsed notification too after reading
period_bytes from the tx_virtqueue.

Will this be enough? From other sound card implementations I found out
about a lot of pointers which
I think were read and write pointers for the buffer. But since we are doing
this via a virtqueue, I don't
feel as if those pointers will be necessary.

Also I do not understand what the tx virtqueue handler is supposed to do. I
have written a handler
for the control queue. But I don't know what to do about the tx queue for
now. I thought it would be
something similar to what the callback does, it wouldn't play the audio
though.

Also since the callback does so many things, I do not understand how I can
implement the
pcm stream prepare, start, stop and release functions. The prepare function
is supposed to
allocate resources for the stream, but we already do that in the realize_fn
for the device
(AUD_open_out). So should I move that part out of the realize function and
into the prepare
stream function? I can then have the write audio callback called in the
start stream function.
The release function would just g_free the stream. This version would have
set_params store
the params of the streams in the device itself, or in a new device state
structure. Then when
prepare is called for a stream, we use the stored audsettings for
AUD_open_out. The start
function would simply call the virtio_snd_callback and write the audio
using AUD_write. I still
do not know what I would have to write in the stop stream function.

Another thing that I wanted to ask was about the hda codec. The
specification mentions that
the virtio sound card has a single codec device in it. I saw a lot of codec
device related code
in hda-codec.c which I think can be re-used for this. But there were no
headers that exposed
the code elsewhere. After reading through the hda specification I realized
that these function
group nids all come under the codec, so the jacks will be pin widgets
attached to this codec.
And the streams will be the streams associated with this codec. But I do
not understand how
I should go about implementing the codec, or if I need to implement it
considering the
already existing source from intel-hda and hda-codec.c.

Also sorry for the late response, I had fallen ill. Also I had to move
thrice in the past
month, so I couldn't really work on this a lot, and I didn't want to write
a mail without
having any work to show to you guys. Thanks a lot for being patient with
me. :)

Regards,
Shreyansh

Reply via email to