Skip to content

Commit

Permalink
Merge pull request #137 from muxinyu1/master
Browse files Browse the repository at this point in the history
Added sound driver based on virtio v1.2.
  • Loading branch information
qwandor authored Jul 29, 2024
2 parents 1a9e99d + 881f902 commit a86f69c
Show file tree
Hide file tree
Showing 15 changed files with 2,152 additions and 30 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
args: --all-features

examples:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
Expand All @@ -77,4 +77,4 @@ jobs:
run: make kernel
- name: Run
working-directory: examples/${{ matrix.example }}
run: QEMU_ARGS="-display none" make qemu accel="off"
run: QEMU_ARGS="-display none -audiodev none,id=audio0" make qemu accel="off"
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ categories = ["hardware-support", "no-std"]
[dependencies]
log = "0.4"
bitflags = "2.3.0"
enumn = "0.1.13"
zerocopy = { version = "0.7.5", features = ["derive"] }

[features]
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ VirtIO guest drivers in Rust. For **no_std** environment.
| Input ||
| Console ||
| Socket ||
| Sound ||
| ... ||

### Transports
Expand Down
9 changes: 6 additions & 3 deletions examples/riscv/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ qemu-legacy: kernel $(img)
-device virtio-gpu-device \
-device virtio-mouse-device \
-device virtio-net-device,netdev=net0 \
-netdev user,id=net0,hostfwd=tcp::5555-:5555
-netdev user,id=net0,hostfwd=tcp::5555-:5555\
-device virtio-sound-device,audiodev=audio0 \
-audiodev alsa,id=audio0

qemu: kernel $(img)
# Wait a few seconds, then try to open a connection to the VM so it can test its networking.
Expand All @@ -75,8 +77,9 @@ qemu: kernel $(img)
-device virtio-gpu-device \
-device virtio-mouse-device \
-device virtio-net-device,netdev=net0 \
-netdev user,id=net0,hostfwd=tcp::5555-:5555

-netdev user,id=net0,hostfwd=tcp::5555-:5555\
-device virtio-sound-device,audiodev=audio0 \
-audiodev alsa,id=audio0

$(img):
dd if=/dev/zero of=$@ bs=512 count=32
Expand Down
1 change: 1 addition & 0 deletions examples/riscv/music_44100Hz_u8_stereo.raw

Large diffs are not rendered by default.

66 changes: 65 additions & 1 deletion examples/riscv/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ use core::ptr::NonNull;
use fdt::{node::FdtNode, standard_nodes::Compatible, Fdt};
use log::LevelFilter;
use virtio_drivers::{
device::{blk::VirtIOBlk, gpu::VirtIOGpu, input::VirtIOInput},
device::{
blk::VirtIOBlk,
gpu::VirtIOGpu,
input::VirtIOInput,
sound::{PcmFormat, PcmRate, VirtIOSound},
},
transport::{
mmio::{MmioTransport, VirtIOHeader},
DeviceType, Transport,
Expand Down Expand Up @@ -85,6 +90,7 @@ fn virtio_device(transport: impl Transport) {
DeviceType::GPU => virtio_gpu(transport),
DeviceType::Input => virtio_input(transport),
DeviceType::Network => virtio_net(transport),
DeviceType::Sound => virtio_sound(transport),
t => warn!("Unrecognized virtio device: {:?}", t),
}
}
Expand Down Expand Up @@ -175,3 +181,61 @@ fn virtio_net<T: Transport>(transport: T) {
tcp::test_echo_server(net);
}
}

fn virtio_sound<T: Transport>(transport: T) {
let mut sound =
VirtIOSound::<HalImpl, T>::new(transport).expect("failed to create sound driver");
let output_streams = sound.output_streams().unwrap();
if output_streams.len() > 0 {
let output_stream_id = *output_streams.first().unwrap();
let rates = sound.rates_supported(output_stream_id).unwrap();
let formats = sound.formats_supported(output_stream_id).unwrap();
let channel_range = sound.channel_range_supported(output_stream_id).unwrap();
let features = sound.features_supported(output_stream_id).unwrap();

let rate = if rates.contains(PcmRate::Rate44100.into()) {
PcmRate::Rate44100
} else {
PcmRate::Rate32000
};
let format = if formats.contains(PcmFormat::U8.into()) {
PcmFormat::U8
} else {
PcmFormat::U32
};
let channel = if channel_range.contains(&2) {
2 as u8
} else {
*channel_range.start()
};
sound
.pcm_set_params(
output_stream_id,
4410 * 2,
4410,
features,
channel,
format,
rate,
)
.expect("pcm_set_params error");
sound
.pcm_prepare(output_stream_id)
.expect("pcm_prepare error");
sound.pcm_start(output_stream_id).expect("pcm_start error");
let music = include_bytes!("../music_44100Hz_u8_stereo.raw");
info!("[sound device] music len is {} bytes.", music.len());
// xfer buffer
sound
.pcm_xfer(output_stream_id, &music[..])
.expect("pcm_xfer error");
sound.pcm_stop(output_stream_id).expect("pcm_stop error");
sound
.pcm_release(output_stream_id)
.expect("pcm_release error");
match sound.latest_notification() {
Ok(notification) => info!("{:?}", notification),
Err(e) => warn!("{}", e),
}
}
}
16 changes: 8 additions & 8 deletions src/device/blk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ mod tests {
State::wait_until_queue_notified(&state, QUEUE);
println!("Transmit queue was notified.");

state
assert!(state
.lock()
.unwrap()
.read_write_queue::<{ QUEUE_SIZE as usize }>(QUEUE, |request| {
Expand All @@ -656,7 +656,7 @@ mod tests {
);

response
});
}));
});

// Read a block from the device.
Expand Down Expand Up @@ -702,7 +702,7 @@ mod tests {
State::wait_until_queue_notified(&state, QUEUE);
println!("Transmit queue was notified.");

state
assert!(state
.lock()
.unwrap()
.read_write_queue::<{ QUEUE_SIZE as usize }>(QUEUE, |request| {
Expand All @@ -728,7 +728,7 @@ mod tests {
);

response
});
}));
});

// Write a block to the device.
Expand Down Expand Up @@ -777,7 +777,7 @@ mod tests {
State::wait_until_queue_notified(&state, QUEUE);
println!("Transmit queue was notified.");

state
assert!(state
.lock()
.unwrap()
.read_write_queue::<{ QUEUE_SIZE as usize }>(QUEUE, |request| {
Expand All @@ -800,7 +800,7 @@ mod tests {
);

response
});
}));
});

// Request to flush.
Expand Down Expand Up @@ -844,7 +844,7 @@ mod tests {
State::wait_until_queue_notified(&state, QUEUE);
println!("Transmit queue was notified.");

state
assert!(state
.lock()
.unwrap()
.read_write_queue::<{ QUEUE_SIZE as usize }>(QUEUE, |request| {
Expand All @@ -868,7 +868,7 @@ mod tests {
);

response
});
}));
});

let mut id = [0; 20];
Expand Down
2 changes: 2 additions & 0 deletions src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ pub mod input;
pub mod net;

pub mod socket;
#[cfg(feature = "alloc")]
pub mod sound;

pub(crate) mod common;
Loading

0 comments on commit a86f69c

Please sign in to comment.