when osu sound i guess
1#![windows_subsystem = "windows"] 2 3use std::collections::HashSet; 4use std::{collections::HashMap, time::Duration}; 5 6use device_query::{DeviceState, Keycode}; 7use quad_snd::{AudioContext, Sound}; 8 9fn main() { 10 let ctx = AudioContext::new(); 11 let sounds = std::fs::read_dir("sounds") 12 .expect("cant read sounds") 13 .flat_map(|f| { 14 let p = f.ok()?.path(); 15 let n = p.file_stem()?.to_string_lossy().into_owned(); 16 (n != "LICENSE" && n != "README").then(|| { 17 ( 18 n, 19 Sound::load(&ctx, &std::fs::read(p).expect("can't load sound")), 20 ) 21 }) 22 }) 23 .collect::<HashMap<String, Sound>>(); 24 let play_sound = |name: &str| { 25 let sound = sounds.get(name).unwrap(); 26 sound.play(&ctx, Default::default()); 27 }; 28 let play_sound_for_key = |key: Keycode| match key { 29 Keycode::CapsLock => play_sound("caps"), 30 Keycode::Delete | Keycode::Backspace => play_sound("delete"), 31 Keycode::Up | Keycode::Down | Keycode::Left | Keycode::Right => play_sound("movement"), 32 _ => { 33 let no = fastrand::u8(1..=4); 34 play_sound(&format!("press-{no}")); 35 } 36 }; 37 38 let state = DeviceState::new(); 39 let mut previously_held_keys = HashSet::<Keycode>::new(); 40 let mut key_press_times = HashMap::<Keycode, std::time::Instant>::new(); 41 let mut last_sound_time = std::time::Instant::now(); 42 let mut sounds_enabled = true; // Toggle for enabling/disabling sounds 43 44 let initial_delay = Duration::from_millis(500); // Wait 500ms before starting to repeat 45 let repeat_interval = Duration::from_millis(50); // Then repeat every 50ms 46 47 loop { 48 let currently_held_keys: HashSet<Keycode> = state.query_keymap().into_iter().collect(); 49 50 // Check for toggle hotkey (Ctrl + Alt + L/R Shift + C) 51 let hotkey_combo = [ 52 [Keycode::LControl, Keycode::RControl], // Either left or right control 53 [Keycode::LAlt, Keycode::RAlt], // Either left or right alt 54 [Keycode::LShift, Keycode::RShift], // Either left or right shift 55 [Keycode::C, Keycode::C], // C key (duplicated for array consistency) 56 ]; 57 58 let check_hotkey = |current: &HashSet<Keycode>, previous: &HashSet<Keycode>| { 59 hotkey_combo.iter().all(|key_group| { 60 key_group 61 .iter() 62 .any(|key| current.contains(key) || previous.contains(key)) 63 }) 64 }; 65 66 let hotkey_active = check_hotkey(&currently_held_keys, &previously_held_keys); 67 let hotkey_was_active = check_hotkey(&previously_held_keys, &HashSet::new()); 68 69 if hotkey_active && !hotkey_was_active { 70 sounds_enabled = !sounds_enabled; 71 } 72 73 // Only process sound logic if sounds are enabled 74 if sounds_enabled { 75 // Track when keys were first pressed 76 for key in &currently_held_keys { 77 if !previously_held_keys.contains(key) { 78 // Key just pressed, record the time and play initial sound 79 key_press_times.insert(*key, std::time::Instant::now()); 80 play_sound_for_key(*key); 81 } 82 } 83 84 // Remove timing info for released keys 85 key_press_times.retain(|key, _| currently_held_keys.contains(key)); 86 87 // Play repeating sounds every 50ms, but only after initial delay 88 if last_sound_time.elapsed() >= repeat_interval { 89 let now = std::time::Instant::now(); 90 for key in &currently_held_keys { 91 if is_modifier_key(key) { 92 continue; 93 } 94 if let Some(press_time) = key_press_times.get(key) { 95 // Only repeat if key has been held longer than initial delay 96 if now.duration_since(*press_time) >= initial_delay { 97 play_sound_for_key(*key); 98 } 99 } 100 } 101 last_sound_time = now; 102 } 103 } else { 104 // Clear key press times when sounds are disabled to avoid stale data 105 key_press_times.clear(); 106 } 107 108 previously_held_keys = currently_held_keys; 109 110 // Buffer inputs at lower interval (5ms) 111 std::thread::sleep(Duration::from_millis(5)); 112 } 113} 114 115fn is_modifier_key(key: &Keycode) -> bool { 116 matches!( 117 key, 118 Keycode::LShift 119 | Keycode::RShift 120 | Keycode::LControl 121 | Keycode::RControl 122 | Keycode::RAlt 123 | Keycode::LAlt 124 | Keycode::RMeta 125 | Keycode::LMeta 126 | Keycode::CapsLock 127 ) 128}