mirror of
https://github.com/LegitCamper/picocalc-os-rs.git
synced 2025-12-27 07:45:28 +00:00
Merge branch 'main' into audio-driver
This commit is contained in:
@@ -4,11 +4,15 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[features]
|
||||
default = ["alloc"]
|
||||
alloc = []
|
||||
defmt = ["dep:defmt"]
|
||||
|
||||
[dependencies]
|
||||
embedded-graphics = "0.8.1"
|
||||
strum = { version = "0.27.2", default-features = false, features = ["derive"] }
|
||||
bitflags = "2.9.4"
|
||||
embedded-graphics = "0.8.1"
|
||||
defmt = { version = "0.3", optional = true }
|
||||
shared = { path = "../shared" }
|
||||
embedded-sdmmc = { version = "0.9.0", default-features = false }
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = "0.24.0"
|
||||
|
||||
@@ -1,85 +1,382 @@
|
||||
#![no_std]
|
||||
#[cfg(feature = "alloc")]
|
||||
use core::alloc::Layout;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
#[allow(unused)]
|
||||
use core::ffi::c_char;
|
||||
use embedded_graphics::{
|
||||
Pixel,
|
||||
geometry::Point,
|
||||
pixelcolor::{Rgb565, RgbColor},
|
||||
pixelcolor::{Rgb565, raw::RawU16},
|
||||
prelude::{IntoStorage, Point},
|
||||
};
|
||||
use embedded_sdmmc::DirEntry;
|
||||
pub use shared::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers};
|
||||
use strum::{EnumCount, EnumIter};
|
||||
|
||||
pub type EntryFn = fn();
|
||||
|
||||
pub const ABI_CALL_TABLE_COUNT: usize = 14;
|
||||
const _: () = assert!(ABI_CALL_TABLE_COUNT == CallTable::COUNT);
|
||||
|
||||
#[derive(Clone, Copy, EnumIter, EnumCount)]
|
||||
#[repr(u8)]
|
||||
pub enum CallTable {
|
||||
Alloc = 0,
|
||||
Dealloc = 1,
|
||||
PrintString = 2,
|
||||
SleepMs = 3,
|
||||
GetMs = 4,
|
||||
DrawIter = 5,
|
||||
GetKey = 6,
|
||||
GenRand = 7,
|
||||
ListDir = 8,
|
||||
ReadFile = 9,
|
||||
WriteFile = 10,
|
||||
FileLen = 11,
|
||||
AudioBufferReady = 12,
|
||||
SendAudioBuffer = 13,
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
#[unsafe(link_section = ".syscall_table")]
|
||||
pub static mut CALL_ABI_TABLE: [usize; CallAbiTable::COUNT] = [0; CallAbiTable::COUNT];
|
||||
pub static mut CALL_ABI_TABLE: [usize; ABI_CALL_TABLE_COUNT] = [0; ABI_CALL_TABLE_COUNT];
|
||||
|
||||
#[repr(usize)]
|
||||
#[derive(Clone, Copy, EnumIter, EnumCount)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum CallAbiTable {
|
||||
PrintString = 0,
|
||||
SleepMs = 1,
|
||||
LockDisplay = 2,
|
||||
DrawIter = 3,
|
||||
GetKey = 4,
|
||||
GenRand = 5,
|
||||
ListDir = 6,
|
||||
ReadFile = 7,
|
||||
FileLen = 8,
|
||||
AudioBufferReady = 9,
|
||||
SendAudioBuffer = 10,
|
||||
#[cfg(feature = "alloc")]
|
||||
#[repr(C)]
|
||||
pub struct CLayout {
|
||||
size: usize,
|
||||
alignment: usize,
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl Into<Layout> for CLayout {
|
||||
fn into(self) -> Layout {
|
||||
unsafe { Layout::from_size_align_unchecked(self.size, self.alignment) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl From<Layout> for CLayout {
|
||||
fn from(value: Layout) -> Self {
|
||||
Self {
|
||||
size: value.size(),
|
||||
alignment: value.align(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type AllocAbi = extern "C" fn(layout: CLayout) -> *mut u8;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn alloc(layout: CLayout) -> *mut u8 {
|
||||
let f: AllocAbi = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::Alloc as usize]) };
|
||||
f(layout)
|
||||
}
|
||||
|
||||
pub type DeallocAbi = extern "C" fn(ptr: *mut u8, layout: CLayout);
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn dealloc(ptr: *mut u8, layout: CLayout) {
|
||||
let f: DeallocAbi =
|
||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::Dealloc as usize]) };
|
||||
f(ptr, layout)
|
||||
}
|
||||
|
||||
pub type PrintAbi = extern "C" fn(ptr: *const u8, len: usize);
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn print(msg: &str) {
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn print(ptr: *const u8, len: usize) {
|
||||
let f: PrintAbi =
|
||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::PrintString as usize]) };
|
||||
f(msg.as_ptr(), msg.len());
|
||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::PrintString as usize]) };
|
||||
f(ptr, len);
|
||||
}
|
||||
|
||||
pub type SleepAbi = extern "C" fn(ms: u64);
|
||||
pub type SleepMsAbi = extern "C" fn(ms: u64);
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn sleep(ms: u64) {
|
||||
let f: SleepAbi =
|
||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::SleepMs as usize]) };
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn sleep(ms: u64) {
|
||||
let f: SleepMsAbi =
|
||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::SleepMs as usize]) };
|
||||
f(ms);
|
||||
}
|
||||
|
||||
pub type LockDisplay = extern "C" fn(lock: bool);
|
||||
pub type GetMsAbi = extern "C" fn() -> u64;
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn lock_display(lock: bool) {
|
||||
let f: LockDisplay =
|
||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::LockDisplay as usize]) };
|
||||
f(lock);
|
||||
}
|
||||
|
||||
pub type DrawIterAbi = extern "C" fn(ptr: *const Pixel<Rgb565>, len: usize);
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn draw_iter(pixels: &[Pixel<Rgb565>]) {
|
||||
let f: DrawIterAbi =
|
||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::DrawIter as usize]) };
|
||||
f(pixels.as_ptr(), pixels.len());
|
||||
}
|
||||
|
||||
pub type GetKeyAbi = extern "C" fn() -> KeyEvent;
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn get_key() -> KeyEvent {
|
||||
let f: GetKeyAbi =
|
||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::GetKey as usize]) };
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn get_ms() -> u64 {
|
||||
let f: GetMsAbi = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::GetMs as usize]) };
|
||||
f()
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CPixel {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub color: u16,
|
||||
}
|
||||
|
||||
impl CPixel {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
x: 0,
|
||||
y: 0,
|
||||
color: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<CPixel> for Pixel<Rgb565> {
|
||||
fn into(self) -> CPixel {
|
||||
CPixel {
|
||||
x: self.0.x,
|
||||
y: self.0.y,
|
||||
color: self.1.into_storage(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Pixel<Rgb565>> for CPixel {
|
||||
fn into(self) -> Pixel<Rgb565> {
|
||||
Pixel(Point::new(self.x, self.y), RawU16::new(self.color).into())
|
||||
}
|
||||
}
|
||||
|
||||
pub type DrawIterAbi = extern "C" fn(ptr: *const CPixel, len: usize);
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn draw_iter(ptr: *const CPixel, len: usize) {
|
||||
let f: DrawIterAbi =
|
||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::DrawIter as usize]) };
|
||||
f(ptr, len);
|
||||
}
|
||||
|
||||
pub mod keyboard {
|
||||
use crate::{CALL_ABI_TABLE, CallTable};
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct Modifiers: u8 {
|
||||
const NONE = 0;
|
||||
const CTRL = 1;
|
||||
const ALT = 2;
|
||||
const LSHIFT = 4;
|
||||
const RSHIFT = 8;
|
||||
const SYM = 16;
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct KeyEventC {
|
||||
pub key: u8,
|
||||
pub state: KeyState,
|
||||
pub mods: Modifiers,
|
||||
}
|
||||
|
||||
impl Into<KeyEvent> for KeyEventC {
|
||||
fn into(self) -> KeyEvent {
|
||||
KeyEvent {
|
||||
key: self.key.into(),
|
||||
state: self.state,
|
||||
mods: self.mods,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct KeyEvent {
|
||||
pub key: KeyCode,
|
||||
pub state: KeyState,
|
||||
pub mods: Modifiers,
|
||||
}
|
||||
|
||||
impl Into<KeyEventC> for KeyEvent {
|
||||
fn into(self) -> KeyEventC {
|
||||
KeyEventC {
|
||||
key: self.key.into(),
|
||||
state: self.state,
|
||||
mods: self.mods,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(C)]
|
||||
pub enum KeyState {
|
||||
Idle = 0,
|
||||
Pressed = 1,
|
||||
Hold = 2,
|
||||
Released = 3,
|
||||
}
|
||||
|
||||
impl From<u8> for KeyState {
|
||||
fn from(value: u8) -> Self {
|
||||
match value {
|
||||
1 => KeyState::Pressed,
|
||||
2 => KeyState::Hold,
|
||||
3 => KeyState::Released,
|
||||
0 | _ => KeyState::Idle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum KeyCode {
|
||||
JoyUp = 0x01,
|
||||
JoyDown = 0x02,
|
||||
JoyLeft = 0x03,
|
||||
JoyRight = 0x04,
|
||||
JoyCenter = 0x05,
|
||||
BtnLeft1 = 0x06,
|
||||
BtnRight1 = 0x07,
|
||||
BtnLeft2 = 0x11,
|
||||
BtnRight2 = 0x12,
|
||||
Backspace = 0x08,
|
||||
Tab = 0x09,
|
||||
Enter = 0x0A,
|
||||
ModAlt = 0xA1,
|
||||
ModShiftLeft = 0xA2,
|
||||
ModShiftRight = 0xA3,
|
||||
ModSym = 0xA4,
|
||||
ModCtrl = 0xA5,
|
||||
Esc = 0xB1,
|
||||
Left = 0xB4,
|
||||
Up = 0xB5,
|
||||
Down = 0xB6,
|
||||
Right = 0xB7,
|
||||
Break = 0xD0,
|
||||
Insert = 0xD1,
|
||||
Home = 0xD2,
|
||||
Del = 0xD4,
|
||||
End = 0xD5,
|
||||
PageUp = 0xD6,
|
||||
PageDown = 0xD7,
|
||||
CapsLock = 0xC1,
|
||||
F1 = 0x81,
|
||||
F2 = 0x82,
|
||||
F3 = 0x83,
|
||||
F4 = 0x84,
|
||||
F5 = 0x85,
|
||||
F6 = 0x86,
|
||||
F7 = 0x87,
|
||||
F8 = 0x88,
|
||||
F9 = 0x89,
|
||||
F10 = 0x90,
|
||||
Char(char),
|
||||
Unknown(u8),
|
||||
}
|
||||
|
||||
impl Into<u8> for KeyCode {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
KeyCode::JoyUp => 0x01,
|
||||
KeyCode::JoyDown => 0x02,
|
||||
KeyCode::JoyLeft => 0x03,
|
||||
KeyCode::JoyRight => 0x04,
|
||||
KeyCode::JoyCenter => 0x05,
|
||||
KeyCode::BtnLeft1 => 0x06,
|
||||
KeyCode::BtnRight1 => 0x07,
|
||||
KeyCode::BtnLeft2 => 0x11,
|
||||
KeyCode::BtnRight2 => 0x12,
|
||||
KeyCode::Backspace => 0x08,
|
||||
KeyCode::Tab => 0x09,
|
||||
KeyCode::Enter => 0x0A,
|
||||
KeyCode::ModAlt => 0xA1,
|
||||
KeyCode::ModShiftLeft => 0xA2,
|
||||
KeyCode::ModShiftRight => 0xA3,
|
||||
KeyCode::ModSym => 0xA4,
|
||||
KeyCode::ModCtrl => 0xA5,
|
||||
KeyCode::Esc => 0xB1,
|
||||
KeyCode::Left => 0xB4,
|
||||
KeyCode::Up => 0xB5,
|
||||
KeyCode::Down => 0xB6,
|
||||
KeyCode::Right => 0xB7,
|
||||
KeyCode::Break => 0xD0,
|
||||
KeyCode::Insert => 0xD1,
|
||||
KeyCode::Home => 0xD2,
|
||||
KeyCode::Del => 0xD4,
|
||||
KeyCode::End => 0xD5,
|
||||
KeyCode::PageUp => 0xD6,
|
||||
KeyCode::PageDown => 0xD7,
|
||||
KeyCode::CapsLock => 0xC1,
|
||||
KeyCode::F1 => 0x81,
|
||||
KeyCode::F2 => 0x82,
|
||||
KeyCode::F3 => 0x83,
|
||||
KeyCode::F4 => 0x84,
|
||||
KeyCode::F5 => 0x85,
|
||||
KeyCode::F6 => 0x86,
|
||||
KeyCode::F7 => 0x87,
|
||||
KeyCode::F8 => 0x88,
|
||||
KeyCode::F9 => 0x89,
|
||||
KeyCode::F10 => 0x90,
|
||||
KeyCode::Char(char) => char as u8,
|
||||
KeyCode::Unknown(i) => i,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for KeyCode {
|
||||
fn from(value: u8) -> Self {
|
||||
match value {
|
||||
0x01 => Self::JoyUp,
|
||||
0x02 => Self::JoyDown,
|
||||
0x03 => Self::JoyLeft,
|
||||
0x04 => Self::JoyRight,
|
||||
0x05 => Self::JoyCenter,
|
||||
0x06 => Self::BtnLeft1,
|
||||
0x07 => Self::BtnRight1,
|
||||
0x08 => Self::Backspace,
|
||||
0x09 => Self::Tab,
|
||||
0x0A => Self::Enter,
|
||||
0x11 => Self::BtnLeft2,
|
||||
0x12 => Self::BtnRight2,
|
||||
0xA1 => Self::ModAlt,
|
||||
0xA2 => Self::ModShiftLeft,
|
||||
0xA3 => Self::ModShiftRight,
|
||||
0xA4 => Self::ModSym,
|
||||
0xA5 => Self::ModCtrl,
|
||||
0xB1 => Self::Esc,
|
||||
0xB4 => Self::Left,
|
||||
0xB5 => Self::Up,
|
||||
0xB6 => Self::Down,
|
||||
0xB7 => Self::Right,
|
||||
0xC1 => Self::CapsLock,
|
||||
0xD0 => Self::Break,
|
||||
0xD1 => Self::Insert,
|
||||
0xD2 => Self::Home,
|
||||
0xD4 => Self::Del,
|
||||
0xD5 => Self::End,
|
||||
0xD6 => Self::PageUp,
|
||||
0xD7 => Self::PageDown,
|
||||
0x81 => Self::F1,
|
||||
0x82 => Self::F2,
|
||||
0x83 => Self::F3,
|
||||
0x84 => Self::F4,
|
||||
0x85 => Self::F5,
|
||||
0x86 => Self::F6,
|
||||
0x87 => Self::F7,
|
||||
0x88 => Self::F8,
|
||||
0x89 => Self::F9,
|
||||
0x90 => Self::F10,
|
||||
_ => match char::from_u32(value as u32) {
|
||||
Some(c) => Self::Char(c),
|
||||
None => Self::Unknown(value),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type GetKeyAbi = extern "C" fn() -> KeyEventC;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn get_key() -> KeyEventC {
|
||||
let f: GetKeyAbi =
|
||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::GetKey as usize]) };
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub enum RngRequest {
|
||||
U32(u32),
|
||||
@@ -89,10 +386,10 @@ pub enum RngRequest {
|
||||
|
||||
pub type GenRand = extern "C" fn(req: &mut RngRequest);
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn gen_rand(req: &mut RngRequest) {
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn gen_rand(req: &mut RngRequest) {
|
||||
unsafe {
|
||||
let ptr = CALL_ABI_TABLE[CallAbiTable::GenRand as usize];
|
||||
let ptr = CALL_ABI_TABLE[CallTable::GenRand as usize];
|
||||
let f: GenRand = core::mem::transmute(ptr);
|
||||
f(req)
|
||||
}
|
||||
@@ -101,16 +398,23 @@ pub fn gen_rand(req: &mut RngRequest) {
|
||||
pub type ListDir = extern "C" fn(
|
||||
str: *const u8,
|
||||
len: usize,
|
||||
files: *mut Option<DirEntry>,
|
||||
entries: *mut *mut c_char,
|
||||
file_len: usize,
|
||||
max_entry_str_len: usize,
|
||||
) -> usize;
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn list_dir(path: &str, files: &mut [Option<DirEntry>]) -> usize {
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn list_dir(
|
||||
str: *const u8,
|
||||
len: usize,
|
||||
entries: *mut *mut c_char,
|
||||
entry_count: usize,
|
||||
max_entry_str_len: usize,
|
||||
) -> usize {
|
||||
unsafe {
|
||||
let ptr = CALL_ABI_TABLE[CallAbiTable::ListDir as usize];
|
||||
let ptr = CALL_ABI_TABLE[CallTable::ListDir as usize];
|
||||
let f: ListDir = core::mem::transmute(ptr);
|
||||
f(path.as_ptr(), path.len(), files.as_mut_ptr(), files.len())
|
||||
f(str, len, entries, entry_count, max_entry_str_len)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,29 +426,47 @@ pub type ReadFile = extern "C" fn(
|
||||
buf_len: usize,
|
||||
) -> usize;
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn read_file(file: &str, read_from: usize, buf: &mut [u8]) -> usize {
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn read_file(
|
||||
str: *const u8,
|
||||
len: usize,
|
||||
read_from: usize,
|
||||
buf: *mut u8,
|
||||
buf_len: usize,
|
||||
) -> usize {
|
||||
unsafe {
|
||||
let ptr = CALL_ABI_TABLE[CallAbiTable::ReadFile as usize];
|
||||
let ptr = CALL_ABI_TABLE[CallTable::ReadFile as usize];
|
||||
let f: ReadFile = core::mem::transmute(ptr);
|
||||
f(
|
||||
file.as_ptr(),
|
||||
file.len(),
|
||||
read_from,
|
||||
buf.as_mut_ptr(),
|
||||
buf.len(),
|
||||
)
|
||||
f(str, len, read_from, buf, buf_len)
|
||||
}
|
||||
}
|
||||
|
||||
pub type WriteFile =
|
||||
extern "C" fn(str: *const u8, len: usize, write_from: usize, buf: *const u8, buf_len: usize);
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn write_file(
|
||||
str: *const u8,
|
||||
len: usize,
|
||||
write_from: usize,
|
||||
buf: *const u8,
|
||||
buf_len: usize,
|
||||
) {
|
||||
unsafe {
|
||||
let ptr = CALL_ABI_TABLE[CallTable::WriteFile as usize];
|
||||
let f: WriteFile = core::mem::transmute(ptr);
|
||||
f(str, len, write_from, buf, buf_len)
|
||||
}
|
||||
}
|
||||
|
||||
pub type FileLen = extern "C" fn(str: *const u8, len: usize) -> usize;
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn file_len(file: &str) -> usize {
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn file_len(str: *const u8, len: usize) -> usize {
|
||||
unsafe {
|
||||
let ptr = CALL_ABI_TABLE[CallAbiTable::FileLen as usize];
|
||||
let ptr = CALL_ABI_TABLE[CallTable::FileLen as usize];
|
||||
let f: FileLen = core::mem::transmute(ptr);
|
||||
f(file.as_ptr(), file.len())
|
||||
f(str, len)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +475,7 @@ pub type AudioBufferReady = extern "C" fn() -> bool;
|
||||
#[allow(unused)]
|
||||
pub fn audio_buffer_ready() -> bool {
|
||||
unsafe {
|
||||
let ptr = CALL_ABI_TABLE[CallAbiTable::AudioBufferReady as usize];
|
||||
let ptr = CALL_ABI_TABLE[CallTable::AudioBufferReady as usize];
|
||||
let f: AudioBufferReady = core::mem::transmute(ptr);
|
||||
f()
|
||||
}
|
||||
@@ -164,10 +486,10 @@ pub const AUDIO_BUFFER_LEN: usize = 1024;
|
||||
pub type SendAudioBuffer = extern "C" fn(ptr: *const u8, len: usize);
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn send_audio_buffer(buf: &[u8; AUDIO_BUFFER_LEN]) {
|
||||
pub fn send_audio_buffer(buf: *const u8, len: usize) {
|
||||
unsafe {
|
||||
let ptr = CALL_ABI_TABLE[CallAbiTable::SendAudioBuffer as usize];
|
||||
let ptr = CALL_ABI_TABLE[CallTable::SendAudioBuffer as usize];
|
||||
let f: SendAudioBuffer = core::mem::transmute(ptr);
|
||||
f(buf.as_ptr(), buf.len())
|
||||
f(buf, len)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user