Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement VirtIO sound device #53

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Cuda-Chen
Copy link
Contributor

@Cuda-Chen Cuda-Chen commented Aug 31, 2024

Implement VirtIO sound device supporting these operations (the item with checked box checked means it is implemented right now):

  • For setting up the device:
    • VIRTIO_SND_R_JACK_INFO
    • VIRTIO_SND_R_PCM_INFO
    • VIRTIO_SND_R_CHMAP_INFO
  • For playing the sound (PCM):
    • VIRTIO_SND_R_PCM_SET_PARAMS
    • VIRTIO_SND_R_PCM_PREPARE
    • VIRTIO_SND_R_PCM_RELEASE
    • VIRTIO_SND_R_PCM_START
    • VIRTIO_SND_R_PCM_STOP

Test Cases

The test cases are subjected to be altered.

boot up test

test procedures

  1. Execute make check to run semu.
  2. Check kernel message (dmesg).

expected results

  1. The following message should appear while booting up:
[    4.011962] ALSA device list:
[    4.015962]   #0: Loopback 1
[    4.015962]   #1: VirtIO SoundCard at platform/f4400000.virtio/virtio2

check driver configuration

test procedures

  1. Execute aplay -l in emulator.
  2. Check the output messages.

expected results

  1. The following message should appear after Step 1:
$ aplay -l          
**** List of PLAYBACK Hardware Devices ****

<other sound device here>

card 1: SoundCard [VirtIO SoundCard], device 0: virtio-snd [VirtIO PCM 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

play sound

test procedures

  1. Execute speaker-test in emulator.
  2. Check the host speaker.

expected results

  1. A white noise will be played by host speaker while speaker-test is executing.

play sequence sound

test procedures

  1. Execute aplay /usr/share/sounds/alsa/Front_Center.wav in emulator.
  2. Check the host speaker.

expected results

  1. A female sound with "Front Center" speaking should be played.

@shengwen-tw
Copy link
Collaborator

Please provide testing procedures once the change is ready.

CNFA_sf.h Outdated Show resolved Hide resolved
virtio-snd.c Outdated Show resolved Hide resolved
configs/linux.config Outdated Show resolved Hide resolved
configs/linux.config Outdated Show resolved Hide resolved
os_generic.h Outdated Show resolved Hide resolved
@Cuda-Chen Cuda-Chen force-pushed the add-virtio-snd branch 3 times, most recently from 2b1009d to be7ad90 Compare September 1, 2024 13:24
Makefile Outdated Show resolved Hide resolved
configs/linux.config Outdated Show resolved Hide resolved
virtio-snd.c Outdated Show resolved Hide resolved
virtio-snd.c Outdated Show resolved Hide resolved
Copy link
Collaborator

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Run clang-format before submitting.

.gitmodules Outdated Show resolved Hide resolved
Makefile Outdated Show resolved Hide resolved
Makefile Outdated Show resolved Hide resolved
Copy link
Collaborator

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consult https://github.com/cntools/cnfa/blob/master/.github/workflows/build-cnfa.yml and mention the build dependency in top-level README.md.

configs/linux.config Outdated Show resolved Hide resolved
feature.h Outdated Show resolved Hide resolved
@Cuda-Chen Cuda-Chen force-pushed the add-virtio-snd branch 2 times, most recently from a67216b to 1fc471c Compare September 3, 2024 09:02
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
configs/linux.config Outdated Show resolved Hide resolved
@Cuda-Chen Cuda-Chen force-pushed the add-virtio-snd branch 2 times, most recently from 862cb51 to da29ce5 Compare September 3, 2024 12:05
@Cuda-Chen Cuda-Chen force-pushed the add-virtio-snd branch 2 times, most recently from 2830a0f to 5251ec6 Compare November 8, 2024 04:21
virtio-snd.c Outdated Show resolved Hide resolved
@Cuda-Chen Cuda-Chen force-pushed the add-virtio-snd branch 3 times, most recently from a7a8782 to ecb2614 Compare December 3, 2024 10:12
@Cuda-Chen Cuda-Chen force-pushed the add-virtio-snd branch 2 times, most recently from 58ecbaa to 3e42d75 Compare December 12, 2024 07:24
uint32_t Status;
uint32_t InterruptStatus;
/* supplied by environment */
uint32_t *ram;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure ram is proper here. Should it be mem?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just copy-and-paste from virtio-net.c. Maybe we can make a difference in this commit?

Copy link
Collaborator

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the content of queue.h to utils.h as rv32emu does. Then, enforce the Linux-like naming scheme.

virtio-snd.c Outdated Show resolved Hide resolved
virtio-snd.c Outdated Show resolved Hide resolved
Comment on lines +346 to +365
uint32_t *ram = vsnd->ram;
void *priv = vsnd->priv;
uint32_t jacks = PRIV(vsnd)->jacks;
uint32_t streams = PRIV(vsnd)->streams;
uint32_t chmaps = PRIV(vsnd)->chmaps;
uint32_t controls = PRIV(vsnd)->controls;
memset(vsnd, 0, sizeof(*vsnd));
vsnd->ram = ram;
vsnd->priv = priv;
PRIV(vsnd)->jacks = jacks;
PRIV(vsnd)->streams = streams;
PRIV(vsnd)->chmaps = chmaps;
PRIV(vsnd)->controls = controls;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use memcpy instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jserv , it seems that copying certain members of a struct using dst->foo = src->foo will be the sane way according this StackOverflow answer.

}

/* Control the callback to prepare the buffer */
/* TODO: add lock to avoid race condition */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may consolidate the testing for producer-consumer implementation in advance.

@jserv

This comment was marked as resolved.

jserv

This comment was marked as resolved.

@Cuda-Chen Cuda-Chen force-pushed the add-virtio-snd branch 2 times, most recently from 2e9b605 to 5b3011e Compare December 17, 2024 11:07
queue.h Outdated Show resolved Hide resolved
void semu_timer_rebase(semu_timer_t *timer, uint64_t time);

/* Linux-like queue API */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's enforce the Linux kernel style naming scheme.

virtio-snd.c Outdated
memcpy(props->ring.buffer + idx, payload, size - idx);
memcpy(props->ring.buffer, payload, n - (size - idx));
}
asm("" ::: "memory");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I create a compiler barrier to make sure the data has to been written to ring buffer thus prevent race condition (see the DPDK counterpart).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is necessary, I will suggest wrapping it with macro for readability.

@jserv
Copy link
Collaborator

jserv commented Dec 18, 2024

  • For playing the sound (PCM):
    • VIRTIO_SND_R_PCM_START
    • VIRTIO_SND_R_PCM_STOP

I can build on macOS with CoreAudio support now. What is missing to complete PCM functionality?

@Cuda-Chen
Copy link
Contributor Author

Cuda-Chen commented Dec 18, 2024

  • For playing the sound (PCM):

    • VIRTIO_SND_R_PCM_START
    • VIRTIO_SND_R_PCM_STOP

I can build on macOS with CoreAudio support now. What is missing to complete PCM functionality?

Hi @jserv , I list the messing parts for completing PCM functionality:

  1. Clean the allocated resources after issuing VIRTIO_SND_R_PCM_RELEASE: on my Linux testing machine, because of PulseAudio, the guest OS hangs when closing the created ALSA device. However, we can't create ALSA device after disabling PulseAudio.
    • Edit: The checked list of VIRTIO_SND_R_PCM_RELEASE is wrong, I am still finding solutions of co-working with PulseAudio.
  2. No sound after VIRTIO_SND_R_PCM_START: I do not hear any sound after issuing VIRTIO_SND_R_PCM_START state on my Linux testing machine.

For testing, I come up with the following two methods and the corresponding expected results:

  1. speaker-test
    • expected result: a white noise should be played.
  2. aplay <any audio file>
    • expected results: the audio should be played without any artifacts (e.g., distortion, lagging, etc.).

@Cuda-Chen Cuda-Chen force-pushed the add-virtio-snd branch 2 times, most recently from 80b61e7 to 56a79dd Compare December 21, 2024 05:12
Enable ALSA driver and System V IPC in Linux Kernel. For
ALSA, the debug is enabled and will be removed once
this commit is ready.

Add description of descriptor chaining, yet need refactoring
the description as well as code (exists uncertainty of
the query struct).

Succeed to initialize virtio-snd.

Handle requests in control and TX queue, and print the address and length
of each virtq element to check the validness of self-implement
queue.

For macOS, an experimental core audio library check is implemented.

As the driver sends the PCM frames asynchronously, use a dedicated
thread for receiving frames from driver.

The reason that pcm_release state hangs is because of PulseAudio,
need to address this later.

Add ring buffer struct so that we don't need to allocate
space frequently.

Can play guest sound. However, the sound only plays a fraction
of the beginning.
@jserv
Copy link
Collaborator

jserv commented Dec 27, 2024

Is it time to review?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants