11use crate :: common:: assert_error_traits;
22use crate :: Source ;
3+ use crate :: Sample ;
34use hound:: { SampleFormat , WavSpec } ;
45use std:: io:: { self , Write } ;
56use std:: path;
@@ -29,7 +30,7 @@ assert_error_traits!(ToWavError);
2930/// # Note
3031/// This is a convenience wrapper around `wav_to_writer`
3132pub fn wav_to_file (
32- source : impl Source ,
33+ source : impl Source , // TODO make this take a spanless source
3334 wav_file : impl AsRef < path:: Path > ,
3435) -> Result < ( ) , ToWavError > {
3536 let mut file = std:: fs:: File :: create ( wav_file)
@@ -58,7 +59,7 @@ pub fn wav_to_file(
5859/// # Ok::<(), Box<dyn std::error::Error>>(())
5960/// ```
6061pub fn wav_to_writer (
61- source : impl Source ,
62+ source : impl Source , // TODO make this take a spanless source
6263 writer : & mut ( impl io:: Write + io:: Seek ) ,
6364) -> Result < ( ) , ToWavError > {
6465 let format = WavSpec {
@@ -72,12 +73,15 @@ pub fn wav_to_writer(
7273 let mut writer = hound:: WavWriter :: new ( & mut writer, format)
7374 . map_err ( Arc :: new)
7475 . map_err ( ToWavError :: Creating ) ?;
75- for sample in source {
76+
77+ let whole_frames = WholeFrames :: new ( source) ;
78+ for sample in whole_frames {
7679 writer
7780 . write_sample ( sample)
7881 . map_err ( Arc :: new)
7982 . map_err ( ToWavError :: Writing ) ?;
8083 }
84+
8185 writer
8286 . finalize ( )
8387 . map_err ( Arc :: new)
@@ -90,6 +94,40 @@ pub fn wav_to_writer(
9094 Ok ( ( ) )
9195}
9296
97+ struct WholeFrames < I : Iterator < Item =Sample > > {
98+ buffer : Vec < Sample > ,
99+ pos : usize ,
100+ source : I
101+ }
102+
103+ impl < S : Source > WholeFrames < S > {
104+ fn new ( source : S ) -> Self {
105+ Self {
106+ buffer : vec ! [ 0.0 ; source. channels( ) . get( ) . into( ) ] ,
107+ pos : source. channels ( ) . get ( ) . into ( ) ,
108+ source,
109+ }
110+ }
111+ }
112+
113+ impl < I : Iterator < Item = Sample > > Iterator for WholeFrames < I > {
114+ type Item = Sample ;
115+
116+ fn next ( & mut self ) -> Option < Sample > {
117+ if self . pos >= self . buffer . len ( ) {
118+ for sample in & mut self . buffer {
119+ * sample = self . source . next ( ) ?;
120+ }
121+ self . pos = 0 ;
122+ }
123+
124+ let to_yield = self . buffer [ self . pos ] ;
125+ self . pos += 1 ;
126+ Some ( to_yield)
127+ }
128+ }
129+
130+
93131#[ cfg( test) ]
94132mod test {
95133 use super :: wav_to_file;
0 commit comments