fix mic level scaling

This commit is contained in:
Emerald 2023-06-16 01:49:40 -04:00
parent 828bf6bb75
commit 2d03f1b5ff
Signed by: emerald
GPG Key ID: 420C9E1863CCB30F
5 changed files with 78 additions and 58 deletions

View File

@ -1,2 +1 @@
nodejs 19.8.1
rust-analyzer latest

View File

@ -33,7 +33,7 @@ fn monitor(world: &mut World) {
let level = Arc::new(Mutex::new(0.));
world.insert_resource(MicLevel(level.clone()));
let sens = Arc::new(Mutex::new(100.));
let sens = Arc::new(Mutex::new(1.));
world.insert_resource(MicSens(sens.clone()));
let stream = device
@ -47,9 +47,9 @@ fn monitor(world: &mut World) {
.unwrap();
},
move |err| {
println!("Audio error: {:?}", err);
error!("Audio error: {:?}", err);
},
Duration::from_millis(100).into(),
None, // Duration::from_millis(5).into(),
)
.unwrap();

View File

@ -5,9 +5,10 @@ use std::time::Duration;
use crate::audio::MicLevel;
pub enum MouthEvent {
Open,
Close,
#[derive(Resource, Clone, Copy)]
pub enum MouthState {
Opened,
Closed,
}
#[derive(Clone, Copy)]
@ -39,10 +40,10 @@ impl Plugin for TubePlugin {
fn build(&self, app: &mut App) {
app.add_startup_system(setup)
.add_system(audio_trigger.in_base_set(CoreSet::PreUpdate))
.add_system(run_animation)
.add_system(run_animation.run_if(resource_changed::<MouthState>()))
.add_system(sync_images)
.add_event::<MouthEvent>()
.insert_resource(TriggerThreshold(0.8));
.insert_resource(MouthState::Closed)
.insert_resource(TriggerThreshold(3.0));
}
}
@ -77,7 +78,7 @@ fn setup(mut commands: Commands, ass: Res<AssetServer>) {
}
fn audio_trigger(
mut events: EventWriter<MouthEvent>,
mut mouth_state: ResMut<MouthState>,
mic_level: Res<MicLevel>,
threshold: Res<TriggerThreshold>,
mut buffer: Local<f32>,
@ -85,10 +86,11 @@ fn audio_trigger(
time: Res<Time>,
) {
let level = mic_level.lock().expect("Poisoned mutex");
// info!("{level}");
if *level > **threshold {
if *buffer == 0. {
info!("Fire mouth open event");
events.send(MouthEvent::Open);
info!("Open mouth");
*mouth_state = MouthState::Opened;
*was_zero = false;
}
*buffer = 1000.;
@ -96,66 +98,64 @@ fn audio_trigger(
//TODO: make this adjustable
*buffer = (*buffer - (2500. * time.delta_seconds())).clamp(0., 1000.);
if *buffer == 0. && !*was_zero {
info!("Fire mouth closed event");
events.send(MouthEvent::Close);
info!("Close mouth");
*mouth_state = MouthState::Closed;
*was_zero = true;
}
}
}
fn run_animation(
mut events: EventReader<MouthEvent>,
mouth_state: Res<MouthState>,
tube_q: Query<(Entity, &TuberFrames, &Blinking), With<Tuber>>,
_anim_q: Query<&mut Animator<Transform>>,
mut commands: Commands,
) {
for event in events.iter() {
match event {
//TODO: in and out animations
MouthEvent::Open => {
let (tuber, frames, blinking) = tube_q.single();
let mut ent = commands.entity(tuber);
let tween = Tween::new(
EaseMethod::Linear,
Duration::from_millis(100),
TransformPositionLens {
start: Vec3::ZERO,
end: Vec3::new(0., 5., 0.),
},
)
.then(Tween::new(
EaseMethod::Linear,
Duration::from_millis(100),
TransformPositionLens {
start: Vec3::new(0., 5., 0.),
end: Vec3::ZERO,
},
));
match *mouth_state {
//TODO: in and out animations
MouthState::Opened => {
let (tuber, frames, blinking) = tube_q.single();
let mut ent = commands.entity(tuber);
let tween = Tween::new(
EaseMethod::Linear,
Duration::from_millis(100),
TransformPositionLens {
start: Vec3::ZERO,
end: Vec3::new(0., 5., 0.),
},
)
.then(Tween::new(
EaseMethod::Linear,
Duration::from_millis(100),
TransformPositionLens {
start: Vec3::new(0., 5., 0.),
end: Vec3::ZERO,
},
));
ent.insert(Animator::new(tween));
let new_state = if blinking.0 {
&frames.0[TuberState::MouthOpenEyesClosed as usize]
} else {
&frames.0[TuberState::MouthOpenEyesOpen as usize]
};
ent.insert(Animator::new(tween));
let new_state = if blinking.0 {
&frames.0[TuberState::MouthOpenEyesClosed as usize]
} else {
&frames.0[TuberState::MouthOpenEyesOpen as usize]
};
if let Some(handle) = new_state {
ent.insert(CurrentState(handle.clone()));
}
if let Some(handle) = new_state {
ent.insert(CurrentState(handle.clone()));
}
}
MouthEvent::Close => {
let (tuber, frames, blinking) = tube_q.single();
MouthState::Closed => {
let (tuber, frames, blinking) = tube_q.single();
let new_state = if blinking.0 {
&frames.0[TuberState::MouthClosedEyesClosed as usize]
} else {
&frames.0[TuberState::MouthClosedEyesOpen as usize]
};
let new_state = if blinking.0 {
&frames.0[TuberState::MouthClosedEyesClosed as usize]
} else {
&frames.0[TuberState::MouthClosedEyesOpen as usize]
};
if let Some(handle) = new_state {
commands.entity(tuber).insert(CurrentState(handle.clone()));
}
if let Some(handle) = new_state {
commands.entity(tuber).insert(CurrentState(handle.clone()));
}
}
}

View File

@ -4,7 +4,7 @@ use bevy::prelude::*;
use bevy_ninepatch::*;
use bevy_tweening::{lens::UiPositionLens, *};
use crate::{audio::MicLevel, utils::UiSizeLens};
use crate::{audio::MicLevel, tube::MouthState, utils::UiSizeLens};
#[derive(Component)]
pub struct LevelBars;
@ -55,6 +55,7 @@ pub(super) fn spawn_levels(
parent.spawn(NinePatchBundle {
style: Style {
size: Size::new(Val::Px(32.), Val::Auto),
padding: UiRect::all(Val::Px(5.)),
..default()
},
nine_patch_data: NinePatchData {
@ -111,6 +112,23 @@ pub(super) fn animate_mic_level(
}
}
pub(super) fn react_mic_level_color(
mut bar_q: Query<&mut BackgroundColor, With<MicLevelBar>>,
mouth_state: Res<MouthState>,
) {
for mut color in bar_q.iter_mut() {
match *mouth_state {
MouthState::Opened => {
*color = Color::GREEN.into();
}
MouthState::Closed => {
*color = Color::BLUE.into();
}
}
}
}
pub(super) fn hide(commands: &mut Commands, current_pos: UiRect, entity: Entity) {
let anim = Tween::new(
EaseFunction::BackInOut,

View File

@ -4,6 +4,8 @@ mod levels;
use bevy::prelude::*;
use bevy_ninepatch::NinePatchPlugin;
use crate::tube::MouthState;
use self::{
frames::{CardImages, FrameCards},
levels::LevelBars,
@ -26,6 +28,7 @@ impl Plugin for UiPlugin {
.add_system(handle_msg)
.add_system(levels::animate_mic_level)
.add_system(frames::update_card_images.before(frames::render_cards))
.add_system(levels::react_mic_level_color.run_if(resource_changed::<MouthState>()))
.add_startup_system(frames::render_cards)
.add_startup_system(levels::spawn_levels);
}