@@ -4,6 +4,7 @@ use std::os::raw::c_void;
4
4
use std:: slice;
5
5
6
6
use cubeb_backend:: SampleFormat ;
7
+ use num:: cast:: AsPrimitive ;
7
8
8
9
use super :: ringbuf:: RingBuffer ;
9
10
@@ -36,12 +37,25 @@ fn drop_first_n_channels_in_place<T: Copy>(
36
37
}
37
38
}
38
39
40
+ trait DataType : AsPrimitive < f32 > {
41
+ fn from_f32 ( v : f32 ) -> Self ;
42
+ }
43
+
44
+ impl < T : AsPrimitive < f32 > > DataType for T
45
+ where
46
+ f32 : AsPrimitive < T > ,
47
+ {
48
+ fn from_f32 ( v : f32 ) -> T {
49
+ v. as_ ( )
50
+ }
51
+ }
52
+
39
53
// It can be that the a stereo microphone is in use, but the user asked for mono input. In this
40
54
// particular case, downmix the stereo pair into a mono channel. In all other cases, simply drop
41
55
// the remaining channels before appending to the ringbuffer, becauses there is no right or wrong
42
56
// way to do this, unlike with the output side, where proper channel matrixing can be done.
43
57
// Return the number of valid samples in the buffer.
44
- fn remix_or_drop_channels < T : Copy + std :: ops :: Add < Output = T > > (
58
+ fn remix_or_drop_channels < T : DataType > (
45
59
input_channels : usize ,
46
60
output_channels : usize ,
47
61
data : & mut [ T ] ,
@@ -56,7 +70,8 @@ fn remix_or_drop_channels<T: Copy + std::ops::Add<Output = T>>(
56
70
if input_channels == 2 && output_channels == 1 {
57
71
let mut read_idx = 0 ;
58
72
for ( write_idx, _) in ( 0 ..frame_count) . enumerate ( ) {
59
- data[ write_idx] = data[ read_idx] + data[ read_idx + 1 ] ;
73
+ let avg = ( data[ read_idx] . as_ ( ) + data[ read_idx + 1 ] . as_ ( ) ) / 2.0 ;
74
+ data[ write_idx] = DataType :: from_f32 ( avg) ;
60
75
read_idx += 2 ;
61
76
}
62
77
return output_channels * frame_count;
@@ -76,7 +91,7 @@ fn remix_or_drop_channels<T: Copy + std::ops::Add<Output = T>>(
76
91
output_channels * frame_count
77
92
}
78
93
79
- fn process_data < T : Copy + std :: ops :: Add < Output = T > > (
94
+ fn process_data < T : DataType > (
80
95
data : * mut c_void ,
81
96
frame_count : usize ,
82
97
input_channel_count : usize ,
@@ -353,3 +368,13 @@ impl fmt::Debug for BufferManager {
353
368
Ok ( ( ) )
354
369
}
355
370
}
371
+
372
+ #[ cfg( test) ]
373
+ mod tests {
374
+ use super :: * ;
375
+ #[ test]
376
+ fn remix_stereo_ints ( ) {
377
+ let mut data = [ i16:: MAX / 2 + 1 , i16:: MAX / 2 + 1 ] ;
378
+ assert_eq ! ( remix_or_drop_channels( 2 , 1 , & mut data, 1 ) , 1 ) ;
379
+ }
380
+ }
0 commit comments