@@ -121,6 +121,7 @@ pub struct AudioRecorder {
121121 channels : u16 ,
122122 sample_rate : u32 ,
123123 gain_db : f32 ,
124+ mono : bool ,
124125}
125126
126127impl Default for AudioRecorder {
@@ -140,6 +141,7 @@ impl AudioRecorder {
140141 channels : 2 ,
141142 sample_rate : 48000 ,
142143 gain_db : 0.0 ,
144+ mono : false ,
143145 }
144146 }
145147
@@ -153,6 +155,11 @@ impl AudioRecorder {
153155 self
154156 }
155157
158+ pub fn with_mono ( mut self , mono : bool ) -> Self {
159+ self . mono = mono;
160+ self
161+ }
162+
156163 pub fn get_input_devices ( & self ) -> Result < Vec < AudioDeviceInfo > > {
157164 let devices = self
158165 . host
@@ -214,6 +221,7 @@ impl AudioRecorder {
214221 let samples = self . recorded_samples . clone ( ) ;
215222 let level_sender = self . level_sender . clone ( ) ;
216223 let channels = self . channels ;
224+ let mono = self . mono ;
217225
218226 let linear_gain = if self . gain_db == 0.0 {
219227 1.0
@@ -229,26 +237,45 @@ impl AudioRecorder {
229237 . build_input_stream (
230238 & config,
231239 move |data : & [ f32 ] , _: & cpal:: InputCallbackInfo | {
232- let gain_samples: Vec < f32 > = data
233- . iter ( )
234- . map ( |s| ( s * linear_gain) . clamp ( -1.0 , 1.0 ) )
235- . collect ( ) ;
240+ let processed_samples: Vec < f32 > = if mono && channels > 1 {
241+ let num_channels = channels as usize ;
242+ let num_frames = data. len ( ) / num_channels;
243+ let mut mono_samples = Vec :: with_capacity ( num_frames) ;
244+
245+ for frame_idx in 0 ..num_frames {
246+ let start = frame_idx * num_channels;
247+ let end = ( start + num_channels) . min ( data. len ( ) ) ;
248+ let frame_samples = & data[ start..end] ;
249+ let avg = frame_samples. iter ( ) . sum :: < f32 > ( ) / num_channels as f32 ;
250+ mono_samples. push ( ( avg * linear_gain) . clamp ( -1.0 , 1.0 ) ) ;
251+ }
252+ mono_samples
253+ } else {
254+ data. iter ( )
255+ . map ( |s| ( s * linear_gain) . clamp ( -1.0 , 1.0 ) )
256+ . collect ( )
257+ } ;
236258
237259 if let Ok ( mut s) = samples. lock ( ) {
238- s. extend_from_slice ( & gain_samples ) ;
260+ s. extend_from_slice ( & processed_samples ) ;
239261 }
240262
241263 if let Some ( sender) = & level_sender
242264 && let Ok ( mut buf) = level_buffer_clone. lock ( )
243265 {
244- buf. extend_from_slice ( & gain_samples ) ;
266+ buf. extend_from_slice ( & processed_samples ) ;
245267
246268 // Calculate and send level every ~100ms worth of samples
247- let threshold = ( config. sample_rate as usize / 10 ) * channels as usize ;
269+ let threshold = if mono && channels > 1 {
270+ config. sample_rate as usize / 10
271+ } else {
272+ ( config. sample_rate as usize / 10 ) * channels as usize
273+ } ;
248274 if buf. len ( ) < threshold {
249275 return ;
250276 }
251277
278+ // For level display, always show left/right even if recording mono
252279 let levels: ( f32 , f32 ) = if channels > 1 {
253280 let parts = split_audio_channels ( buf. clone ( ) , channels as usize ) ;
254281
@@ -301,9 +328,15 @@ impl AudioRecorder {
301328 Vec :: new ( )
302329 } ;
303330
331+ let output_channels = if self . mono && self . channels > 1 {
332+ 1
333+ } else {
334+ self . channels
335+ } ;
336+
304337 Ok ( RecordedAudio {
305338 samples,
306- channels : self . channels ,
339+ channels : output_channels ,
307340 sample_rate : self . sample_rate ,
308341 } )
309342 }
0 commit comments