Browse and listen to thousands of radio stations across the globe right from your terminal ๐ŸŒŽ ๐Ÿ“ป ๐ŸŽตโœจ
radio rust tokio web-radio command-line-tool tui

app: Volume: use percentage to store

This prevents the problems of floating point, usually the person just
wants to adjust the percentage, doesn't care about the actual ratio.

Changed files
+25 -22
src
+25 -22
src/app.rs
··· 37 37 /// Volume of the player. 38 38 #[derive(Debug, Clone, PartialEq)] 39 39 pub struct Volume { 40 - /// Raw volume. 41 - volume: f32, 40 + /// Raw volume stored as percentage. 41 + raw_volume_percent: f32, 42 42 /// Is muted? 43 43 is_muted: bool, 44 44 } 45 45 46 46 impl Volume { 47 47 /// Create a new [`Volume`]. 48 - pub const fn new(volume: f32, is_muted: bool) -> Self { 49 - Self { volume, is_muted } 48 + pub const fn new(raw_volume_percent: f32, is_muted: bool) -> Self { 49 + Self { 50 + raw_volume_percent, 51 + is_muted, 52 + } 50 53 } 51 54 52 - /// Get the current volume. Returns `0.0` if muted. 53 - pub const fn volume(&self) -> f32 { 55 + /// Get the current volume ratio. Returns `0.0` if muted. 56 + pub const fn volume_ratio(&self) -> f32 { 54 57 if self.is_muted { 55 58 0.0 56 59 } else { 57 - self.volume 60 + self.raw_volume_percent / 100.0 58 61 } 59 62 } 60 63 61 - /// Get the raw volume. 62 - pub const fn raw_volume(&self) -> f32 { 63 - self.volume 64 + /// Get the raw volume percent. 65 + pub const fn raw_volume_percent(&self) -> f32 { 66 + self.raw_volume_percent 64 67 } 65 68 66 69 /// Is volume muted? ··· 73 76 self.is_muted = !self.is_muted; 74 77 } 75 78 76 - /// Change the volume by the given step. 79 + /// Change the volume by the given step percent. 77 80 /// 78 81 /// To increase the volume, use a positive step. To decrease the 79 82 /// volume, use a negative step. 80 - pub const fn change_volume(&mut self, step: f32) { 81 - self.volume += step; 83 + pub const fn change_volume(&mut self, step_percent: f32) { 84 + self.raw_volume_percent += step_percent; 82 85 // limit to 0 volume, no upper bound 83 - self.volume = self.volume.max(0.0); 86 + self.raw_volume_percent = self.raw_volume_percent.max(0.0); 84 87 } 85 88 } 86 89 87 90 impl Default for Volume { 88 91 fn default() -> Self { 89 - Self::new(1.0, false) 92 + Self::new(100.0, false) 90 93 } 91 94 } 92 95 ··· 239 242 render_line( 240 243 "Volume ", 241 244 &if state.volume.is_muted() { 242 - format!("{} muted", state.volume.raw_volume()) 245 + format!("{}% muted", state.volume.raw_volume_percent()) 243 246 } else { 244 - format!("{}", state.volume.raw_volume()) 247 + format!("{}%", state.volume.raw_volume_percent()) 245 248 }, 246 249 Rect { 247 250 x: size.x, ··· 388 391 389 392 let lower_volume = || { 390 393 let mut state = state.lock().unwrap(); 391 - state.volume.change_volume(-0.01); 394 + state.volume.change_volume(-1.0); 392 395 sink_cmd_tx 393 - .send(SinkCommand::SetVolume(state.volume.volume())) 396 + .send(SinkCommand::SetVolume(state.volume.volume_ratio())) 394 397 .expect("receiver never dropped"); 395 398 }; 396 399 397 400 let raise_volume = || { 398 401 let mut state = state.lock().unwrap(); 399 - state.volume.change_volume(0.01); 402 + state.volume.change_volume(1.0); 400 403 sink_cmd_tx 401 - .send(SinkCommand::SetVolume(state.volume.volume())) 404 + .send(SinkCommand::SetVolume(state.volume.volume_ratio())) 402 405 .expect("receiver never dropped"); 403 406 }; 404 407 ··· 406 409 let mut state = state.lock().unwrap(); 407 410 state.volume.toggle_mute(); 408 411 sink_cmd_tx 409 - .send(SinkCommand::SetVolume(state.volume.volume())) 412 + .send(SinkCommand::SetVolume(state.volume.volume_ratio())) 410 413 .expect("receiver never dropped"); 411 414 }; 412 415