Skip to content

Commit

Permalink
sound: Small daemon improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalmiel committed Oct 8, 2024
1 parent 9930df9 commit fd79549
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 26 deletions.
13 changes: 2 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 9 additions & 7 deletions cykusz-rs/src/drivers/acpi/pci_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 => {
Expand Down
2 changes: 1 addition & 1 deletion userspace/playaudio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ pub fn play(buf: &[u8]) -> Result<(), ExitCode> {
println!("write finished");

Ok(())
}
}
49 changes: 48 additions & 1 deletion userspace/playaudio/src/playmidi/bin/main.rs
Original file line number Diff line number Diff line change
@@ -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<P: AsRef<Path>>(path: P) -> std::io::Result<Self> {
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<usize> {
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();

Expand All @@ -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...");
Expand Down
7 changes: 6 additions & 1 deletion userspace/playaudio/src/playwav/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;

Expand Down
55 changes: 50 additions & 5 deletions userspace/sound-daemon/src/sound-daemon/bin/main.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<const MAX: u64>(pub u64);

impl<const MAX: u64> WritePos<MAX> {
fn from_pos(pos: u64) -> Self {
WritePos(pos / 2048)
}
}

impl<const MAX: u64> From<WritePos<MAX>> for usize {
fn from(value: WritePos<MAX>) -> Self {
value.0 as usize
}
}

impl<const MAX: u64> Add for WritePos<MAX> {
type Output = WritePos<MAX>;

fn add(self, rhs: Self) -> Self::Output {
WritePos::<MAX>((self.0 + rhs.0) % MAX)
}
}

impl<const MAX: u64> Add<u64> for WritePos<MAX> {
type Output = WritePos<MAX>;

fn add(self, rhs: u64) -> Self::Output {
WritePos::<MAX>((self.0 + rhs) % MAX)
}
}

impl MixChunk {
fn new() -> MixChunk {
MixChunk([0i32; 1024])
Expand Down Expand Up @@ -82,7 +116,7 @@ struct Output<'a> {
clients: HashMap<i32, Client>,
pos: &'a [u64; 512],
sound: &'a mut [SoundChunk; 32],
write_pos: u64,
last_write_pos: HdaWritePos,
poll_fds: Vec<PollFd>,
}

Expand All @@ -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)
Expand Down Expand Up @@ -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<PollFd> {
if self.poll_fds.len() != self.clients.len() + 1 {
self.reinit_fds();
Expand All @@ -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();

Expand All @@ -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);
}
Expand Down

0 comments on commit fd79549

Please sign in to comment.