11use std:: { fs:: File , io:: BufReader , path:: PathBuf } ;
22
3- use hound:: WavReader ;
3+ use hound:: { WavReader , WavSpec } ;
44
55use super :: time:: AudioTime ;
66
7- pub struct Buffer {
8- reader : WavReader < BufReader < File > > ,
7+ pub type WavFileReader = WavReader < BufReader < File > > ;
8+
9+ pub trait SampleReader {
10+ fn extract_audio (
11+ & mut self ,
12+ start : AudioTime ,
13+ end : AudioTime ,
14+ ) -> Result < Vec < i16 > , OutOfBoundsError > ;
15+ }
16+
17+ pub struct Buffer < R > {
18+ reader : R ,
19+ spec : WavSpec ,
920}
1021
1122#[ derive( Debug ) ]
@@ -17,34 +28,17 @@ impl From<std::io::Error> for OutOfBoundsError {
1728 }
1829}
1930
20- impl Buffer {
21- pub fn new ( buffer_file : PathBuf ) -> Buffer {
31+ impl Buffer < WavReader < BufReader < File > > > {
32+ pub fn new ( buffer_file : PathBuf ) -> Self {
2233 let reader = hound:: WavReader :: open ( buffer_file) . unwrap ( ) ;
23- Self { reader }
34+ let spec = reader. spec ( ) ;
35+ Self { reader, spec }
2436 }
37+ }
2538
26- pub fn spec ( & self ) -> hound:: WavSpec {
27- self . reader . spec ( )
28- }
29-
30- fn extract_audio (
31- & mut self ,
32- start : AudioTime ,
33- end : AudioTime ,
34- ) -> Result < Vec < i16 > , OutOfBoundsError > {
35- let num_samples = ( end - start) . interleaved_sample_num ;
36- self . reader . seek ( start. frame_num ( ) ) ?;
37- let samples_interleaved: Vec < i16 > = self
38- . reader
39- . samples :: < i16 > ( )
40- . take ( num_samples as usize )
41- . collect :: < Result < Vec < _ > , hound:: Error > > ( )
42- . map_err ( |_| OutOfBoundsError ) ?;
43- if samples_interleaved. len ( ) as u32 != num_samples {
44- Err ( OutOfBoundsError { } )
45- } else {
46- Ok ( samples_interleaved)
47- }
39+ impl < R : SampleReader > Buffer < R > {
40+ pub fn spec ( & self ) -> & hound:: WavSpec {
41+ & self . spec
4842 }
4943
5044 pub fn get_volume_at ( & mut self , time : AudioTime ) -> Result < f64 , OutOfBoundsError > {
@@ -61,11 +55,32 @@ impl Buffer {
6155 ) ;
6256 let inv_len = 1.0 / ( ( end. interleaved_sample_num - start. interleaved_sample_num ) as f64 ) ;
6357 let inv_i16 = 1.0 / ( i16:: MAX as f64 ) ;
64- let samples = self . extract_audio ( start, end) ?;
58+ let samples = self . reader . extract_audio ( start, end) ?;
6559 let average: f64 = samples
6660 . iter ( )
6761 . map ( |x| ( * x as f64 ) . abs ( ) * inv_len * inv_i16)
6862 . sum :: < f64 > ( ) ;
6963 Ok ( average)
7064 }
7165}
66+
67+ impl SampleReader for WavReader < BufReader < File > > {
68+ fn extract_audio (
69+ & mut self ,
70+ start : AudioTime ,
71+ end : AudioTime ,
72+ ) -> Result < Vec < i16 > , OutOfBoundsError > {
73+ let num_samples = ( end - start) . interleaved_sample_num ;
74+ self . seek ( start. frame_num ( ) ) ?;
75+ let samples_interleaved: Vec < i16 > = self
76+ . samples :: < i16 > ( )
77+ . take ( num_samples as usize )
78+ . collect :: < Result < Vec < _ > , hound:: Error > > ( )
79+ . map_err ( |_| OutOfBoundsError ) ?;
80+ if samples_interleaved. len ( ) as u32 != num_samples {
81+ Err ( OutOfBoundsError { } )
82+ } else {
83+ Ok ( samples_interleaved)
84+ }
85+ }
86+ }
0 commit comments