11use anyhow:: { Result , anyhow} ;
22use claxon:: { FlacReader , FlacReaderOptions } ;
33use flac_bound:: FlacEncoder ;
4- use md5:: { Digest , Md5 } ;
54use metaflac:: { Block , Tag } ;
65use std:: {
76 path:: Path ,
@@ -13,15 +12,14 @@ use std::{
1312
1413pub const CURRENT_VENDOR : & str = "reference libFLAC 1.5.0 20250211" ;
1514
16- fn write_tags ( filename : impl AsRef < Path > , hash : Vec < u8 > ) -> Result < ( ) > {
15+ fn write_tags ( filename : impl AsRef < Path > ) -> Result < ( ) > {
1716 let tags = Tag :: read_from_path ( & filename) ?;
1817 let temp_name = filename. as_ref ( ) . with_extension ( "tmp" ) ;
1918 let mut output = Tag :: read_from_path ( & temp_name) ?;
2019
21- let mut streaminfo = tags. get_streaminfo ( ) . unwrap ( ) . clone ( ) ;
22-
23- streaminfo. md5 = hash;
24- output. set_streaminfo ( streaminfo) ;
20+ if let Some ( streaminfo) = tags. get_streaminfo ( ) {
21+ output. set_streaminfo ( streaminfo. clone ( ) ) ;
22+ }
2523
2624 for block in tags. blocks ( ) {
2725 match block {
@@ -50,7 +48,6 @@ fn encode_file(filename: impl AsRef<Path>, handler: Arc<AtomicBool>) -> Result<b
5048 let streaminfo = decoder. streaminfo ( ) ;
5149
5250 let num_channels: usize = streaminfo. channels . try_into ( ) ?;
53- let bps = streaminfo. bits_per_sample ;
5451
5552 let mut encoder = if let Some ( encoder) = FlacEncoder :: new ( ) {
5653 if let Ok ( encoder) = encoder
@@ -69,50 +66,44 @@ fn encode_file(filename: impl AsRef<Path>, handler: Arc<AtomicBool>) -> Result<b
6966 return Err ( anyhow ! ( "failed to create encoder" ) ) ;
7067 } ;
7168
72- let mut hasher = Md5 :: new ( ) ;
73-
74- let mut samples_iter = decoder. samples ( ) ;
75-
76- let mut buf = Vec :: with_capacity ( num_channels) ;
69+ let mut frame_reader = decoder. blocks ( ) ;
70+ let mut buffer = Vec :: new ( ) ;
71+ let mut block_buffer =
72+ Vec :: with_capacity ( streaminfo. max_block_size as usize * num_channels as usize ) ;
7773
78- while let Some ( Ok ( sample) ) = samples_iter. next ( ) {
79- if handler. load ( Ordering :: SeqCst ) {
80- match bps {
81- 16 => {
82- hasher. update ( i16:: try_from ( sample) ?. to_le_bytes ( ) ) ;
83- }
84- 24 => {
85- hasher. update ( if let Some ( conv_sample) = i24:: i24:: try_from_i32 ( sample) {
86- conv_sample. to_le_bytes ( )
87- } else {
88- return Err ( anyhow ! ( "failed to hash samples" ) ) ;
89- } ) ;
90- }
91- 32 => {
92- hasher. update ( sample. to_le_bytes ( ) ) ;
74+ loop {
75+ if !handler. load ( Ordering :: SeqCst ) {
76+ let _ = encoder. finish ( ) ;
77+ std:: fs:: remove_file ( temp_name) ?;
78+ return Ok ( true ) ;
79+ }
80+ match frame_reader. read_next_or_eof ( block_buffer) {
81+ Ok ( Some ( block) ) => {
82+ for sample in 0 ..( block. len ( ) / block. channels ( ) ) {
83+ for ch in 0 ..block. channels ( ) {
84+ buffer. push ( block. sample ( ch, sample) ) ;
85+ }
9386 }
94- _ => { }
95- }
96- buf. push ( sample) ;
9787
98- if num_channels == buf. len ( ) {
99- if let Err ( _) = encoder. process_interleaved ( & buf, 1 ) {
100- return Err ( anyhow ! ( "failed to process samples:\t {:?}" , encoder. state( ) ) ) ;
88+ if let Err ( _) = encoder. process_interleaved ( & buffer, block. len ( ) / block. channels ( ) )
89+ {
90+ return Err ( anyhow ! (
91+ "Error while processing samples:\t {:?}" ,
92+ encoder. state( )
93+ ) ) ;
10194 } ;
102- buf. clear ( ) ;
95+ buffer. clear ( ) ;
96+ block_buffer = block. into_buffer ( ) ;
10397 }
104- } else {
105- let _ = std:: fs:: remove_file ( temp_name) ;
106- return Ok ( true ) ;
98+ Ok ( None ) => break ,
99+ Err ( error) => return Err ( error. into ( ) ) ,
107100 }
108101 }
109102
110103 if let Err ( enc) = encoder. finish ( ) {
111104 return Err ( anyhow ! ( "Encoding failed:\t {:?}" , enc. state( ) ) ) ;
112105 }
113-
114- let hash = hasher. finalize ( ) . to_vec ( ) ;
115- write_tags ( & filename, hash) ?;
106+ write_tags ( & filename) ?;
116107 std:: fs:: rename ( temp_name, filename) ?;
117108 Ok ( false )
118109}
@@ -154,11 +145,12 @@ mod tests {
154145 std:: fs:: copy ( name, tempname) . unwrap ( ) ;
155146 let handler = Arc :: new ( AtomicBool :: new ( true ) ) ;
156147 encode_file ( name, handler) . unwrap ( ) ;
157- let target_md5 = FlacReader :: open ( tempname) . unwrap ( ) . streaminfo ( ) . md5sum ;
158- let temp_md5 = FlacReader :: open ( name) . unwrap ( ) . streaminfo ( ) . md5sum ;
159-
148+ let output = std:: process:: Command :: new ( "flac" )
149+ . arg ( "-wts" )
150+ . arg ( name)
151+ . status ( ) ;
160152 std:: fs:: rename ( tempname, name) . unwrap ( ) ;
161- assert_eq ! ( target_md5 , temp_md5 ) ;
153+ assert ! ( output . unwrap ( ) . success ( ) ) ;
162154 }
163155
164156 #[ test]
@@ -168,11 +160,12 @@ mod tests {
168160 std:: fs:: copy ( name, tempname) . unwrap ( ) ;
169161 let handler = Arc :: new ( AtomicBool :: new ( true ) ) ;
170162 encode_file ( name, handler) . unwrap ( ) ;
171- let target_md5 = FlacReader :: open ( tempname) . unwrap ( ) . streaminfo ( ) . md5sum ;
172- let temp_md5 = FlacReader :: open ( name) . unwrap ( ) . streaminfo ( ) . md5sum ;
173-
163+ let output = std:: process:: Command :: new ( "flac" )
164+ . arg ( "-wts" )
165+ . arg ( name)
166+ . status ( ) ;
174167 std:: fs:: rename ( tempname, name) . unwrap ( ) ;
175- assert_eq ! ( target_md5 , temp_md5 ) ;
168+ assert ! ( output . unwrap ( ) . success ( ) ) ;
176169 }
177170
178171 #[ test]
@@ -182,10 +175,11 @@ mod tests {
182175 std:: fs:: copy ( name, tempname) . unwrap ( ) ;
183176 let handler = Arc :: new ( AtomicBool :: new ( true ) ) ;
184177 encode_file ( name, handler) . unwrap ( ) ;
185- let target_md5 = FlacReader :: open ( tempname) . unwrap ( ) . streaminfo ( ) . md5sum ;
186- let temp_md5 = FlacReader :: open ( name) . unwrap ( ) . streaminfo ( ) . md5sum ;
187-
178+ let output = std:: process:: Command :: new ( "flac" )
179+ . arg ( "-wts" )
180+ . arg ( name)
181+ . status ( ) ;
188182 std:: fs:: rename ( tempname, name) . unwrap ( ) ;
189- assert_eq ! ( target_md5 , temp_md5 ) ;
183+ assert ! ( output . unwrap ( ) . success ( ) ) ;
190184 }
191185}
0 commit comments