Skip to content

Commit

Permalink
Implement audio_read_samples()
Browse files Browse the repository at this point in the history
  • Loading branch information
maximecb committed Sep 10, 2024
1 parent c0b195f commit 8352959
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 1 deletion.
20 changes: 20 additions & 0 deletions api/syscalls.json
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,26 @@
"permission": "audio_input",
"const_idx": 12,
"description": "Open an audio input device, then spawn a new thread which will regularly call the specified callback function to process audio samples."
},
{
"name": "audio_read_samples",
"args": [
[
"i16*",
"dst_buf"
],
[
"u32",
"num_samples"
]
],
"returns": [
"void",
""
],
"permission": "audio_input",
"const_idx": 13,
"description": "Read available input samples. Must be called from the audio input thread."
}
],
"constants": [
Expand Down
8 changes: 8 additions & 0 deletions doc/syscalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,14 @@ u32 audio_open_input(u32 sample_rate, u16 num_channels, u16 format, void* callba

Open an audio input device, then spawn a new thread which will regularly call the specified callback function to process audio samples.

## audio_read_samples

```
void audio_read_samples(i16* dst_buf, u32 num_samples)
```

Read available input samples. Must be called from the audio input thread.

## Constants
These are the constants associated with the audio subsystem:

Expand Down
4 changes: 4 additions & 0 deletions ncc/include/uvm/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@
// Open an audio input device, then spawn a new thread which will regularly call the specified callback function to process audio samples.
#define audio_open_input(__sample_rate, __num_channels, __format, __callback) asm (__sample_rate, __num_channels, __format, __callback) -> u32 { syscall audio_open_input; }

// void audio_read_samples(i16* dst_buf, u32 num_samples)
// Read available input samples. Must be called from the audio input thread.
#define audio_read_samples(__dst_buf, __num_samples) asm (__dst_buf, __num_samples) -> void { syscall audio_read_samples; }

// u64 net_listen(const char* listen_addr, void* on_new_conn)
// Open a listening TCP socket to accept incoming connections. A callback function is called when a new connection request is received.
#define net_listen(__listen_addr, __on_new_conn) asm (__listen_addr, __on_new_conn) -> u64 { syscall net_listen; }
Expand Down
23 changes: 23 additions & 0 deletions vm/src/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,26 @@ pub fn audio_open_input(thread: &mut Thread, sample_rate: Value, num_channels: V
// FIXME: return the device_id (u32)
Value::from(1)
}

/// Read audio samples from an audio input thread
pub fn audio_read_samples(thread: &mut Thread, dst_ptr: Value, num_samples: Value)
{
let dst_ptr = dst_ptr.as_usize();
let num_samples = num_samples.as_usize();

INPUT_STATE.with_borrow_mut(|s| {
if s.input_tid != thread.id {
panic!("can only read audio samples from audio input thread");
}

// For now, force reading all available samples
if num_samples != s.samples.len() {
panic!("must read all available samples");
}

let dst_buf: &mut [i16] = thread.get_heap_slice_mut(dst_ptr, num_samples);
dst_buf.copy_from_slice(&s.samples);

s.samples.clear();
});
}
3 changes: 2 additions & 1 deletion vm/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub const WINDOW_POLL_EVENT: u16 = 9;
pub const WINDOW_DRAW_FRAME: u16 = 10;
pub const EXIT: u16 = 11;
pub const AUDIO_OPEN_INPUT: u16 = 12;
pub const AUDIO_READ_SAMPLES: u16 = 13;
pub const VM_HEAP_SIZE: u16 = 14;
pub const MEMSET32: u16 = 16;
pub const VM_GROW_HEAP: u16 = 17;
Expand Down Expand Up @@ -58,7 +59,7 @@ pub const SYSCALL_DESCS: [Option<SysCallDesc>; SYSCALL_TBL_LEN] = [
Some(SysCallDesc { name: "window_draw_frame", const_idx: 10, argc: 2, has_ret: false }),
Some(SysCallDesc { name: "exit", const_idx: 11, argc: 1, has_ret: false }),
Some(SysCallDesc { name: "audio_open_input", const_idx: 12, argc: 4, has_ret: true }),
None,
Some(SysCallDesc { name: "audio_read_samples", const_idx: 13, argc: 2, has_ret: false }),
Some(SysCallDesc { name: "vm_heap_size", const_idx: 14, argc: 0, has_ret: true }),
None,
Some(SysCallDesc { name: "memset32", const_idx: 16, argc: 3, has_ret: false }),
Expand Down
2 changes: 2 additions & 0 deletions vm/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ pub fn get_syscall(const_idx: u16) -> HostFn
WINDOW_WAIT_EVENT => HostFn::Fn1_0(window_wait_event),

AUDIO_OPEN_OUTPUT => HostFn::Fn4_1(audio_open_output),
AUDIO_OPEN_INPUT => HostFn::Fn4_1(audio_open_input),
AUDIO_READ_SAMPLES => HostFn::Fn2_0(audio_read_samples),

_ => panic!("unknown syscall \"{}\"", const_idx),
}
Expand Down

0 comments on commit 8352959

Please sign in to comment.