@@ -13,6 +13,10 @@ use symphonia::core::io::MediaSourceStream;
1313use symphonia:: core:: meta:: MetadataOptions ;
1414use symphonia:: core:: probe:: Hint ;
1515
16+ mod build_time {
17+ include ! ( concat!( env!( "OUT_DIR" ) , "/build_time.rs" ) ) ;
18+ }
19+
1620#[ derive( Parser ) ]
1721#[ command( author, version, about, long_about = None ) ]
1822struct Args {
@@ -138,33 +142,12 @@ fn read_generic_audio(path: &str) -> Result<(Vec<f32>, u32), Box<dyn std::error:
138142 Ok ( ( merged_samples, sample_rate) )
139143}
140144
141- fn main ( ) {
142- let args = Args :: parse ( ) ;
143-
144- let output_path = args. output . unwrap_or_else ( || {
145- let input_path = std:: path:: Path :: new ( & args. input ) ;
146- let stem = input_path. file_stem ( ) . unwrap_or_default ( ) ;
147- format ! ( "{}.png" , stem. to_string_lossy( ) )
148- } ) ;
149-
150- let ( samples, sample_rate) =
151- read_audio_samples ( & args. input ) . expect ( "Failed to read audio file" ) ;
152-
153- let fft_size = args. fft_size ;
154- let hop_size = args. hop_size . unwrap_or ( fft_size / 2 ) ;
155-
156- let spectrogram = generate_spectrogram ( & samples, sample_rate, fft_size, hop_size) ;
157-
158- spectrogram. save ( & output_path) . unwrap ( ) ;
159- println ! ( "Spectrogram saved to: {}" , output_path) ;
160- }
161-
162145fn read_wav_samples ( path : & str ) -> Result < ( Vec < f32 > , u32 ) , hound:: Error > {
163146 let reader = WavReader :: open ( path) ?;
164147 let sample_rate = reader. spec ( ) . sample_rate ;
165148 let sample_format = reader. spec ( ) . sample_format ;
166149 let channels = reader. spec ( ) . channels as usize ;
167- println ! ( "Audio spec: {:?}" , reader. spec( ) ) ;
150+ println ! ( "{:?}" , reader. spec( ) ) ;
168151
169152 let mut channel_samples: Vec < Vec < f32 > > = vec ! [ Vec :: new( ) ; channels] ;
170153
@@ -173,7 +156,6 @@ fn read_wav_samples(path: &str) -> Result<(Vec<f32>, u32), hound::Error> {
173156 SampleFormat :: Int => {
174157 let samples: Vec < i32 > = reader. into_samples :: < i32 > ( ) . map ( |s| s. unwrap ( ) ) . collect ( ) ;
175158 let max_value = samples. iter ( ) . fold ( 0 , |a, & b| a. max ( b. abs ( ) ) ) ;
176- println ! ( "Original sample max value: {}" , max_value) ;
177159
178160 // Distribute samples to channels
179161 for ( i, & sample) in samples. iter ( ) . enumerate ( ) {
@@ -214,11 +196,6 @@ fn compute_spectrum(samples: &[f32], fft_size: usize) -> Vec<f32> {
214196 let mut planner = FftPlanner :: new ( ) ;
215197 let fft = planner. plan_fft_forward ( fft_size) ;
216198
217- // // Check input samples
218- // let sample_max = samples.iter().fold(f32::MIN, |a, &b| a.max(b.abs()));
219- // let sample_min = samples.iter().fold(f32::MAX, |a, &b| a.min(b.abs()));
220- // println!("Input sample range: min={}, max={}", sample_min, sample_max);
221-
222199 // 1. Apply Hanning window and convert to complex input
223200 let window: Vec < f32 > = ( 0 ..fft_size)
224201 . map ( |i| {
@@ -236,9 +213,7 @@ fn compute_spectrum(samples: &[f32], fft_size: usize) -> Vec<f32> {
236213 fft. process ( & mut input) ;
237214
238215 // 3. Compute magnitude spectrum
239- let spectrum: Vec < f32 > = input[ ..fft_size / 2 ] . iter ( ) . map ( |c| c. norm ( ) ) . collect ( ) ;
240-
241- spectrum
216+ input[ ..fft_size / 2 ] . iter ( ) . map ( |c| c. norm ( ) ) . collect ( )
242217}
243218
244219fn get_system_font ( ) -> Option < Vec < u8 > > {
@@ -272,7 +247,7 @@ fn generate_spectrogram(
272247 0
273248 } ;
274249 let height = fft_size / 2 ;
275- println ! ( "num_frames: {}, height: {}" , num_frames, height) ;
250+ // println!("num_frames: {}, height: {}", num_frames, height);
276251
277252 // Calculate colorbar position and dimensions
278253 let colorbar_x = margin_left + ( num_frames as u32 ) + 40 ; // Colorbar position
@@ -300,29 +275,6 @@ fn generate_spectrogram(
300275 all_magnitudes. extend ( spectrum) ;
301276 }
302277
303- println ! ( "all_magnitudes len: {}" , all_magnitudes. len( ) ) ;
304-
305- // Calculate logarithmic spectrum values
306- let log_magnitudes: Vec < f32 > = all_magnitudes
307- . iter ( )
308- . map ( |& x| if x > 1e-10 { x. log10 ( ) } else { -10.0 } )
309- . collect ( ) ;
310-
311- let max_magnitude = log_magnitudes. iter ( ) . fold ( f32:: MIN , |a, & b| a. max ( b) ) ;
312- let min_magnitude = log_magnitudes. iter ( ) . fold ( f32:: MAX , |a, & b| a. min ( b) ) ;
313- println ! (
314- "Log spectrum value range: min={}, max={}" ,
315- min_magnitude, max_magnitude
316- ) ;
317-
318- // Check if all spectrum values are zero or very close to zero
319- let non_zero_count = all_magnitudes. iter ( ) . filter ( |& & x| x > 1e-10 ) . count ( ) ;
320- println ! (
321- "Non-zero spectrum value count: {} / {}" ,
322- non_zero_count,
323- all_magnitudes. len( )
324- ) ;
325-
326278 // Draw spectrogram body
327279 for ( x, i) in ( 0 ..num_frames) . enumerate ( ) {
328280 let start = i * hop_size;
@@ -351,14 +303,6 @@ fn generate_spectrogram(
351303 let color = gradient. at ( normalized as f64 ) . to_rgba8 ( ) ;
352304 let y_pos = total_height - margin_bottom - ( y as u32 ) - 1 ;
353305
354- // Check the color value of the first pixel
355- if x == 0 && y == 0 {
356- println ! (
357- "Color mapping - normalized: {}, color: R:{}, G:{}, B:{}" ,
358- normalized, color[ 0 ] , color[ 1 ] , color[ 2 ]
359- ) ;
360- }
361-
362306 // Only draw within valid spectrogram area
363307 if y_pos >= margin_top && y_pos < ( total_height - margin_bottom) {
364308 img. put_pixel (
@@ -627,8 +571,6 @@ fn draw_colorbar_with_scale(
627571 let db_start = db_min;
628572 let db_end = db_max;
629573
630- println ! ( "dB scale range: {} dB to {} dB" , db_start, db_end) ;
631-
632574 // Calculate dB values
633575 let mut db_values: Vec < f32 > = Vec :: new ( ) ;
634576 let mut current_db = db_start;
@@ -669,3 +611,31 @@ fn draw_colorbar_with_scale(
669611 }
670612 }
671613}
614+
615+ fn main ( ) {
616+ println ! ( "Program : {}" , env!( "CARGO_PKG_NAME" ) ) ;
617+ println ! ( "Version : {}" , env!( "CARGO_PKG_VERSION" ) ) ;
618+ println ! ( "Author : {}" , env!( "CARGO_PKG_AUTHORS" ) ) ;
619+ println ! ( "Built : {}" , build_time:: BUILD_TIME ) ;
620+ println ! ( "─────────────────────────────────────────────────" ) ;
621+
622+ let args = Args :: parse ( ) ;
623+
624+ let output_path = args. output . unwrap_or_else ( || {
625+ let input_path = std:: path:: Path :: new ( & args. input ) ;
626+ let stem = input_path. file_stem ( ) . unwrap_or_default ( ) ;
627+ format ! ( "{}.png" , stem. to_string_lossy( ) )
628+ } ) ;
629+
630+ let ( samples, sample_rate) =
631+ read_audio_samples ( & args. input ) . expect ( "Failed to read audio file" ) ;
632+
633+ let fft_size = args. fft_size ;
634+ let hop_size = args. hop_size . unwrap_or ( fft_size / 2 ) ;
635+
636+ println ! ( "Generating spectrogram..." ) ;
637+ let spectrogram = generate_spectrogram ( & samples, sample_rate, fft_size, hop_size) ;
638+
639+ spectrogram. save ( & output_path) . unwrap ( ) ;
640+ println ! ( "Spectrogram saved to: {}" , output_path) ;
641+ }
0 commit comments