diff --git a/assets/buzz.mp3 b/assets/buzz.mp3 new file mode 100644 index 0000000..1c0543e Binary files /dev/null and b/assets/buzz.mp3 differ diff --git a/src/lib/buzzer.rs b/src/lib/buzzer.rs index b03f3f6..febe2d2 100644 --- a/src/lib/buzzer.rs +++ b/src/lib/buzzer.rs @@ -1,13 +1,11 @@ use std::collections::HashSet; -use std::f32::consts::TAU; -use std::io::Cursor; use std::sync::Arc; use serenity::all::{ ButtonStyle, ChannelId, CreateActionRow, CreateButton, GuildId, MessageId, UserId, }; use serenity::prelude::TypeMapKey; -use songbird::input::{Input, RawAdapter}; +use songbird::input::Input; use tokio::sync::Mutex; pub const BUZZER_CUSTOM_ID: &str = "buzzer:press"; @@ -87,33 +85,11 @@ fn control_components(is_open: bool, session_ended: bool) -> Vec Input { - const SAMPLE_RATE: u32 = 48_000; - const DURATION_SECONDS: f32 = 0.4; - const FREQUENCY_HZ: f32 = 180.0; + const BUZZ_MP3: &[u8] = include_bytes!("../../assets/buzz.mp3"); - let sample_count = (SAMPLE_RATE as f32 * DURATION_SECONDS) as usize; - let mut pcm = Vec::with_capacity(sample_count * 2 * size_of::()); - - for sample_index in 0..sample_count { - let time = sample_index as f32 / SAMPLE_RATE as f32; - let progress = sample_index as f32 / sample_count as f32; - let attack = (time / 0.01).min(1.0); - let release = ((1.0 - progress) / 0.08).min(1.0); - let envelope = attack * release; - - // Odd harmonics give the tone the rasp of a physical game-show buzzer. - let phase = TAU * FREQUENCY_HZ * time; - let value = - envelope * (phase.sin() + (3.0 * phase).sin() / 3.0 + (5.0 * phase).sin() / 5.0) * 0.32; - - for _ in 0..2 { - pcm.extend_from_slice(&value.to_le_bytes()); - } - } - - RawAdapter::new(Cursor::new(pcm), SAMPLE_RATE, 2).into() + BUZZ_MP3.into() } /// The application's single active buzzer session. diff --git a/src/main.rs b/src/main.rs index 2696f8b..f03dec2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -83,6 +83,17 @@ impl EventHandler for Handler { async fn ready(&self, ctx: Context, ready: Ready) { println!("{} is connected!", ready.user.name); + // Commands were previously registered per guild. Clear those legacy + // registrations so only the global command set appears. + for guild in &ready.guilds { + if let Err(why) = guild.id.set_commands(&ctx.http, Vec::new()).await { + println!( + "Cannot remove legacy slash commands from guild {}: {why}", + guild.id + ); + } + } + let commands = vec![ commands::start::register(), commands::reset::register(),