mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
intermediate checkin, taking a break
This commit is contained in:
parent
61611caddd
commit
7a7e77d346
4 changed files with 48 additions and 22 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -302,6 +302,7 @@ dependencies = [
|
|||
"log-server",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"rkyv 0.4.3",
|
||||
"susres",
|
||||
"ticktimer-server",
|
||||
"utralib",
|
||||
|
|
|
|||
|
|
@ -12,13 +12,15 @@ log-server = { path = "../log-server" }
|
|||
ticktimer-server = { path = "../ticktimer-server" }
|
||||
xous-names = { path = "../xous-names" }
|
||||
log = "0.4"
|
||||
xous-ipc = {path="../../xous-ipc"}
|
||||
num-derive = {version = "0.3", default-features = false}
|
||||
num-traits = {version = "0.2", default-features = false}
|
||||
susres = {path = "../susres"}
|
||||
llio = {path = "../llio"}
|
||||
volatile = "0.4"
|
||||
|
||||
xous-ipc = {path="../../xous-ipc"}
|
||||
num-derive = {version = "0.3", default-features = false}
|
||||
num-traits = {version = "0.2", default-features = false}
|
||||
rkyv = {version = "0.4.3", default-features = false, features = ["const_generics"]}
|
||||
|
||||
[target.'cfg(not(any(windows,unix)))'.dependencies]
|
||||
utralib = { path = "../../utralib"}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ pub(crate) enum EventCallback {
|
|||
Drop,
|
||||
}
|
||||
|
||||
#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Copy, Clone)]
|
||||
pub(crate) struct ScalarHook {
|
||||
pub sid: (u32, u32, u32, u32),
|
||||
pub id: u32, // ID of the scalar message to send through (e.g. the discriminant of the Enum on the caller's side API)
|
||||
pub cid: xous::CID, // caller-side connection ID for the scalar message to route to. Created by the caller before hooking.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub(crate) const ZERO_PCM: u16 = 0x0; // assumes 2's compliment. 0x8000 otherwise.
|
||||
|
|
@ -56,25 +63,38 @@ The format of samples appears to be
|
|||
u32: |31 right 16|15 left 0|
|
||||
*/
|
||||
|
||||
pub struct FrameRing<const DEPTH: usize, const FRAMES: usize> {
|
||||
/*
|
||||
Implementation note: rkyv's derives are having trouble with specifying the
|
||||
depth of the frame as a const generic, eg.
|
||||
pub struct FrameRing::<const F: usize> {...}
|
||||
because the derive macro is not putting the `const F` at the end. This problem
|
||||
exists as of rkyv 0.6.2. Implement using fixed-size variants, with traits.
|
||||
|
||||
We would ideally like to be able to specify various-sized frame rings for
|
||||
more efficient memory usage and message passing, but for now, we will fix
|
||||
the size at 16 frames.
|
||||
*/
|
||||
const FRAMES: usize = 16;
|
||||
#[derive(rkyv::Serialize, rkyv::Deserialize, Debug, rkyv::Archive, Copy, Clone)]
|
||||
pub struct FrameRing {
|
||||
// a set of frames we will circulate through
|
||||
buffer: [[u32; DEPTH]; FRAMES],
|
||||
buffer: [[u32; FIFO_DEPTH]; FRAMES],
|
||||
// the current readable frame number
|
||||
rd_frame: usize,
|
||||
// the current writeable frame number
|
||||
wr_frame: usize,
|
||||
}
|
||||
impl<const DEPTH: usize, const FRAMES: usize> FrameRing<DEPTH, FRAMES> {
|
||||
pub fn new() -> FrameRing::<DEPTH, FRAMES> {
|
||||
impl FrameRing {
|
||||
pub fn new() -> FrameRing {
|
||||
FrameRing {
|
||||
buffer: [[(ZERO_PCM as u32 | (ZERO_PCM as u32) << 16); DEPTH]; FRAMES],
|
||||
buffer: [[(ZERO_PCM as u32 | (ZERO_PCM as u32) << 16); FIFO_DEPTH]; FRAMES],
|
||||
rd_frame: 0,
|
||||
wr_frame: 0,
|
||||
}
|
||||
}
|
||||
/*
|
||||
empty: rd_frame == wr_frame
|
||||
full: wr_frame == (rd_frame - 1) || (rd_frame == 0) && (wr_frame == FRAMES-1)
|
||||
full: wr_frame == (rd_frame - 1) || (rd_frame == 0) && (wr_frame == F-1)
|
||||
*/
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.rd_frame == self.wr_frame
|
||||
|
|
@ -96,25 +116,26 @@ impl<const DEPTH: usize, const FRAMES: usize> FrameRing<DEPTH, FRAMES> {
|
|||
pub fn writeable_count(&self) -> usize {
|
||||
(FRAMES-1) - self.readable_count()
|
||||
}
|
||||
pub fn nq_frame(&mut self, frame: [u32; DEPTH]) -> Result<(), [u32; DEPTH]> {
|
||||
pub fn nq_frame(&mut self, frame: [u32; FIFO_DEPTH]) -> Result<(), [u32; FIFO_DEPTH]> {
|
||||
if self.is_full() {
|
||||
Err(frame)
|
||||
return Err(frame);
|
||||
} else {
|
||||
for (src, &stereo_sample) in frame.iter().zip(self.buffer[self.wr_frame].iter_mut()) {
|
||||
for (&src, stereo_sample) in frame.iter().zip(self.buffer[self.wr_frame].iter_mut()) {
|
||||
*stereo_sample = src;
|
||||
}
|
||||
}
|
||||
self.wr_frame = ((self.wr_frame + 1) % FRAMES);
|
||||
self.wr_frame = (self.wr_frame + 1) % FRAMES;
|
||||
Ok(())
|
||||
}
|
||||
pub fn dq_frame(&mut self) -> Option<[u32; DEPTH]> {
|
||||
pub fn dq_frame(&mut self) -> Option<[u32; FIFO_DEPTH]> {
|
||||
if self.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let playbuf = [u32; DEPTH];
|
||||
for (src, &dst) in self.buffer[self.rd_frame].iter().zip(playbuf.iter_mut()) {
|
||||
let playbuf: [u32; FIFO_DEPTH];
|
||||
for (&src, dst) in self.buffer[self.rd_frame].iter().zip(playbuf.iter_mut()) {
|
||||
*dst = src;
|
||||
}
|
||||
self.rd_frame = ((self.rd_frame + 1) % FRAMES);
|
||||
self.rd_frame = (self.rd_frame + 1) % FRAMES;
|
||||
Some(playbuf)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#![cfg_attr(target_os = "none", no_std)]
|
||||
|
||||
pub mod api;
|
||||
use xous::{CID, send_message};
|
||||
use num_traits::ToPrimitive;
|
||||
use xous::{CID, send_message, Message};
|
||||
use num_traits::{ToPrimitive, FromPrimitive};
|
||||
use xous_ipc::Buffer;
|
||||
use api::*;
|
||||
|
||||
pub struct Codec {
|
||||
conn: CID,
|
||||
|
|
@ -40,7 +42,7 @@ impl Codec {
|
|||
).map(|_| ())
|
||||
}
|
||||
|
||||
pub fn free_frames(&mut self) -> Result<(play, rec), xous::Error> {
|
||||
pub fn free_frames(&mut self) -> Result<(usize, usize), xous::Error> {
|
||||
let response = send_message(self.conn,
|
||||
Message::new_blocking_scalar(Opcode::FreeFrames.to_usize().unwrap(), 0, 0, 0, 0))?;
|
||||
if let xous::Result::Scalar2(play_free, rec_avail) = response {
|
||||
|
|
@ -53,11 +55,11 @@ impl Codec {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn swap_frames(&mut self, frames: &mut FrameRing::<FIFO_DEPTH, 4>) -> Result<(), xous::Error> {
|
||||
pub fn swap_frames(&mut self, frames: &mut FrameRing) -> Result<(), xous::Error> {
|
||||
let mut buf = Buffer::into_buf(*frames).or(Err(xous::Error::InternalError))?;
|
||||
buf.lend_mut(self.conn, Opcode::SwapFrames.to_u32().unwrap()).or(Err(xous::Error::InternalError))?;
|
||||
|
||||
frames = buf.to_original::<FrameRing::<FIFO_DEPTH, 4>, _>().unwrap();
|
||||
*frames = buf.to_original::<FrameRing, _>().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue