diff --git a/Cargo.lock b/Cargo.lock index 016c3f08..65f1975a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -205,12 +205,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "paste" @@ -218,12 +215,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "ppv-lite86" version = "0.2.20" diff --git a/cykusz-rs/src/drivers/acpi/pci_map.rs b/cykusz-rs/src/drivers/acpi/pci_map.rs index 46ee37c6..3be303bd 100644 --- a/cykusz-rs/src/drivers/acpi/pci_map.rs +++ b/cykusz-rs/src/drivers/acpi/pci_map.rs @@ -15,10 +15,7 @@ fn call_pic1() { Type: ACPI_TYPE_INTEGER as i32, }; - #[allow(unused_unsafe)] - unsafe { - arg.Integer.Value = 1; - } + unsafe { arg.Integer }.Value = 1; let mut arg_list = ACPI_OBJECT_LIST { Count: 1, @@ -63,9 +60,14 @@ unsafe extern "C" fn get_irq_resource( tbl.Address as u64 >> 16, tbl.Pin as u8, *res.Data - .Irq.as_ref() - .Interrupts.Interrupts.as_ref() - .Interrupts.as_ptr().offset(tbl.SourceIndex as u8 as isize) as u32 + .Irq + .as_ref() + .Interrupts + .Interrupts + .as_ref() + .Interrupts + .as_ptr() + .offset(tbl.SourceIndex as u8 as isize) as u32, ); } ACPI_RESOURCE_TYPE_EXTENDED_IRQ => { diff --git a/userspace/playaudio/src/lib.rs b/userspace/playaudio/src/lib.rs index 5c79ae1f..7f2dcb4c 100644 --- a/userspace/playaudio/src/lib.rs +++ b/userspace/playaudio/src/lib.rs @@ -18,4 +18,4 @@ pub fn play(buf: &[u8]) -> Result<(), ExitCode> { println!("write finished"); Ok(()) -} \ No newline at end of file +} diff --git a/userspace/playaudio/src/playmidi/bin/main.rs b/userspace/playaudio/src/playmidi/bin/main.rs index 37dfb61c..557e6810 100644 --- a/userspace/playaudio/src/playmidi/bin/main.rs +++ b/userspace/playaudio/src/playmidi/bin/main.rs @@ -1,9 +1,56 @@ use rustysynth::{MidiFile, MidiFileSequencer, SoundFont, Synthesizer, SynthesizerSettings}; use std::fs::File; +use std::io::Read; +use std::os::fd::AsRawFd; +use std::path::Path; use std::process::ExitCode; use std::sync::Arc; +use syscall_defs::{MMapFlags, MMapProt}; use wavers::Samples; +#[allow(dead_code)] +struct MMapFileReader<'a> { + buffer: &'a [u8], + pos: usize, +} + +#[allow(dead_code)] +impl MMapFileReader<'_> { + fn open>(path: P) -> std::io::Result { + let file = File::open(path)?; + + let size = file.metadata()?.len() as usize; + + println!("size: {size}"); + + let mmap = syscall_user::mmap( + None, + size, + MMapProt::PROT_READ, + MMapFlags::MAP_PRIVATE, + Some(file.as_raw_fd() as usize), + 0, + ) + .map_err(|_| std::io::Error::from(std::io::ErrorKind::Other))?; + + let buffer = unsafe { std::slice::from_raw_parts(mmap as *const u8, size) }; + + Ok(MMapFileReader::<'_> { + buffer, + pos: 0, + }) + } +} + +impl<'a> Read for MMapFileReader<'a> { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let to_read = std::cmp::min(buf.len(), self.buffer.len() - self.pos); + buf[..to_read].copy_from_slice(&self.buffer[self.pos..self.pos + to_read]); + self.pos += to_read; + Ok(to_read) + } +} + fn main() -> Result<(), ExitCode> { let mut args = std::env::args(); @@ -18,7 +65,7 @@ fn main() -> Result<(), ExitCode> { println!("soundfont: {soundfont_path}, midi: {midi_path}"); - let mut sf2 = File::open(soundfont_path).unwrap(); + let mut sf2 = File::open(soundfont_path).map_err(|_| ExitCode::FAILURE)?; let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap()); println!("Creating sequencer..."); diff --git a/userspace/playaudio/src/playwav/bin/main.rs b/userspace/playaudio/src/playwav/bin/main.rs index 5eb922a9..8814b9e0 100644 --- a/userspace/playaudio/src/playwav/bin/main.rs +++ b/userspace/playaudio/src/playwav/bin/main.rs @@ -21,7 +21,12 @@ fn send_to_daemon(song: &str) -> Result<(), ExitCode> { ) .map_err(|_e| ExitCode::from(1))?; - let buf = unsafe { &*slice_from_raw_parts(wav_map as *const u8, wav_size) }; + let data_size = unsafe { + ((wav_map + 40) as *const u32).read() + }; + + // +44 to skip headers + let buf = unsafe { &*slice_from_raw_parts((wav_map + 44) as *const u8, data_size as usize) }; playaudio::play(buf)?; diff --git a/userspace/sound-daemon/src/sound-daemon/bin/main.rs b/userspace/sound-daemon/src/sound-daemon/bin/main.rs index 8105c3f4..7ba3c42d 100644 --- a/userspace/sound-daemon/src/sound-daemon/bin/main.rs +++ b/userspace/sound-daemon/src/sound-daemon/bin/main.rs @@ -1,5 +1,6 @@ use std::collections::{HashMap, LinkedList}; use std::io::Read; +use std::ops::Add; use std::os::fd::AsRawFd; use std::os::unix::net::{UnixListener, UnixStream}; use std::process::ExitCode; @@ -12,6 +13,39 @@ struct SoundChunk([i16; 1024]); #[repr(transparent)] struct MixChunk([i32; 1024]); +type HdaWritePos = WritePos<32>; + +#[derive(Eq, PartialEq, Copy, Clone)] +struct WritePos(pub u64); + +impl WritePos { + fn from_pos(pos: u64) -> Self { + WritePos(pos / 2048) + } +} + +impl From> for usize { + fn from(value: WritePos) -> Self { + value.0 as usize + } +} + +impl Add for WritePos { + type Output = WritePos; + + fn add(self, rhs: Self) -> Self::Output { + WritePos::((self.0 + rhs.0) % MAX) + } +} + +impl Add for WritePos { + type Output = WritePos; + + fn add(self, rhs: u64) -> Self::Output { + WritePos::((self.0 + rhs) % MAX) + } +} + impl MixChunk { fn new() -> MixChunk { MixChunk([0i32; 1024]) @@ -82,7 +116,7 @@ struct Output<'a> { clients: HashMap, pos: &'a [u64; 512], sound: &'a mut [SoundChunk; 32], - write_pos: u64, + last_write_pos: HdaWritePos, poll_fds: Vec, } @@ -106,11 +140,14 @@ impl<'a> Output<'a> { listener, clients: HashMap::new(), pos: unsafe { &*(hda_map as *const [u64; 512]) }, - write_pos: 0, + last_write_pos: HdaWritePos::from_pos(0), sound: unsafe { &mut *((hda_map + 4096) as *mut [SoundChunk; 32]) }, poll_fds: Vec::new(), }; + // 3 chunks headroom + output.last_write_pos = output.hda_write_pos() + 3; + output.reinit_fds(); Ok(output) @@ -150,6 +187,10 @@ impl<'a> Output<'a> { } } + fn hda_write_pos(&self) -> HdaWritePos { + HdaWritePos::from_pos(self.pos[4]) + } + fn poll_fds(&mut self) -> Vec { if self.poll_fds.len() != self.clients.len() + 1 { self.reinit_fds(); @@ -159,7 +200,8 @@ impl<'a> Output<'a> { fn process(&mut self) { let mut to_delete = Vec::new(); - if (self.pos[4] / 2048 + 3) % 32 == self.write_pos { + let hda_pos = self.hda_write_pos() + 3; + while hda_pos != self.last_write_pos { //println!("got pos: {}", self.pos[4] / 2048); let mut chunk = MixChunk::new(); @@ -168,14 +210,17 @@ impl<'a> Output<'a> { chunk.mix(&s); } else if c.disconnected { to_delete.push(c.input.as_raw_fd()); + c.disconnected = false; // to not push into vector twice } } - self.sound[self.write_pos as usize] = chunk.to_sound_chunk(); + self.sound[self.last_write_pos.0 as usize] = chunk.to_sound_chunk(); - self.write_pos = (self.write_pos + 1) % 32; + self.last_write_pos = self.last_write_pos + 1; } + self.last_write_pos = hda_pos; + for c in &to_delete { self.clients.remove(c); }