Skip to content

Commit

Permalink
Show loudness
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolaschan committed Sep 9, 2024
1 parent b687297 commit 98307de
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 11 deletions.
1 change: 1 addition & 0 deletions insanity-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod audio_source;
pub mod user_input_event;
pub mod loudness;
25 changes: 25 additions & 0 deletions insanity-core/src/loudness.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pub fn calculate_loudness(samples: &[f32]) -> f64 {
if samples.is_empty() {
return 0.0;
}

// Calculate the root mean square (RMS)
let rms: f64 = (samples
.iter()
.map(|&s| {
let sample = s as f64;
sample * sample
})
.sum::<f64>()
/ samples.len() as f64)
.sqrt();

// Convert to decibels
let db = 20.0 * rms.log10();

// Map decibels to 0-100 range
// Assuming -60 dB as the minimum audible level and 0 dB as the maximum
let normalized_loudness = (db + 60.0) * (1.0 / 60.0);

normalized_loudness.clamp(0.0, 1.0)
}
2 changes: 2 additions & 0 deletions insanity-native-tui-app/src/clerver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ async fn run_receiver(
enable_denoise,
volume,
config.sample_rate,
app_event_sender.clone(),
id.clone(),
));
let processor_clone = processor.clone();
let config_clone = config.clone();
Expand Down
6 changes: 5 additions & 1 deletion insanity-native-tui-app/src/connection_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,11 @@ fn manage_peers(
}
let id = snow_public_keys_to_uuid(&socket.connection_info().public_key, &augmented_info.connection_info.public_key);
if let Some(managed_peer) = update_peer_info(
id, augmented_info, socket.clone(), app_event_tx.clone(), &mut managed_peers, sender_is_muted.clone()) {
id, augmented_info,
socket.clone(),
app_event_tx.clone(),
&mut managed_peers,
sender_is_muted.clone()) {
log::debug!("Updated peer info for {id} to: {:?}", managed_peer.info());
log::debug!("(Re)Connecting to peer {id}.");
reconnect(managed_peer);
Expand Down
18 changes: 18 additions & 0 deletions insanity-native-tui-app/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ use std::sync::{Arc, Mutex};

use cpal::{Sample, SampleRate};
use insanity_core::audio_source::SyncAudioSource;
use insanity_core::loudness::calculate_loudness;
use insanity_tui_adapter::AppEvent;
use log::error;
use nnnoiseless::DenoiseState;
use rubato_audio_source::ResampledAudioSource;
use serde::{Deserialize, Serialize};
use tokio::sync::mpsc::UnboundedSender;

use crate::realtime_buffer::RealTimeBuffer;
use crate::server::RealtimeAudioSource;
Expand Down Expand Up @@ -143,13 +147,17 @@ pub struct AudioProcessor<'a> {
denoiser: Mutex<MultiChannelDenoiser<'a>>,
chunk_buffer: Arc<Mutex<RealTimeBuffer<AudioChunk>>>,
audio_receiver: Mutex<ResampledAudioSource<RealtimeAudioSource>>,
app_event_sender: Option<UnboundedSender<AppEvent>>,
peer_id: String,
}

impl AudioProcessor<'_> {
pub fn new(
enable_denoise: Arc<AtomicBool>,
volume: Arc<Mutex<usize>>,
output_sample_rate: SampleRate,
app_event_sender: Option<UnboundedSender<AppEvent>>,
peer_id: String,
) -> Self {
let chunk_buffer = Arc::new(Mutex::new(RealTimeBuffer::new(10)));
let audio_receiver = RealtimeAudioSource::new(chunk_buffer.clone(), 48000, 2);
Expand All @@ -162,6 +170,8 @@ impl AudioProcessor<'_> {
denoiser: Mutex::new(MultiChannelDenoiser::new()),
audio_receiver: Mutex::new(audio_receiver),
chunk_buffer,
app_event_sender,
peer_id,
}
}

Expand All @@ -183,6 +193,14 @@ impl AudioProcessor<'_> {
chunk.audio_data = audio_data;
}

if let Some(app_event_sender) = &self.app_event_sender {
let loudness = calculate_loudness(&chunk.audio_data[..]);
let loudness_event = AppEvent::Loudness(self.peer_id.clone(), loudness);
if let Err(e) = app_event_sender.send(loudness_event) {
error!("Failed to send loudness event: {:?}", e);
}
}

let mut guard = self.chunk_buffer.lock().unwrap();
guard.set(chunk.sequence_number, chunk);
}
Expand Down
8 changes: 8 additions & 0 deletions insanity-tui-adapter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub struct Peer {
state: PeerState,
denoised: bool,
volume: usize,
loudness: f64,
}

impl Peer {
Expand All @@ -69,6 +70,7 @@ impl Peer {
state,
denoised,
volume,
loudness: 0.0,
}
}

Expand Down Expand Up @@ -116,6 +118,7 @@ pub enum AppEvent {
SetPeerDenoise(String, bool),
SetPeerVolume(String, usize),
MuteSelf(bool),
Loudness(String, f64),
}

pub struct App {
Expand Down Expand Up @@ -306,6 +309,11 @@ impl App {
AppEvent::MuteSelf(is_muted) => {
self.mute_self = is_muted;
}
AppEvent::Loudness(peer_id, loudness) => {
if let Some(peer) = self.peers.get_mut(&peer_id) {
peer.loudness = loudness;
}
}
}
}

Expand Down
34 changes: 24 additions & 10 deletions insanity-tui-adapter/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,31 @@ fn peer_row<'a>(peer: &Peer, selected: bool) -> Row<'a> {
)]));

let display_name = peer.display_name.as_ref().unwrap_or(&peer.id).to_string();

match peer.state {
crate::PeerState::Connected(ref address) => Row::new(vec![
Cell::from(denoise_symbol),
attributes,
Cell::from(Spans::from(vec![
Span::styled(display_name, style.fg(CONNECTED)),
Span::styled(" <-> ", style.fg(Color::DarkGray)),
Span::styled(address.clone(), style.fg(Color::Cyan)),
]))
.style(style),
]),
crate::PeerState::Connected(ref address) => {
let loudness_length = (display_name.len() as f64 * peer.loudness) as usize;
let display_name_with_loudness_bg = display_name
.chars()
.take(loudness_length)
.collect::<String>();
let display_name_normal_bg = display_name
.chars()
.skip(loudness_length)
.collect::<String>();

Row::new(vec![
Cell::from(denoise_symbol),
attributes,
Cell::from(Spans::from(vec![
Span::styled(display_name_with_loudness_bg, style.fg(Color::Yellow)),
Span::styled(display_name_normal_bg, style.fg(CONNECTED)),
Span::styled(" <-> ", style.fg(Color::DarkGray)),
Span::styled(address.clone(), style.fg(Color::Cyan)),
]))
.style(style),
])
}
crate::PeerState::Disconnected => Row::new(vec![
Cell::from(denoise_symbol),
attributes,
Expand Down

0 comments on commit 98307de

Please sign in to comment.