Skip to content

Commit

Permalink
Add audio related code.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundo-villa committed Dec 20, 2023
1 parent 45764f0 commit 2712f86
Show file tree
Hide file tree
Showing 18 changed files with 334 additions and 415 deletions.
352 changes: 10 additions & 342 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ meshopt = "0.1.9"
colored = "2.0.4"
downcast-rs = "1.2.0"
intertrait = "0.2.2"
cpal = "0.15.2"
alsa = "0.8.1"

[profile.dev]
incremental = true
Expand Down
73 changes: 73 additions & 0 deletions src/ahi/audio_hardware_interface.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use crate::orchestrator::{EntityReturn, Entity, System};

pub trait AudioHardwareInterface {
fn play(&self);

fn pause(&self);
}

struct ALSAAudioHardwareInterface {
pcm: Option<alsa::pcm::PCM>,
}

impl ALSAAudioHardwareInterface {
fn open() -> Self {
let name = std::ffi::CString::new("default").unwrap();
let pcm = alsa::pcm::PCM::open(&name, alsa::Direction::Playback, false).unwrap();

{
let hwp = alsa::pcm::HwParams::any(&pcm).unwrap();
hwp.set_channels(1).unwrap();
hwp.set_rate(44100, alsa::ValueOr::Nearest).unwrap();
hwp.set_format(alsa::pcm::Format::s16()).unwrap();
hwp.set_access(alsa::pcm::Access::RWInterleaved).unwrap();
pcm.hw_params(&hwp).unwrap();
}

{
let hwp = pcm.hw_params_current().unwrap();
let swp = pcm.sw_params_current().unwrap();
swp.set_start_threshold(hwp.get_buffer_size().unwrap()).unwrap();
pcm.sw_params(&swp).unwrap();
}

ALSAAudioHardwareInterface {
pcm: Some(pcm),
}
}
}

impl AudioHardwareInterface for ALSAAudioHardwareInterface {
fn play(&self) {
let pcm = if let Some(pcm) = &self.pcm { pcm } else { return; };

// Make a sine wave
let mut buf = [0i16; 1024];
for (i, a) in buf.iter_mut().enumerate() {
*a = ((i as f32 * 2.0 * ::std::f32::consts::PI / 32.0).sin() * 8192.0) as i16
}

let io = pcm.io_i16().unwrap();

// Play it back for 2 seconds.
for _ in 0..2*44100/1024 {
assert_eq!(io.writei(&buf[..]).unwrap(), 1024);
}

// In case the buffer was larger than 2 seconds, start the stream manually.
if pcm.state() != alsa::pcm::State::Running { pcm.start().unwrap() };
// Wait for the stream to finish playback.
pcm.drain().unwrap();
}

fn pause(&self) {
let pcm = if let Some(pcm) = &self.pcm { pcm } else { return; };

pcm.pause(true).unwrap();
}
}

pub fn create_ahi() -> impl AudioHardwareInterface {
#[cfg(target_os = "linux")]
ALSAAudioHardwareInterface::open()
}
1 change: 1 addition & 0 deletions src/ahi/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod audio_hardware_interface;
7 changes: 5 additions & 2 deletions src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl Application for BaseApplication {
use log::{info, trace};
use maths_rs::prelude::Base;

use crate::{orchestrator::{self, EntityHandle}, rendering::render_system, window_system, input_manager, Vector2, rendering::{self}, resource_manager, file_tracker};
use crate::{orchestrator::{self, EntityHandle}, rendering::render_system, window_system, input_manager, Vector2, rendering::{self}, resource_manager, file_tracker, ahi};

/// An orchestrated application is an application that uses the orchestrator to manage systems.
/// It is the recommended way to create a simple application.
Expand Down Expand Up @@ -129,6 +129,7 @@ pub struct GraphicsApplication {
input_system_handle: orchestrator::EntityHandle<input_manager::InputManager>,
renderer_handle: orchestrator::EntityHandle<rendering::renderer::Renderer>,
render_system_handle: orchestrator::EntityHandle<dyn render_system::RenderSystem>,
audio_system_handle: Box<dyn ahi::audio_hardware_interface::AudioHardwareInterface>,
}

impl Application for GraphicsApplication {
Expand Down Expand Up @@ -171,7 +172,9 @@ impl Application for GraphicsApplication {

let _: orchestrator::EntityHandle<window_system::Window> = orchestrator.spawn(window_system::Window{ name: "Main Window".to_string(), extent: crate::Extent { width: 1920, height: 1080, depth: 1 }, id_name: "main_window".to_string() });

GraphicsApplication { application, file_tracker_handle, window_system_handle, input_system_handle, mouse_device_handle, renderer_handle, tick_count: 0, render_system_handle }
let audio_system_handle = Box::new(ahi::audio_hardware_interface::create_ahi());

GraphicsApplication { application, file_tracker_handle, window_system_handle, input_system_handle, mouse_device_handle, renderer_handle, tick_count: 0, render_system_handle, audio_system_handle }
}

fn initialize(&mut self, _arguments: std::env::Args) {
Expand Down
36 changes: 0 additions & 36 deletions src/audio/audio_system.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/audio/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
pub mod audio_system;
57 changes: 42 additions & 15 deletions src/input_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ impl InputManager {
let most_recent_record = action_records.max_by_key(|r| r.time);

if let Some(record) = most_recent_record {
let value = self.resolve_action_value_from_record(action, record);
let value = self.resolve_action_value_from_record(action, record).unwrap_or(Value::Bool(false));

match value {
Value::Vector2(v) => {
Expand Down Expand Up @@ -650,7 +650,7 @@ impl InputManager {
let action = &self.actions[input_event_handle.0 as usize];

if let Some(record) = self.records.iter().filter(|r| action.input_event_descriptions.iter().any(|ied| ied.input_source_handle == r.input_source_handle)).max_by_key(|r| r.time) {
let value = self.resolve_action_value_from_record(action, record);
let value = self.resolve_action_value_from_record(action, record).unwrap_or(Value::Bool(false));

InputEventState {
device_handle: device_handle.clone(),
Expand Down Expand Up @@ -683,10 +683,10 @@ impl InputManager {
}
}

fn resolve_action_value_from_record(&self, action: &InputAction, record: &Record) -> Value {
fn resolve_action_value_from_record(&self, action: &InputAction, record: &Record) -> Option<Value> {
let mapping = action.input_event_descriptions.iter().find(|ied| ied.input_source_handle == record.input_source_handle).unwrap();

match action.type_ {
let value = match action.type_ {
Types::Float => {
let float = match record.value {
Value::Bool(record_value) => {
Expand Down Expand Up @@ -720,18 +720,36 @@ impl InputManager {
}
}
}
_ => panic!("Not implemented!"),
_ => {
log::error!("Not implemented!");
return None;
},
};

Value::Float(float)
}
Types::Vector3 => {
match record.value {
Value::Bool(_) => panic!("Not implemented!"),
Value::Unicode(_) => panic!("Not implemented!"),
Value::Float(_) => panic!("Not implemented!"),
Value::Int(_) => panic!("Not implemented!"),
Value::Rgba(_) => panic!("Not implemented!"),
Value::Bool(_) => {
log::error!("Not implemented!");
return None;
},
Value::Unicode(_) => {
log::error!("Not implemented!");
return None;
},
Value::Float(_) => {
log::error!("Not implemented!");
return None;
},
Value::Int(_) => {
log::error!("Not implemented!");
return None;
},
Value::Rgba(_) => {
log::error!("Not implemented!");
return None;
},
Value::Vector2(record_value) => {
if let Some(function) = mapping.function {
if let Function::Sphere = function {
Expand All @@ -744,22 +762,31 @@ impl InputManager {
let y = y_pi.sin();
let z = x_pi.cos() * y_pi.cos();

let transformation = if let Value::Vector3(transformation) = mapping.mapping { transformation } else { panic!("Not implemented!"); };
let transformation = if let Value::Vector3(transformation) = mapping.mapping { transformation } else { log::error!("Not implemented!"); return None; };

Value::Vector3(Vector3 { x, y, z } * transformation)
} else {
panic!("Not implemented!");
log::error!("Not implemented!");
return None;
}
} else {
Value::Vector3(Vector3 { x: record_value.x, y: record_value.y, z: 0f32 })
}
},
Value::Vector3(value) => Value::Vector3(value),
Value::Quaternion(_) => panic!("Not implemented!"),
Value::Quaternion(_) => {
log::error!("Not implemented!");
return None;
},
}
}
_ => panic!("Not implemented!"),
}
_ => {
log::error!("Not implemented!");
return None;
},
};

Some(value)
}

fn get_input_source_from_input_source_action(&self, input_source_action: &InputSourceAction) -> Option<&InputSource> {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub mod file_tracker;
pub mod executor;
pub mod camera;
pub mod audio;
pub mod ahi;

pub mod math;
pub mod rendering;
Expand Down
55 changes: 55 additions & 0 deletions src/orchestrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,61 @@ mod tests {
assert_eq!(unsafe { COUNTER }, 1);
}

#[test]
fn events() {
let mut orchestrator = Orchestrator::new();

struct Component {
name: String,
value: u32,
}

// struct ComponentParameters {
// name: String,
// }

impl Entity for Component {}

impl super::Component for Component {
// type Parameters<'a> = ComponentParameters;
}

let handle: EntityHandle<Component> = orchestrator.spawn(Component { name: "test".to_string(), value: 1 });

struct System {

}

impl Entity for System {}
impl super::System for System {}

impl System {
fn new<'c>() -> EntityReturn<'c, System> {
EntityReturn::new(System {}).add_listener::<Component>()
}
}

static mut COUNTER: u32 = 0;

impl EntitySubscriber<Component> for System {
fn on_create(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle<Component>, component: &Component) {
unsafe {
COUNTER += 1;
}
}

fn on_update(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle<Component>, params: &Component) {}
}

let _: Option<EntityHandle<System>> = orchestrator.spawn_entity(System::new());

assert_eq!(unsafe { COUNTER }, 0);

let component: EntityHandle<Component> = orchestrator.spawn(Component { name: "test".to_string(), value: 1 });

assert_eq!(unsafe { COUNTER }, 1);
}

// #[test]
// fn test_systems() {
// let mut orchestrator = Orchestrator::new();
Expand Down
Loading

0 comments on commit 2712f86

Please sign in to comment.